/drivers/staging/iio/accel/adis16240_ring.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2 · C · 152 lines · 120 code · 24 blank · 8 comment · 11 complexity · 8f87dddbcda45d2e3144c17f9860129f MD5 · raw file

  1. #include <linux/interrupt.h>
  2. #include <linux/irq.h>
  3. #include <linux/gpio.h>
  4. #include <linux/workqueue.h>
  5. #include <linux/mutex.h>
  6. #include <linux/device.h>
  7. #include <linux/kernel.h>
  8. #include <linux/spi/spi.h>
  9. #include <linux/slab.h>
  10. #include <linux/sysfs.h>
  11. #include <linux/list.h>
  12. #include "../iio.h"
  13. #include "../sysfs.h"
  14. #include "../ring_sw.h"
  15. #include "accel.h"
  16. #include "../trigger.h"
  17. #include "adis16240.h"
  18. /**
  19. * adis16240_read_ring_data() read data registers which will be placed into ring
  20. * @dev: device associated with child of actual device (iio_dev or iio_trig)
  21. * @rx: somewhere to pass back the value read
  22. **/
  23. static int adis16240_read_ring_data(struct device *dev, u8 *rx)
  24. {
  25. struct spi_message msg;
  26. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  27. struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
  28. struct spi_transfer xfers[ADIS16240_OUTPUTS + 1];
  29. int ret;
  30. int i;
  31. mutex_lock(&st->buf_lock);
  32. spi_message_init(&msg);
  33. memset(xfers, 0, sizeof(xfers));
  34. for (i = 0; i <= ADIS16240_OUTPUTS; i++) {
  35. xfers[i].bits_per_word = 8;
  36. xfers[i].cs_change = 1;
  37. xfers[i].len = 2;
  38. xfers[i].delay_usecs = 30;
  39. xfers[i].tx_buf = st->tx + 2 * i;
  40. st->tx[2 * i]
  41. = ADIS16240_READ_REG(ADIS16240_SUPPLY_OUT + 2 * i);
  42. st->tx[2 * i + 1] = 0;
  43. if (i >= 1)
  44. xfers[i].rx_buf = rx + 2 * (i - 1);
  45. spi_message_add_tail(&xfers[i], &msg);
  46. }
  47. ret = spi_sync(st->us, &msg);
  48. if (ret)
  49. dev_err(&st->us->dev, "problem when burst reading");
  50. mutex_unlock(&st->buf_lock);
  51. return ret;
  52. }
  53. static irqreturn_t adis16240_trigger_handler(int irq, void *p)
  54. {
  55. struct iio_poll_func *pf = p;
  56. struct iio_dev *indio_dev = pf->private_data;
  57. struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
  58. struct iio_ring_buffer *ring = indio_dev->ring;
  59. int i = 0;
  60. s16 *data;
  61. size_t datasize = ring->access->get_bytes_per_datum(ring);
  62. data = kmalloc(datasize, GFP_KERNEL);
  63. if (data == NULL) {
  64. dev_err(&st->us->dev, "memory alloc failed in ring bh");
  65. return -ENOMEM;
  66. }
  67. if (ring->scan_count &&
  68. adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
  69. for (; i < ring->scan_count; i++)
  70. data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
  71. /* Guaranteed to be aligned with 8 byte boundary */
  72. if (ring->scan_timestamp)
  73. *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
  74. ring->access->store_to(ring, (u8 *)data, pf->timestamp);
  75. iio_trigger_notify_done(st->indio_dev->trig);
  76. kfree(data);
  77. return IRQ_HANDLED;
  78. }
  79. void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
  80. {
  81. iio_dealloc_pollfunc(indio_dev->pollfunc);
  82. iio_sw_rb_free(indio_dev->ring);
  83. }
  84. static const struct iio_ring_setup_ops adis16240_ring_setup_ops = {
  85. .preenable = &iio_sw_ring_preenable,
  86. .postenable = &iio_triggered_ring_postenable,
  87. .predisable = &iio_triggered_ring_predisable,
  88. };
  89. int adis16240_configure_ring(struct iio_dev *indio_dev)
  90. {
  91. int ret = 0;
  92. struct iio_ring_buffer *ring;
  93. ring = iio_sw_rb_allocate(indio_dev);
  94. if (!ring) {
  95. ret = -ENOMEM;
  96. return ret;
  97. }
  98. indio_dev->ring = ring;
  99. /* Effectively select the ring buffer implementation */
  100. ring->access = &ring_sw_access_funcs;
  101. ring->bpe = 2;
  102. ring->scan_timestamp = true;
  103. ring->setup_ops = &adis16240_ring_setup_ops;
  104. ring->owner = THIS_MODULE;
  105. /* Set default scan mode */
  106. iio_scan_mask_set(ring, ADIS16240_SCAN_SUPPLY);
  107. iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_X);
  108. iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_Y);
  109. iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_Z);
  110. iio_scan_mask_set(ring, ADIS16240_SCAN_AUX_ADC);
  111. iio_scan_mask_set(ring, ADIS16240_SCAN_TEMP);
  112. indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
  113. &adis16240_trigger_handler,
  114. IRQF_ONESHOT,
  115. indio_dev,
  116. "%s_consumer%d",
  117. indio_dev->name,
  118. indio_dev->id);
  119. if (indio_dev->pollfunc == NULL) {
  120. ret = -ENOMEM;
  121. goto error_iio_sw_rb_free;
  122. }
  123. indio_dev->modes |= INDIO_RING_TRIGGERED;
  124. return 0;
  125. error_iio_sw_rb_free:
  126. iio_sw_rb_free(indio_dev->ring);
  127. return ret;
  128. }