/drivers/staging/iio/accel/adis16204_core.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 611 lines · 509 code · 68 blank · 34 comment · 48 complexity · 22d0480e9d5508c61ab560c61bcc719e MD5 · raw file

  1. /*
  2. * ADIS16204 Programmable High-g Digital Impact Sensor and Recorder
  3. *
  4. * Copyright 2010 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <linux/interrupt.h>
  9. #include <linux/irq.h>
  10. #include <linux/gpio.h>
  11. #include <linux/delay.h>
  12. #include <linux/mutex.h>
  13. #include <linux/device.h>
  14. #include <linux/kernel.h>
  15. #include <linux/spi/spi.h>
  16. #include <linux/slab.h>
  17. #include <linux/sysfs.h>
  18. #include <linux/list.h>
  19. #include "../iio.h"
  20. #include "../sysfs.h"
  21. #include "../ring_generic.h"
  22. #include "accel.h"
  23. #include "../adc/adc.h"
  24. #include "adis16204.h"
  25. #define DRIVER_NAME "adis16204"
  26. /**
  27. * adis16204_spi_write_reg_8() - write single byte to a register
  28. * @dev: device associated with child of actual device (iio_dev or iio_trig)
  29. * @reg_address: the address of the register to be written
  30. * @val: the value to write
  31. **/
  32. static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev,
  33. u8 reg_address,
  34. u8 val)
  35. {
  36. int ret;
  37. struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
  38. mutex_lock(&st->buf_lock);
  39. st->tx[0] = ADIS16204_WRITE_REG(reg_address);
  40. st->tx[1] = val;
  41. ret = spi_write(st->us, st->tx, 2);
  42. mutex_unlock(&st->buf_lock);
  43. return ret;
  44. }
  45. /**
  46. * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers
  47. * @indio_dev: iio device associated with child of actual device
  48. * @reg_address: the address of the lower of the two registers. Second register
  49. * is assumed to have address one greater.
  50. * @val: value to be written
  51. **/
  52. static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev,
  53. u8 lower_reg_address,
  54. u16 value)
  55. {
  56. int ret;
  57. struct spi_message msg;
  58. struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
  59. struct spi_transfer xfers[] = {
  60. {
  61. .tx_buf = st->tx,
  62. .bits_per_word = 8,
  63. .len = 2,
  64. .cs_change = 1,
  65. }, {
  66. .tx_buf = st->tx + 2,
  67. .bits_per_word = 8,
  68. .len = 2,
  69. .cs_change = 1,
  70. },
  71. };
  72. mutex_lock(&st->buf_lock);
  73. st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address);
  74. st->tx[1] = value & 0xFF;
  75. st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1);
  76. st->tx[3] = (value >> 8) & 0xFF;
  77. spi_message_init(&msg);
  78. spi_message_add_tail(&xfers[0], &msg);
  79. spi_message_add_tail(&xfers[1], &msg);
  80. ret = spi_sync(st->us, &msg);
  81. mutex_unlock(&st->buf_lock);
  82. return ret;
  83. }
  84. /**
  85. * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register
  86. * @indio_dev: iio device associated with child of actual device
  87. * @reg_address: the address of the lower of the two registers. Second register
  88. * is assumed to have address one greater.
  89. * @val: somewhere to pass back the value read
  90. **/
  91. static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev,
  92. u8 lower_reg_address,
  93. u16 *val)
  94. {
  95. struct spi_message msg;
  96. struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
  97. int ret;
  98. struct spi_transfer xfers[] = {
  99. {
  100. .tx_buf = st->tx,
  101. .bits_per_word = 8,
  102. .len = 2,
  103. .cs_change = 1,
  104. .delay_usecs = 20,
  105. }, {
  106. .rx_buf = st->rx,
  107. .bits_per_word = 8,
  108. .len = 2,
  109. .delay_usecs = 20,
  110. },
  111. };
  112. mutex_lock(&st->buf_lock);
  113. st->tx[0] = ADIS16204_READ_REG(lower_reg_address);
  114. st->tx[1] = 0;
  115. spi_message_init(&msg);
  116. spi_message_add_tail(&xfers[0], &msg);
  117. spi_message_add_tail(&xfers[1], &msg);
  118. ret = spi_sync(st->us, &msg);
  119. if (ret) {
  120. dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
  121. lower_reg_address);
  122. goto error_ret;
  123. }
  124. *val = (st->rx[0] << 8) | st->rx[1];
  125. error_ret:
  126. mutex_unlock(&st->buf_lock);
  127. return ret;
  128. }
  129. static int adis16204_check_status(struct iio_dev *indio_dev)
  130. {
  131. u16 status;
  132. int ret;
  133. ret = adis16204_spi_read_reg_16(indio_dev,
  134. ADIS16204_DIAG_STAT, &status);
  135. if (ret < 0) {
  136. dev_err(&indio_dev->dev, "Reading status failed\n");
  137. goto error_ret;
  138. }
  139. ret = status & 0x1F;
  140. if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
  141. dev_err(&indio_dev->dev, "Self test failure\n");
  142. if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
  143. dev_err(&indio_dev->dev, "SPI failure\n");
  144. if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
  145. dev_err(&indio_dev->dev, "Flash update failed\n");
  146. if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
  147. dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
  148. if (status & ADIS16204_DIAG_STAT_POWER_LOW)
  149. dev_err(&indio_dev->dev, "Power supply below 2.975V\n");
  150. error_ret:
  151. return ret;
  152. }
  153. static ssize_t adis16204_read_14bit_signed(struct device *dev,
  154. struct device_attribute *attr,
  155. char *buf)
  156. {
  157. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  158. struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
  159. s16 val = 0;
  160. ssize_t ret;
  161. mutex_lock(&indio_dev->mlock);
  162. ret = adis16204_spi_read_reg_16(indio_dev,
  163. this_attr->address, (u16 *)&val);
  164. if (!ret) {
  165. if (val & ADIS16204_ERROR_ACTIVE)
  166. adis16204_check_status(indio_dev);
  167. val = ((s16)(val << 2) >> 2);
  168. ret = sprintf(buf, "%d\n", val);
  169. }
  170. mutex_unlock(&indio_dev->mlock);
  171. return ret;
  172. }
  173. static int adis16204_reset(struct iio_dev *indio_dev)
  174. {
  175. int ret;
  176. ret = adis16204_spi_write_reg_8(indio_dev,
  177. ADIS16204_GLOB_CMD,
  178. ADIS16204_GLOB_CMD_SW_RESET);
  179. if (ret)
  180. dev_err(&indio_dev->dev, "problem resetting device");
  181. return ret;
  182. }
  183. static ssize_t adis16204_write_reset(struct device *dev,
  184. struct device_attribute *attr,
  185. const char *buf, size_t len)
  186. {
  187. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  188. if (len < 1)
  189. return -EINVAL;
  190. switch (buf[0]) {
  191. case '1':
  192. case 'y':
  193. case 'Y':
  194. return adis16204_reset(indio_dev);
  195. }
  196. return -EINVAL;
  197. }
  198. int adis16204_set_irq(struct iio_dev *indio_dev, bool enable)
  199. {
  200. int ret = 0;
  201. u16 msc;
  202. ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc);
  203. if (ret)
  204. goto error_ret;
  205. msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH;
  206. msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2;
  207. if (enable)
  208. msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN;
  209. else
  210. msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN;
  211. ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc);
  212. error_ret:
  213. return ret;
  214. }
  215. static int adis16204_self_test(struct iio_dev *indio_dev)
  216. {
  217. int ret;
  218. ret = adis16204_spi_write_reg_16(indio_dev,
  219. ADIS16204_MSC_CTRL,
  220. ADIS16204_MSC_CTRL_SELF_TEST_EN);
  221. if (ret) {
  222. dev_err(&indio_dev->dev, "problem starting self test");
  223. goto err_ret;
  224. }
  225. adis16204_check_status(indio_dev);
  226. err_ret:
  227. return ret;
  228. }
  229. static int adis16204_initial_setup(struct iio_dev *indio_dev)
  230. {
  231. int ret;
  232. /* Disable IRQ */
  233. ret = adis16204_set_irq(indio_dev, false);
  234. if (ret) {
  235. dev_err(&indio_dev->dev, "disable irq failed");
  236. goto err_ret;
  237. }
  238. /* Do self test */
  239. ret = adis16204_self_test(indio_dev);
  240. if (ret) {
  241. dev_err(&indio_dev->dev, "self test failure");
  242. goto err_ret;
  243. }
  244. /* Read status register to check the result */
  245. ret = adis16204_check_status(indio_dev);
  246. if (ret) {
  247. adis16204_reset(indio_dev);
  248. dev_err(&indio_dev->dev, "device not playing ball -> reset");
  249. msleep(ADIS16204_STARTUP_DELAY);
  250. ret = adis16204_check_status(indio_dev);
  251. if (ret) {
  252. dev_err(&indio_dev->dev, "giving up");
  253. goto err_ret;
  254. }
  255. }
  256. err_ret:
  257. return ret;
  258. }
  259. static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed,
  260. ADIS16204_XY_RSS_OUT);
  261. static IIO_DEV_ATTR_ACCEL_XPEAK(adis16204_read_14bit_signed,
  262. ADIS16204_X_PEAK_OUT);
  263. static IIO_DEV_ATTR_ACCEL_YPEAK(adis16204_read_14bit_signed,
  264. ADIS16204_Y_PEAK_OUT);
  265. static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed,
  266. ADIS16204_XY_PEAK_OUT);
  267. static IIO_CONST_ATTR(accel_xy_scale, "0.017125");
  268. static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0);
  269. enum adis16204_channel {
  270. in_supply,
  271. in_aux,
  272. temp,
  273. accel_x,
  274. accel_y,
  275. };
  276. static u8 adis16204_addresses[5][2] = {
  277. [in_supply] = { ADIS16204_SUPPLY_OUT },
  278. [in_aux] = { ADIS16204_AUX_ADC },
  279. [temp] = { ADIS16204_TEMP_OUT },
  280. [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL },
  281. [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL },
  282. };
  283. static int adis16204_read_raw(struct iio_dev *indio_dev,
  284. struct iio_chan_spec const *chan,
  285. int *val, int *val2,
  286. long mask)
  287. {
  288. int ret;
  289. int bits;
  290. u8 addr;
  291. s16 val16;
  292. switch (mask) {
  293. case 0:
  294. mutex_lock(&indio_dev->mlock);
  295. addr = adis16204_addresses[chan->address][0];
  296. ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
  297. if (ret)
  298. return ret;
  299. if (val16 & ADIS16204_ERROR_ACTIVE) {
  300. ret = adis16204_check_status(indio_dev);
  301. if (ret)
  302. return ret;
  303. }
  304. val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
  305. if (chan->scan_type.sign == 's')
  306. val16 = (s16)(val16 <<
  307. (16 - chan->scan_type.realbits)) >>
  308. (16 - chan->scan_type.realbits);
  309. *val = val16;
  310. mutex_unlock(&indio_dev->mlock);
  311. return IIO_VAL_INT;
  312. case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
  313. switch (chan->type) {
  314. case IIO_IN:
  315. *val = 0;
  316. if (chan->channel == 0)
  317. *val2 = 1220;
  318. else
  319. *val2 = 610;
  320. return IIO_VAL_INT_PLUS_MICRO;
  321. case IIO_TEMP:
  322. *val = 0;
  323. *val2 = -470000;
  324. return IIO_VAL_INT_PLUS_MICRO;
  325. case IIO_ACCEL:
  326. *val = 0;
  327. if (chan->channel == 'x')
  328. *val2 = 17125;
  329. else
  330. *val2 = 8407;
  331. return IIO_VAL_INT_PLUS_MICRO;
  332. default:
  333. return -EINVAL;
  334. }
  335. break;
  336. case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
  337. *val = 25;
  338. return IIO_VAL_INT;
  339. case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
  340. switch (chan->type) {
  341. case IIO_ACCEL:
  342. bits = 12;
  343. break;
  344. default:
  345. return -EINVAL;
  346. };
  347. mutex_lock(&indio_dev->mlock);
  348. addr = adis16204_addresses[chan->address][1];
  349. ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
  350. if (ret) {
  351. mutex_unlock(&indio_dev->mlock);
  352. return ret;
  353. }
  354. val16 &= (1 << bits) - 1;
  355. val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
  356. *val = val16;
  357. mutex_unlock(&indio_dev->mlock);
  358. return IIO_VAL_INT;
  359. }
  360. return -EINVAL;
  361. }
  362. static int adis16204_write_raw(struct iio_dev *indio_dev,
  363. struct iio_chan_spec const *chan,
  364. int val,
  365. int val2,
  366. long mask)
  367. {
  368. int bits;
  369. s16 val16;
  370. u8 addr;
  371. switch (mask) {
  372. case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
  373. switch (chan->type) {
  374. case IIO_ACCEL:
  375. bits = 12;
  376. break;
  377. default:
  378. return -EINVAL;
  379. };
  380. val16 = val & ((1 << bits) - 1);
  381. addr = adis16204_addresses[chan->address][1];
  382. return adis16204_spi_write_reg_16(indio_dev, addr, val16);
  383. }
  384. return -EINVAL;
  385. }
  386. static struct iio_chan_spec adis16204_channels[] = {
  387. IIO_CHAN(IIO_IN, 0, 0, 0, "supply", 0, 0,
  388. (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
  389. in_supply, ADIS16204_SCAN_SUPPLY,
  390. IIO_ST('u', 12, 16, 0), 0),
  391. IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
  392. (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
  393. in_aux, ADIS16204_SCAN_AUX_ADC,
  394. IIO_ST('u', 12, 16, 0), 0),
  395. IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
  396. (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
  397. (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
  398. temp, ADIS16204_SCAN_TEMP,
  399. IIO_ST('u', 12, 16, 0), 0),
  400. IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
  401. (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
  402. (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
  403. accel_x, ADIS16204_SCAN_ACC_X,
  404. IIO_ST('s', 14, 16, 0), 0),
  405. IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
  406. (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
  407. (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
  408. accel_y, ADIS16204_SCAN_ACC_Y,
  409. IIO_ST('s', 14, 16, 0), 0),
  410. IIO_CHAN_SOFT_TIMESTAMP(5),
  411. };
  412. static struct attribute *adis16204_attributes[] = {
  413. &iio_dev_attr_reset.dev_attr.attr,
  414. &iio_dev_attr_accel_xy.dev_attr.attr,
  415. &iio_dev_attr_accel_xpeak.dev_attr.attr,
  416. &iio_dev_attr_accel_ypeak.dev_attr.attr,
  417. &iio_dev_attr_accel_xypeak.dev_attr.attr,
  418. &iio_const_attr_accel_xy_scale.dev_attr.attr,
  419. NULL
  420. };
  421. static const struct attribute_group adis16204_attribute_group = {
  422. .attrs = adis16204_attributes,
  423. };
  424. static const struct iio_info adis16204_info = {
  425. .attrs = &adis16204_attribute_group,
  426. .read_raw = &adis16204_read_raw,
  427. .write_raw = &adis16204_write_raw,
  428. .driver_module = THIS_MODULE,
  429. };
  430. static int __devinit adis16204_probe(struct spi_device *spi)
  431. {
  432. int ret, regdone = 0;
  433. struct adis16204_state *st = kzalloc(sizeof *st, GFP_KERNEL);
  434. if (!st) {
  435. ret = -ENOMEM;
  436. goto error_ret;
  437. }
  438. /* this is only used for removal purposes */
  439. spi_set_drvdata(spi, st);
  440. /* Allocate the comms buffers */
  441. st->rx = kzalloc(sizeof(*st->rx)*ADIS16204_MAX_RX, GFP_KERNEL);
  442. if (st->rx == NULL) {
  443. ret = -ENOMEM;
  444. goto error_free_st;
  445. }
  446. st->tx = kzalloc(sizeof(*st->tx)*ADIS16204_MAX_TX, GFP_KERNEL);
  447. if (st->tx == NULL) {
  448. ret = -ENOMEM;
  449. goto error_free_rx;
  450. }
  451. st->us = spi;
  452. mutex_init(&st->buf_lock);
  453. /* setup the industrialio driver allocated elements */
  454. st->indio_dev = iio_allocate_device(0);
  455. if (st->indio_dev == NULL) {
  456. ret = -ENOMEM;
  457. goto error_free_tx;
  458. }
  459. st->indio_dev->name = spi->dev.driver->name;
  460. st->indio_dev->dev.parent = &spi->dev;
  461. st->indio_dev->info = &adis16204_info;
  462. st->indio_dev->channels = adis16204_channels;
  463. st->indio_dev->num_channels = ARRAY_SIZE(adis16204_channels);
  464. st->indio_dev->dev_data = (void *)(st);
  465. st->indio_dev->modes = INDIO_DIRECT_MODE;
  466. ret = adis16204_configure_ring(st->indio_dev);
  467. if (ret)
  468. goto error_free_dev;
  469. ret = iio_device_register(st->indio_dev);
  470. if (ret)
  471. goto error_unreg_ring_funcs;
  472. regdone = 1;
  473. ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
  474. adis16204_channels,
  475. ARRAY_SIZE(adis16204_channels));
  476. if (ret) {
  477. printk(KERN_ERR "failed to initialize the ring\n");
  478. goto error_unreg_ring_funcs;
  479. }
  480. if (spi->irq) {
  481. ret = adis16204_probe_trigger(st->indio_dev);
  482. if (ret)
  483. goto error_uninitialize_ring;
  484. }
  485. /* Get the device into a sane initial state */
  486. ret = adis16204_initial_setup(st->indio_dev);
  487. if (ret)
  488. goto error_remove_trigger;
  489. return 0;
  490. error_remove_trigger:
  491. adis16204_remove_trigger(st->indio_dev);
  492. error_uninitialize_ring:
  493. iio_ring_buffer_unregister(st->indio_dev->ring);
  494. error_unreg_ring_funcs:
  495. adis16204_unconfigure_ring(st->indio_dev);
  496. error_free_dev:
  497. if (regdone)
  498. iio_device_unregister(st->indio_dev);
  499. else
  500. iio_free_device(st->indio_dev);
  501. error_free_tx:
  502. kfree(st->tx);
  503. error_free_rx:
  504. kfree(st->rx);
  505. error_free_st:
  506. kfree(st);
  507. error_ret:
  508. return ret;
  509. }
  510. static int adis16204_remove(struct spi_device *spi)
  511. {
  512. struct adis16204_state *st = spi_get_drvdata(spi);
  513. struct iio_dev *indio_dev = st->indio_dev;
  514. adis16204_remove_trigger(indio_dev);
  515. iio_ring_buffer_unregister(st->indio_dev->ring);
  516. iio_device_unregister(indio_dev);
  517. adis16204_unconfigure_ring(indio_dev);
  518. kfree(st->tx);
  519. kfree(st->rx);
  520. kfree(st);
  521. return 0;
  522. }
  523. static struct spi_driver adis16204_driver = {
  524. .driver = {
  525. .name = "adis16204",
  526. .owner = THIS_MODULE,
  527. },
  528. .probe = adis16204_probe,
  529. .remove = __devexit_p(adis16204_remove),
  530. };
  531. static __init int adis16204_init(void)
  532. {
  533. return spi_register_driver(&adis16204_driver);
  534. }
  535. module_init(adis16204_init);
  536. static __exit void adis16204_exit(void)
  537. {
  538. spi_unregister_driver(&adis16204_driver);
  539. }
  540. module_exit(adis16204_exit);
  541. MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
  542. MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder");
  543. MODULE_LICENSE("GPL v2");