aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorBarry Song <Barry.Song@analog.com>2010-05-17 06:40:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-18 17:44:28 -0400
commit5763dcab5cd7de27d6db50efd393c416177c56c7 (patch)
tree2dc46c7b8fcf707bb8603d10d4fbfd2c95c1d984 /drivers/staging
parent81b77f94a10b64a3620e32531b5d8dbc495f1727 (diff)
staging: iio: adis16350 and similar IMU driver
This version has the right part number in the commit message. Whilst technically the part I listed last time is also supported by the driver, the commit message might have caused confusion. Another driver from Barry at Analog. Again, I've lifted if from the blackfin tree and done the usual sparse and checkpatch fixes + the abi changes. I actually have one of these, so am particularly pleased to see it supported! Signed-off-by: Barry Song <Barry.Song@analog.com> Signed-off-by: Jonathan Cameron <jic23@cam.ac.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/iio/imu/Kconfig9
-rw-r--r--drivers/staging/iio/imu/Makefile4
-rw-r--r--drivers/staging/iio/imu/adis16350.h193
-rw-r--r--drivers/staging/iio/imu/adis16350_core.c736
-rw-r--r--drivers/staging/iio/imu/adis16350_ring.c286
-rw-r--r--drivers/staging/iio/imu/adis16350_trigger.c127
6 files changed, 1355 insertions, 0 deletions
diff --git a/drivers/staging/iio/imu/Kconfig b/drivers/staging/iio/imu/Kconfig
index 411804f11a7..6308d6faad5 100644
--- a/drivers/staging/iio/imu/Kconfig
+++ b/drivers/staging/iio/imu/Kconfig
@@ -13,6 +13,15 @@ config ADIS16300
13 Say yes here to build support for Analog Devices adis16300 four degrees 13 Say yes here to build support for Analog Devices adis16300 four degrees
14 of freedom inertial sensor. 14 of freedom inertial sensor.
15 15
16config ADIS16350
17 tristate "Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver"
18 depends on SPI
19 select IIO_TRIGGER if IIO_RING_BUFFER
20 select IIO_SW_RING if IIO_RING_BUFFER
21 help
22 Say yes here to build support for Analog Devices adis16350/54/55/60/62/64/65
23 high precision tri-axis inertial sensor.
24
16config ADIS16400 25config ADIS16400
17 tristate "Analog Devices ADIS16400/5 IMU SPI driver" 26 tristate "Analog Devices ADIS16400/5 IMU SPI driver"
18 depends on SPI 27 depends on SPI
diff --git a/drivers/staging/iio/imu/Makefile b/drivers/staging/iio/imu/Makefile
index de454dd08c6..31df7359e20 100644
--- a/drivers/staging/iio/imu/Makefile
+++ b/drivers/staging/iio/imu/Makefile
@@ -5,6 +5,10 @@ adis16300-y := adis16300_core.o
5adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o 5adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o
6obj-$(CONFIG_ADIS16300) += adis16300.o 6obj-$(CONFIG_ADIS16300) += adis16300.o
7 7
8adis16350-y := adis16350_core.o
9adis16350-$(CONFIG_IIO_RING_BUFFER) += adis16350_ring.o adis16350_trigger.o
10obj-$(CONFIG_ADIS16350) += adis16350.o
11
8adis16400-y := adis16400_core.o 12adis16400-y := adis16400_core.o
9adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o 13adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o
10obj-$(CONFIG_ADIS16400) += adis16400.o \ No newline at end of file 14obj-$(CONFIG_ADIS16400) += adis16400.o \ No newline at end of file
diff --git a/drivers/staging/iio/imu/adis16350.h b/drivers/staging/iio/imu/adis16350.h
new file mode 100644
index 00000000000..334b18ace38
--- /dev/null
+++ b/drivers/staging/iio/imu/adis16350.h
@@ -0,0 +1,193 @@
1#ifndef SPI_ADIS16350_H_
2#define SPI_ADIS16350_H_
3
4#define ADIS16350_STARTUP_DELAY 220 /* ms */
5
6#define ADIS16350_READ_REG(a) a
7#define ADIS16350_WRITE_REG(a) ((a) | 0x80)
8
9#define ADIS16350_FLASH_CNT 0x00 /* Flash memory write count */
10#define ADIS16350_SUPPLY_OUT 0x02 /* Power supply measurement */
11#define ADIS16350_XGYRO_OUT 0x04 /* X-axis gyroscope output */
12#define ADIS16350_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
13#define ADIS16350_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
14#define ADIS16350_XACCL_OUT 0x0A /* X-axis accelerometer output */
15#define ADIS16350_YACCL_OUT 0x0C /* Y-axis accelerometer output */
16#define ADIS16350_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
17#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
18#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
19#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
20#define ADIS16350_AUX_ADC 0x16 /* Auxiliary ADC measurement */
21
22/* Calibration parameters */
23#define ADIS16350_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
24#define ADIS16350_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
25#define ADIS16350_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
26#define ADIS16350_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
27#define ADIS16350_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
28#define ADIS16350_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
29
30#define ADIS16350_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
31#define ADIS16350_MSC_CTRL 0x34 /* Miscellaneous control */
32#define ADIS16350_SMPL_PRD 0x36 /* Internal sample period (rate) control */
33#define ADIS16350_SENS_AVG 0x38 /* Dynamic range and digital filter control */
34#define ADIS16350_SLP_CNT 0x3A /* Sleep mode control */
35#define ADIS16350_DIAG_STAT 0x3C /* System status */
36
37/* Alarm functions */
38#define ADIS16350_GLOB_CMD 0x3E /* System command */
39#define ADIS16350_ALM_MAG1 0x26 /* Alarm 1 amplitude threshold */
40#define ADIS16350_ALM_MAG2 0x28 /* Alarm 2 amplitude threshold */
41#define ADIS16350_ALM_SMPL1 0x2A /* Alarm 1 sample size */
42#define ADIS16350_ALM_SMPL2 0x2C /* Alarm 2 sample size */
43#define ADIS16350_ALM_CTRL 0x2E /* Alarm control */
44#define ADIS16350_AUX_DAC 0x30 /* Auxiliary DAC data */
45
46#define ADIS16350_ERROR_ACTIVE (1<<14)
47#define ADIS16350_NEW_DATA (1<<15)
48
49/* MSC_CTRL */
50#define ADIS16350_MSC_CTRL_MEM_TEST (1<<11)
51#define ADIS16350_MSC_CTRL_INT_SELF_TEST (1<<10)
52#define ADIS16350_MSC_CTRL_NEG_SELF_TEST (1<<9)
53#define ADIS16350_MSC_CTRL_POS_SELF_TEST (1<<8)
54#define ADIS16350_MSC_CTRL_GYRO_BIAS (1<<7)
55#define ADIS16350_MSC_CTRL_ACCL_ALIGN (1<<6)
56#define ADIS16350_MSC_CTRL_DATA_RDY_EN (1<<2)
57#define ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1)
58#define ADIS16350_MSC_CTRL_DATA_RDY_DIO2 (1<<0)
59
60/* SMPL_PRD */
61#define ADIS16350_SMPL_PRD_TIME_BASE (1<<7)
62#define ADIS16350_SMPL_PRD_DIV_MASK 0x7F
63
64/* DIAG_STAT */
65#define ADIS16350_DIAG_STAT_ZACCL_FAIL (1<<15)
66#define ADIS16350_DIAG_STAT_YACCL_FAIL (1<<14)
67#define ADIS16350_DIAG_STAT_XACCL_FAIL (1<<13)
68#define ADIS16350_DIAG_STAT_XGYRO_FAIL (1<<12)
69#define ADIS16350_DIAG_STAT_YGYRO_FAIL (1<<11)
70#define ADIS16350_DIAG_STAT_ZGYRO_FAIL (1<<10)
71#define ADIS16350_DIAG_STAT_ALARM2 (1<<9)
72#define ADIS16350_DIAG_STAT_ALARM1 (1<<8)
73#define ADIS16350_DIAG_STAT_FLASH_CHK (1<<6)
74#define ADIS16350_DIAG_STAT_SELF_TEST (1<<5)
75#define ADIS16350_DIAG_STAT_OVERFLOW (1<<4)
76#define ADIS16350_DIAG_STAT_SPI_FAIL (1<<3)
77#define ADIS16350_DIAG_STAT_FLASH_UPT (1<<2)
78#define ADIS16350_DIAG_STAT_POWER_HIGH (1<<1)
79#define ADIS16350_DIAG_STAT_POWER_LOW (1<<0)
80
81/* GLOB_CMD */
82#define ADIS16350_GLOB_CMD_SW_RESET (1<<7)
83#define ADIS16350_GLOB_CMD_P_AUTO_NULL (1<<4)
84#define ADIS16350_GLOB_CMD_FLASH_UPD (1<<3)
85#define ADIS16350_GLOB_CMD_DAC_LATCH (1<<2)
86#define ADIS16350_GLOB_CMD_FAC_CALIB (1<<1)
87#define ADIS16350_GLOB_CMD_AUTO_NULL (1<<0)
88
89/* SLP_CNT */
90#define ADIS16350_SLP_CNT_POWER_OFF (1<<8)
91
92#define ADIS16350_MAX_TX 24
93#define ADIS16350_MAX_RX 24
94
95#define ADIS16350_SPI_SLOW (u32)(300 * 1000)
96#define ADIS16350_SPI_BURST (u32)(1000 * 1000)
97#define ADIS16350_SPI_FAST (u32)(2000 * 1000)
98
99/**
100 * struct adis16350_state - device instance specific data
101 * @us: actual spi_device
102 * @work_trigger_to_ring: bh for triggered event handling
103 * @work_cont_thresh: CLEAN
104 * @inter: used to check if new interrupt has been triggered
105 * @last_timestamp: passing timestamp from th to bh of interrupt handler
106 * @indio_dev: industrial I/O device structure
107 * @trig: data ready trigger registered with iio
108 * @tx: transmit buffer
109 * @rx: recieve buffer
110 * @buf_lock: mutex to protect tx and rx
111 **/
112struct adis16350_state {
113 struct spi_device *us;
114 struct work_struct work_trigger_to_ring;
115 struct iio_work_cont work_cont_data_rdy;
116 s64 last_timestamp;
117 struct iio_dev *indio_dev;
118 struct iio_trigger *trig;
119 u8 *tx;
120 u8 *rx;
121 struct mutex buf_lock;
122};
123
124int adis16350_set_irq(struct device *dev, bool enable);
125
126#ifdef CONFIG_IIO_RING_BUFFER
127
128enum adis16350_scan {
129 ADIS16350_SCAN_SUPPLY,
130 ADIS16350_SCAN_GYRO_X,
131 ADIS16350_SCAN_GYRO_Y,
132 ADIS16350_SCAN_GYRO_Z,
133 ADIS16350_SCAN_ACC_X,
134 ADIS16350_SCAN_ACC_Y,
135 ADIS16350_SCAN_ACC_Z,
136 ADIS16350_SCAN_TEMP_X,
137 ADIS16350_SCAN_TEMP_Y,
138 ADIS16350_SCAN_TEMP_Z,
139 ADIS16350_SCAN_ADC_0
140};
141
142void adis16350_remove_trigger(struct iio_dev *indio_dev);
143int adis16350_probe_trigger(struct iio_dev *indio_dev);
144
145ssize_t adis16350_read_data_from_ring(struct device *dev,
146 struct device_attribute *attr,
147 char *buf);
148
149
150int adis16350_configure_ring(struct iio_dev *indio_dev);
151void adis16350_unconfigure_ring(struct iio_dev *indio_dev);
152
153int adis16350_initialize_ring(struct iio_ring_buffer *ring);
154void adis16350_uninitialize_ring(struct iio_ring_buffer *ring);
155#else /* CONFIG_IIO_RING_BUFFER */
156
157static inline void adis16350_remove_trigger(struct iio_dev *indio_dev)
158{
159}
160
161static inline int adis16350_probe_trigger(struct iio_dev *indio_dev)
162{
163 return 0;
164}
165
166static inline ssize_t
167adis16350_read_data_from_ring(struct device *dev,
168 struct device_attribute *attr,
169 char *buf)
170{
171 return 0;
172}
173
174static int adis16350_configure_ring(struct iio_dev *indio_dev)
175{
176 return 0;
177}
178
179static inline void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
180{
181}
182
183static inline int adis16350_initialize_ring(struct iio_ring_buffer *ring)
184{
185 return 0;
186}
187
188static inline void adis16350_uninitialize_ring(struct iio_ring_buffer *ring)
189{
190}
191
192#endif /* CONFIG_IIO_RING_BUFFER */
193#endif /* SPI_ADIS16350_H_ */
diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c
new file mode 100644
index 00000000000..0edde73ce5c
--- /dev/null
+++ b/drivers/staging/iio/imu/adis16350_core.c
@@ -0,0 +1,736 @@
1/*
2 * ADIS16350/54/55/60/62/64/65 high precision tri-axis inertial sensor
3 *
4 * Copyright 2010 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/irq.h>
11#include <linux/gpio.h>
12#include <linux/delay.h>
13#include <linux/mutex.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
16#include <linux/spi/spi.h>
17
18#include <linux/sysfs.h>
19#include <linux/list.h>
20
21#include "../iio.h"
22#include "../sysfs.h"
23#include "../accel/accel.h"
24#include "../adc/adc.h"
25#include "../gyro/gyro.h"
26
27#include "adis16350.h"
28
29#define DRIVER_NAME "adis16350"
30
31static int adis16350_check_status(struct device *dev);
32
33/**
34 * adis16350_spi_write_reg_8() - write single byte to a register
35 * @dev: device associated with child of actual device (iio_dev or iio_trig)
36 * @reg_address: the address of the register to be written
37 * @val: the value to write
38 **/
39static int adis16350_spi_write_reg_8(struct device *dev,
40 u8 reg_address,
41 u8 val)
42{
43 int ret;
44 struct iio_dev *indio_dev = dev_get_drvdata(dev);
45 struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
46
47 mutex_lock(&st->buf_lock);
48 st->tx[0] = ADIS16350_WRITE_REG(reg_address);
49 st->tx[1] = val;
50
51 ret = spi_write(st->us, st->tx, 2);
52 mutex_unlock(&st->buf_lock);
53
54 return ret;
55}
56
57/**
58 * adis16350_spi_write_reg_16() - write 2 bytes to a pair of registers
59 * @dev: device associated with child of actual device (iio_dev or iio_trig)
60 * @reg_address: the address of the lower of the two registers. Second register
61 * is assumed to have address one greater.
62 * @val: value to be written
63 **/
64static int adis16350_spi_write_reg_16(struct device *dev,
65 u8 lower_reg_address,
66 u16 value)
67{
68 int ret;
69 struct spi_message msg;
70 struct iio_dev *indio_dev = dev_get_drvdata(dev);
71 struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
72 struct spi_transfer xfers[] = {
73 {
74 .tx_buf = st->tx,
75 .bits_per_word = 8,
76 .len = 2,
77 .cs_change = 1,
78 .delay_usecs = 25,
79 }, {
80 .tx_buf = st->tx + 2,
81 .bits_per_word = 8,
82 .len = 2,
83 .cs_change = 1,
84 .delay_usecs = 25,
85 },
86 };
87
88 mutex_lock(&st->buf_lock);
89 st->tx[0] = ADIS16350_WRITE_REG(lower_reg_address);
90 st->tx[1] = value & 0xFF;
91 st->tx[2] = ADIS16350_WRITE_REG(lower_reg_address + 1);
92 st->tx[3] = (value >> 8) & 0xFF;
93
94 spi_message_init(&msg);
95 spi_message_add_tail(&xfers[0], &msg);
96 spi_message_add_tail(&xfers[1], &msg);
97 ret = spi_sync(st->us, &msg);
98 mutex_unlock(&st->buf_lock);
99
100 return ret;
101}
102
103/**
104 * adis16350_spi_read_reg_16() - read 2 bytes from a 16-bit register
105 * @dev: device associated with child of actual device (iio_dev or iio_trig)
106 * @reg_address: the address of the lower of the two registers. Second register
107 * is assumed to have address one greater.
108 * @val: somewhere to pass back the value read
109 **/
110static int adis16350_spi_read_reg_16(struct device *dev,
111 u8 lower_reg_address,
112 u16 *val)
113{
114 struct spi_message msg;
115 struct iio_dev *indio_dev = dev_get_drvdata(dev);
116 struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
117 int ret;
118 struct spi_transfer xfers[] = {
119 {
120 .tx_buf = st->tx,
121 .bits_per_word = 8,
122 .len = 2,
123 .cs_change = 1,
124 .delay_usecs = 25,
125 }, {
126 .rx_buf = st->rx,
127 .bits_per_word = 8,
128 .len = 2,
129 .cs_change = 1,
130 .delay_usecs = 25,
131 },
132 };
133
134 mutex_lock(&st->buf_lock);
135 st->tx[0] = ADIS16350_READ_REG(lower_reg_address);
136 st->tx[1] = 0;
137 st->tx[2] = 0;
138 st->tx[3] = 0;
139
140 spi_message_init(&msg);
141 spi_message_add_tail(&xfers[0], &msg);
142 spi_message_add_tail(&xfers[1], &msg);
143 ret = spi_sync(st->us, &msg);
144 if (ret) {
145 dev_err(&st->us->dev,
146 "problem when reading 16 bit register 0x%02X",
147 lower_reg_address);
148 goto error_ret;
149 }
150 *val = (st->rx[0] << 8) | st->rx[1];
151
152error_ret:
153 mutex_unlock(&st->buf_lock);
154 return ret;
155}
156
157
158static ssize_t adis16350_spi_read_signed(struct device *dev,
159 struct device_attribute *attr,
160 char *buf,
161 unsigned bits)
162{
163 int ret;
164 s16 val = 0;
165 unsigned shift = 16 - bits;
166 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
167
168 ret = adis16350_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
169 if (ret)
170 return ret;
171
172 if (val & ADIS16350_ERROR_ACTIVE)
173 adis16350_check_status(dev);
174 val = ((s16)(val << shift) >> shift);
175 return sprintf(buf, "%d\n", val);
176}
177
178static ssize_t adis16350_read_12bit_unsigned(struct device *dev,
179 struct device_attribute *attr,
180 char *buf)
181{
182 int ret;
183 u16 val = 0;
184 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
185
186 ret = adis16350_spi_read_reg_16(dev, this_attr->address, &val);
187 if (ret)
188 return ret;
189
190 if (val & ADIS16350_ERROR_ACTIVE)
191 adis16350_check_status(dev);
192
193 return sprintf(buf, "%u\n", val & 0x0FFF);
194}
195
196static ssize_t adis16350_read_14bit_signed(struct device *dev,
197 struct device_attribute *attr,
198 char *buf)
199{
200 struct iio_dev *indio_dev = dev_get_drvdata(dev);
201 ssize_t ret;
202
203 /* Take the iio_dev status lock */
204 mutex_lock(&indio_dev->mlock);
205 ret = adis16350_spi_read_signed(dev, attr, buf, 14);
206 mutex_unlock(&indio_dev->mlock);
207
208 return ret;
209}
210
211static ssize_t adis16350_read_12bit_signed(struct device *dev,
212 struct device_attribute *attr,
213 char *buf)
214{
215 struct iio_dev *indio_dev = dev_get_drvdata(dev);
216 ssize_t ret;
217
218 /* Take the iio_dev status lock */
219 mutex_lock(&indio_dev->mlock);
220 ret = adis16350_spi_read_signed(dev, attr, buf, 12);
221 mutex_unlock(&indio_dev->mlock);
222
223 return ret;
224}
225
226static ssize_t adis16350_write_16bit(struct device *dev,
227 struct device_attribute *attr,
228 const char *buf,
229 size_t len)
230{
231 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
232 int ret;
233 long val;
234
235 ret = strict_strtol(buf, 10, &val);
236 if (ret)
237 goto error_ret;
238 ret = adis16350_spi_write_reg_16(dev, this_attr->address, val);
239
240error_ret:
241 return ret ? ret : len;
242}
243
244static ssize_t adis16350_read_frequency(struct device *dev,
245 struct device_attribute *attr,
246 char *buf)
247{
248 int ret, len = 0;
249 u16 t;
250 int sps;
251 ret = adis16350_spi_read_reg_16(dev,
252 ADIS16350_SMPL_PRD,
253 &t);
254 if (ret)
255 return ret;
256 sps = (t & ADIS16350_SMPL_PRD_TIME_BASE) ? 53 : 1638;
257 sps /= (t & ADIS16350_SMPL_PRD_DIV_MASK) + 1;
258 len = sprintf(buf, "%d SPS\n", sps);
259 return len;
260}
261
262static ssize_t adis16350_write_frequency(struct device *dev,
263 struct device_attribute *attr,
264 const char *buf,
265 size_t len)
266{
267 struct iio_dev *indio_dev = dev_get_drvdata(dev);
268 struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
269 long val;
270 int ret;
271 u8 t;
272
273 ret = strict_strtol(buf, 10, &val);
274 if (ret)
275 return ret;
276
277 mutex_lock(&indio_dev->mlock);
278
279 t = (1638 / val);
280 if (t > 0)
281 t--;
282 t &= ADIS16350_SMPL_PRD_DIV_MASK;
283 if ((t & ADIS16350_SMPL_PRD_DIV_MASK) >= 0x0A)
284 st->us->max_speed_hz = ADIS16350_SPI_SLOW;
285 else
286 st->us->max_speed_hz = ADIS16350_SPI_FAST;
287
288 ret = adis16350_spi_write_reg_8(dev,
289 ADIS16350_SMPL_PRD,
290 t);
291
292 mutex_unlock(&indio_dev->mlock);
293
294 return ret ? ret : len;
295}
296
297static int adis16350_reset(struct device *dev)
298{
299 int ret;
300 ret = adis16350_spi_write_reg_8(dev,
301 ADIS16350_GLOB_CMD,
302 ADIS16350_GLOB_CMD_SW_RESET);
303 if (ret)
304 dev_err(dev, "problem resetting device");
305
306 return ret;
307}
308
309static ssize_t adis16350_write_reset(struct device *dev,
310 struct device_attribute *attr,
311 const char *buf, size_t len)
312{
313 if (len < 1)
314 return -1;
315 switch (buf[0]) {
316 case '1':
317 case 'y':
318 case 'Y':
319 return adis16350_reset(dev);
320 }
321 return -1;
322}
323
324int adis16350_set_irq(struct device *dev, bool enable)
325{
326 int ret;
327 u16 msc;
328 ret = adis16350_spi_read_reg_16(dev, ADIS16350_MSC_CTRL, &msc);
329 if (ret)
330 goto error_ret;
331
332 msc |= ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH;
333 msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_DIO2;
334
335 if (enable)
336 msc |= ADIS16350_MSC_CTRL_DATA_RDY_EN;
337 else
338 msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_EN;
339
340 ret = adis16350_spi_write_reg_16(dev, ADIS16350_MSC_CTRL, msc);
341 if (ret)
342 goto error_ret;
343
344error_ret:
345 return ret;
346}
347
348/* Power down the device */
349static int adis16350_stop_device(struct device *dev)
350{
351 int ret;
352 u16 val = ADIS16350_SLP_CNT_POWER_OFF;
353
354 ret = adis16350_spi_write_reg_16(dev, ADIS16350_SLP_CNT, val);
355 if (ret)
356 dev_err(dev, "problem with turning device off: SLP_CNT");
357
358 return ret;
359}
360
361static int adis16350_self_test(struct device *dev)
362{
363 int ret;
364 ret = adis16350_spi_write_reg_16(dev,
365 ADIS16350_MSC_CTRL,
366 ADIS16350_MSC_CTRL_MEM_TEST);
367 if (ret) {
368 dev_err(dev, "problem starting self test");
369 goto err_ret;
370 }
371
372 adis16350_check_status(dev);
373
374err_ret:
375 return ret;
376}
377
378static int adis16350_check_status(struct device *dev)
379{
380 u16 status;
381 int ret;
382
383 ret = adis16350_spi_read_reg_16(dev, ADIS16350_DIAG_STAT, &status);
384
385 if (ret < 0) {
386 dev_err(dev, "Reading status failed\n");
387 goto error_ret;
388 }
389 ret = status;
390 if (status & ADIS16350_DIAG_STAT_ZACCL_FAIL)
391 dev_err(dev, "Z-axis accelerometer self-test failure\n");
392 if (status & ADIS16350_DIAG_STAT_YACCL_FAIL)
393 dev_err(dev, "Y-axis accelerometer self-test failure\n");
394 if (status & ADIS16350_DIAG_STAT_XACCL_FAIL)
395 dev_err(dev, "X-axis accelerometer self-test failure\n");
396 if (status & ADIS16350_DIAG_STAT_XGYRO_FAIL)
397 dev_err(dev, "X-axis gyroscope self-test failure\n");
398 if (status & ADIS16350_DIAG_STAT_YGYRO_FAIL)
399 dev_err(dev, "Y-axis gyroscope self-test failure\n");
400 if (status & ADIS16350_DIAG_STAT_ZGYRO_FAIL)
401 dev_err(dev, "Z-axis gyroscope self-test failure\n");
402 if (status & ADIS16350_DIAG_STAT_ALARM2)
403 dev_err(dev, "Alarm 2 active\n");
404 if (status & ADIS16350_DIAG_STAT_ALARM1)
405 dev_err(dev, "Alarm 1 active\n");
406 if (status & ADIS16350_DIAG_STAT_FLASH_CHK)
407 dev_err(dev, "Flash checksum error\n");
408 if (status & ADIS16350_DIAG_STAT_SELF_TEST)
409 dev_err(dev, "Self test error\n");
410 if (status & ADIS16350_DIAG_STAT_OVERFLOW)
411 dev_err(dev, "Sensor overrange\n");
412 if (status & ADIS16350_DIAG_STAT_SPI_FAIL)
413 dev_err(dev, "SPI failure\n");
414 if (status & ADIS16350_DIAG_STAT_FLASH_UPT)
415 dev_err(dev, "Flash update failed\n");
416 if (status & ADIS16350_DIAG_STAT_POWER_HIGH)
417 dev_err(dev, "Power supply above 5.25V\n");
418 if (status & ADIS16350_DIAG_STAT_POWER_LOW)
419 dev_err(dev, "Power supply below 4.75V\n");
420
421error_ret:
422 return ret;
423}
424
425static int adis16350_initial_setup(struct adis16350_state *st)
426{
427 int ret;
428 u16 smp_prd;
429 struct device *dev = &st->indio_dev->dev;
430
431 /* use low spi speed for init */
432 st->us->max_speed_hz = ADIS16350_SPI_SLOW;
433 st->us->mode = SPI_MODE_3;
434 spi_setup(st->us);
435
436 /* Disable IRQ */
437 ret = adis16350_set_irq(dev, false);
438 if (ret) {
439 dev_err(dev, "disable irq failed");
440 goto err_ret;
441 }
442
443 /* Do self test */
444 ret = adis16350_self_test(dev);
445 if (ret) {
446 dev_err(dev, "self test failure");
447 goto err_ret;
448 }
449
450 /* Read status register to check the result */
451 ret = adis16350_check_status(dev);
452 if (ret) {
453 adis16350_reset(dev);
454 dev_err(dev, "device not playing ball -> reset");
455 msleep(ADIS16350_STARTUP_DELAY);
456 ret = adis16350_check_status(dev);
457 if (ret) {
458 dev_err(dev, "giving up");
459 goto err_ret;
460 }
461 }
462
463 printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
464 st->us->chip_select, st->us->irq);
465
466 /* use high spi speed if possible */
467 ret = adis16350_spi_read_reg_16(dev, ADIS16350_SMPL_PRD, &smp_prd);
468 if (!ret && (smp_prd & ADIS16350_SMPL_PRD_DIV_MASK) < 0x0A) {
469 st->us->max_speed_hz = ADIS16350_SPI_SLOW;
470 spi_setup(st->us);
471 }
472
473err_ret:
474 return ret;
475}
476
477static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
478 adis16350_read_12bit_signed,
479 adis16350_write_16bit,
480 ADIS16350_XACCL_OFF);
481
482static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
483 adis16350_read_12bit_signed,
484 adis16350_write_16bit,
485 ADIS16350_YACCL_OFF);
486
487static IIO_DEV_ATTR_ACCEL_Z_OFFSET(S_IWUSR | S_IRUGO,
488 adis16350_read_12bit_signed,
489 adis16350_write_16bit,
490 ADIS16350_ZACCL_OFF);
491
492static IIO_DEV_ATTR_IN_NAMED_RAW(supply, adis16350_read_12bit_unsigned,
493 ADIS16350_SUPPLY_OUT);
494static IIO_CONST_ATTR(in_supply_scale, "0.002418");
495
496static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed,
497 ADIS16350_XGYRO_OUT);
498static IIO_DEV_ATTR_GYRO_Y(adis16350_read_14bit_signed,
499 ADIS16350_YGYRO_OUT);
500static IIO_DEV_ATTR_GYRO_Z(adis16350_read_14bit_signed,
501 ADIS16350_ZGYRO_OUT);
502static IIO_CONST_ATTR(gyro_scale, "0.05");
503
504static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed,
505 ADIS16350_XACCL_OUT);
506static IIO_DEV_ATTR_ACCEL_Y(adis16350_read_14bit_signed,
507 ADIS16350_YACCL_OUT);
508static IIO_DEV_ATTR_ACCEL_Z(adis16350_read_14bit_signed,
509 ADIS16350_ZACCL_OUT);
510static IIO_CONST_ATTR(accel_scale, "0.00333");
511
512static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed,
513 NULL, ADIS16350_XTEMP_OUT);
514static IIO_DEVICE_ATTR(temp_y_raw, S_IRUGO, adis16350_read_12bit_signed,
515 NULL, ADIS16350_YTEMP_OUT);
516static IIO_DEVICE_ATTR(temp_z_raw, S_IRUGO, adis16350_read_12bit_signed,
517 NULL, ADIS16350_ZTEMP_OUT);
518static IIO_CONST_ATTR(temp_scale, "0.0005");
519
520static IIO_DEV_ATTR_IN_RAW(0, adis16350_read_12bit_unsigned,
521 ADIS16350_AUX_ADC);
522static IIO_CONST_ATTR(in0_scale, "0.000806");
523
524static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
525 adis16350_read_frequency,
526 adis16350_write_frequency);
527
528static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
529 adis16350_write_reset, 0);
530
531static IIO_CONST_ATTR_AVAIL_SAMP_FREQ("409 546 819 1638");
532
533static IIO_CONST_ATTR(name, "adis16350");
534
535static struct attribute *adis16350_attributes[] = {
536 &iio_dev_attr_accel_x_offset.dev_attr.attr,
537 &iio_dev_attr_accel_y_offset.dev_attr.attr,
538 &iio_dev_attr_accel_z_offset.dev_attr.attr,
539 &iio_dev_attr_in_supply_raw.dev_attr.attr,
540 &iio_const_attr_in_supply_scale.dev_attr.attr,
541 &iio_dev_attr_gyro_x_raw.dev_attr.attr,
542 &iio_dev_attr_gyro_y_raw.dev_attr.attr,
543 &iio_dev_attr_gyro_z_raw.dev_attr.attr,
544 &iio_const_attr_gyro_scale.dev_attr.attr,
545 &iio_dev_attr_accel_x_raw.dev_attr.attr,
546 &iio_dev_attr_accel_y_raw.dev_attr.attr,
547 &iio_dev_attr_accel_z_raw.dev_attr.attr,
548 &iio_const_attr_accel_scale.dev_attr.attr,
549 &iio_dev_attr_temp_x_raw.dev_attr.attr,
550 &iio_dev_attr_temp_y_raw.dev_attr.attr,
551 &iio_dev_attr_temp_z_raw.dev_attr.attr,
552 &iio_const_attr_temp_scale.dev_attr.attr,
553 &iio_dev_attr_in0_raw.dev_attr.attr,
554 &iio_const_attr_in0_scale.dev_attr.attr,
555 &iio_dev_attr_sampling_frequency.dev_attr.attr,
556 &iio_const_attr_available_sampling_frequency.dev_attr.attr,
557 &iio_dev_attr_reset.dev_attr.attr,
558 &iio_const_attr_name.dev_attr.attr,
559 NULL
560};
561
562static const struct attribute_group adis16350_attribute_group = {
563 .attrs = adis16350_attributes,
564};
565
566static struct attribute *adis16350_event_attributes[] = {
567 NULL,
568};
569
570static struct attribute_group adis16350_event_attribute_group = {
571 .attrs = adis16350_event_attributes,
572};
573
574static int __devinit adis16350_probe(struct spi_device *spi)
575{
576 int ret, regdone = 0;
577 struct adis16350_state *st = kzalloc(sizeof *st, GFP_KERNEL);
578 if (!st) {
579 ret = -ENOMEM;
580 goto error_ret;
581 }
582 /* this is only used for removal purposes */
583 spi_set_drvdata(spi, st);
584
585 /* Allocate the comms buffers */
586 st->rx = kzalloc(sizeof(*st->rx)*ADIS16350_MAX_RX, GFP_KERNEL);
587 if (st->rx == NULL) {
588 ret = -ENOMEM;
589 goto error_free_st;
590 }
591 st->tx = kzalloc(sizeof(*st->tx)*ADIS16350_MAX_TX, GFP_KERNEL);
592 if (st->tx == NULL) {
593 ret = -ENOMEM;
594 goto error_free_rx;
595 }
596 st->us = spi;
597 mutex_init(&st->buf_lock);
598 /* setup the industrialio driver allocated elements */
599 st->indio_dev = iio_allocate_device();
600 if (st->indio_dev == NULL) {
601 ret = -ENOMEM;
602 goto error_free_tx;
603 }
604
605 st->indio_dev->dev.parent = &spi->dev;
606 st->indio_dev->num_interrupt_lines = 1;
607 st->indio_dev->event_attrs = &adis16350_event_attribute_group;
608 st->indio_dev->attrs = &adis16350_attribute_group;
609 st->indio_dev->dev_data = (void *)(st);
610 st->indio_dev->driver_module = THIS_MODULE;
611 st->indio_dev->modes = INDIO_DIRECT_MODE;
612
613 ret = adis16350_configure_ring(st->indio_dev);
614 if (ret)
615 goto error_free_dev;
616
617 ret = iio_device_register(st->indio_dev);
618 if (ret)
619 goto error_unreg_ring_funcs;
620 regdone = 1;
621
622 ret = adis16350_initialize_ring(st->indio_dev->ring);
623 if (ret) {
624 printk(KERN_ERR "failed to initialize the ring\n");
625 goto error_unreg_ring_funcs;
626 }
627
628 if (spi->irq) {
629 ret = iio_register_interrupt_line(spi->irq,
630 st->indio_dev,
631 0,
632 IRQF_TRIGGER_RISING,
633 "adis16350");
634 if (ret)
635 goto error_uninitialize_ring;
636
637 ret = adis16350_probe_trigger(st->indio_dev);
638 if (ret)
639 goto error_unregister_line;
640 }
641
642 /* Get the device into a sane initial state */
643 ret = adis16350_initial_setup(st);
644 if (ret)
645 goto error_remove_trigger;
646 return 0;
647
648error_remove_trigger:
649 adis16350_remove_trigger(st->indio_dev);
650error_unregister_line:
651 if (spi->irq)
652 iio_unregister_interrupt_line(st->indio_dev, 0);
653error_uninitialize_ring:
654 adis16350_uninitialize_ring(st->indio_dev->ring);
655error_unreg_ring_funcs:
656 adis16350_unconfigure_ring(st->indio_dev);
657error_free_dev:
658 if (regdone)
659 iio_device_unregister(st->indio_dev);
660 else
661 iio_free_device(st->indio_dev);
662error_free_tx:
663 kfree(st->tx);
664error_free_rx:
665 kfree(st->rx);
666error_free_st:
667 kfree(st);
668error_ret:
669 return ret;
670}
671
672static int adis16350_remove(struct spi_device *spi)
673{
674 int ret;
675 struct adis16350_state *st = spi_get_drvdata(spi);
676 struct iio_dev *indio_dev = st->indio_dev;
677
678 ret = adis16350_stop_device(&(indio_dev->dev));
679 if (ret)
680 goto err_ret;
681
682 flush_scheduled_work();
683
684 adis16350_remove_trigger(indio_dev);
685 if (spi->irq)
686 iio_unregister_interrupt_line(indio_dev, 0);
687
688 adis16350_uninitialize_ring(indio_dev->ring);
689 iio_device_unregister(indio_dev);
690 adis16350_unconfigure_ring(indio_dev);
691 kfree(st->tx);
692 kfree(st->rx);
693 kfree(st);
694
695 return 0;
696
697err_ret:
698 return ret;
699}
700
701static const struct spi_device_id adis16350_id[] = {
702 {"adis16350", 0},
703 {"adis16354", 0},
704 {"adis16355", 0},
705 {"adis16360", 0},
706 {"adis16362", 0},
707 {"adis16364", 0},
708 {"adis16365", 0},
709 {}
710};
711
712static struct spi_driver adis16350_driver = {
713 .driver = {
714 .name = "adis16350",
715 .owner = THIS_MODULE,
716 },
717 .probe = adis16350_probe,
718 .remove = __devexit_p(adis16350_remove),
719 .id_table = adis16350_id,
720};
721
722static __init int adis16350_init(void)
723{
724 return spi_register_driver(&adis16350_driver);
725}
726module_init(adis16350_init);
727
728static __exit void adis16350_exit(void)
729{
730 spi_unregister_driver(&adis16350_driver);
731}
732module_exit(adis16350_exit);
733
734MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
735MODULE_DESCRIPTION("Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver");
736MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/iio/imu/adis16350_ring.c b/drivers/staging/iio/imu/adis16350_ring.c
new file mode 100644
index 00000000000..5e9716ea7c7
--- /dev/null
+++ b/drivers/staging/iio/imu/adis16350_ring.c
@@ -0,0 +1,286 @@
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/sysfs.h>
10#include <linux/list.h>
11
12#include "../iio.h"
13#include "../sysfs.h"
14#include "../ring_sw.h"
15#include "../accel/accel.h"
16#include "../trigger.h"
17#include "adis16350.h"
18
19/**
20 * combine_8_to_16() utility function to munge to u8s into u16
21 **/
22static inline u16 combine_8_to_16(u8 lower, u8 upper)
23{
24 u16 _lower = lower;
25 u16 _upper = upper;
26 return _lower | (_upper << 8);
27}
28
29static IIO_SCAN_EL_C(supply, ADIS16350_SCAN_SUPPLY, IIO_UNSIGNED(12),
30 ADIS16350_SUPPLY_OUT, NULL);
31
32static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, IIO_SIGNED(14),
33 ADIS16350_XGYRO_OUT, NULL);
34static IIO_SCAN_EL_C(gyro_y, ADIS16350_SCAN_GYRO_Y, IIO_SIGNED(14),
35 ADIS16350_YGYRO_OUT, NULL);
36static IIO_SCAN_EL_C(gyro_z, ADIS16350_SCAN_GYRO_Z, IIO_SIGNED(14),
37 ADIS16350_ZGYRO_OUT, NULL);
38
39static IIO_SCAN_EL_C(accel_x, ADIS16350_SCAN_ACC_X, IIO_SIGNED(14),
40 ADIS16350_XACCL_OUT, NULL);
41static IIO_SCAN_EL_C(accel_y, ADIS16350_SCAN_ACC_Y, IIO_SIGNED(14),
42 ADIS16350_YACCL_OUT, NULL);
43static IIO_SCAN_EL_C(accel_z, ADIS16350_SCAN_ACC_Z, IIO_SIGNED(14),
44 ADIS16350_ZACCL_OUT, NULL);
45
46static IIO_SCAN_EL_C(temp_x, ADIS16350_SCAN_TEMP_X, IIO_SIGNED(12),
47 ADIS16350_XTEMP_OUT, NULL);
48static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, IIO_SIGNED(12),
49 ADIS16350_YTEMP_OUT, NULL);
50static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, IIO_SIGNED(12),
51 ADIS16350_ZTEMP_OUT, NULL);
52
53static IIO_SCAN_EL_C(adc_0, ADIS16350_SCAN_ADC_0, IIO_UNSIGNED(12),
54 ADIS16350_AUX_ADC, NULL);
55
56static IIO_SCAN_EL_TIMESTAMP(11);
57
58static struct attribute *adis16350_scan_el_attrs[] = {
59 &iio_scan_el_supply.dev_attr.attr,
60 &iio_scan_el_gyro_x.dev_attr.attr,
61 &iio_scan_el_gyro_y.dev_attr.attr,
62 &iio_scan_el_gyro_z.dev_attr.attr,
63 &iio_scan_el_accel_x.dev_attr.attr,
64 &iio_scan_el_accel_y.dev_attr.attr,
65 &iio_scan_el_accel_z.dev_attr.attr,
66 &iio_scan_el_temp_x.dev_attr.attr,
67 &iio_scan_el_temp_y.dev_attr.attr,
68 &iio_scan_el_temp_z.dev_attr.attr,
69 &iio_scan_el_adc_0.dev_attr.attr,
70 &iio_scan_el_timestamp.dev_attr.attr,
71 NULL,
72};
73
74static struct attribute_group adis16350_scan_el_group = {
75 .attrs = adis16350_scan_el_attrs,
76 .name = "scan_elements",
77};
78
79/**
80 * adis16350_poll_func_th() top half interrupt handler called by trigger
81 * @private_data: iio_dev
82 **/
83static void adis16350_poll_func_th(struct iio_dev *indio_dev)
84{
85 struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
86 st->last_timestamp = indio_dev->trig->timestamp;
87 schedule_work(&st->work_trigger_to_ring);
88}
89
90/**
91 * adis16350_spi_read_burst() - read all data registers
92 * @dev: device associated with child of actual device (iio_dev or iio_trig)
93 * @rx: somewhere to pass back the value read (min size is 24 bytes)
94 **/
95static int adis16350_spi_read_burst(struct device *dev, u8 *rx)
96{
97 struct spi_message msg;
98 struct iio_dev *indio_dev = dev_get_drvdata(dev);
99 struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
100 u32 old_speed_hz = st->us->max_speed_hz;
101 int ret;
102
103 struct spi_transfer xfers[] = {
104 {
105 .tx_buf = st->tx,
106 .bits_per_word = 8,
107 .len = 2,
108 .cs_change = 0,
109 }, {
110 .rx_buf = rx,
111 .bits_per_word = 8,
112 .len = 22,
113 .cs_change = 0,
114 },
115 };
116
117 mutex_lock(&st->buf_lock);
118 st->tx[0] = ADIS16350_READ_REG(ADIS16350_GLOB_CMD);
119 st->tx[1] = 0;
120
121 spi_message_init(&msg);
122 spi_message_add_tail(&xfers[0], &msg);
123 spi_message_add_tail(&xfers[1], &msg);
124
125 st->us->max_speed_hz = ADIS16350_SPI_BURST;
126 spi_setup(st->us);
127
128 ret = spi_sync(st->us, &msg);
129 if (ret)
130 dev_err(&st->us->dev, "problem when burst reading");
131
132 st->us->max_speed_hz = old_speed_hz;
133 spi_setup(st->us);
134 mutex_unlock(&st->buf_lock);
135 return ret;
136}
137
138/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
139 * specific to be rolled into the core.
140 */
141static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
142{
143 struct adis16350_state *st
144 = container_of(work_s, struct adis16350_state,
145 work_trigger_to_ring);
146
147 int i = 0;
148 s16 *data;
149 size_t datasize = st->indio_dev
150 ->ring->access.get_bpd(st->indio_dev->ring);
151
152 data = kmalloc(datasize , GFP_KERNEL);
153 if (data == NULL) {
154 dev_err(&st->us->dev, "memory alloc failed in ring bh");
155 return;
156 }
157
158 if (st->indio_dev->scan_count)
159 if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
160 for (; i < st->indio_dev->scan_count; i++) {
161 data[i] = combine_8_to_16(st->rx[i*2+1],
162 st->rx[i*2]);
163 }
164
165 /* Guaranteed to be aligned with 8 byte boundary */
166 if (st->indio_dev->scan_timestamp)
167 *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
168
169 st->indio_dev->ring->access.store_to(st->indio_dev->ring,
170 (u8 *)data,
171 st->last_timestamp);
172
173 iio_trigger_notify_done(st->indio_dev->trig);
174 kfree(data);
175
176 return;
177}
178
179static int adis16350_data_rdy_ring_preenable(struct iio_dev *indio_dev)
180{
181 size_t size;
182 dev_dbg(&indio_dev->dev, "%s\n", __func__);
183 /* Check if there are any scan elements enabled, if not fail*/
184 if (!(indio_dev->scan_count || indio_dev->scan_timestamp))
185 return -EINVAL;
186
187 if (indio_dev->ring->access.set_bpd) {
188 if (indio_dev->scan_timestamp)
189 if (indio_dev->scan_count)
190 /* Timestamp (aligned sizeof(s64) and data */
191 size = (((indio_dev->scan_count * sizeof(s16))
192 + sizeof(s64) - 1)
193 & ~(sizeof(s64) - 1))
194 + sizeof(s64);
195 else /* Timestamp only */
196 size = sizeof(s64);
197 else /* Data only */
198 size = indio_dev->scan_count*sizeof(s16);
199 indio_dev->ring->access.set_bpd(indio_dev->ring, size);
200 }
201
202 return 0;
203}
204
205static int adis16350_data_rdy_ring_postenable(struct iio_dev *indio_dev)
206{
207 return indio_dev->trig
208 ? iio_trigger_attach_poll_func(indio_dev->trig,
209 indio_dev->pollfunc)
210 : 0;
211}
212
213static int adis16350_data_rdy_ring_predisable(struct iio_dev *indio_dev)
214{
215 return indio_dev->trig
216 ? iio_trigger_dettach_poll_func(indio_dev->trig,
217 indio_dev->pollfunc)
218 : 0;
219}
220
221void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
222{
223 kfree(indio_dev->pollfunc);
224 iio_sw_rb_free(indio_dev->ring);
225}
226
227int adis16350_configure_ring(struct iio_dev *indio_dev)
228{
229 int ret = 0;
230 struct adis16350_state *st = indio_dev->dev_data;
231 struct iio_ring_buffer *ring;
232 INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
233 /* Set default scan mode */
234
235 iio_scan_mask_set(indio_dev, iio_scan_el_supply.number);
236 iio_scan_mask_set(indio_dev, iio_scan_el_gyro_x.number);
237 iio_scan_mask_set(indio_dev, iio_scan_el_gyro_y.number);
238 iio_scan_mask_set(indio_dev, iio_scan_el_gyro_z.number);
239 iio_scan_mask_set(indio_dev, iio_scan_el_accel_x.number);
240 iio_scan_mask_set(indio_dev, iio_scan_el_accel_y.number);
241 iio_scan_mask_set(indio_dev, iio_scan_el_accel_z.number);
242 iio_scan_mask_set(indio_dev, iio_scan_el_temp_x.number);
243 iio_scan_mask_set(indio_dev, iio_scan_el_temp_y.number);
244 iio_scan_mask_set(indio_dev, iio_scan_el_temp_z.number);
245 iio_scan_mask_set(indio_dev, iio_scan_el_adc_0.number);
246 indio_dev->scan_timestamp = true;
247
248 indio_dev->scan_el_attrs = &adis16350_scan_el_group;
249
250 ring = iio_sw_rb_allocate(indio_dev);
251 if (!ring) {
252 ret = -ENOMEM;
253 return ret;
254 }
255 indio_dev->ring = ring;
256 /* Effectively select the ring buffer implementation */
257 iio_ring_sw_register_funcs(&ring->access);
258 ring->preenable = &adis16350_data_rdy_ring_preenable;
259 ring->postenable = &adis16350_data_rdy_ring_postenable;
260 ring->predisable = &adis16350_data_rdy_ring_predisable;
261 ring->owner = THIS_MODULE;
262
263 indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
264 if (indio_dev->pollfunc == NULL) {
265 ret = -ENOMEM;
266 goto error_iio_sw_rb_free;;
267 }
268 indio_dev->pollfunc->poll_func_main = &adis16350_poll_func_th;
269 indio_dev->pollfunc->private_data = indio_dev;
270 indio_dev->modes |= INDIO_RING_TRIGGERED;
271 return 0;
272
273error_iio_sw_rb_free:
274 iio_sw_rb_free(indio_dev->ring);
275 return ret;
276}
277
278int adis16350_initialize_ring(struct iio_ring_buffer *ring)
279{
280 return iio_ring_buffer_register(ring, 0);
281}
282
283void adis16350_uninitialize_ring(struct iio_ring_buffer *ring)
284{
285 iio_ring_buffer_unregister(ring);
286}
diff --git a/drivers/staging/iio/imu/adis16350_trigger.c b/drivers/staging/iio/imu/adis16350_trigger.c
new file mode 100644
index 00000000000..1ffa75d05fa
--- /dev/null
+++ b/drivers/staging/iio/imu/adis16350_trigger.c
@@ -0,0 +1,127 @@
1#include <linux/interrupt.h>
2#include <linux/irq.h>
3#include <linux/mutex.h>
4#include <linux/device.h>
5#include <linux/kernel.h>
6#include <linux/sysfs.h>
7#include <linux/list.h>
8#include <linux/spi/spi.h>
9
10#include "../iio.h"
11#include "../sysfs.h"
12#include "../trigger.h"
13#include "adis16350.h"
14
15/**
16 * adis16350_data_rdy_trig_poll() the event handler for the data rdy trig
17 **/
18static int adis16350_data_rdy_trig_poll(struct iio_dev *dev_info,
19 int index,
20 s64 timestamp,
21 int no_test)
22{
23 struct adis16350_state *st = iio_dev_get_devdata(dev_info);
24 struct iio_trigger *trig = st->trig;
25
26 trig->timestamp = timestamp;
27 iio_trigger_poll(trig);
28
29 return IRQ_HANDLED;
30}
31
32IIO_EVENT_SH(data_rdy_trig, &adis16350_data_rdy_trig_poll);
33
34static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
35
36static struct attribute *adis16350_trigger_attrs[] = {
37 &dev_attr_name.attr,
38 NULL,
39};
40
41static const struct attribute_group adis16350_trigger_attr_group = {
42 .attrs = adis16350_trigger_attrs,
43};
44
45/**
46 * adis16350_data_rdy_trigger_set_state() set datardy interrupt state
47 **/
48static int adis16350_data_rdy_trigger_set_state(struct iio_trigger *trig,
49 bool state)
50{
51 struct adis16350_state *st = trig->private_data;
52 struct iio_dev *indio_dev = st->indio_dev;
53 int ret = 0;
54
55 dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
56 ret = adis16350_set_irq(&st->indio_dev->dev, state);
57 if (state == false) {
58 iio_remove_event_from_list(&iio_event_data_rdy_trig,
59 &indio_dev->interrupts[0]
60 ->ev_list);
61 /* possible quirk with handler currently worked around
62 by ensuring the work queue is empty */
63 flush_scheduled_work();
64 } else {
65 iio_add_event_to_list(&iio_event_data_rdy_trig,
66 &indio_dev->interrupts[0]->ev_list);
67 }
68 return ret;
69}
70
71/**
72 * adis16350_trig_try_reen() try renabling irq for data rdy trigger
73 * @trig: the datardy trigger
74 **/
75static int adis16350_trig_try_reen(struct iio_trigger *trig)
76{
77 struct adis16350_state *st = trig->private_data;
78 enable_irq(st->us->irq);
79 /* irq reenabled so success! */
80 return 0;
81}
82
83int adis16350_probe_trigger(struct iio_dev *indio_dev)
84{
85 int ret;
86 struct adis16350_state *st = indio_dev->dev_data;
87
88 st->trig = iio_allocate_trigger();
89 st->trig->name = kmalloc(IIO_TRIGGER_NAME_LENGTH, GFP_KERNEL);
90 if (!st->trig->name) {
91 ret = -ENOMEM;
92 goto error_free_trig;
93 }
94 snprintf((char *)st->trig->name,
95 IIO_TRIGGER_NAME_LENGTH,
96 "adis16350-dev%d", indio_dev->id);
97 st->trig->dev.parent = &st->us->dev;
98 st->trig->owner = THIS_MODULE;
99 st->trig->private_data = st;
100 st->trig->set_trigger_state = &adis16350_data_rdy_trigger_set_state;
101 st->trig->try_reenable = &adis16350_trig_try_reen;
102 st->trig->control_attrs = &adis16350_trigger_attr_group;
103 ret = iio_trigger_register(st->trig);
104
105 /* select default trigger */
106 indio_dev->trig = st->trig;
107 if (ret)
108 goto error_free_trig_name;
109
110 return 0;
111
112error_free_trig_name:
113 kfree(st->trig->name);
114error_free_trig:
115 iio_free_trigger(st->trig);
116
117 return ret;
118}
119
120void adis16350_remove_trigger(struct iio_dev *indio_dev)
121{
122 struct adis16350_state *state = indio_dev->dev_data;
123
124 iio_trigger_unregister(state->trig);
125 kfree(state->trig->name);
126 iio_free_trigger(state->trig);
127}