blob: e421278e8d791aae4c177f074f8add6aeeb09ede [file] [log] [blame]
Barry Songa9d26f02010-05-04 14:43:15 +01001#include <linux/interrupt.h>
Barry Songa9d26f02010-05-04 14:43:15 +01002#include <linux/mutex.h>
Barry Songa9d26f02010-05-04 14:43:15 +01003#include <linux/kernel.h>
4#include <linux/spi/spi.h>
Mike Frysinger1cb6c1f2010-05-23 03:10:35 -04005#include <linux/slab.h>
Jonathan Cameron2a29a902011-05-18 14:41:28 +01006#include <linux/bitops.h>
Paul Gortmaker8e336a72011-07-10 13:09:12 -04007#include <linux/export.h>
Barry Songa9d26f02010-05-04 14:43:15 +01008
Jonathan Cameron06458e22012-04-25 15:54:58 +01009#include <linux/iio/iio.h>
Lars-Peter Clausen1ffe2e72013-01-16 12:48:00 +000010#include <linux/iio/buffer.h>
11#include <linux/iio/triggered_buffer.h>
Jonathan Cameron06458e22012-04-25 15:54:58 +010012#include <linux/iio/trigger_consumer.h>
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000013
Barry Songa9d26f02010-05-04 14:43:15 +010014#include "adis16400.h"
15
Barry Song3fd66da2010-06-04 17:19:53 +080016/**
17 * adis16400_spi_read_burst() - read all data registers
Lars-Peter Clausenea19ed32012-05-12 15:39:41 +020018 * @indio_dev: the IIO device
Barry Song3fd66da2010-06-04 17:19:53 +080019 * @rx: somewhere to pass back the value read (min size is 24 bytes)
20 **/
Lars-Peter Clausenea19ed32012-05-12 15:39:41 +020021static int adis16400_spi_read_burst(struct iio_dev *indio_dev, u8 *rx)
Barry Song3fd66da2010-06-04 17:19:53 +080022{
23 struct spi_message msg;
Jonathan Cameron38d15f02011-05-18 14:42:23 +010024 struct adis16400_state *st = iio_priv(indio_dev);
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000025 u32 old_speed_hz = st->adis.spi->max_speed_hz;
Barry Song3fd66da2010-06-04 17:19:53 +080026 int ret;
27
28 struct spi_transfer xfers[] = {
29 {
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000030 .tx_buf = st->adis.tx,
Barry Song3fd66da2010-06-04 17:19:53 +080031 .bits_per_word = 8,
32 .len = 2,
Barry Song3fd66da2010-06-04 17:19:53 +080033 }, {
34 .rx_buf = rx,
35 .bits_per_word = 8,
36 .len = 24,
Barry Song3fd66da2010-06-04 17:19:53 +080037 },
38 };
39
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000040 mutex_lock(&st->adis.txrx_lock);
41 st->adis.tx[0] = ADIS_READ_REG(ADIS16400_GLOB_CMD);
42 st->adis.tx[1] = 0;
Barry Song3fd66da2010-06-04 17:19:53 +080043
44 spi_message_init(&msg);
45 spi_message_add_tail(&xfers[0], &msg);
46 spi_message_add_tail(&xfers[1], &msg);
47
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000048 st->adis.spi->max_speed_hz = min(ADIS16400_SPI_BURST, old_speed_hz);
49 spi_setup(st->adis.spi);
Barry Song3fd66da2010-06-04 17:19:53 +080050
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000051 ret = spi_sync(st->adis.spi, &msg);
Barry Song3fd66da2010-06-04 17:19:53 +080052 if (ret)
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000053 dev_err(&st->adis.spi->dev, "problem when burst reading");
Barry Song3fd66da2010-06-04 17:19:53 +080054
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000055 st->adis.spi->max_speed_hz = old_speed_hz;
56 spi_setup(st->adis.spi);
57 mutex_unlock(&st->adis.txrx_lock);
Barry Song3fd66da2010-06-04 17:19:53 +080058 return ret;
59}
60
Jonathan Cameron2a29a902011-05-18 14:41:28 +010061static const u16 read_all_tx_array[] = {
Lars-Peter Clausencd888a172013-01-16 12:48:00 +000062 cpu_to_be16(ADIS_READ_REG(ADIS16400_SUPPLY_OUT)),
63 cpu_to_be16(ADIS_READ_REG(ADIS16400_XGYRO_OUT)),
64 cpu_to_be16(ADIS_READ_REG(ADIS16400_YGYRO_OUT)),
65 cpu_to_be16(ADIS_READ_REG(ADIS16400_ZGYRO_OUT)),
66 cpu_to_be16(ADIS_READ_REG(ADIS16400_XACCL_OUT)),
67 cpu_to_be16(ADIS_READ_REG(ADIS16400_YACCL_OUT)),
68 cpu_to_be16(ADIS_READ_REG(ADIS16400_ZACCL_OUT)),
69 cpu_to_be16(ADIS_READ_REG(ADIS16350_XTEMP_OUT)),
70 cpu_to_be16(ADIS_READ_REG(ADIS16350_YTEMP_OUT)),
71 cpu_to_be16(ADIS_READ_REG(ADIS16350_ZTEMP_OUT)),
72 cpu_to_be16(ADIS_READ_REG(ADIS16400_AUX_ADC)),
Jonathan Cameron2a29a902011-05-18 14:41:28 +010073};
74
Lars-Peter Clausenea19ed32012-05-12 15:39:41 +020075static int adis16350_spi_read_all(struct iio_dev *indio_dev, u8 *rx)
Jonathan Cameron2a29a902011-05-18 14:41:28 +010076{
Jonathan Cameron38d15f02011-05-18 14:42:23 +010077 struct adis16400_state *st = iio_priv(indio_dev);
Jonathan Cameron2a29a902011-05-18 14:41:28 +010078
79 struct spi_message msg;
80 int i, j = 0, ret;
81 struct spi_transfer *xfers;
Jonathan Cameron550268ca2011-12-05 22:18:15 +000082 int scan_count = bitmap_weight(indio_dev->active_scan_mask,
83 indio_dev->masklength);
Jonathan Cameron2a29a902011-05-18 14:41:28 +010084
Jonathan Cameron550268ca2011-12-05 22:18:15 +000085 xfers = kzalloc(sizeof(*xfers)*(scan_count + 1),
Jonathan Cameron38d15f02011-05-18 14:42:23 +010086 GFP_KERNEL);
Jonathan Cameron2a29a902011-05-18 14:41:28 +010087 if (xfers == NULL)
88 return -ENOMEM;
89
90 for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
Jonathan Cameron550268ca2011-12-05 22:18:15 +000091 if (test_bit(i, indio_dev->active_scan_mask)) {
Jonathan Cameron2a29a902011-05-18 14:41:28 +010092 xfers[j].tx_buf = &read_all_tx_array[i];
93 xfers[j].bits_per_word = 16;
94 xfers[j].len = 2;
95 xfers[j + 1].rx_buf = rx + j*2;
96 j++;
97 }
98 xfers[j].bits_per_word = 16;
99 xfers[j].len = 2;
100
101 spi_message_init(&msg);
Jonathan Cameron550268ca2011-12-05 22:18:15 +0000102 for (j = 0; j < scan_count + 1; j++)
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100103 spi_message_add_tail(&xfers[j], &msg);
104
Lars-Peter Clausencd888a172013-01-16 12:48:00 +0000105 ret = spi_sync(st->adis.spi, &msg);
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100106 kfree(xfers);
107
108 return ret;
109}
110
Barry Songa9d26f02010-05-04 14:43:15 +0100111/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
112 * specific to be rolled into the core.
113 */
Jonathan Camerone7854842011-05-18 14:41:27 +0100114static irqreturn_t adis16400_trigger_handler(int irq, void *p)
Barry Songa9d26f02010-05-04 14:43:15 +0100115{
Jonathan Camerone7854842011-05-18 14:41:27 +0100116 struct iio_poll_func *pf = p;
Jonathan Camerone65bc6a2011-08-24 17:28:36 +0100117 struct iio_dev *indio_dev = pf->indio_dev;
Jonathan Cameron38d15f02011-05-18 14:42:23 +0100118 struct adis16400_state *st = iio_priv(indio_dev);
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100119 int i = 0, j, ret = 0;
Barry Songa9d26f02010-05-04 14:43:15 +0100120 s16 *data;
Jonathan Cameron420fe2e2012-04-21 10:09:35 +0100121
Jonathan Cameron32b5eec2011-09-02 17:14:38 +0100122 /* Asumption that long is enough for maximum channels */
Jonathan Cameron550268ca2011-12-05 22:18:15 +0000123 unsigned long mask = *indio_dev->active_scan_mask;
124 int scan_count = bitmap_weight(indio_dev->active_scan_mask,
125 indio_dev->masklength);
Jonathan Cameron420fe2e2012-04-21 10:09:35 +0100126 data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
Barry Songa9d26f02010-05-04 14:43:15 +0100127 if (data == NULL) {
Lars-Peter Clausencd888a172013-01-16 12:48:00 +0000128 dev_err(&st->adis.spi->dev, "memory alloc failed in ring bh");
Lars-Peter Clausen462c8d22012-07-04 17:09:00 +0100129 goto done;
Barry Songa9d26f02010-05-04 14:43:15 +0100130 }
131
Jonathan Cameron550268ca2011-12-05 22:18:15 +0000132 if (scan_count) {
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100133 if (st->variant->flags & ADIS16400_NO_BURST) {
Lars-Peter Clausencd888a172013-01-16 12:48:00 +0000134 ret = adis16350_spi_read_all(indio_dev, st->adis.rx);
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100135 if (ret < 0)
Lars-Peter Clausen462c8d22012-07-04 17:09:00 +0100136 goto done;
Jonathan Cameron550268ca2011-12-05 22:18:15 +0000137 for (; i < scan_count; i++)
Lars-Peter Clausencd888a172013-01-16 12:48:00 +0000138 data[i] = *(s16 *)(st->adis.rx + i*2);
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100139 } else {
Lars-Peter Clausencd888a172013-01-16 12:48:00 +0000140 ret = adis16400_spi_read_burst(indio_dev, st->adis.rx);
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100141 if (ret < 0)
Lars-Peter Clausen462c8d22012-07-04 17:09:00 +0100142 goto done;
Jonathan Cameron550268ca2011-12-05 22:18:15 +0000143 for (; i < scan_count; i++) {
Michael Hennerich0fea4d62011-03-21 16:44:38 +0100144 j = __ffs(mask);
145 mask &= ~(1 << j);
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100146 data[i] = be16_to_cpup(
Lars-Peter Clausencd888a172013-01-16 12:48:00 +0000147 (__be16 *)&(st->adis.rx[j*2]));
Michael Hennerich0fea4d62011-03-21 16:44:38 +0100148 }
Jonathan Cameron2a29a902011-05-18 14:41:28 +0100149 }
150 }
Barry Songa9d26f02010-05-04 14:43:15 +0100151 /* Guaranteed to be aligned with 8 byte boundary */
Jonathan Cameron84b36ce2012-06-30 20:06:00 +0100152 if (indio_dev->scan_timestamp)
Jonathan Camerone7854842011-05-18 14:41:27 +0100153 *((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
Jonathan Cameron84b36ce2012-06-30 20:06:00 +0100154 iio_push_to_buffers(indio_dev, (u8 *) data);
Barry Songa9d26f02010-05-04 14:43:15 +0100155
Lars-Peter Clausen462c8d22012-07-04 17:09:00 +0100156done:
157 kfree(data);
Jonathan Camerone7854842011-05-18 14:41:27 +0100158 iio_trigger_notify_done(indio_dev->trig);
Barry Songa9d26f02010-05-04 14:43:15 +0100159
Jonathan Camerone7854842011-05-18 14:41:27 +0100160 return IRQ_HANDLED;
Barry Songa9d26f02010-05-04 14:43:15 +0100161}
Barry Songa9d26f02010-05-04 14:43:15 +0100162
Barry Songa9d26f02010-05-04 14:43:15 +0100163int adis16400_configure_ring(struct iio_dev *indio_dev)
164{
Lars-Peter Clausen1ffe2e72013-01-16 12:48:00 +0000165 return iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
166 &adis16400_trigger_handler, NULL);
167}
Barry Songa9d26f02010-05-04 14:43:15 +0100168
Lars-Peter Clausen1ffe2e72013-01-16 12:48:00 +0000169void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
170{
171 iio_triggered_buffer_cleanup(indio_dev);
Barry Songa9d26f02010-05-04 14:43:15 +0100172}