inv_mpu_ring.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright (C) 2012 Invensense, Inc.
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/module.h>
  14. #include <linux/slab.h>
  15. #include <linux/i2c.h>
  16. #include <linux/err.h>
  17. #include <linux/delay.h>
  18. #include <linux/sysfs.h>
  19. #include <linux/jiffies.h>
  20. #include <linux/irq.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/kfifo.h>
  23. #include <linux/poll.h>
  24. #include "inv_mpu_iio.h"
  25. static void inv_clear_kfifo(struct inv_mpu6050_state *st)
  26. {
  27. unsigned long flags;
  28. /* take the spin lock sem to avoid interrupt kick in */
  29. spin_lock_irqsave(&st->time_stamp_lock, flags);
  30. kfifo_reset(&st->timestamps);
  31. spin_unlock_irqrestore(&st->time_stamp_lock, flags);
  32. }
  33. int inv_reset_fifo(struct iio_dev *indio_dev)
  34. {
  35. int result;
  36. u8 d;
  37. struct inv_mpu6050_state *st = iio_priv(indio_dev);
  38. /* disable interrupt */
  39. result = inv_mpu6050_write_reg(st, st->reg->int_enable, 0);
  40. if (result) {
  41. dev_err(&st->client->dev, "int_enable failed %d\n", result);
  42. return result;
  43. }
  44. /* disable the sensor output to FIFO */
  45. result = inv_mpu6050_write_reg(st, st->reg->fifo_en, 0);
  46. if (result)
  47. goto reset_fifo_fail;
  48. /* disable fifo reading */
  49. result = inv_mpu6050_write_reg(st, st->reg->user_ctrl, 0);
  50. if (result)
  51. goto reset_fifo_fail;
  52. /* reset FIFO*/
  53. result = inv_mpu6050_write_reg(st, st->reg->user_ctrl,
  54. INV_MPU6050_BIT_FIFO_RST);
  55. if (result)
  56. goto reset_fifo_fail;
  57. /* clear timestamps fifo */
  58. inv_clear_kfifo(st);
  59. /* enable interrupt */
  60. if (st->chip_config.accl_fifo_enable ||
  61. st->chip_config.gyro_fifo_enable) {
  62. result = inv_mpu6050_write_reg(st, st->reg->int_enable,
  63. INV_MPU6050_BIT_DATA_RDY_EN);
  64. if (result)
  65. return result;
  66. }
  67. /* enable FIFO reading and I2C master interface*/
  68. result = inv_mpu6050_write_reg(st, st->reg->user_ctrl,
  69. INV_MPU6050_BIT_FIFO_EN);
  70. if (result)
  71. goto reset_fifo_fail;
  72. /* enable sensor output to FIFO */
  73. d = 0;
  74. if (st->chip_config.gyro_fifo_enable)
  75. d |= INV_MPU6050_BITS_GYRO_OUT;
  76. if (st->chip_config.accl_fifo_enable)
  77. d |= INV_MPU6050_BIT_ACCEL_OUT;
  78. result = inv_mpu6050_write_reg(st, st->reg->fifo_en, d);
  79. if (result)
  80. goto reset_fifo_fail;
  81. return 0;
  82. reset_fifo_fail:
  83. dev_err(&st->client->dev, "reset fifo failed %d\n", result);
  84. result = inv_mpu6050_write_reg(st, st->reg->int_enable,
  85. INV_MPU6050_BIT_DATA_RDY_EN);
  86. return result;
  87. }
  88. /**
  89. * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
  90. */
  91. irqreturn_t inv_mpu6050_irq_handler(int irq, void *p)
  92. {
  93. struct iio_poll_func *pf = p;
  94. struct iio_dev *indio_dev = pf->indio_dev;
  95. struct inv_mpu6050_state *st = iio_priv(indio_dev);
  96. s64 timestamp;
  97. timestamp = iio_get_time_ns();
  98. kfifo_in_spinlocked(&st->timestamps, &timestamp, 1,
  99. &st->time_stamp_lock);
  100. return IRQ_WAKE_THREAD;
  101. }
  102. /**
  103. * inv_mpu6050_read_fifo() - Transfer data from hardware FIFO to KFIFO.
  104. */
  105. irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
  106. {
  107. struct iio_poll_func *pf = p;
  108. struct iio_dev *indio_dev = pf->indio_dev;
  109. struct inv_mpu6050_state *st = iio_priv(indio_dev);
  110. size_t bytes_per_datum;
  111. int result;
  112. u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
  113. u16 fifo_count;
  114. s64 timestamp;
  115. mutex_lock(&indio_dev->mlock);
  116. if (!(st->chip_config.accl_fifo_enable |
  117. st->chip_config.gyro_fifo_enable))
  118. goto end_session;
  119. bytes_per_datum = 0;
  120. if (st->chip_config.accl_fifo_enable)
  121. bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
  122. if (st->chip_config.gyro_fifo_enable)
  123. bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR;
  124. /*
  125. * read fifo_count register to know how many bytes inside FIFO
  126. * right now
  127. */
  128. result = i2c_smbus_read_i2c_block_data(st->client,
  129. st->reg->fifo_count_h,
  130. INV_MPU6050_FIFO_COUNT_BYTE, data);
  131. if (result != INV_MPU6050_FIFO_COUNT_BYTE)
  132. goto end_session;
  133. fifo_count = be16_to_cpup((__be16 *)(&data[0]));
  134. if (fifo_count < bytes_per_datum)
  135. goto end_session;
  136. /* fifo count can't be odd number, if it is odd, reset fifo*/
  137. if (fifo_count & 1)
  138. goto flush_fifo;
  139. if (fifo_count > INV_MPU6050_FIFO_THRESHOLD)
  140. goto flush_fifo;
  141. /* Timestamp mismatch. */
  142. if (kfifo_len(&st->timestamps) >
  143. fifo_count / bytes_per_datum + INV_MPU6050_TIME_STAMP_TOR)
  144. goto flush_fifo;
  145. while (fifo_count >= bytes_per_datum) {
  146. result = i2c_smbus_read_i2c_block_data(st->client,
  147. st->reg->fifo_r_w,
  148. bytes_per_datum, data);
  149. if (result != bytes_per_datum)
  150. goto flush_fifo;
  151. result = kfifo_out(&st->timestamps, &timestamp, 1);
  152. /* when there is no timestamp, put timestamp as 0 */
  153. if (0 == result)
  154. timestamp = 0;
  155. result = iio_push_to_buffers_with_timestamp(indio_dev, data,
  156. timestamp);
  157. if (result)
  158. goto flush_fifo;
  159. fifo_count -= bytes_per_datum;
  160. }
  161. end_session:
  162. mutex_unlock(&indio_dev->mlock);
  163. iio_trigger_notify_done(indio_dev->trig);
  164. return IRQ_HANDLED;
  165. flush_fifo:
  166. /* Flush HW and SW FIFOs. */
  167. inv_reset_fifo(indio_dev);
  168. mutex_unlock(&indio_dev->mlock);
  169. iio_trigger_notify_done(indio_dev->trig);
  170. return IRQ_HANDLED;
  171. }