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