iio:adis16400: Increase samplerate precession
[deliverable/linux.git] / drivers / iio / imu / adis16400_core.c
CommitLineData
a9d26f00
BS
1/*
2 * adis16400.c support Analog Devices ADIS16400/5
3 * 3d 2g Linear Accelerometers,
4 * 3d Gyroscopes,
5 * 3d Magnetometers via SPI
6 *
7 * Copyright (c) 2009 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
0f8c9620 8 * Copyright (c) 2007 Jonathan Cameron <jic23@kernel.org>
6a6ec623 9 * Copyright (c) 2011 Analog Devices Inc.
a9d26f00
BS
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/interrupt.h>
18#include <linux/irq.h>
a9d26f00
BS
19#include <linux/delay.h>
20#include <linux/mutex.h>
21#include <linux/device.h>
22#include <linux/kernel.h>
23#include <linux/spi/spi.h>
1cb6c1f5 24#include <linux/slab.h>
a9d26f00
BS
25#include <linux/sysfs.h>
26#include <linux/list.h>
99c97852 27#include <linux/module.h>
a9d26f00 28
06458e27
JC
29#include <linux/iio/iio.h>
30#include <linux/iio/sysfs.h>
31#include <linux/iio/buffer.h>
cd888a17 32
a9d26f00
BS
33#include "adis16400.h"
34
2a29a90b 35enum adis16400_chip_variant {
8e886e65 36 ADIS16300,
85da5059 37 ADIS16334,
2a29a90b
JC
38 ADIS16350,
39 ADIS16360,
40 ADIS16362,
41 ADIS16364,
2a29a90b
JC
42 ADIS16400,
43};
44
cd888a17 45static int adis16334_get_freq(struct adis16400_state *st)
98c9373d 46{
ea2ccb3e 47 int ret;
f4c6d64b 48 uint16_t t;
ea2ccb3e 49
cd888a17 50 ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
ea2ccb3e
LPC
51 if (ret < 0)
52 return ret;
53
54 t >>= ADIS16334_RATE_DIV_SHIFT;
55
b24150e3 56 return 819200 >> t;
ea2ccb3e
LPC
57}
58
cd888a17 59static int adis16334_set_freq(struct adis16400_state *st, unsigned int freq)
ea2ccb3e
LPC
60{
61 unsigned int t;
62
b24150e3
LPC
63 if (freq < 819200)
64 t = ilog2(819200 / freq);
06220b89
LPC
65 else
66 t = 0;
ea2ccb3e
LPC
67
68 if (t > 0x31)
69 t = 0x31;
70
71 t <<= ADIS16334_RATE_DIV_SHIFT;
72 t |= ADIS16334_RATE_INT_CLK;
73
cd888a17 74 return adis_write_reg_16(&st->adis, ADIS16400_SMPL_PRD, t);
ea2ccb3e
LPC
75}
76
cd888a17 77static int adis16400_get_freq(struct adis16400_state *st)
ea2ccb3e 78{
98c9373d 79 int sps, ret;
f4c6d64b 80 uint16_t t;
98c9373d 81
cd888a17 82 ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &t);
98c9373d
JC
83 if (ret < 0)
84 return ret;
f4c6d64b 85
b24150e3 86 sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 52851 : 1638404;
98c9373d
JC
87 sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
88
89 return sps;
90}
91
cd888a17 92static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
ea2ccb3e 93{
ea2ccb3e
LPC
94 unsigned int t;
95
b24150e3 96 t = 1638404 / freq;
ea2ccb3e
LPC
97 if (t > 0)
98 t--;
99 t &= ADIS16400_SMPL_PRD_DIV_MASK;
f4c6d64b 100
ea2ccb3e 101 if ((t & ADIS16400_SMPL_PRD_DIV_MASK) >= 0x0A)
cd888a17 102 st->adis.spi->max_speed_hz = ADIS16400_SPI_SLOW;
ea2ccb3e 103 else
cd888a17 104 st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
ea2ccb3e 105
cd888a17 106 return adis_write_reg_8(&st->adis, ADIS16400_SMPL_PRD, t);
ea2ccb3e
LPC
107}
108
a9d26f00
BS
109static ssize_t adis16400_read_frequency(struct device *dev,
110 struct device_attribute *attr,
111 char *buf)
112{
dedb1e77 113 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
ea2ccb3e 114 struct adis16400_state *st = iio_priv(indio_dev);
f4c6d64b 115 int ret;
ea2ccb3e 116
cd888a17 117 ret = st->variant->get_freq(st);
98c9373d 118 if (ret < 0)
a9d26f00 119 return ret;
f4c6d64b 120
b24150e3 121 return sprintf(buf, "%d.%.3d\n", ret / 1000, ret % 1000);
a9d26f00
BS
122}
123
98c9373d
JC
124static const unsigned adis16400_3db_divisors[] = {
125 [0] = 2, /* Special case */
bdb20bdb
LPC
126 [1] = 6,
127 [2] = 12,
128 [3] = 25,
129 [4] = 50,
130 [5] = 100,
131 [6] = 200,
132 [7] = 200, /* Not a valid setting */
98c9373d
JC
133};
134
135static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
136{
cd888a17 137 struct adis16400_state *st = iio_priv(indio_dev);
f4c6d64b 138 uint16_t val16;
98c9373d 139 int i, ret;
bdb20bdb
LPC
140
141 for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 1; i--) {
142 if (sps / adis16400_3db_divisors[i] >= val)
98c9373d 143 break;
bdb20bdb
LPC
144 }
145
cd888a17 146 ret = adis_read_reg_16(&st->adis, ADIS16400_SENS_AVG, &val16);
bdb20bdb
LPC
147 if (ret < 0)
148 return ret;
98c9373d 149
cd888a17 150 ret = adis_write_reg_16(&st->adis, ADIS16400_SENS_AVG,
bdb20bdb 151 (val16 & ~0x07) | i);
98c9373d
JC
152 return ret;
153}
154
a9d26f00 155static ssize_t adis16400_write_frequency(struct device *dev,
f4c6d64b 156 struct device_attribute *attr, const char *buf, size_t len)
a9d26f00 157{
dedb1e77 158 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
38d15f06 159 struct adis16400_state *st = iio_priv(indio_dev);
b24150e3 160 int i, f, val;
a9d26f00 161 int ret;
a9d26f00 162
b24150e3 163 ret = iio_str_to_fixpoint(buf, 100, &i, &f);
a9d26f00
BS
164 if (ret)
165 return ret;
f4c6d64b 166
b24150e3
LPC
167 val = i * 1000 + f;
168
169 if (val <= 0)
50d4b306 170 return -EINVAL;
a9d26f00
BS
171
172 mutex_lock(&indio_dev->mlock);
cd888a17 173 st->variant->set_freq(st, val);
a9d26f00
BS
174 mutex_unlock(&indio_dev->mlock);
175
176 return ret ? ret : len;
177}
178
a9d26f00 179/* Power down the device */
e7854845 180static int adis16400_stop_device(struct iio_dev *indio_dev)
a9d26f00 181{
cd888a17 182 struct adis16400_state *st = iio_priv(indio_dev);
a9d26f00 183 int ret;
a9d26f00 184
f4c6d64b
LPC
185 ret = adis_write_reg_16(&st->adis, ADIS16400_SLP_CNT,
186 ADIS16400_SLP_CNT_POWER_OFF);
a9d26f00 187 if (ret)
e7854845
JC
188 dev_err(&indio_dev->dev,
189 "problem with turning device off: SLP_CNT");
a9d26f00
BS
190
191 return ret;
192}
193
38d15f06 194static int adis16400_initial_setup(struct iio_dev *indio_dev)
a9d26f00 195{
38d15f06 196 struct adis16400_state *st = iio_priv(indio_dev);
f4c6d64b
LPC
197 uint16_t prod_id, smp_prd;
198 unsigned int device_id;
199 int ret;
a9d26f00 200
ea2ccb3e
LPC
201 /* use low spi speed for init if the device has a slow mode */
202 if (st->variant->flags & ADIS16400_HAS_SLOW_MODE)
cd888a17 203 st->adis.spi->max_speed_hz = ADIS16400_SPI_SLOW;
ea2ccb3e 204 else
cd888a17
LPC
205 st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
206 st->adis.spi->mode = SPI_MODE_3;
207 spi_setup(st->adis.spi);
a9d26f00 208
cd888a17
LPC
209 ret = adis_initial_startup(&st->adis);
210 if (ret)
211 return ret;
a9d26f00 212
2a29a90b 213 if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
cd888a17 214 ret = adis_read_reg_16(&st->adis,
2a29a90b
JC
215 ADIS16400_PRODUCT_ID, &prod_id);
216 if (ret)
217 goto err_ret;
a9d26f00 218
fc8850c0
LPC
219 sscanf(indio_dev->name, "adis%u\n", &device_id);
220
221 if (prod_id != device_id)
222 dev_warn(&indio_dev->dev, "Device ID(%u) and product ID(%u) do not match.",
223 device_id, prod_id);
a9d26f00 224
69d80bae 225 dev_info(&indio_dev->dev, "%s: prod_id 0x%04x at CS%d (irq %d)\n",
f4c6d64b
LPC
226 indio_dev->name, prod_id,
227 st->adis.spi->chip_select, st->adis.spi->irq);
2a29a90b 228 }
a9d26f00 229 /* use high spi speed if possible */
ea2ccb3e 230 if (st->variant->flags & ADIS16400_HAS_SLOW_MODE) {
cd888a17 231 ret = adis_read_reg_16(&st->adis, ADIS16400_SMPL_PRD, &smp_prd);
ea2ccb3e
LPC
232 if (ret)
233 goto err_ret;
234
235 if ((smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
cd888a17
LPC
236 st->adis.spi->max_speed_hz = ADIS16400_SPI_FAST;
237 spi_setup(st->adis.spi);
ea2ccb3e 238 }
a9d26f00
BS
239 }
240
a9d26f00 241err_ret:
a9d26f00
BS
242 return ret;
243}
244
a9d26f00 245static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
521de518
JC
246 adis16400_read_frequency,
247 adis16400_write_frequency);
a9d26f00 248
f4c6d64b 249static const uint8_t adis16400_addresses[] = {
cd888a17
LPC
250 [ADIS16400_SCAN_GYRO_X] = ADIS16400_XGYRO_OFF,
251 [ADIS16400_SCAN_GYRO_Y] = ADIS16400_YGYRO_OFF,
252 [ADIS16400_SCAN_GYRO_Z] = ADIS16400_ZGYRO_OFF,
253 [ADIS16400_SCAN_ACC_X] = ADIS16400_XACCL_OFF,
254 [ADIS16400_SCAN_ACC_Y] = ADIS16400_YACCL_OFF,
255 [ADIS16400_SCAN_ACC_Z] = ADIS16400_ZACCL_OFF,
e7854845
JC
256};
257
258static int adis16400_write_raw(struct iio_dev *indio_dev,
f4c6d64b 259 struct iio_chan_spec const *chan, int val, int val2, long info)
e7854845 260{
98c9373d
JC
261 struct adis16400_state *st = iio_priv(indio_dev);
262 int ret, sps;
521de518 263
f4c6d64b 264 switch (info) {
c8a9f805 265 case IIO_CHAN_INFO_CALIBBIAS:
e7854845 266 mutex_lock(&indio_dev->mlock);
cd888a17
LPC
267 ret = adis_write_reg_16(&st->adis,
268 adis16400_addresses[chan->scan_index], val);
e7854845
JC
269 mutex_unlock(&indio_dev->mlock);
270 return ret;
98c9373d 271 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
f4c6d64b
LPC
272 /*
273 * Need to cache values so we can update if the frequency
274 * changes.
275 */
98c9373d
JC
276 mutex_lock(&indio_dev->mlock);
277 st->filt_int = val;
278 /* Work out update to current value */
cd888a17 279 sps = st->variant->get_freq(st);
98c9373d
JC
280 if (sps < 0) {
281 mutex_unlock(&indio_dev->mlock);
282 return sps;
283 }
284
b24150e3
LPC
285 ret = adis16400_set_filter(indio_dev, sps,
286 val * 1000 + val2 / 1000);
98c9373d
JC
287 mutex_unlock(&indio_dev->mlock);
288 return ret;
e7854845
JC
289 default:
290 return -EINVAL;
291 }
292}
293
294static int adis16400_read_raw(struct iio_dev *indio_dev,
f4c6d64b 295 struct iio_chan_spec const *chan, int *val, int *val2, long info)
e7854845 296{
38d15f06 297 struct adis16400_state *st = iio_priv(indio_dev);
f4c6d64b 298 int16_t val16;
cd888a17 299 int ret;
e7854845 300
f4c6d64b 301 switch (info) {
a5d016d4 302 case IIO_CHAN_INFO_RAW:
cd888a17 303 return adis_single_conversion(indio_dev, chan, 0, val);
c8a9f805 304 case IIO_CHAN_INFO_SCALE:
e7854845 305 switch (chan->type) {
41ea040c 306 case IIO_ANGL_VEL:
e7854845 307 *val = 0;
2a29a90b 308 *val2 = st->variant->gyro_scale_micro;
e7854845 309 return IIO_VAL_INT_PLUS_MICRO;
6835cb6b 310 case IIO_VOLTAGE:
e7854845 311 *val = 0;
1cf8c97f
LPC
312 if (chan->channel == 0) {
313 *val = 2;
314 *val2 = 418000; /* 2.418 mV */
315 } else {
316 *val = 0;
317 *val2 = 805800; /* 805.8 uV */
318 }
e7854845
JC
319 return IIO_VAL_INT_PLUS_MICRO;
320 case IIO_ACCEL:
321 *val = 0;
2a29a90b 322 *val2 = st->variant->accel_scale_micro;
e7854845
JC
323 return IIO_VAL_INT_PLUS_MICRO;
324 case IIO_MAGN:
325 *val = 0;
1cf8c97f 326 *val2 = 500; /* 0.5 mgauss */
e7854845
JC
327 return IIO_VAL_INT_PLUS_MICRO;
328 case IIO_TEMP:
760ebc0d
LPC
329 *val = st->variant->temp_scale_nano / 1000000;
330 *val2 = (st->variant->temp_scale_nano % 1000000);
e7854845
JC
331 return IIO_VAL_INT_PLUS_MICRO;
332 default:
333 return -EINVAL;
334 }
c8a9f805 335 case IIO_CHAN_INFO_CALIBBIAS:
e7854845 336 mutex_lock(&indio_dev->mlock);
cd888a17
LPC
337 ret = adis_read_reg_16(&st->adis,
338 adis16400_addresses[chan->scan_index], &val16);
2a29a90b
JC
339 mutex_unlock(&indio_dev->mlock);
340 if (ret)
e7854845 341 return ret;
e7854845
JC
342 val16 = ((val16 & 0xFFF) << 4) >> 4;
343 *val = val16;
344 return IIO_VAL_INT;
c8a9f805 345 case IIO_CHAN_INFO_OFFSET:
e7854845 346 /* currently only temperature */
760ebc0d 347 *val = st->variant->temp_offset;
1cf8c97f 348 return IIO_VAL_INT;
98c9373d
JC
349 case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
350 mutex_lock(&indio_dev->mlock);
351 /* Need both the number of taps and the sampling frequency */
cd888a17 352 ret = adis_read_reg_16(&st->adis,
98c9373d
JC
353 ADIS16400_SENS_AVG,
354 &val16);
355 if (ret < 0) {
356 mutex_unlock(&indio_dev->mlock);
357 return ret;
358 }
cd888a17 359 ret = st->variant->get_freq(st);
b24150e3
LPC
360 if (ret >= 0) {
361 ret /= adis16400_3db_divisors[val16 & 0x07];
362 *val = ret / 1000;
363 *val2 = (ret % 1000) * 1000;
364 }
98c9373d
JC
365 mutex_unlock(&indio_dev->mlock);
366 if (ret < 0)
367 return ret;
368 return IIO_VAL_INT_PLUS_MICRO;
e7854845
JC
369 default:
370 return -EINVAL;
371 }
372}
373
599acfbb
LPC
374#define ADIS16400_VOLTAGE_CHAN(addr, bits, name, si) { \
375 .type = IIO_VOLTAGE, \
376 .indexed = 1, \
377 .channel = 0, \
378 .extend_name = name, \
379 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
380 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
381 .address = (addr), \
382 .scan_index = (si), \
5eda3550
LPC
383 .scan_type = { \
384 .sign = 'u', \
385 .realbits = (bits), \
386 .storagebits = 16, \
387 .shift = 0, \
388 .endianness = IIO_BE, \
389 }, \
599acfbb
LPC
390}
391
392#define ADIS16400_SUPPLY_CHAN(addr, bits) \
393 ADIS16400_VOLTAGE_CHAN(addr, bits, "supply", ADIS16400_SCAN_SUPPLY)
394
395#define ADIS16400_AUX_ADC_CHAN(addr, bits) \
396 ADIS16400_VOLTAGE_CHAN(addr, bits, NULL, ADIS16400_SCAN_ADC)
397
398#define ADIS16400_GYRO_CHAN(mod, addr, bits) { \
399 .type = IIO_ANGL_VEL, \
400 .modified = 1, \
401 .channel2 = IIO_MOD_ ## mod, \
402 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
403 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
404 IIO_CHAN_INFO_SCALE_SHARED_BIT | \
405 IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
406 .address = addr, \
407 .scan_index = ADIS16400_SCAN_GYRO_ ## mod, \
5eda3550
LPC
408 .scan_type = { \
409 .sign = 's', \
410 .realbits = (bits), \
411 .storagebits = 16, \
412 .shift = 0, \
413 .endianness = IIO_BE, \
414 }, \
599acfbb
LPC
415}
416
417#define ADIS16400_ACCEL_CHAN(mod, addr, bits) { \
418 .type = IIO_ACCEL, \
419 .modified = 1, \
420 .channel2 = IIO_MOD_ ## mod, \
421 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
422 IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT | \
423 IIO_CHAN_INFO_SCALE_SHARED_BIT | \
424 IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
425 .address = (addr), \
426 .scan_index = ADIS16400_SCAN_ACC_ ## mod, \
5eda3550
LPC
427 .scan_type = { \
428 .sign = 's', \
429 .realbits = (bits), \
430 .storagebits = 16, \
431 .shift = 0, \
432 .endianness = IIO_BE, \
433 }, \
599acfbb
LPC
434}
435
436#define ADIS16400_MAGN_CHAN(mod, addr, bits) { \
437 .type = IIO_MAGN, \
438 .modified = 1, \
439 .channel2 = IIO_MOD_ ## mod, \
440 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
441 IIO_CHAN_INFO_SCALE_SHARED_BIT | \
442 IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
443 .address = (addr), \
444 .scan_index = ADIS16400_SCAN_MAGN_ ## mod, \
5eda3550
LPC
445 .scan_type = { \
446 .sign = 's', \
447 .realbits = (bits), \
448 .storagebits = 16, \
449 .shift = 0, \
450 .endianness = IIO_BE, \
451 }, \
599acfbb
LPC
452}
453
454#define ADIS16400_MOD_TEMP_NAME_X "x"
455#define ADIS16400_MOD_TEMP_NAME_Y "y"
456#define ADIS16400_MOD_TEMP_NAME_Z "z"
457
458#define ADIS16400_MOD_TEMP_CHAN(mod, addr, bits) { \
459 .type = IIO_TEMP, \
460 .indexed = 1, \
461 .channel = 0, \
462 .extend_name = ADIS16400_MOD_TEMP_NAME_ ## mod, \
463 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
464 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
465 IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \
466 IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY_SHARED_BIT, \
467 .address = (addr), \
468 .scan_index = ADIS16350_SCAN_TEMP_ ## mod, \
5eda3550
LPC
469 .scan_type = { \
470 .sign = 's', \
471 .realbits = (bits), \
472 .storagebits = 16, \
473 .shift = 0, \
474 .endianness = IIO_BE, \
475 }, \
599acfbb
LPC
476}
477
478#define ADIS16400_TEMP_CHAN(addr, bits) { \
479 .type = IIO_TEMP, \
480 .indexed = 1, \
481 .channel = 0, \
482 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
483 IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \
484 IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
485 .address = (addr), \
486 .scan_index = ADIS16350_SCAN_TEMP_X, \
5eda3550
LPC
487 .scan_type = { \
488 .sign = 's', \
489 .realbits = (bits), \
490 .storagebits = 16, \
491 .shift = 0, \
492 .endianness = IIO_BE, \
493 }, \
599acfbb
LPC
494}
495
496#define ADIS16400_INCLI_CHAN(mod, addr, bits) { \
497 .type = IIO_INCLI, \
498 .modified = 1, \
499 .channel2 = IIO_MOD_ ## mod, \
500 .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
501 IIO_CHAN_INFO_SCALE_SHARED_BIT, \
502 .address = (addr), \
503 .scan_index = ADIS16300_SCAN_INCLI_ ## mod, \
5eda3550
LPC
504 .scan_type = { \
505 .sign = 's', \
506 .realbits = (bits), \
507 .storagebits = 16, \
508 .shift = 0, \
509 .endianness = IIO_BE, \
510 }, \
599acfbb
LPC
511}
512
f4e4b955 513static const struct iio_chan_spec adis16400_channels[] = {
599acfbb
LPC
514 ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 14),
515 ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
516 ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
517 ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
518 ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
519 ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
520 ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
521 ADIS16400_MAGN_CHAN(X, ADIS16400_XMAGN_OUT, 14),
522 ADIS16400_MAGN_CHAN(Y, ADIS16400_YMAGN_OUT, 14),
523 ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14),
524 ADIS16400_TEMP_CHAN(ADIS16400_TEMP_OUT, 12),
525 ADIS16400_AUX_ADC_CHAN(ADIS16400_AUX_ADC, 12),
e7854845
JC
526 IIO_CHAN_SOFT_TIMESTAMP(12)
527};
528
f4e4b955 529static const struct iio_chan_spec adis16350_channels[] = {
599acfbb
LPC
530 ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 12),
531 ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
532 ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
533 ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
534 ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
535 ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
536 ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
537 ADIS16400_MAGN_CHAN(X, ADIS16400_XMAGN_OUT, 14),
538 ADIS16400_MAGN_CHAN(Y, ADIS16400_YMAGN_OUT, 14),
539 ADIS16400_MAGN_CHAN(Z, ADIS16400_ZMAGN_OUT, 14),
540 ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12),
541 ADIS16400_MOD_TEMP_CHAN(X, ADIS16350_XTEMP_OUT, 12),
542 ADIS16400_MOD_TEMP_CHAN(Y, ADIS16350_YTEMP_OUT, 12),
543 ADIS16400_MOD_TEMP_CHAN(Z, ADIS16350_ZTEMP_OUT, 12),
2a29a90b
JC
544 IIO_CHAN_SOFT_TIMESTAMP(11)
545};
546
f4e4b955 547static const struct iio_chan_spec adis16300_channels[] = {
599acfbb
LPC
548 ADIS16400_SUPPLY_CHAN(ADIS16400_SUPPLY_OUT, 12),
549 ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
550 ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
551 ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
552 ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
553 ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12),
554 ADIS16400_AUX_ADC_CHAN(ADIS16300_AUX_ADC, 12),
555 ADIS16400_INCLI_CHAN(X, ADIS16300_PITCH_OUT, 13),
556 ADIS16400_INCLI_CHAN(Y, ADIS16300_ROLL_OUT, 13),
8e886e65
JC
557 IIO_CHAN_SOFT_TIMESTAMP(14)
558};
559
85da5059 560static const struct iio_chan_spec adis16334_channels[] = {
599acfbb
LPC
561 ADIS16400_GYRO_CHAN(X, ADIS16400_XGYRO_OUT, 14),
562 ADIS16400_GYRO_CHAN(Y, ADIS16400_YGYRO_OUT, 14),
563 ADIS16400_GYRO_CHAN(Z, ADIS16400_ZGYRO_OUT, 14),
564 ADIS16400_ACCEL_CHAN(X, ADIS16400_XACCL_OUT, 14),
565 ADIS16400_ACCEL_CHAN(Y, ADIS16400_YACCL_OUT, 14),
566 ADIS16400_ACCEL_CHAN(Z, ADIS16400_ZACCL_OUT, 14),
567 ADIS16400_TEMP_CHAN(ADIS16350_XTEMP_OUT, 12),
568 IIO_CHAN_SOFT_TIMESTAMP(8)
88b42f3a
JC
569};
570
a9d26f00 571static struct attribute *adis16400_attributes[] = {
a9d26f00 572 &iio_dev_attr_sampling_frequency.dev_attr.attr,
a9d26f00
BS
573 NULL
574};
575
576static const struct attribute_group adis16400_attribute_group = {
577 .attrs = adis16400_attributes,
578};
579
2a29a90b 580static struct adis16400_chip_info adis16400_chips[] = {
8e886e65
JC
581 [ADIS16300] = {
582 .channels = adis16300_channels,
583 .num_channels = ARRAY_SIZE(adis16300_channels),
ea2ccb3e 584 .flags = ADIS16400_HAS_SLOW_MODE,
1cf8c97f 585 .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
8e886e65 586 .accel_scale_micro = 5884,
760ebc0d
LPC
587 .temp_scale_nano = 140000000, /* 0.14 C */
588 .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
ea2ccb3e
LPC
589 .set_freq = adis16400_set_freq,
590 .get_freq = adis16400_get_freq,
8e886e65 591 },
85da5059
JC
592 [ADIS16334] = {
593 .channels = adis16334_channels,
594 .num_channels = ARRAY_SIZE(adis16334_channels),
3c7f0c2b 595 .flags = ADIS16400_HAS_PROD_ID,
1cf8c97f
LPC
596 .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
597 .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
760ebc0d
LPC
598 .temp_scale_nano = 67850000, /* 0.06785 C */
599 .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */
ea2ccb3e
LPC
600 .set_freq = adis16334_set_freq,
601 .get_freq = adis16334_get_freq,
88b42f3a 602 },
2a29a90b
JC
603 [ADIS16350] = {
604 .channels = adis16350_channels,
605 .num_channels = ARRAY_SIZE(adis16350_channels),
1cf8c97f
LPC
606 .gyro_scale_micro = IIO_DEGREE_TO_RAD(73260), /* 0.07326 deg/s */
607 .accel_scale_micro = IIO_G_TO_M_S_2(2522), /* 0.002522 g */
760ebc0d
LPC
608 .temp_scale_nano = 145300000, /* 0.1453 C */
609 .temp_offset = 25000000 / 145300, /* 25 C = 0x00 */
ea2ccb3e
LPC
610 .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE,
611 .set_freq = adis16400_set_freq,
612 .get_freq = adis16400_get_freq,
2a29a90b
JC
613 },
614 [ADIS16360] = {
615 .channels = adis16350_channels,
616 .num_channels = ARRAY_SIZE(adis16350_channels),
ea2ccb3e 617 .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
1cf8c97f
LPC
618 .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
619 .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
760ebc0d
LPC
620 .temp_scale_nano = 136000000, /* 0.136 C */
621 .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
ea2ccb3e
LPC
622 .set_freq = adis16400_set_freq,
623 .get_freq = adis16400_get_freq,
2a29a90b
JC
624 },
625 [ADIS16362] = {
626 .channels = adis16350_channels,
627 .num_channels = ARRAY_SIZE(adis16350_channels),
ea2ccb3e 628 .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
1cf8c97f
LPC
629 .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
630 .accel_scale_micro = IIO_G_TO_M_S_2(333), /* 0.333 mg */
760ebc0d
LPC
631 .temp_scale_nano = 136000000, /* 0.136 C */
632 .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
ea2ccb3e
LPC
633 .set_freq = adis16400_set_freq,
634 .get_freq = adis16400_get_freq,
2a29a90b
JC
635 },
636 [ADIS16364] = {
637 .channels = adis16350_channels,
638 .num_channels = ARRAY_SIZE(adis16350_channels),
ea2ccb3e 639 .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
1cf8c97f
LPC
640 .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
641 .accel_scale_micro = IIO_G_TO_M_S_2(1000), /* 1 mg */
760ebc0d
LPC
642 .temp_scale_nano = 136000000, /* 0.136 C */
643 .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */
ea2ccb3e
LPC
644 .set_freq = adis16400_set_freq,
645 .get_freq = adis16400_get_freq,
2a29a90b 646 },
2a29a90b
JC
647 [ADIS16400] = {
648 .channels = adis16400_channels,
649 .num_channels = ARRAY_SIZE(adis16400_channels),
ea2ccb3e 650 .flags = ADIS16400_HAS_PROD_ID | ADIS16400_HAS_SLOW_MODE,
1cf8c97f
LPC
651 .gyro_scale_micro = IIO_DEGREE_TO_RAD(50000), /* 0.05 deg/s */
652 .accel_scale_micro = IIO_G_TO_M_S_2(3333), /* 3.333 mg */
760ebc0d
LPC
653 .temp_scale_nano = 140000000, /* 0.14 C */
654 .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */
ea2ccb3e
LPC
655 .set_freq = adis16400_set_freq,
656 .get_freq = adis16400_get_freq,
2a29a90b
JC
657 }
658};
659
6fe8135f
JC
660static const struct iio_info adis16400_info = {
661 .driver_module = THIS_MODULE,
662 .read_raw = &adis16400_read_raw,
663 .write_raw = &adis16400_write_raw,
664 .attrs = &adis16400_attribute_group,
5eda3550
LPC
665 .update_scan_mode = adis16400_update_scan_mode,
666};
667
668static const unsigned long adis16400_burst_scan_mask[] = {
669 ~0UL,
670 0,
6fe8135f 671};
2a29a90b 672
cd888a17
LPC
673static const char * const adis16400_status_error_msgs[] = {
674 [ADIS16400_DIAG_STAT_ZACCL_FAIL] = "Z-axis accelerometer self-test failure",
675 [ADIS16400_DIAG_STAT_YACCL_FAIL] = "Y-axis accelerometer self-test failure",
676 [ADIS16400_DIAG_STAT_XACCL_FAIL] = "X-axis accelerometer self-test failure",
677 [ADIS16400_DIAG_STAT_XGYRO_FAIL] = "X-axis gyroscope self-test failure",
678 [ADIS16400_DIAG_STAT_YGYRO_FAIL] = "Y-axis gyroscope self-test failure",
679 [ADIS16400_DIAG_STAT_ZGYRO_FAIL] = "Z-axis gyroscope self-test failure",
680 [ADIS16400_DIAG_STAT_ALARM2] = "Alarm 2 active",
681 [ADIS16400_DIAG_STAT_ALARM1] = "Alarm 1 active",
682 [ADIS16400_DIAG_STAT_FLASH_CHK] = "Flash checksum error",
683 [ADIS16400_DIAG_STAT_SELF_TEST] = "Self test error",
684 [ADIS16400_DIAG_STAT_OVERFLOW] = "Sensor overrange",
685 [ADIS16400_DIAG_STAT_SPI_FAIL] = "SPI failure",
686 [ADIS16400_DIAG_STAT_FLASH_UPT] = "Flash update failed",
687 [ADIS16400_DIAG_STAT_POWER_HIGH] = "Power supply above 5.25V",
688 [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V",
689};
690
691static const struct adis_data adis16400_data = {
692 .msc_ctrl_reg = ADIS16400_MSC_CTRL,
693 .glob_cmd_reg = ADIS16400_GLOB_CMD,
694 .diag_stat_reg = ADIS16400_DIAG_STAT,
695
696 .read_delay = 50,
697 .write_delay = 50,
698
699 .self_test_mask = ADIS16400_MSC_CTRL_MEM_TEST,
700 .startup_delay = ADIS16400_STARTUP_DELAY,
701
702 .status_error_msgs = adis16400_status_error_msgs,
703 .status_error_mask = BIT(ADIS16400_DIAG_STAT_ZACCL_FAIL) |
704 BIT(ADIS16400_DIAG_STAT_YACCL_FAIL) |
705 BIT(ADIS16400_DIAG_STAT_XACCL_FAIL) |
706 BIT(ADIS16400_DIAG_STAT_XGYRO_FAIL) |
707 BIT(ADIS16400_DIAG_STAT_YGYRO_FAIL) |
708 BIT(ADIS16400_DIAG_STAT_ZGYRO_FAIL) |
709 BIT(ADIS16400_DIAG_STAT_ALARM2) |
710 BIT(ADIS16400_DIAG_STAT_ALARM1) |
711 BIT(ADIS16400_DIAG_STAT_FLASH_CHK) |
712 BIT(ADIS16400_DIAG_STAT_SELF_TEST) |
713 BIT(ADIS16400_DIAG_STAT_OVERFLOW) |
714 BIT(ADIS16400_DIAG_STAT_SPI_FAIL) |
715 BIT(ADIS16400_DIAG_STAT_FLASH_UPT) |
716 BIT(ADIS16400_DIAG_STAT_POWER_HIGH) |
717 BIT(ADIS16400_DIAG_STAT_POWER_LOW),
718};
719
4ae1c61f 720static int adis16400_probe(struct spi_device *spi)
a9d26f00 721{
38d15f06 722 struct adis16400_state *st;
f4c6d64b
LPC
723 struct iio_dev *indio_dev;
724 int ret;
725
726 indio_dev = iio_device_alloc(sizeof(*st));
727 if (indio_dev == NULL)
728 return -ENOMEM;
729
38d15f06 730 st = iio_priv(indio_dev);
a9d26f00 731 /* this is only used for removal purposes */
38d15f06 732 spi_set_drvdata(spi, indio_dev);
a9d26f00 733
a9d26f00 734 /* setup the industrialio driver allocated elements */
2a29a90b 735 st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
38d15f06
JC
736 indio_dev->dev.parent = &spi->dev;
737 indio_dev->name = spi_get_device_id(spi)->name;
38d15f06
JC
738 indio_dev->channels = st->variant->channels;
739 indio_dev->num_channels = st->variant->num_channels;
6fe8135f 740 indio_dev->info = &adis16400_info;
38d15f06
JC
741 indio_dev->modes = INDIO_DIRECT_MODE;
742
5eda3550
LPC
743 if (!(st->variant->flags & ADIS16400_NO_BURST))
744 indio_dev->available_scan_masks = adis16400_burst_scan_mask;
745
cd888a17
LPC
746 ret = adis_init(&st->adis, indio_dev, spi, &adis16400_data);
747 if (ret)
748 goto error_free_dev;
749
5eda3550
LPC
750 ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev,
751 adis16400_trigger_handler);
a9d26f00
BS
752 if (ret)
753 goto error_free_dev;
754
a9d26f00 755 /* Get the device into a sane initial state */
38d15f06 756 ret = adis16400_initial_setup(indio_dev);
a9d26f00 757 if (ret)
5eda3550 758 goto error_cleanup_buffer;
26d25ae3
JC
759 ret = iio_device_register(indio_dev);
760 if (ret)
5eda3550 761 goto error_cleanup_buffer;
26d25ae3 762
a9d26f00
BS
763 return 0;
764
5eda3550
LPC
765error_cleanup_buffer:
766 adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
a9d26f00 767error_free_dev:
7cbb7537 768 iio_device_free(indio_dev);
a9d26f00
BS
769 return ret;
770}
771
447d4f29 772static int adis16400_remove(struct spi_device *spi)
a9d26f00 773{
f4c6d64b 774 struct iio_dev *indio_dev = spi_get_drvdata(spi);
cd888a17 775 struct adis16400_state *st = iio_priv(indio_dev);
a9d26f00 776
d2fffd6c 777 iio_device_unregister(indio_dev);
0b4ac3dc 778 adis16400_stop_device(indio_dev);
a9d26f00 779
5eda3550 780 adis_cleanup_buffer_and_trigger(&st->adis, indio_dev);
cd888a17 781
7cbb7537 782 iio_device_free(indio_dev);
2a29a90b 783
a9d26f00 784 return 0;
a9d26f00
BS
785}
786
2a29a90b 787static const struct spi_device_id adis16400_id[] = {
8e886e65 788 {"adis16300", ADIS16300},
85da5059 789 {"adis16334", ADIS16334},
2a29a90b
JC
790 {"adis16350", ADIS16350},
791 {"adis16354", ADIS16350},
792 {"adis16355", ADIS16350},
793 {"adis16360", ADIS16360},
794 {"adis16362", ADIS16362},
795 {"adis16364", ADIS16364},
a7462e64 796 {"adis16365", ADIS16360},
2a29a90b
JC
797 {"adis16400", ADIS16400},
798 {"adis16405", ADIS16400},
799 {}
800};
55e4390c 801MODULE_DEVICE_TABLE(spi, adis16400_id);
2a29a90b 802
a9d26f00
BS
803static struct spi_driver adis16400_driver = {
804 .driver = {
805 .name = "adis16400",
806 .owner = THIS_MODULE,
807 },
2a29a90b 808 .id_table = adis16400_id,
a9d26f00 809 .probe = adis16400_probe,
e543acf0 810 .remove = adis16400_remove,
a9d26f00 811};
ae6ae6fe 812module_spi_driver(adis16400_driver);
a9d26f00
BS
813
814MODULE_AUTHOR("Manuel Stahl <manuel.stahl@iis.fraunhofer.de>");
815MODULE_DESCRIPTION("Analog Devices ADIS16400/5 IMU SPI driver");
816MODULE_LICENSE("GPL v2");
This page took 0.361263 seconds and 5 git commands to generate.