mma9551_core.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. /*
  2. * Common code for Freescale MMA955x Intelligent Sensor Platform drivers
  3. * Copyright (c) 2014, Intel Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms and conditions of the GNU General Public License,
  7. * version 2, as published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/i2c.h>
  16. #include <linux/delay.h>
  17. #include <linux/iio/iio.h>
  18. #include <linux/pm_runtime.h>
  19. #include "mma9551_core.h"
  20. /* Command masks for mailbox write command */
  21. #define MMA9551_CMD_READ_VERSION_INFO 0x00
  22. #define MMA9551_CMD_READ_CONFIG 0x10
  23. #define MMA9551_CMD_WRITE_CONFIG 0x20
  24. #define MMA9551_CMD_READ_STATUS 0x30
  25. /* Mailbox read command */
  26. #define MMA9551_RESPONSE_COCO BIT(7)
  27. /* Error-Status codes returned in mailbox read command */
  28. #define MMA9551_MCI_ERROR_NONE 0x00
  29. #define MMA9551_MCI_ERROR_PARAM 0x04
  30. #define MMA9551_MCI_INVALID_COUNT 0x19
  31. #define MMA9551_MCI_ERROR_COMMAND 0x1C
  32. #define MMA9551_MCI_ERROR_INVALID_LENGTH 0x21
  33. #define MMA9551_MCI_ERROR_FIFO_BUSY 0x22
  34. #define MMA9551_MCI_ERROR_FIFO_ALLOCATED 0x23
  35. #define MMA9551_MCI_ERROR_FIFO_OVERSIZE 0x24
  36. /* GPIO Application */
  37. #define MMA9551_GPIO_POL_MSB 0x08
  38. #define MMA9551_GPIO_POL_LSB 0x09
  39. /* Sleep/Wake application */
  40. #define MMA9551_SLEEP_CFG 0x06
  41. #define MMA9551_SLEEP_CFG_SNCEN BIT(0)
  42. #define MMA9551_SLEEP_CFG_FLEEN BIT(1)
  43. #define MMA9551_SLEEP_CFG_SCHEN BIT(2)
  44. /* AFE application */
  45. #define MMA9551_AFE_X_ACCEL_REG 0x00
  46. #define MMA9551_AFE_Y_ACCEL_REG 0x02
  47. #define MMA9551_AFE_Z_ACCEL_REG 0x04
  48. /* Reset/Suspend/Clear application */
  49. #define MMA9551_RSC_RESET 0x00
  50. #define MMA9551_RSC_OFFSET(mask) (3 - (ffs(mask) - 1) / 8)
  51. #define MMA9551_RSC_VAL(mask) (mask >> (((ffs(mask) - 1) / 8) * 8))
  52. /*
  53. * A response is composed of:
  54. * - control registers: MB0-3
  55. * - data registers: MB4-31
  56. *
  57. * A request is composed of:
  58. * - mbox to write to (always 0)
  59. * - control registers: MB1-4
  60. * - data registers: MB5-31
  61. */
  62. #define MMA9551_MAILBOX_CTRL_REGS 4
  63. #define MMA9551_MAX_MAILBOX_DATA_REGS 28
  64. #define MMA9551_MAILBOX_REGS 32
  65. #define MMA9551_I2C_READ_RETRIES 5
  66. #define MMA9551_I2C_READ_DELAY 50 /* us */
  67. struct mma9551_mbox_request {
  68. u8 start_mbox; /* Always 0. */
  69. u8 app_id;
  70. /*
  71. * See Section 5.3.1 of the MMA955xL Software Reference Manual.
  72. *
  73. * Bit 7: reserved, always 0
  74. * Bits 6-4: command
  75. * Bits 3-0: upper bits of register offset
  76. */
  77. u8 cmd_off;
  78. u8 lower_off;
  79. u8 nbytes;
  80. u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS - 1];
  81. } __packed;
  82. struct mma9551_mbox_response {
  83. u8 app_id;
  84. /*
  85. * See Section 5.3.3 of the MMA955xL Software Reference Manual.
  86. *
  87. * Bit 7: COCO
  88. * Bits 6-0: Error code.
  89. */
  90. u8 coco_err;
  91. u8 nbytes;
  92. u8 req_bytes;
  93. u8 buf[MMA9551_MAX_MAILBOX_DATA_REGS];
  94. } __packed;
  95. struct mma9551_version_info {
  96. __be32 device_id;
  97. u8 rom_version[2];
  98. u8 fw_version[2];
  99. u8 hw_version[2];
  100. u8 fw_build[2];
  101. };
  102. static int mma9551_transfer(struct i2c_client *client,
  103. u8 app_id, u8 command, u16 offset,
  104. u8 *inbytes, int num_inbytes,
  105. u8 *outbytes, int num_outbytes)
  106. {
  107. struct mma9551_mbox_request req;
  108. struct mma9551_mbox_response rsp;
  109. struct i2c_msg in, out;
  110. u8 req_len, err_code;
  111. int ret, retries;
  112. if (offset >= 1 << 12) {
  113. dev_err(&client->dev, "register offset too large\n");
  114. return -EINVAL;
  115. }
  116. req_len = 1 + MMA9551_MAILBOX_CTRL_REGS + num_inbytes;
  117. req.start_mbox = 0;
  118. req.app_id = app_id;
  119. req.cmd_off = command | (offset >> 8);
  120. req.lower_off = offset;
  121. if (command == MMA9551_CMD_WRITE_CONFIG)
  122. req.nbytes = num_inbytes;
  123. else
  124. req.nbytes = num_outbytes;
  125. if (num_inbytes)
  126. memcpy(req.buf, inbytes, num_inbytes);
  127. out.addr = client->addr;
  128. out.flags = 0;
  129. out.len = req_len;
  130. out.buf = (u8 *)&req;
  131. ret = i2c_transfer(client->adapter, &out, 1);
  132. if (ret < 0) {
  133. dev_err(&client->dev, "i2c write failed\n");
  134. return ret;
  135. }
  136. retries = MMA9551_I2C_READ_RETRIES;
  137. do {
  138. udelay(MMA9551_I2C_READ_DELAY);
  139. in.addr = client->addr;
  140. in.flags = I2C_M_RD;
  141. in.len = sizeof(rsp);
  142. in.buf = (u8 *)&rsp;
  143. ret = i2c_transfer(client->adapter, &in, 1);
  144. if (ret < 0) {
  145. dev_err(&client->dev, "i2c read failed\n");
  146. return ret;
  147. }
  148. if (rsp.coco_err & MMA9551_RESPONSE_COCO)
  149. break;
  150. } while (--retries > 0);
  151. if (retries == 0) {
  152. dev_err(&client->dev,
  153. "timed out while waiting for command response\n");
  154. return -ETIMEDOUT;
  155. }
  156. if (rsp.app_id != app_id) {
  157. dev_err(&client->dev,
  158. "app_id mismatch in response got %02x expected %02x\n",
  159. rsp.app_id, app_id);
  160. return -EINVAL;
  161. }
  162. err_code = rsp.coco_err & ~MMA9551_RESPONSE_COCO;
  163. if (err_code != MMA9551_MCI_ERROR_NONE) {
  164. dev_err(&client->dev, "read returned error %x\n", err_code);
  165. return -EINVAL;
  166. }
  167. if (rsp.nbytes != rsp.req_bytes) {
  168. dev_err(&client->dev,
  169. "output length mismatch got %d expected %d\n",
  170. rsp.nbytes, rsp.req_bytes);
  171. return -EINVAL;
  172. }
  173. if (num_outbytes)
  174. memcpy(outbytes, rsp.buf, num_outbytes);
  175. return 0;
  176. }
  177. /**
  178. * mma9551_read_config_byte() - read 1 configuration byte
  179. * @client: I2C client
  180. * @app_id: Application ID
  181. * @reg: Application register
  182. * @val: Pointer to store value read
  183. *
  184. * Read one configuration byte from the device using MMA955xL command format.
  185. * Commands to the MMA955xL platform consist of a write followed
  186. * by one or more reads.
  187. *
  188. * Locking note: This function must be called with the device lock held.
  189. * Locking is not handled inside the function. Callers should ensure they
  190. * serialize access to the HW.
  191. *
  192. * Returns: 0 on success, negative value on failure.
  193. */
  194. int mma9551_read_config_byte(struct i2c_client *client, u8 app_id,
  195. u16 reg, u8 *val)
  196. {
  197. return mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
  198. reg, NULL, 0, val, 1);
  199. }
  200. EXPORT_SYMBOL(mma9551_read_config_byte);
  201. /**
  202. * mma9551_write_config_byte() - write 1 configuration byte
  203. * @client: I2C client
  204. * @app_id: Application ID
  205. * @reg: Application register
  206. * @val: Value to write
  207. *
  208. * Write one configuration byte from the device using MMA955xL command format.
  209. * Commands to the MMA955xL platform consist of a write followed by one or
  210. * more reads.
  211. *
  212. * Locking note: This function must be called with the device lock held.
  213. * Locking is not handled inside the function. Callers should ensure they
  214. * serialize access to the HW.
  215. *
  216. * Returns: 0 on success, negative value on failure.
  217. */
  218. int mma9551_write_config_byte(struct i2c_client *client, u8 app_id,
  219. u16 reg, u8 val)
  220. {
  221. return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
  222. &val, 1, NULL, 0);
  223. }
  224. EXPORT_SYMBOL(mma9551_write_config_byte);
  225. /**
  226. * mma9551_read_status_byte() - read 1 status byte
  227. * @client: I2C client
  228. * @app_id: Application ID
  229. * @reg: Application register
  230. * @val: Pointer to store value read
  231. *
  232. * Read one status byte from the device using MMA955xL command format.
  233. * Commands to the MMA955xL platform consist of a write followed by one or
  234. * more reads.
  235. *
  236. * Locking note: This function must be called with the device lock held.
  237. * Locking is not handled inside the function. Callers should ensure they
  238. * serialize access to the HW.
  239. *
  240. * Returns: 0 on success, negative value on failure.
  241. */
  242. int mma9551_read_status_byte(struct i2c_client *client, u8 app_id,
  243. u16 reg, u8 *val)
  244. {
  245. return mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
  246. reg, NULL, 0, val, 1);
  247. }
  248. EXPORT_SYMBOL(mma9551_read_status_byte);
  249. /**
  250. * mma9551_read_config_word() - read 1 config word
  251. * @client: I2C client
  252. * @app_id: Application ID
  253. * @reg: Application register
  254. * @val: Pointer to store value read
  255. *
  256. * Read one configuration word from the device using MMA955xL command format.
  257. * Commands to the MMA955xL platform consist of a write followed by one or
  258. * more reads.
  259. *
  260. * Locking note: This function must be called with the device lock held.
  261. * Locking is not handled inside the function. Callers should ensure they
  262. * serialize access to the HW.
  263. *
  264. * Returns: 0 on success, negative value on failure.
  265. */
  266. int mma9551_read_config_word(struct i2c_client *client, u8 app_id,
  267. u16 reg, u16 *val)
  268. {
  269. int ret;
  270. __be16 v;
  271. ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
  272. reg, NULL, 0, (u8 *)&v, 2);
  273. *val = be16_to_cpu(v);
  274. return ret;
  275. }
  276. EXPORT_SYMBOL(mma9551_read_config_word);
  277. /**
  278. * mma9551_write_config_word() - write 1 config word
  279. * @client: I2C client
  280. * @app_id: Application ID
  281. * @reg: Application register
  282. * @val: Value to write
  283. *
  284. * Write one configuration word from the device using MMA955xL command format.
  285. * Commands to the MMA955xL platform consist of a write followed by one or
  286. * more reads.
  287. *
  288. * Locking note: This function must be called with the device lock held.
  289. * Locking is not handled inside the function. Callers should ensure they
  290. * serialize access to the HW.
  291. *
  292. * Returns: 0 on success, negative value on failure.
  293. */
  294. int mma9551_write_config_word(struct i2c_client *client, u8 app_id,
  295. u16 reg, u16 val)
  296. {
  297. __be16 v = cpu_to_be16(val);
  298. return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG, reg,
  299. (u8 *)&v, 2, NULL, 0);
  300. }
  301. EXPORT_SYMBOL(mma9551_write_config_word);
  302. /**
  303. * mma9551_read_status_word() - read 1 status word
  304. * @client: I2C client
  305. * @app_id: Application ID
  306. * @reg: Application register
  307. * @val: Pointer to store value read
  308. *
  309. * Read one status word from the device using MMA955xL command format.
  310. * Commands to the MMA955xL platform consist of a write followed by one or
  311. * more reads.
  312. *
  313. * Locking note: This function must be called with the device lock held.
  314. * Locking is not handled inside the function. Callers should ensure they
  315. * serialize access to the HW.
  316. *
  317. * Returns: 0 on success, negative value on failure.
  318. */
  319. int mma9551_read_status_word(struct i2c_client *client, u8 app_id,
  320. u16 reg, u16 *val)
  321. {
  322. int ret;
  323. __be16 v;
  324. ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
  325. reg, NULL, 0, (u8 *)&v, 2);
  326. *val = be16_to_cpu(v);
  327. return ret;
  328. }
  329. EXPORT_SYMBOL(mma9551_read_status_word);
  330. /**
  331. * mma9551_read_config_words() - read multiple config words
  332. * @client: I2C client
  333. * @app_id: Application ID
  334. * @reg: Application register
  335. * @len: Length of array to read (in words)
  336. * @buf: Array of words to read
  337. *
  338. * Read multiple configuration registers (word-sized registers).
  339. *
  340. * Locking note: This function must be called with the device lock held.
  341. * Locking is not handled inside the function. Callers should ensure they
  342. * serialize access to the HW.
  343. *
  344. * Returns: 0 on success, negative value on failure.
  345. */
  346. int mma9551_read_config_words(struct i2c_client *client, u8 app_id,
  347. u16 reg, u8 len, u16 *buf)
  348. {
  349. int ret, i;
  350. __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
  351. if (len > ARRAY_SIZE(be_buf)) {
  352. dev_err(&client->dev, "Invalid buffer size %d\n", len);
  353. return -EINVAL;
  354. }
  355. ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_CONFIG,
  356. reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
  357. if (ret < 0)
  358. return ret;
  359. for (i = 0; i < len; i++)
  360. buf[i] = be16_to_cpu(be_buf[i]);
  361. return 0;
  362. }
  363. EXPORT_SYMBOL(mma9551_read_config_words);
  364. /**
  365. * mma9551_read_status_words() - read multiple status words
  366. * @client: I2C client
  367. * @app_id: Application ID
  368. * @reg: Application register
  369. * @len: Length of array to read (in words)
  370. * @buf: Array of words to read
  371. *
  372. * Read multiple status registers (word-sized registers).
  373. *
  374. * Locking note: This function must be called with the device lock held.
  375. * Locking is not handled inside the function. Callers should ensure they
  376. * serialize access to the HW.
  377. *
  378. * Returns: 0 on success, negative value on failure.
  379. */
  380. int mma9551_read_status_words(struct i2c_client *client, u8 app_id,
  381. u16 reg, u8 len, u16 *buf)
  382. {
  383. int ret, i;
  384. __be16 be_buf[MMA9551_MAX_MAILBOX_DATA_REGS / 2];
  385. if (len > ARRAY_SIZE(be_buf)) {
  386. dev_err(&client->dev, "Invalid buffer size %d\n", len);
  387. return -EINVAL;
  388. }
  389. ret = mma9551_transfer(client, app_id, MMA9551_CMD_READ_STATUS,
  390. reg, NULL, 0, (u8 *)be_buf, len * sizeof(u16));
  391. if (ret < 0)
  392. return ret;
  393. for (i = 0; i < len; i++)
  394. buf[i] = be16_to_cpu(be_buf[i]);
  395. return 0;
  396. }
  397. EXPORT_SYMBOL(mma9551_read_status_words);
  398. /**
  399. * mma9551_write_config_words() - write multiple config words
  400. * @client: I2C client
  401. * @app_id: Application ID
  402. * @reg: Application register
  403. * @len: Length of array to write (in words)
  404. * @buf: Array of words to write
  405. *
  406. * Write multiple configuration registers (word-sized registers).
  407. *
  408. * Locking note: This function must be called with the device lock held.
  409. * Locking is not handled inside the function. Callers should ensure they
  410. * serialize access to the HW.
  411. *
  412. * Returns: 0 on success, negative value on failure.
  413. */
  414. int mma9551_write_config_words(struct i2c_client *client, u8 app_id,
  415. u16 reg, u8 len, u16 *buf)
  416. {
  417. int i;
  418. __be16 be_buf[(MMA9551_MAX_MAILBOX_DATA_REGS - 1) / 2];
  419. if (len > ARRAY_SIZE(be_buf)) {
  420. dev_err(&client->dev, "Invalid buffer size %d\n", len);
  421. return -EINVAL;
  422. }
  423. for (i = 0; i < len; i++)
  424. be_buf[i] = cpu_to_be16(buf[i]);
  425. return mma9551_transfer(client, app_id, MMA9551_CMD_WRITE_CONFIG,
  426. reg, (u8 *)be_buf, len * sizeof(u16), NULL, 0);
  427. }
  428. EXPORT_SYMBOL(mma9551_write_config_words);
  429. /**
  430. * mma9551_update_config_bits() - update bits in register
  431. * @client: I2C client
  432. * @app_id: Application ID
  433. * @reg: Application register
  434. * @mask: Mask for the bits to update
  435. * @val: Value of the bits to update
  436. *
  437. * Update bits in the given register using a bit mask.
  438. *
  439. * Locking note: This function must be called with the device lock held.
  440. * Locking is not handled inside the function. Callers should ensure they
  441. * serialize access to the HW.
  442. *
  443. * Returns: 0 on success, negative value on failure.
  444. */
  445. int mma9551_update_config_bits(struct i2c_client *client, u8 app_id,
  446. u16 reg, u8 mask, u8 val)
  447. {
  448. int ret;
  449. u8 tmp, orig;
  450. ret = mma9551_read_config_byte(client, app_id, reg, &orig);
  451. if (ret < 0)
  452. return ret;
  453. tmp = orig & ~mask;
  454. tmp |= val & mask;
  455. if (tmp == orig)
  456. return 0;
  457. return mma9551_write_config_byte(client, app_id, reg, tmp);
  458. }
  459. EXPORT_SYMBOL(mma9551_update_config_bits);
  460. /**
  461. * mma9551_gpio_config() - configure gpio
  462. * @client: I2C client
  463. * @pin: GPIO pin to configure
  464. * @app_id: Application ID
  465. * @bitnum: Bit number of status register being assigned to the GPIO pin.
  466. * @polarity: The polarity parameter is described in section 6.2.2, page 66,
  467. * of the Software Reference Manual. Basically, polarity=0 means
  468. * the interrupt line has the same value as the selected bit,
  469. * while polarity=1 means the line is inverted.
  470. *
  471. * Assign a bit from an application’s status register to a specific GPIO pin.
  472. *
  473. * Locking note: This function must be called with the device lock held.
  474. * Locking is not handled inside the function. Callers should ensure they
  475. * serialize access to the HW.
  476. *
  477. * Returns: 0 on success, negative value on failure.
  478. */
  479. int mma9551_gpio_config(struct i2c_client *client, enum mma9551_gpio_pin pin,
  480. u8 app_id, u8 bitnum, int polarity)
  481. {
  482. u8 reg, pol_mask, pol_val;
  483. int ret;
  484. if (pin > mma9551_gpio_max) {
  485. dev_err(&client->dev, "bad GPIO pin\n");
  486. return -EINVAL;
  487. }
  488. /*
  489. * Pin 6 is configured by regs 0x00 and 0x01, pin 7 by 0x02 and
  490. * 0x03, and so on.
  491. */
  492. reg = pin * 2;
  493. ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
  494. reg, app_id);
  495. if (ret < 0) {
  496. dev_err(&client->dev, "error setting GPIO app_id\n");
  497. return ret;
  498. }
  499. ret = mma9551_write_config_byte(client, MMA9551_APPID_GPIO,
  500. reg + 1, bitnum);
  501. if (ret < 0) {
  502. dev_err(&client->dev, "error setting GPIO bit number\n");
  503. return ret;
  504. }
  505. switch (pin) {
  506. case mma9551_gpio6:
  507. reg = MMA9551_GPIO_POL_LSB;
  508. pol_mask = 1 << 6;
  509. break;
  510. case mma9551_gpio7:
  511. reg = MMA9551_GPIO_POL_LSB;
  512. pol_mask = 1 << 7;
  513. break;
  514. case mma9551_gpio8:
  515. reg = MMA9551_GPIO_POL_MSB;
  516. pol_mask = 1 << 0;
  517. break;
  518. case mma9551_gpio9:
  519. reg = MMA9551_GPIO_POL_MSB;
  520. pol_mask = 1 << 1;
  521. break;
  522. }
  523. pol_val = polarity ? pol_mask : 0;
  524. ret = mma9551_update_config_bits(client, MMA9551_APPID_GPIO, reg,
  525. pol_mask, pol_val);
  526. if (ret < 0)
  527. dev_err(&client->dev, "error setting GPIO polarity\n");
  528. return ret;
  529. }
  530. EXPORT_SYMBOL(mma9551_gpio_config);
  531. /**
  532. * mma9551_read_version() - read device version information
  533. * @client: I2C client
  534. *
  535. * Read version information and print device id and firmware version.
  536. *
  537. * Locking note: This function must be called with the device lock held.
  538. * Locking is not handled inside the function. Callers should ensure they
  539. * serialize access to the HW.
  540. *
  541. * Returns: 0 on success, negative value on failure.
  542. */
  543. int mma9551_read_version(struct i2c_client *client)
  544. {
  545. struct mma9551_version_info info;
  546. int ret;
  547. ret = mma9551_transfer(client, MMA9551_APPID_VERSION, 0x00, 0x00,
  548. NULL, 0, (u8 *)&info, sizeof(info));
  549. if (ret < 0)
  550. return ret;
  551. dev_info(&client->dev, "device ID 0x%x, firmware version %02x.%02x\n",
  552. be32_to_cpu(info.device_id), info.fw_version[0],
  553. info.fw_version[1]);
  554. return 0;
  555. }
  556. EXPORT_SYMBOL(mma9551_read_version);
  557. /**
  558. * mma9551_set_device_state() - sets HW power mode
  559. * @client: I2C client
  560. * @enable: Use true to power on device, false to cause the device
  561. * to enter sleep.
  562. *
  563. * Set power on/off for device using the Sleep/Wake Application.
  564. * When enable is true, power on chip and enable doze mode.
  565. * When enable is false, enter sleep mode (device remains in the
  566. * lowest-power mode).
  567. *
  568. * Locking note: This function must be called with the device lock held.
  569. * Locking is not handled inside the function. Callers should ensure they
  570. * serialize access to the HW.
  571. *
  572. * Returns: 0 on success, negative value on failure.
  573. */
  574. int mma9551_set_device_state(struct i2c_client *client, bool enable)
  575. {
  576. return mma9551_update_config_bits(client, MMA9551_APPID_SLEEP_WAKE,
  577. MMA9551_SLEEP_CFG,
  578. MMA9551_SLEEP_CFG_SNCEN |
  579. MMA9551_SLEEP_CFG_FLEEN |
  580. MMA9551_SLEEP_CFG_SCHEN,
  581. enable ? MMA9551_SLEEP_CFG_SCHEN |
  582. MMA9551_SLEEP_CFG_FLEEN :
  583. MMA9551_SLEEP_CFG_SNCEN);
  584. }
  585. EXPORT_SYMBOL(mma9551_set_device_state);
  586. /**
  587. * mma9551_set_power_state() - sets runtime PM state
  588. * @client: I2C client
  589. * @on: Use true to power on device, false to power off
  590. *
  591. * Resume or suspend the device using Runtime PM.
  592. * The device will suspend after the autosuspend delay.
  593. *
  594. * Returns: 0 on success, negative value on failure.
  595. */
  596. int mma9551_set_power_state(struct i2c_client *client, bool on)
  597. {
  598. #ifdef CONFIG_PM
  599. int ret;
  600. if (on)
  601. ret = pm_runtime_get_sync(&client->dev);
  602. else {
  603. pm_runtime_mark_last_busy(&client->dev);
  604. ret = pm_runtime_put_autosuspend(&client->dev);
  605. }
  606. if (ret < 0) {
  607. dev_err(&client->dev,
  608. "failed to change power state to %d\n", on);
  609. if (on)
  610. pm_runtime_put_noidle(&client->dev);
  611. return ret;
  612. }
  613. #endif
  614. return 0;
  615. }
  616. EXPORT_SYMBOL(mma9551_set_power_state);
  617. /**
  618. * mma9551_sleep() - sleep
  619. * @freq: Application frequency
  620. *
  621. * Firmware applications run at a certain frequency on the
  622. * device. Sleep for one application cycle to make sure the
  623. * application had time to run once and initialize set values.
  624. */
  625. void mma9551_sleep(int freq)
  626. {
  627. int sleep_val = 1000 / freq;
  628. if (sleep_val < 20)
  629. usleep_range(sleep_val * 1000, 20000);
  630. else
  631. msleep_interruptible(sleep_val);
  632. }
  633. EXPORT_SYMBOL(mma9551_sleep);
  634. /**
  635. * mma9551_read_accel_chan() - read accelerometer channel
  636. * @client: I2C client
  637. * @chan: IIO channel
  638. * @val: Pointer to the accelerometer value read
  639. * @val2: Unused
  640. *
  641. * Read accelerometer value for the specified channel.
  642. *
  643. * Locking note: This function must be called with the device lock held.
  644. * Locking is not handled inside the function. Callers should ensure they
  645. * serialize access to the HW.
  646. *
  647. * Returns: IIO_VAL_INT on success, negative value on failure.
  648. */
  649. int mma9551_read_accel_chan(struct i2c_client *client,
  650. const struct iio_chan_spec *chan,
  651. int *val, int *val2)
  652. {
  653. u16 reg_addr;
  654. s16 raw_accel;
  655. int ret;
  656. switch (chan->channel2) {
  657. case IIO_MOD_X:
  658. reg_addr = MMA9551_AFE_X_ACCEL_REG;
  659. break;
  660. case IIO_MOD_Y:
  661. reg_addr = MMA9551_AFE_Y_ACCEL_REG;
  662. break;
  663. case IIO_MOD_Z:
  664. reg_addr = MMA9551_AFE_Z_ACCEL_REG;
  665. break;
  666. default:
  667. return -EINVAL;
  668. }
  669. ret = mma9551_set_power_state(client, true);
  670. if (ret < 0)
  671. return ret;
  672. ret = mma9551_read_status_word(client, MMA9551_APPID_AFE,
  673. reg_addr, &raw_accel);
  674. if (ret < 0)
  675. goto out_poweroff;
  676. *val = raw_accel;
  677. ret = IIO_VAL_INT;
  678. out_poweroff:
  679. mma9551_set_power_state(client, false);
  680. return ret;
  681. }
  682. EXPORT_SYMBOL(mma9551_read_accel_chan);
  683. /**
  684. * mma9551_read_accel_scale() - read accelerometer scale
  685. * @val: Pointer to the accelerometer scale (int value)
  686. * @val2: Pointer to the accelerometer scale (micro value)
  687. *
  688. * Read accelerometer scale.
  689. *
  690. * Returns: IIO_VAL_INT_PLUS_MICRO.
  691. */
  692. int mma9551_read_accel_scale(int *val, int *val2)
  693. {
  694. *val = 0;
  695. *val2 = 2440;
  696. return IIO_VAL_INT_PLUS_MICRO;
  697. }
  698. EXPORT_SYMBOL(mma9551_read_accel_scale);
  699. /**
  700. * mma9551_app_reset() - reset application
  701. * @client: I2C client
  702. * @app_mask: Application to reset
  703. *
  704. * Reset the given application (using the Reset/Suspend/Clear
  705. * Control Application)
  706. *
  707. * Returns: 0 on success, negative value on failure.
  708. */
  709. int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
  710. {
  711. return mma9551_write_config_byte(client, MMA9551_APPID_RSC,
  712. MMA9551_RSC_RESET +
  713. MMA9551_RSC_OFFSET(app_mask),
  714. MMA9551_RSC_VAL(app_mask));
  715. }
  716. EXPORT_SYMBOL(mma9551_app_reset);
  717. MODULE_AUTHOR("Irina Tirdea <irina.tirdea@intel.com>");
  718. MODULE_AUTHOR("Vlad Dogaru <vlad.dogaru@intel.com>");
  719. MODULE_LICENSE("GPL v2");
  720. MODULE_DESCRIPTION("MMA955xL sensors core");