mma9551_core.c 21 KB

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