1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * ADIS16475 IMU driver |
4 | * |
5 | * Copyright 2019 Analog Devices Inc. |
6 | */ |
7 | #include <linux/bitfield.h> |
8 | #include <linux/bitops.h> |
9 | #include <linux/clk.h> |
10 | #include <linux/debugfs.h> |
11 | #include <linux/delay.h> |
12 | #include <linux/device.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/iio/buffer.h> |
15 | #include <linux/iio/iio.h> |
16 | #include <linux/iio/imu/adis.h> |
17 | #include <linux/iio/trigger_consumer.h> |
18 | #include <linux/irq.h> |
19 | #include <linux/lcm.h> |
20 | #include <linux/math.h> |
21 | #include <linux/module.h> |
22 | #include <linux/mod_devicetable.h> |
23 | #include <linux/property.h> |
24 | #include <linux/spi/spi.h> |
25 | |
26 | #define ADIS16475_REG_DIAG_STAT 0x02 |
27 | #define ADIS16475_REG_X_GYRO_L 0x04 |
28 | #define ADIS16475_REG_Y_GYRO_L 0x08 |
29 | #define ADIS16475_REG_Z_GYRO_L 0x0C |
30 | #define ADIS16475_REG_X_ACCEL_L 0x10 |
31 | #define ADIS16475_REG_Y_ACCEL_L 0x14 |
32 | #define ADIS16475_REG_Z_ACCEL_L 0x18 |
33 | #define ADIS16475_REG_TEMP_OUT 0x1c |
34 | #define ADIS16475_REG_X_DELTANG_L 0x24 |
35 | #define ADIS16475_REG_Y_DELTANG_L 0x28 |
36 | #define ADIS16475_REG_Z_DELTANG_L 0x2C |
37 | #define ADIS16475_REG_X_DELTVEL_L 0x30 |
38 | #define ADIS16475_REG_Y_DELTVEL_L 0x34 |
39 | #define ADIS16475_REG_Z_DELTVEL_L 0x38 |
40 | #define ADIS16475_REG_X_GYRO_BIAS_L 0x40 |
41 | #define ADIS16475_REG_Y_GYRO_BIAS_L 0x44 |
42 | #define ADIS16475_REG_Z_GYRO_BIAS_L 0x48 |
43 | #define ADIS16475_REG_X_ACCEL_BIAS_L 0x4c |
44 | #define ADIS16475_REG_Y_ACCEL_BIAS_L 0x50 |
45 | #define ADIS16475_REG_Z_ACCEL_BIAS_L 0x54 |
46 | #define ADIS16475_REG_FILT_CTRL 0x5c |
47 | #define ADIS16475_FILT_CTRL_MASK GENMASK(2, 0) |
48 | #define ADIS16475_FILT_CTRL(x) FIELD_PREP(ADIS16475_FILT_CTRL_MASK, x) |
49 | #define ADIS16475_REG_MSG_CTRL 0x60 |
50 | #define ADIS16475_MSG_CTRL_DR_POL_MASK BIT(0) |
51 | #define ADIS16475_MSG_CTRL_DR_POL(x) \ |
52 | FIELD_PREP(ADIS16475_MSG_CTRL_DR_POL_MASK, x) |
53 | #define ADIS16475_SYNC_MODE_MASK GENMASK(4, 2) |
54 | #define ADIS16475_SYNC_MODE(x) FIELD_PREP(ADIS16475_SYNC_MODE_MASK, x) |
55 | #define ADIS16475_REG_UP_SCALE 0x62 |
56 | #define ADIS16475_REG_DEC_RATE 0x64 |
57 | #define ADIS16475_REG_GLOB_CMD 0x68 |
58 | #define ADIS16475_REG_FIRM_REV 0x6c |
59 | #define ADIS16475_REG_FIRM_DM 0x6e |
60 | #define ADIS16475_REG_FIRM_Y 0x70 |
61 | #define ADIS16475_REG_PROD_ID 0x72 |
62 | #define ADIS16475_REG_SERIAL_NUM 0x74 |
63 | #define ADIS16475_REG_FLASH_CNT 0x7c |
64 | #define ADIS16500_BURST_DATA_SEL_MASK BIT(8) |
65 | #define ADIS16500_BURST32_MASK BIT(9) |
66 | #define ADIS16500_BURST32(x) FIELD_PREP(ADIS16500_BURST32_MASK, x) |
67 | /* number of data elements in burst mode */ |
68 | #define ADIS16475_BURST32_MAX_DATA 32 |
69 | #define ADIS16475_BURST_MAX_DATA 20 |
70 | #define ADIS16475_MAX_SCAN_DATA 20 |
71 | /* spi max speed in brust mode */ |
72 | #define ADIS16475_BURST_MAX_SPEED 1000000 |
73 | #define ADIS16475_LSB_DEC_MASK 0 |
74 | #define ADIS16475_LSB_FIR_MASK 1 |
75 | #define ADIS16500_BURST_DATA_SEL_0_CHN_MASK GENMASK(5, 0) |
76 | #define ADIS16500_BURST_DATA_SEL_1_CHN_MASK GENMASK(12, 7) |
77 | |
78 | enum { |
79 | ADIS16475_SYNC_DIRECT = 1, |
80 | ADIS16475_SYNC_SCALED, |
81 | ADIS16475_SYNC_OUTPUT, |
82 | ADIS16475_SYNC_PULSE = 5, |
83 | }; |
84 | |
85 | struct adis16475_sync { |
86 | u16 sync_mode; |
87 | u16 min_rate; |
88 | u16 max_rate; |
89 | }; |
90 | |
91 | struct adis16475_chip_info { |
92 | const struct iio_chan_spec *channels; |
93 | const struct adis16475_sync *sync; |
94 | const struct adis_data adis_data; |
95 | const char *name; |
96 | #define ADIS16475_HAS_BURST32 BIT(0) |
97 | #define ADIS16475_HAS_BURST_DELTA_DATA BIT(1) |
98 | const long flags; |
99 | u32 num_channels; |
100 | u32 gyro_max_val; |
101 | u32 gyro_max_scale; |
102 | u32 accel_max_val; |
103 | u32 accel_max_scale; |
104 | u32 temp_scale; |
105 | u32 deltang_max_val; |
106 | u32 deltvel_max_val; |
107 | u32 int_clk; |
108 | u16 max_dec; |
109 | u8 num_sync; |
110 | }; |
111 | |
112 | struct adis16475 { |
113 | const struct adis16475_chip_info *info; |
114 | struct adis adis; |
115 | u32 clk_freq; |
116 | bool burst32; |
117 | unsigned long lsb_flag; |
118 | u16 sync_mode; |
119 | /* Alignment needed for the timestamp */ |
120 | __be16 data[ADIS16475_MAX_SCAN_DATA] __aligned(8); |
121 | }; |
122 | |
123 | enum { |
124 | ADIS16475_SCAN_GYRO_X, |
125 | ADIS16475_SCAN_GYRO_Y, |
126 | ADIS16475_SCAN_GYRO_Z, |
127 | ADIS16475_SCAN_ACCEL_X, |
128 | ADIS16475_SCAN_ACCEL_Y, |
129 | ADIS16475_SCAN_ACCEL_Z, |
130 | ADIS16475_SCAN_TEMP, |
131 | ADIS16475_SCAN_DELTANG_X, |
132 | ADIS16475_SCAN_DELTANG_Y, |
133 | ADIS16475_SCAN_DELTANG_Z, |
134 | ADIS16475_SCAN_DELTVEL_X, |
135 | ADIS16475_SCAN_DELTVEL_Y, |
136 | ADIS16475_SCAN_DELTVEL_Z, |
137 | }; |
138 | |
139 | static bool low_rate_allow; |
140 | module_param(low_rate_allow, bool, 0444); |
141 | MODULE_PARM_DESC(low_rate_allow, |
142 | "Allow IMU rates below the minimum advisable when external clk is used in SCALED mode (default: N)" ); |
143 | |
144 | #ifdef CONFIG_DEBUG_FS |
145 | static ssize_t adis16475_show_firmware_revision(struct file *file, |
146 | char __user *userbuf, |
147 | size_t count, loff_t *ppos) |
148 | { |
149 | struct adis16475 *st = file->private_data; |
150 | char buf[7]; |
151 | size_t len; |
152 | u16 rev; |
153 | int ret; |
154 | |
155 | ret = adis_read_reg_16(adis: &st->adis, ADIS16475_REG_FIRM_REV, val: &rev); |
156 | if (ret) |
157 | return ret; |
158 | |
159 | len = scnprintf(buf, size: sizeof(buf), fmt: "%x.%x\n" , rev >> 8, rev & 0xff); |
160 | |
161 | return simple_read_from_buffer(to: userbuf, count, ppos, from: buf, available: len); |
162 | } |
163 | |
164 | static const struct file_operations adis16475_firmware_revision_fops = { |
165 | .open = simple_open, |
166 | .read = adis16475_show_firmware_revision, |
167 | .llseek = default_llseek, |
168 | .owner = THIS_MODULE, |
169 | }; |
170 | |
171 | static ssize_t adis16475_show_firmware_date(struct file *file, |
172 | char __user *userbuf, |
173 | size_t count, loff_t *ppos) |
174 | { |
175 | struct adis16475 *st = file->private_data; |
176 | u16 md, year; |
177 | char buf[12]; |
178 | size_t len; |
179 | int ret; |
180 | |
181 | ret = adis_read_reg_16(adis: &st->adis, ADIS16475_REG_FIRM_Y, val: &year); |
182 | if (ret) |
183 | return ret; |
184 | |
185 | ret = adis_read_reg_16(adis: &st->adis, ADIS16475_REG_FIRM_DM, val: &md); |
186 | if (ret) |
187 | return ret; |
188 | |
189 | len = snprintf(buf, size: sizeof(buf), fmt: "%.2x-%.2x-%.4x\n" , md >> 8, md & 0xff, |
190 | year); |
191 | |
192 | return simple_read_from_buffer(to: userbuf, count, ppos, from: buf, available: len); |
193 | } |
194 | |
195 | static const struct file_operations adis16475_firmware_date_fops = { |
196 | .open = simple_open, |
197 | .read = adis16475_show_firmware_date, |
198 | .llseek = default_llseek, |
199 | .owner = THIS_MODULE, |
200 | }; |
201 | |
202 | static int adis16475_show_serial_number(void *arg, u64 *val) |
203 | { |
204 | struct adis16475 *st = arg; |
205 | u16 serial; |
206 | int ret; |
207 | |
208 | ret = adis_read_reg_16(adis: &st->adis, ADIS16475_REG_SERIAL_NUM, val: &serial); |
209 | if (ret) |
210 | return ret; |
211 | |
212 | *val = serial; |
213 | |
214 | return 0; |
215 | } |
216 | DEFINE_DEBUGFS_ATTRIBUTE(adis16475_serial_number_fops, |
217 | adis16475_show_serial_number, NULL, "0x%.4llx\n" ); |
218 | |
219 | static int adis16475_show_product_id(void *arg, u64 *val) |
220 | { |
221 | struct adis16475 *st = arg; |
222 | u16 prod_id; |
223 | int ret; |
224 | |
225 | ret = adis_read_reg_16(adis: &st->adis, ADIS16475_REG_PROD_ID, val: &prod_id); |
226 | if (ret) |
227 | return ret; |
228 | |
229 | *val = prod_id; |
230 | |
231 | return 0; |
232 | } |
233 | DEFINE_DEBUGFS_ATTRIBUTE(adis16475_product_id_fops, |
234 | adis16475_show_product_id, NULL, "%llu\n" ); |
235 | |
236 | static int adis16475_show_flash_count(void *arg, u64 *val) |
237 | { |
238 | struct adis16475 *st = arg; |
239 | u32 flash_count; |
240 | int ret; |
241 | |
242 | ret = adis_read_reg_32(adis: &st->adis, ADIS16475_REG_FLASH_CNT, |
243 | val: &flash_count); |
244 | if (ret) |
245 | return ret; |
246 | |
247 | *val = flash_count; |
248 | |
249 | return 0; |
250 | } |
251 | DEFINE_DEBUGFS_ATTRIBUTE(adis16475_flash_count_fops, |
252 | adis16475_show_flash_count, NULL, "%lld\n" ); |
253 | |
254 | static void adis16475_debugfs_init(struct iio_dev *indio_dev) |
255 | { |
256 | struct adis16475 *st = iio_priv(indio_dev); |
257 | struct dentry *d = iio_get_debugfs_dentry(indio_dev); |
258 | |
259 | debugfs_create_file_unsafe(name: "serial_number" , mode: 0400, |
260 | parent: d, data: st, fops: &adis16475_serial_number_fops); |
261 | debugfs_create_file_unsafe(name: "product_id" , mode: 0400, |
262 | parent: d, data: st, fops: &adis16475_product_id_fops); |
263 | debugfs_create_file_unsafe(name: "flash_count" , mode: 0400, |
264 | parent: d, data: st, fops: &adis16475_flash_count_fops); |
265 | debugfs_create_file(name: "firmware_revision" , mode: 0400, |
266 | parent: d, data: st, fops: &adis16475_firmware_revision_fops); |
267 | debugfs_create_file(name: "firmware_date" , mode: 0400, parent: d, |
268 | data: st, fops: &adis16475_firmware_date_fops); |
269 | } |
270 | #else |
271 | static void adis16475_debugfs_init(struct iio_dev *indio_dev) |
272 | { |
273 | } |
274 | #endif |
275 | |
276 | static int adis16475_get_freq(struct adis16475 *st, u32 *freq) |
277 | { |
278 | int ret; |
279 | u16 dec; |
280 | u32 sample_rate = st->clk_freq; |
281 | |
282 | adis_dev_lock(adis: &st->adis); |
283 | |
284 | if (st->sync_mode == ADIS16475_SYNC_SCALED) { |
285 | u16 sync_scale; |
286 | |
287 | ret = __adis_read_reg_16(adis: &st->adis, ADIS16475_REG_UP_SCALE, val: &sync_scale); |
288 | if (ret) |
289 | goto error; |
290 | |
291 | sample_rate = st->clk_freq * sync_scale; |
292 | } |
293 | |
294 | ret = __adis_read_reg_16(adis: &st->adis, ADIS16475_REG_DEC_RATE, val: &dec); |
295 | if (ret) |
296 | goto error; |
297 | |
298 | adis_dev_unlock(adis: &st->adis); |
299 | |
300 | *freq = DIV_ROUND_CLOSEST(sample_rate, dec + 1); |
301 | |
302 | return 0; |
303 | error: |
304 | adis_dev_unlock(adis: &st->adis); |
305 | return ret; |
306 | } |
307 | |
308 | static int adis16475_set_freq(struct adis16475 *st, const u32 freq) |
309 | { |
310 | u16 dec; |
311 | int ret; |
312 | u32 sample_rate = st->clk_freq; |
313 | |
314 | if (!freq) |
315 | return -EINVAL; |
316 | |
317 | adis_dev_lock(adis: &st->adis); |
318 | /* |
319 | * When using sync scaled mode, the input clock needs to be scaled so that we have |
320 | * an IMU sample rate between (optimally) 1900 and 2100. After this, we can use the |
321 | * decimation filter to lower the sampling rate in order to get what the user wants. |
322 | * Optimally, the user sample rate is a multiple of both the IMU sample rate and |
323 | * the input clock. Hence, calculating the sync_scale dynamically gives us better |
324 | * chances of achieving a perfect/integer value for DEC_RATE. The math here is: |
325 | * 1. lcm of the input clock and the desired output rate. |
326 | * 2. get the highest multiple of the previous result lower than the adis max rate. |
327 | * 3. The last result becomes the IMU sample rate. Use that to calculate SYNC_SCALE |
328 | * and DEC_RATE (to get the user output rate) |
329 | */ |
330 | if (st->sync_mode == ADIS16475_SYNC_SCALED) { |
331 | unsigned long scaled_rate = lcm(a: st->clk_freq, b: freq); |
332 | int sync_scale; |
333 | |
334 | /* |
335 | * If lcm is bigger than the IMU maximum sampling rate there's no perfect |
336 | * solution. In this case, we get the highest multiple of the input clock |
337 | * lower than the IMU max sample rate. |
338 | */ |
339 | if (scaled_rate > 2100000) |
340 | scaled_rate = 2100000 / st->clk_freq * st->clk_freq; |
341 | else |
342 | scaled_rate = 2100000 / scaled_rate * scaled_rate; |
343 | |
344 | /* |
345 | * This is not an hard requirement but it's not advised to run the IMU |
346 | * with a sample rate lower than 1900Hz due to possible undersampling |
347 | * issues. However, there are users that might really want to take the risk. |
348 | * Hence, we provide a module parameter for them. If set, we allow sample |
349 | * rates lower than 1.9KHz. By default, we won't allow this and we just roundup |
350 | * the rate to the next multiple of the input clock bigger than 1.9KHz. This |
351 | * is done like this as in some cases (when DEC_RATE is 0) might give |
352 | * us the closest value to the one desired by the user... |
353 | */ |
354 | if (scaled_rate < 1900000 && !low_rate_allow) |
355 | scaled_rate = roundup(1900000, st->clk_freq); |
356 | |
357 | sync_scale = scaled_rate / st->clk_freq; |
358 | ret = __adis_write_reg_16(adis: &st->adis, ADIS16475_REG_UP_SCALE, val: sync_scale); |
359 | if (ret) |
360 | goto error; |
361 | |
362 | sample_rate = scaled_rate; |
363 | } |
364 | |
365 | dec = DIV_ROUND_CLOSEST(sample_rate, freq); |
366 | |
367 | if (dec) |
368 | dec--; |
369 | |
370 | if (dec > st->info->max_dec) |
371 | dec = st->info->max_dec; |
372 | |
373 | ret = __adis_write_reg_16(adis: &st->adis, ADIS16475_REG_DEC_RATE, val: dec); |
374 | if (ret) |
375 | goto error; |
376 | |
377 | adis_dev_unlock(adis: &st->adis); |
378 | /* |
379 | * If decimation is used, then gyro and accel data will have meaningful |
380 | * bits on the LSB registers. This info is used on the trigger handler. |
381 | */ |
382 | assign_bit(ADIS16475_LSB_DEC_MASK, addr: &st->lsb_flag, value: dec); |
383 | |
384 | return 0; |
385 | error: |
386 | adis_dev_unlock(adis: &st->adis); |
387 | return ret; |
388 | } |
389 | |
390 | /* The values are approximated. */ |
391 | static const u32 adis16475_3db_freqs[] = { |
392 | [0] = 720, /* Filter disabled, full BW (~720Hz) */ |
393 | [1] = 360, |
394 | [2] = 164, |
395 | [3] = 80, |
396 | [4] = 40, |
397 | [5] = 20, |
398 | [6] = 10, |
399 | }; |
400 | |
401 | static int adis16475_get_filter(struct adis16475 *st, u32 *filter) |
402 | { |
403 | u16 filter_sz; |
404 | int ret; |
405 | const int mask = ADIS16475_FILT_CTRL_MASK; |
406 | |
407 | ret = adis_read_reg_16(adis: &st->adis, ADIS16475_REG_FILT_CTRL, val: &filter_sz); |
408 | if (ret) |
409 | return ret; |
410 | |
411 | *filter = adis16475_3db_freqs[filter_sz & mask]; |
412 | |
413 | return 0; |
414 | } |
415 | |
416 | static int adis16475_set_filter(struct adis16475 *st, const u32 filter) |
417 | { |
418 | int i = ARRAY_SIZE(adis16475_3db_freqs); |
419 | int ret; |
420 | |
421 | while (--i) { |
422 | if (adis16475_3db_freqs[i] >= filter) |
423 | break; |
424 | } |
425 | |
426 | ret = adis_write_reg_16(adis: &st->adis, ADIS16475_REG_FILT_CTRL, |
427 | ADIS16475_FILT_CTRL(i)); |
428 | if (ret) |
429 | return ret; |
430 | |
431 | /* |
432 | * If FIR is used, then gyro and accel data will have meaningful |
433 | * bits on the LSB registers. This info is used on the trigger handler. |
434 | */ |
435 | assign_bit(ADIS16475_LSB_FIR_MASK, addr: &st->lsb_flag, value: i); |
436 | |
437 | return 0; |
438 | } |
439 | |
440 | static const u32 adis16475_calib_regs[] = { |
441 | [ADIS16475_SCAN_GYRO_X] = ADIS16475_REG_X_GYRO_BIAS_L, |
442 | [ADIS16475_SCAN_GYRO_Y] = ADIS16475_REG_Y_GYRO_BIAS_L, |
443 | [ADIS16475_SCAN_GYRO_Z] = ADIS16475_REG_Z_GYRO_BIAS_L, |
444 | [ADIS16475_SCAN_ACCEL_X] = ADIS16475_REG_X_ACCEL_BIAS_L, |
445 | [ADIS16475_SCAN_ACCEL_Y] = ADIS16475_REG_Y_ACCEL_BIAS_L, |
446 | [ADIS16475_SCAN_ACCEL_Z] = ADIS16475_REG_Z_ACCEL_BIAS_L, |
447 | }; |
448 | |
449 | static int adis16475_read_raw(struct iio_dev *indio_dev, |
450 | const struct iio_chan_spec *chan, |
451 | int *val, int *val2, long info) |
452 | { |
453 | struct adis16475 *st = iio_priv(indio_dev); |
454 | int ret; |
455 | u32 tmp; |
456 | |
457 | switch (info) { |
458 | case IIO_CHAN_INFO_RAW: |
459 | return adis_single_conversion(indio_dev, chan, error_mask: 0, val); |
460 | case IIO_CHAN_INFO_SCALE: |
461 | switch (chan->type) { |
462 | case IIO_ANGL_VEL: |
463 | *val = st->info->gyro_max_val; |
464 | *val2 = st->info->gyro_max_scale; |
465 | return IIO_VAL_FRACTIONAL; |
466 | case IIO_ACCEL: |
467 | *val = st->info->accel_max_val; |
468 | *val2 = st->info->accel_max_scale; |
469 | return IIO_VAL_FRACTIONAL; |
470 | case IIO_TEMP: |
471 | *val = st->info->temp_scale; |
472 | return IIO_VAL_INT; |
473 | case IIO_DELTA_ANGL: |
474 | *val = st->info->deltang_max_val; |
475 | *val2 = 31; |
476 | return IIO_VAL_FRACTIONAL_LOG2; |
477 | case IIO_DELTA_VELOCITY: |
478 | *val = st->info->deltvel_max_val; |
479 | *val2 = 31; |
480 | return IIO_VAL_FRACTIONAL_LOG2; |
481 | default: |
482 | return -EINVAL; |
483 | } |
484 | case IIO_CHAN_INFO_CALIBBIAS: |
485 | ret = adis_read_reg_32(adis: &st->adis, |
486 | reg: adis16475_calib_regs[chan->scan_index], |
487 | val); |
488 | if (ret) |
489 | return ret; |
490 | |
491 | return IIO_VAL_INT; |
492 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
493 | ret = adis16475_get_filter(st, filter: val); |
494 | if (ret) |
495 | return ret; |
496 | |
497 | return IIO_VAL_INT; |
498 | case IIO_CHAN_INFO_SAMP_FREQ: |
499 | ret = adis16475_get_freq(st, freq: &tmp); |
500 | if (ret) |
501 | return ret; |
502 | |
503 | *val = tmp / 1000; |
504 | *val2 = (tmp % 1000) * 1000; |
505 | return IIO_VAL_INT_PLUS_MICRO; |
506 | default: |
507 | return -EINVAL; |
508 | } |
509 | } |
510 | |
511 | static int adis16475_write_raw(struct iio_dev *indio_dev, |
512 | const struct iio_chan_spec *chan, |
513 | int val, int val2, long info) |
514 | { |
515 | struct adis16475 *st = iio_priv(indio_dev); |
516 | u32 tmp; |
517 | |
518 | switch (info) { |
519 | case IIO_CHAN_INFO_SAMP_FREQ: |
520 | tmp = val * 1000 + val2 / 1000; |
521 | return adis16475_set_freq(st, freq: tmp); |
522 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
523 | return adis16475_set_filter(st, filter: val); |
524 | case IIO_CHAN_INFO_CALIBBIAS: |
525 | return adis_write_reg_32(adis: &st->adis, |
526 | reg: adis16475_calib_regs[chan->scan_index], |
527 | val); |
528 | default: |
529 | return -EINVAL; |
530 | } |
531 | } |
532 | |
533 | #define ADIS16475_MOD_CHAN(_type, _mod, _address, _si, _r_bits, _s_bits) \ |
534 | { \ |
535 | .type = (_type), \ |
536 | .modified = 1, \ |
537 | .channel2 = (_mod), \ |
538 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
539 | BIT(IIO_CHAN_INFO_CALIBBIAS), \ |
540 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
541 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
542 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ |
543 | .address = (_address), \ |
544 | .scan_index = (_si), \ |
545 | .scan_type = { \ |
546 | .sign = 's', \ |
547 | .realbits = (_r_bits), \ |
548 | .storagebits = (_s_bits), \ |
549 | .endianness = IIO_BE, \ |
550 | }, \ |
551 | } |
552 | |
553 | #define ADIS16475_GYRO_CHANNEL(_mod) \ |
554 | ADIS16475_MOD_CHAN(IIO_ANGL_VEL, IIO_MOD_ ## _mod, \ |
555 | ADIS16475_REG_ ## _mod ## _GYRO_L, \ |
556 | ADIS16475_SCAN_GYRO_ ## _mod, 32, 32) |
557 | |
558 | #define ADIS16475_ACCEL_CHANNEL(_mod) \ |
559 | ADIS16475_MOD_CHAN(IIO_ACCEL, IIO_MOD_ ## _mod, \ |
560 | ADIS16475_REG_ ## _mod ## _ACCEL_L, \ |
561 | ADIS16475_SCAN_ACCEL_ ## _mod, 32, 32) |
562 | |
563 | #define ADIS16475_TEMP_CHANNEL() { \ |
564 | .type = IIO_TEMP, \ |
565 | .indexed = 1, \ |
566 | .channel = 0, \ |
567 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
568 | BIT(IIO_CHAN_INFO_SCALE), \ |
569 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
570 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ |
571 | .address = ADIS16475_REG_TEMP_OUT, \ |
572 | .scan_index = ADIS16475_SCAN_TEMP, \ |
573 | .scan_type = { \ |
574 | .sign = 's', \ |
575 | .realbits = 16, \ |
576 | .storagebits = 16, \ |
577 | .endianness = IIO_BE, \ |
578 | }, \ |
579 | } |
580 | |
581 | #define ADIS16475_MOD_CHAN_DELTA(_type, _mod, _address, _si, _r_bits, _s_bits) { \ |
582 | .type = (_type), \ |
583 | .modified = 1, \ |
584 | .channel2 = (_mod), \ |
585 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
586 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
587 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ |
588 | BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ |
589 | .address = (_address), \ |
590 | .scan_index = _si, \ |
591 | .scan_type = { \ |
592 | .sign = 's', \ |
593 | .realbits = (_r_bits), \ |
594 | .storagebits = (_s_bits), \ |
595 | .endianness = IIO_BE, \ |
596 | }, \ |
597 | } |
598 | |
599 | #define ADIS16475_DELTANG_CHAN(_mod) \ |
600 | ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_ANGL, IIO_MOD_ ## _mod, \ |
601 | ADIS16475_REG_ ## _mod ## _DELTANG_L, ADIS16475_SCAN_DELTANG_ ## _mod, 32, 32) |
602 | |
603 | #define ADIS16475_DELTVEL_CHAN(_mod) \ |
604 | ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_VELOCITY, IIO_MOD_ ## _mod, \ |
605 | ADIS16475_REG_ ## _mod ## _DELTVEL_L, ADIS16475_SCAN_DELTVEL_ ## _mod, 32, 32) |
606 | |
607 | #define ADIS16475_DELTANG_CHAN_NO_SCAN(_mod) \ |
608 | ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_ANGL, IIO_MOD_ ## _mod, \ |
609 | ADIS16475_REG_ ## _mod ## _DELTANG_L, -1, 32, 32) |
610 | |
611 | #define ADIS16475_DELTVEL_CHAN_NO_SCAN(_mod) \ |
612 | ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_VELOCITY, IIO_MOD_ ## _mod, \ |
613 | ADIS16475_REG_ ## _mod ## _DELTVEL_L, -1, 32, 32) |
614 | |
615 | static const struct iio_chan_spec adis16477_channels[] = { |
616 | ADIS16475_GYRO_CHANNEL(X), |
617 | ADIS16475_GYRO_CHANNEL(Y), |
618 | ADIS16475_GYRO_CHANNEL(Z), |
619 | ADIS16475_ACCEL_CHANNEL(X), |
620 | ADIS16475_ACCEL_CHANNEL(Y), |
621 | ADIS16475_ACCEL_CHANNEL(Z), |
622 | ADIS16475_TEMP_CHANNEL(), |
623 | ADIS16475_DELTANG_CHAN(X), |
624 | ADIS16475_DELTANG_CHAN(Y), |
625 | ADIS16475_DELTANG_CHAN(Z), |
626 | ADIS16475_DELTVEL_CHAN(X), |
627 | ADIS16475_DELTVEL_CHAN(Y), |
628 | ADIS16475_DELTVEL_CHAN(Z), |
629 | IIO_CHAN_SOFT_TIMESTAMP(13) |
630 | }; |
631 | |
632 | static const struct iio_chan_spec adis16475_channels[] = { |
633 | ADIS16475_GYRO_CHANNEL(X), |
634 | ADIS16475_GYRO_CHANNEL(Y), |
635 | ADIS16475_GYRO_CHANNEL(Z), |
636 | ADIS16475_ACCEL_CHANNEL(X), |
637 | ADIS16475_ACCEL_CHANNEL(Y), |
638 | ADIS16475_ACCEL_CHANNEL(Z), |
639 | ADIS16475_TEMP_CHANNEL(), |
640 | ADIS16475_DELTANG_CHAN_NO_SCAN(X), |
641 | ADIS16475_DELTANG_CHAN_NO_SCAN(Y), |
642 | ADIS16475_DELTANG_CHAN_NO_SCAN(Z), |
643 | ADIS16475_DELTVEL_CHAN_NO_SCAN(X), |
644 | ADIS16475_DELTVEL_CHAN_NO_SCAN(Y), |
645 | ADIS16475_DELTVEL_CHAN_NO_SCAN(Z), |
646 | IIO_CHAN_SOFT_TIMESTAMP(7) |
647 | }; |
648 | |
649 | enum adis16475_variant { |
650 | ADIS16470, |
651 | ADIS16475_1, |
652 | ADIS16475_2, |
653 | ADIS16475_3, |
654 | ADIS16477_1, |
655 | ADIS16477_2, |
656 | ADIS16477_3, |
657 | ADIS16465_1, |
658 | ADIS16465_2, |
659 | ADIS16465_3, |
660 | ADIS16467_1, |
661 | ADIS16467_2, |
662 | ADIS16467_3, |
663 | ADIS16500, |
664 | ADIS16505_1, |
665 | ADIS16505_2, |
666 | ADIS16505_3, |
667 | ADIS16507_1, |
668 | ADIS16507_2, |
669 | ADIS16507_3, |
670 | }; |
671 | |
672 | enum { |
673 | ADIS16475_DIAG_STAT_DATA_PATH = 1, |
674 | ADIS16475_DIAG_STAT_FLASH_MEM, |
675 | ADIS16475_DIAG_STAT_SPI, |
676 | ADIS16475_DIAG_STAT_STANDBY, |
677 | ADIS16475_DIAG_STAT_SENSOR, |
678 | ADIS16475_DIAG_STAT_MEMORY, |
679 | ADIS16475_DIAG_STAT_CLK, |
680 | }; |
681 | |
682 | static const char * const adis16475_status_error_msgs[] = { |
683 | [ADIS16475_DIAG_STAT_DATA_PATH] = "Data Path Overrun" , |
684 | [ADIS16475_DIAG_STAT_FLASH_MEM] = "Flash memory update failure" , |
685 | [ADIS16475_DIAG_STAT_SPI] = "SPI communication error" , |
686 | [ADIS16475_DIAG_STAT_STANDBY] = "Standby mode" , |
687 | [ADIS16475_DIAG_STAT_SENSOR] = "Sensor failure" , |
688 | [ADIS16475_DIAG_STAT_MEMORY] = "Memory failure" , |
689 | [ADIS16475_DIAG_STAT_CLK] = "Clock error" , |
690 | }; |
691 | |
692 | #define ADIS16475_DATA(_prod_id, _timeouts) \ |
693 | { \ |
694 | .msc_ctrl_reg = ADIS16475_REG_MSG_CTRL, \ |
695 | .glob_cmd_reg = ADIS16475_REG_GLOB_CMD, \ |
696 | .diag_stat_reg = ADIS16475_REG_DIAG_STAT, \ |
697 | .prod_id_reg = ADIS16475_REG_PROD_ID, \ |
698 | .prod_id = (_prod_id), \ |
699 | .self_test_mask = BIT(2), \ |
700 | .self_test_reg = ADIS16475_REG_GLOB_CMD, \ |
701 | .cs_change_delay = 16, \ |
702 | .read_delay = 5, \ |
703 | .write_delay = 5, \ |
704 | .status_error_msgs = adis16475_status_error_msgs, \ |
705 | .status_error_mask = BIT(ADIS16475_DIAG_STAT_DATA_PATH) | \ |
706 | BIT(ADIS16475_DIAG_STAT_FLASH_MEM) | \ |
707 | BIT(ADIS16475_DIAG_STAT_SPI) | \ |
708 | BIT(ADIS16475_DIAG_STAT_STANDBY) | \ |
709 | BIT(ADIS16475_DIAG_STAT_SENSOR) | \ |
710 | BIT(ADIS16475_DIAG_STAT_MEMORY) | \ |
711 | BIT(ADIS16475_DIAG_STAT_CLK), \ |
712 | .unmasked_drdy = true, \ |
713 | .timeouts = (_timeouts), \ |
714 | .burst_reg_cmd = ADIS16475_REG_GLOB_CMD, \ |
715 | .burst_len = ADIS16475_BURST_MAX_DATA, \ |
716 | .burst_max_len = ADIS16475_BURST32_MAX_DATA, \ |
717 | .burst_max_speed_hz = ADIS16475_BURST_MAX_SPEED \ |
718 | } |
719 | |
720 | static const struct adis16475_sync adis16475_sync_mode[] = { |
721 | { ADIS16475_SYNC_OUTPUT }, |
722 | { ADIS16475_SYNC_DIRECT, 1900, 2100 }, |
723 | { ADIS16475_SYNC_SCALED, 1, 128 }, |
724 | { ADIS16475_SYNC_PULSE, 1000, 2100 }, |
725 | }; |
726 | |
727 | static const struct adis_timeout adis16475_timeouts = { |
728 | .reset_ms = 200, |
729 | .sw_reset_ms = 200, |
730 | .self_test_ms = 20, |
731 | }; |
732 | |
733 | static const struct adis_timeout adis1650x_timeouts = { |
734 | .reset_ms = 260, |
735 | .sw_reset_ms = 260, |
736 | .self_test_ms = 30, |
737 | }; |
738 | |
739 | static const struct adis16475_chip_info adis16475_chip_info[] = { |
740 | [ADIS16470] = { |
741 | .name = "adis16470" , |
742 | .num_channels = ARRAY_SIZE(adis16475_channels), |
743 | .channels = adis16475_channels, |
744 | .gyro_max_val = 1, |
745 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
746 | .accel_max_val = 1, |
747 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
748 | .temp_scale = 100, |
749 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
750 | .deltvel_max_val = 400, |
751 | .int_clk = 2000, |
752 | .max_dec = 1999, |
753 | .sync = adis16475_sync_mode, |
754 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
755 | .adis_data = ADIS16475_DATA(16470, &adis16475_timeouts), |
756 | }, |
757 | [ADIS16475_1] = { |
758 | .name = "adis16475-1" , |
759 | .num_channels = ARRAY_SIZE(adis16475_channels), |
760 | .channels = adis16475_channels, |
761 | .gyro_max_val = 1, |
762 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), |
763 | .accel_max_val = 1, |
764 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), |
765 | .temp_scale = 100, |
766 | .deltang_max_val = IIO_DEGREE_TO_RAD(360), |
767 | .deltvel_max_val = 100, |
768 | .int_clk = 2000, |
769 | .max_dec = 1999, |
770 | .sync = adis16475_sync_mode, |
771 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
772 | .adis_data = ADIS16475_DATA(16475, &adis16475_timeouts), |
773 | }, |
774 | [ADIS16475_2] = { |
775 | .name = "adis16475-2" , |
776 | .num_channels = ARRAY_SIZE(adis16475_channels), |
777 | .channels = adis16475_channels, |
778 | .gyro_max_val = 1, |
779 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), |
780 | .accel_max_val = 1, |
781 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), |
782 | .temp_scale = 100, |
783 | .deltang_max_val = IIO_DEGREE_TO_RAD(720), |
784 | .deltvel_max_val = 100, |
785 | .int_clk = 2000, |
786 | .max_dec = 1999, |
787 | .sync = adis16475_sync_mode, |
788 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
789 | .adis_data = ADIS16475_DATA(16475, &adis16475_timeouts), |
790 | }, |
791 | [ADIS16475_3] = { |
792 | .name = "adis16475-3" , |
793 | .num_channels = ARRAY_SIZE(adis16475_channels), |
794 | .channels = adis16475_channels, |
795 | .gyro_max_val = 1, |
796 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
797 | .accel_max_val = 1, |
798 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), |
799 | .temp_scale = 100, |
800 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
801 | .deltvel_max_val = 100, |
802 | .int_clk = 2000, |
803 | .max_dec = 1999, |
804 | .sync = adis16475_sync_mode, |
805 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
806 | .adis_data = ADIS16475_DATA(16475, &adis16475_timeouts), |
807 | }, |
808 | [ADIS16477_1] = { |
809 | .name = "adis16477-1" , |
810 | .num_channels = ARRAY_SIZE(adis16477_channels), |
811 | .channels = adis16477_channels, |
812 | .gyro_max_val = 1, |
813 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), |
814 | .accel_max_val = 1, |
815 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
816 | .temp_scale = 100, |
817 | .deltang_max_val = IIO_DEGREE_TO_RAD(360), |
818 | .deltvel_max_val = 400, |
819 | .int_clk = 2000, |
820 | .max_dec = 1999, |
821 | .sync = adis16475_sync_mode, |
822 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
823 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
824 | .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), |
825 | }, |
826 | [ADIS16477_2] = { |
827 | .name = "adis16477-2" , |
828 | .num_channels = ARRAY_SIZE(adis16477_channels), |
829 | .channels = adis16477_channels, |
830 | .gyro_max_val = 1, |
831 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), |
832 | .accel_max_val = 1, |
833 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
834 | .temp_scale = 100, |
835 | .deltang_max_val = IIO_DEGREE_TO_RAD(720), |
836 | .deltvel_max_val = 400, |
837 | .int_clk = 2000, |
838 | .max_dec = 1999, |
839 | .sync = adis16475_sync_mode, |
840 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
841 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
842 | .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), |
843 | }, |
844 | [ADIS16477_3] = { |
845 | .name = "adis16477-3" , |
846 | .num_channels = ARRAY_SIZE(adis16477_channels), |
847 | .channels = adis16477_channels, |
848 | .gyro_max_val = 1, |
849 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
850 | .accel_max_val = 1, |
851 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
852 | .temp_scale = 100, |
853 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
854 | .deltvel_max_val = 400, |
855 | .int_clk = 2000, |
856 | .max_dec = 1999, |
857 | .sync = adis16475_sync_mode, |
858 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
859 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
860 | .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), |
861 | }, |
862 | [ADIS16465_1] = { |
863 | .name = "adis16465-1" , |
864 | .num_channels = ARRAY_SIZE(adis16475_channels), |
865 | .channels = adis16475_channels, |
866 | .gyro_max_val = 1, |
867 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), |
868 | .accel_max_val = 1, |
869 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), |
870 | .temp_scale = 100, |
871 | .deltang_max_val = IIO_DEGREE_TO_RAD(360), |
872 | .deltvel_max_val = 100, |
873 | .int_clk = 2000, |
874 | .max_dec = 1999, |
875 | .sync = adis16475_sync_mode, |
876 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
877 | .adis_data = ADIS16475_DATA(16465, &adis16475_timeouts), |
878 | }, |
879 | [ADIS16465_2] = { |
880 | .name = "adis16465-2" , |
881 | .num_channels = ARRAY_SIZE(adis16475_channels), |
882 | .channels = adis16475_channels, |
883 | .gyro_max_val = 1, |
884 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), |
885 | .accel_max_val = 1, |
886 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), |
887 | .temp_scale = 100, |
888 | .deltang_max_val = IIO_DEGREE_TO_RAD(720), |
889 | .deltvel_max_val = 100, |
890 | .int_clk = 2000, |
891 | .max_dec = 1999, |
892 | .sync = adis16475_sync_mode, |
893 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
894 | .adis_data = ADIS16475_DATA(16465, &adis16475_timeouts), |
895 | }, |
896 | [ADIS16465_3] = { |
897 | .name = "adis16465-3" , |
898 | .num_channels = ARRAY_SIZE(adis16475_channels), |
899 | .channels = adis16475_channels, |
900 | .gyro_max_val = 1, |
901 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
902 | .accel_max_val = 1, |
903 | .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), |
904 | .temp_scale = 100, |
905 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
906 | .deltvel_max_val = 100, |
907 | .int_clk = 2000, |
908 | .max_dec = 1999, |
909 | .sync = adis16475_sync_mode, |
910 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
911 | .adis_data = ADIS16475_DATA(16465, &adis16475_timeouts), |
912 | }, |
913 | [ADIS16467_1] = { |
914 | .name = "adis16467-1" , |
915 | .num_channels = ARRAY_SIZE(adis16475_channels), |
916 | .channels = adis16475_channels, |
917 | .gyro_max_val = 1, |
918 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), |
919 | .accel_max_val = 1, |
920 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
921 | .temp_scale = 100, |
922 | .deltang_max_val = IIO_DEGREE_TO_RAD(360), |
923 | .deltvel_max_val = 400, |
924 | .int_clk = 2000, |
925 | .max_dec = 1999, |
926 | .sync = adis16475_sync_mode, |
927 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
928 | .adis_data = ADIS16475_DATA(16467, &adis16475_timeouts), |
929 | }, |
930 | [ADIS16467_2] = { |
931 | .name = "adis16467-2" , |
932 | .num_channels = ARRAY_SIZE(adis16475_channels), |
933 | .channels = adis16475_channels, |
934 | .gyro_max_val = 1, |
935 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), |
936 | .accel_max_val = 1, |
937 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
938 | .temp_scale = 100, |
939 | .deltang_max_val = IIO_DEGREE_TO_RAD(720), |
940 | .deltvel_max_val = 400, |
941 | .int_clk = 2000, |
942 | .max_dec = 1999, |
943 | .sync = adis16475_sync_mode, |
944 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
945 | .adis_data = ADIS16475_DATA(16467, &adis16475_timeouts), |
946 | }, |
947 | [ADIS16467_3] = { |
948 | .name = "adis16467-3" , |
949 | .num_channels = ARRAY_SIZE(adis16475_channels), |
950 | .channels = adis16475_channels, |
951 | .gyro_max_val = 1, |
952 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
953 | .accel_max_val = 1, |
954 | .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), |
955 | .temp_scale = 100, |
956 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
957 | .deltvel_max_val = 400, |
958 | .int_clk = 2000, |
959 | .max_dec = 1999, |
960 | .sync = adis16475_sync_mode, |
961 | .num_sync = ARRAY_SIZE(adis16475_sync_mode), |
962 | .adis_data = ADIS16475_DATA(16467, &adis16475_timeouts), |
963 | }, |
964 | [ADIS16500] = { |
965 | .name = "adis16500" , |
966 | .num_channels = ARRAY_SIZE(adis16477_channels), |
967 | .channels = adis16477_channels, |
968 | .gyro_max_val = 1, |
969 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
970 | .accel_max_val = 392, |
971 | .accel_max_scale = 32000 << 16, |
972 | .temp_scale = 100, |
973 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
974 | .deltvel_max_val = 400, |
975 | .int_clk = 2000, |
976 | .max_dec = 1999, |
977 | .sync = adis16475_sync_mode, |
978 | /* pulse sync not supported */ |
979 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
980 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
981 | .adis_data = ADIS16475_DATA(16500, &adis1650x_timeouts), |
982 | }, |
983 | [ADIS16505_1] = { |
984 | .name = "adis16505-1" , |
985 | .num_channels = ARRAY_SIZE(adis16477_channels), |
986 | .channels = adis16477_channels, |
987 | .gyro_max_val = 1, |
988 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), |
989 | .accel_max_val = 78, |
990 | .accel_max_scale = 32000 << 16, |
991 | .temp_scale = 100, |
992 | .deltang_max_val = IIO_DEGREE_TO_RAD(360), |
993 | .deltvel_max_val = 100, |
994 | .int_clk = 2000, |
995 | .max_dec = 1999, |
996 | .sync = adis16475_sync_mode, |
997 | /* pulse sync not supported */ |
998 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
999 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
1000 | .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), |
1001 | }, |
1002 | [ADIS16505_2] = { |
1003 | .name = "adis16505-2" , |
1004 | .num_channels = ARRAY_SIZE(adis16477_channels), |
1005 | .channels = adis16477_channels, |
1006 | .gyro_max_val = 1, |
1007 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), |
1008 | .accel_max_val = 78, |
1009 | .accel_max_scale = 32000 << 16, |
1010 | .temp_scale = 100, |
1011 | .deltang_max_val = IIO_DEGREE_TO_RAD(720), |
1012 | .deltvel_max_val = 100, |
1013 | .int_clk = 2000, |
1014 | .max_dec = 1999, |
1015 | .sync = adis16475_sync_mode, |
1016 | /* pulse sync not supported */ |
1017 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
1018 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
1019 | .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), |
1020 | }, |
1021 | [ADIS16505_3] = { |
1022 | .name = "adis16505-3" , |
1023 | .num_channels = ARRAY_SIZE(adis16477_channels), |
1024 | .channels = adis16477_channels, |
1025 | .gyro_max_val = 1, |
1026 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
1027 | .accel_max_val = 78, |
1028 | .accel_max_scale = 32000 << 16, |
1029 | .temp_scale = 100, |
1030 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
1031 | .deltvel_max_val = 100, |
1032 | .int_clk = 2000, |
1033 | .max_dec = 1999, |
1034 | .sync = adis16475_sync_mode, |
1035 | /* pulse sync not supported */ |
1036 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
1037 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
1038 | .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), |
1039 | }, |
1040 | [ADIS16507_1] = { |
1041 | .name = "adis16507-1" , |
1042 | .num_channels = ARRAY_SIZE(adis16477_channels), |
1043 | .channels = adis16477_channels, |
1044 | .gyro_max_val = 1, |
1045 | .gyro_max_scale = IIO_RAD_TO_DEGREE(160 << 16), |
1046 | .accel_max_val = 392, |
1047 | .accel_max_scale = 32000 << 16, |
1048 | .temp_scale = 100, |
1049 | .deltang_max_val = IIO_DEGREE_TO_RAD(360), |
1050 | .deltvel_max_val = 400, |
1051 | .int_clk = 2000, |
1052 | .max_dec = 1999, |
1053 | .sync = adis16475_sync_mode, |
1054 | /* pulse sync not supported */ |
1055 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
1056 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
1057 | .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), |
1058 | }, |
1059 | [ADIS16507_2] = { |
1060 | .name = "adis16507-2" , |
1061 | .num_channels = ARRAY_SIZE(adis16477_channels), |
1062 | .channels = adis16477_channels, |
1063 | .gyro_max_val = 1, |
1064 | .gyro_max_scale = IIO_RAD_TO_DEGREE(40 << 16), |
1065 | .accel_max_val = 392, |
1066 | .accel_max_scale = 32000 << 16, |
1067 | .temp_scale = 100, |
1068 | .deltang_max_val = IIO_DEGREE_TO_RAD(720), |
1069 | .deltvel_max_val = 400, |
1070 | .int_clk = 2000, |
1071 | .max_dec = 1999, |
1072 | .sync = adis16475_sync_mode, |
1073 | /* pulse sync not supported */ |
1074 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
1075 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
1076 | .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), |
1077 | }, |
1078 | [ADIS16507_3] = { |
1079 | .name = "adis16507-3" , |
1080 | .num_channels = ARRAY_SIZE(adis16477_channels), |
1081 | .channels = adis16477_channels, |
1082 | .gyro_max_val = 1, |
1083 | .gyro_max_scale = IIO_RAD_TO_DEGREE(10 << 16), |
1084 | .accel_max_val = 392, |
1085 | .accel_max_scale = 32000 << 16, |
1086 | .temp_scale = 100, |
1087 | .deltang_max_val = IIO_DEGREE_TO_RAD(2160), |
1088 | .deltvel_max_val = 400, |
1089 | .int_clk = 2000, |
1090 | .max_dec = 1999, |
1091 | .sync = adis16475_sync_mode, |
1092 | /* pulse sync not supported */ |
1093 | .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, |
1094 | .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, |
1095 | .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), |
1096 | }, |
1097 | }; |
1098 | |
1099 | static int adis16475_update_scan_mode(struct iio_dev *indio_dev, |
1100 | const unsigned long *scan_mask) |
1101 | { |
1102 | u16 en; |
1103 | int ret; |
1104 | struct adis16475 *st = iio_priv(indio_dev); |
1105 | |
1106 | if (st->info->flags & ADIS16475_HAS_BURST_DELTA_DATA) { |
1107 | if ((*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK) && |
1108 | (*scan_mask & ADIS16500_BURST_DATA_SEL_1_CHN_MASK)) |
1109 | return -EINVAL; |
1110 | if (*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK) |
1111 | en = FIELD_PREP(ADIS16500_BURST_DATA_SEL_MASK, 0); |
1112 | else |
1113 | en = FIELD_PREP(ADIS16500_BURST_DATA_SEL_MASK, 1); |
1114 | |
1115 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, |
1116 | ADIS16500_BURST_DATA_SEL_MASK, en); |
1117 | if (ret) |
1118 | return ret; |
1119 | } |
1120 | |
1121 | return adis_update_scan_mode(indio_dev, scan_mask); |
1122 | } |
1123 | |
1124 | static const struct iio_info adis16475_info = { |
1125 | .read_raw = &adis16475_read_raw, |
1126 | .write_raw = &adis16475_write_raw, |
1127 | .update_scan_mode = adis16475_update_scan_mode, |
1128 | .debugfs_reg_access = adis_debugfs_reg_access, |
1129 | }; |
1130 | |
1131 | static bool adis16475_validate_crc(const u8 *buffer, u16 crc, |
1132 | const bool burst32) |
1133 | { |
1134 | int i; |
1135 | /* extra 6 elements for low gyro and accel */ |
1136 | const u16 sz = burst32 ? ADIS16475_BURST32_MAX_DATA : |
1137 | ADIS16475_BURST_MAX_DATA; |
1138 | |
1139 | for (i = 0; i < sz - 2; i++) |
1140 | crc -= buffer[i]; |
1141 | |
1142 | return crc == 0; |
1143 | } |
1144 | |
1145 | static void adis16475_burst32_check(struct adis16475 *st) |
1146 | { |
1147 | int ret; |
1148 | struct adis *adis = &st->adis; |
1149 | |
1150 | if (!(st->info->flags & ADIS16475_HAS_BURST32)) |
1151 | return; |
1152 | |
1153 | if (st->lsb_flag && !st->burst32) { |
1154 | const u16 en = ADIS16500_BURST32(1); |
1155 | |
1156 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, |
1157 | ADIS16500_BURST32_MASK, en); |
1158 | if (ret) |
1159 | return; |
1160 | |
1161 | st->burst32 = true; |
1162 | |
1163 | /* |
1164 | * In 32-bit mode we need extra 2 bytes for all gyro |
1165 | * and accel channels. |
1166 | */ |
1167 | adis->burst_extra_len = 6 * sizeof(u16); |
1168 | adis->xfer[1].len += 6 * sizeof(u16); |
1169 | dev_dbg(&adis->spi->dev, "Enable burst32 mode, xfer:%d" , |
1170 | adis->xfer[1].len); |
1171 | |
1172 | } else if (!st->lsb_flag && st->burst32) { |
1173 | const u16 en = ADIS16500_BURST32(0); |
1174 | |
1175 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, |
1176 | ADIS16500_BURST32_MASK, en); |
1177 | if (ret) |
1178 | return; |
1179 | |
1180 | st->burst32 = false; |
1181 | |
1182 | /* Remove the extra bits */ |
1183 | adis->burst_extra_len = 0; |
1184 | adis->xfer[1].len -= 6 * sizeof(u16); |
1185 | dev_dbg(&adis->spi->dev, "Disable burst32 mode, xfer:%d\n" , |
1186 | adis->xfer[1].len); |
1187 | } |
1188 | } |
1189 | |
1190 | static irqreturn_t adis16475_trigger_handler(int irq, void *p) |
1191 | { |
1192 | struct iio_poll_func *pf = p; |
1193 | struct iio_dev *indio_dev = pf->indio_dev; |
1194 | struct adis16475 *st = iio_priv(indio_dev); |
1195 | struct adis *adis = &st->adis; |
1196 | int ret, bit, buff_offset = 0, i = 0; |
1197 | __be16 *buffer; |
1198 | u16 crc; |
1199 | bool valid; |
1200 | /* offset until the first element after gyro and accel */ |
1201 | const u8 offset = st->burst32 ? 13 : 7; |
1202 | |
1203 | ret = spi_sync(spi: adis->spi, message: &adis->msg); |
1204 | if (ret) |
1205 | goto check_burst32; |
1206 | |
1207 | buffer = adis->buffer; |
1208 | |
1209 | crc = be16_to_cpu(buffer[offset + 2]); |
1210 | valid = adis16475_validate_crc(buffer: adis->buffer, crc, burst32: st->burst32); |
1211 | if (!valid) { |
1212 | dev_err(&adis->spi->dev, "Invalid crc\n" ); |
1213 | goto check_burst32; |
1214 | } |
1215 | |
1216 | for_each_set_bit(bit, indio_dev->active_scan_mask, |
1217 | indio_dev->masklength) { |
1218 | /* |
1219 | * When burst mode is used, system flags is the first data |
1220 | * channel in the sequence, but the scan index is 7. |
1221 | */ |
1222 | switch (bit) { |
1223 | case ADIS16475_SCAN_TEMP: |
1224 | st->data[i++] = buffer[offset]; |
1225 | /* |
1226 | * The temperature channel has 16-bit storage size. |
1227 | * We need to perform the padding to have the buffer |
1228 | * elements naturally aligned in case there are any |
1229 | * 32-bit storage size channels enabled which have a |
1230 | * scan index higher than the temperature channel scan |
1231 | * index. |
1232 | */ |
1233 | if (*indio_dev->active_scan_mask & GENMASK(ADIS16475_SCAN_DELTVEL_Z, ADIS16475_SCAN_DELTANG_X)) |
1234 | st->data[i++] = 0; |
1235 | break; |
1236 | case ADIS16475_SCAN_DELTANG_X ... ADIS16475_SCAN_DELTVEL_Z: |
1237 | buff_offset = ADIS16475_SCAN_DELTANG_X; |
1238 | fallthrough; |
1239 | case ADIS16475_SCAN_GYRO_X ... ADIS16475_SCAN_ACCEL_Z: |
1240 | /* |
1241 | * The first 2 bytes on the received data are the |
1242 | * DIAG_STAT reg, hence the +1 offset here... |
1243 | */ |
1244 | if (st->burst32) { |
1245 | /* upper 16 */ |
1246 | st->data[i++] = buffer[(bit - buff_offset) * 2 + 2]; |
1247 | /* lower 16 */ |
1248 | st->data[i++] = buffer[(bit - buff_offset) * 2 + 1]; |
1249 | } else { |
1250 | st->data[i++] = buffer[(bit - buff_offset) + 1]; |
1251 | /* |
1252 | * Don't bother in doing the manual read if the |
1253 | * device supports burst32. burst32 will be |
1254 | * enabled in the next call to |
1255 | * adis16475_burst32_check()... |
1256 | */ |
1257 | if (st->lsb_flag && !(st->info->flags & ADIS16475_HAS_BURST32)) { |
1258 | u16 val = 0; |
1259 | const u32 reg = ADIS16475_REG_X_GYRO_L + |
1260 | bit * 4; |
1261 | |
1262 | adis_read_reg_16(adis, reg, val: &val); |
1263 | st->data[i++] = cpu_to_be16(val); |
1264 | } else { |
1265 | /* lower not used */ |
1266 | st->data[i++] = 0; |
1267 | } |
1268 | } |
1269 | break; |
1270 | } |
1271 | } |
1272 | |
1273 | iio_push_to_buffers_with_timestamp(indio_dev, data: st->data, timestamp: pf->timestamp); |
1274 | check_burst32: |
1275 | /* |
1276 | * We only check the burst mode at the end of the current capture since |
1277 | * it takes a full data ready cycle for the device to update the burst |
1278 | * array. |
1279 | */ |
1280 | adis16475_burst32_check(st); |
1281 | iio_trigger_notify_done(trig: indio_dev->trig); |
1282 | |
1283 | return IRQ_HANDLED; |
1284 | } |
1285 | |
1286 | static int adis16475_config_sync_mode(struct adis16475 *st) |
1287 | { |
1288 | int ret; |
1289 | struct device *dev = &st->adis.spi->dev; |
1290 | const struct adis16475_sync *sync; |
1291 | u32 sync_mode; |
1292 | |
1293 | /* default to internal clk */ |
1294 | st->clk_freq = st->info->int_clk * 1000; |
1295 | |
1296 | ret = device_property_read_u32(dev, propname: "adi,sync-mode" , val: &sync_mode); |
1297 | if (ret) |
1298 | return 0; |
1299 | |
1300 | if (sync_mode >= st->info->num_sync) { |
1301 | dev_err(dev, "Invalid sync mode: %u for %s\n" , sync_mode, |
1302 | st->info->name); |
1303 | return -EINVAL; |
1304 | } |
1305 | |
1306 | sync = &st->info->sync[sync_mode]; |
1307 | st->sync_mode = sync->sync_mode; |
1308 | |
1309 | /* All the other modes require external input signal */ |
1310 | if (sync->sync_mode != ADIS16475_SYNC_OUTPUT) { |
1311 | struct clk *clk = devm_clk_get_enabled(dev, NULL); |
1312 | |
1313 | if (IS_ERR(ptr: clk)) |
1314 | return PTR_ERR(ptr: clk); |
1315 | |
1316 | st->clk_freq = clk_get_rate(clk); |
1317 | if (st->clk_freq < sync->min_rate || |
1318 | st->clk_freq > sync->max_rate) { |
1319 | dev_err(dev, |
1320 | "Clk rate:%u not in a valid range:[%u %u]\n" , |
1321 | st->clk_freq, sync->min_rate, sync->max_rate); |
1322 | return -EINVAL; |
1323 | } |
1324 | |
1325 | if (sync->sync_mode == ADIS16475_SYNC_SCALED) { |
1326 | u16 up_scale; |
1327 | |
1328 | /* |
1329 | * In sync scaled mode, the IMU sample rate is the clk_freq * sync_scale. |
1330 | * Hence, default the IMU sample rate to the highest multiple of the input |
1331 | * clock lower than the IMU max sample rate. The optimal range is |
1332 | * 1900-2100 sps... |
1333 | */ |
1334 | up_scale = 2100 / st->clk_freq; |
1335 | |
1336 | ret = __adis_write_reg_16(adis: &st->adis, |
1337 | ADIS16475_REG_UP_SCALE, |
1338 | val: up_scale); |
1339 | if (ret) |
1340 | return ret; |
1341 | } |
1342 | |
1343 | st->clk_freq *= 1000; |
1344 | } |
1345 | /* |
1346 | * Keep in mind that the mask for the clk modes in adis1650* |
1347 | * chips is different (1100 instead of 11100). However, we |
1348 | * are not configuring BIT(4) in these chips and the default |
1349 | * value is 0, so we are fine in doing the below operations. |
1350 | * I'm keeping this for simplicity and avoiding extra variables |
1351 | * in chip_info. |
1352 | */ |
1353 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, |
1354 | ADIS16475_SYNC_MODE_MASK, sync->sync_mode); |
1355 | if (ret) |
1356 | return ret; |
1357 | |
1358 | usleep_range(min: 250, max: 260); |
1359 | |
1360 | return 0; |
1361 | } |
1362 | |
1363 | static int adis16475_config_irq_pin(struct adis16475 *st) |
1364 | { |
1365 | int ret; |
1366 | u32 irq_type; |
1367 | u16 val = 0; |
1368 | u8 polarity; |
1369 | struct spi_device *spi = st->adis.spi; |
1370 | |
1371 | /* |
1372 | * It is possible to configure the data ready polarity. Furthermore, we |
1373 | * need to update the adis struct if we want data ready as active low. |
1374 | */ |
1375 | irq_type = irq_get_trigger_type(irq: spi->irq); |
1376 | if (irq_type == IRQ_TYPE_EDGE_RISING) { |
1377 | polarity = 1; |
1378 | st->adis.irq_flag = IRQF_TRIGGER_RISING; |
1379 | } else if (irq_type == IRQ_TYPE_EDGE_FALLING) { |
1380 | polarity = 0; |
1381 | st->adis.irq_flag = IRQF_TRIGGER_FALLING; |
1382 | } else { |
1383 | dev_err(&spi->dev, "Invalid interrupt type 0x%x specified\n" , |
1384 | irq_type); |
1385 | return -EINVAL; |
1386 | } |
1387 | |
1388 | val = ADIS16475_MSG_CTRL_DR_POL(polarity); |
1389 | ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, |
1390 | ADIS16475_MSG_CTRL_DR_POL_MASK, val); |
1391 | if (ret) |
1392 | return ret; |
1393 | /* |
1394 | * There is a delay writing to any bits written to the MSC_CTRL |
1395 | * register. It should not be bigger than 200us, so 250 should be more |
1396 | * than enough! |
1397 | */ |
1398 | usleep_range(min: 250, max: 260); |
1399 | |
1400 | return 0; |
1401 | } |
1402 | |
1403 | |
1404 | static int adis16475_probe(struct spi_device *spi) |
1405 | { |
1406 | struct iio_dev *indio_dev; |
1407 | struct adis16475 *st; |
1408 | int ret; |
1409 | |
1410 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*st)); |
1411 | if (!indio_dev) |
1412 | return -ENOMEM; |
1413 | |
1414 | st = iio_priv(indio_dev); |
1415 | |
1416 | st->info = spi_get_device_match_data(sdev: spi); |
1417 | if (!st->info) |
1418 | return -EINVAL; |
1419 | |
1420 | ret = adis_init(adis: &st->adis, indio_dev, spi, data: &st->info->adis_data); |
1421 | if (ret) |
1422 | return ret; |
1423 | |
1424 | indio_dev->name = st->info->name; |
1425 | indio_dev->channels = st->info->channels; |
1426 | indio_dev->num_channels = st->info->num_channels; |
1427 | indio_dev->info = &adis16475_info; |
1428 | indio_dev->modes = INDIO_DIRECT_MODE; |
1429 | |
1430 | ret = __adis_initial_startup(adis: &st->adis); |
1431 | if (ret) |
1432 | return ret; |
1433 | |
1434 | ret = adis16475_config_irq_pin(st); |
1435 | if (ret) |
1436 | return ret; |
1437 | |
1438 | ret = adis16475_config_sync_mode(st); |
1439 | if (ret) |
1440 | return ret; |
1441 | |
1442 | ret = devm_adis_setup_buffer_and_trigger(adis: &st->adis, indio_dev, |
1443 | trigger_handler: adis16475_trigger_handler); |
1444 | if (ret) |
1445 | return ret; |
1446 | |
1447 | ret = devm_iio_device_register(&spi->dev, indio_dev); |
1448 | if (ret) |
1449 | return ret; |
1450 | |
1451 | adis16475_debugfs_init(indio_dev); |
1452 | |
1453 | return 0; |
1454 | } |
1455 | |
1456 | static const struct of_device_id adis16475_of_match[] = { |
1457 | { .compatible = "adi,adis16470" , |
1458 | .data = &adis16475_chip_info[ADIS16470] }, |
1459 | { .compatible = "adi,adis16475-1" , |
1460 | .data = &adis16475_chip_info[ADIS16475_1] }, |
1461 | { .compatible = "adi,adis16475-2" , |
1462 | .data = &adis16475_chip_info[ADIS16475_2] }, |
1463 | { .compatible = "adi,adis16475-3" , |
1464 | .data = &adis16475_chip_info[ADIS16475_3] }, |
1465 | { .compatible = "adi,adis16477-1" , |
1466 | .data = &adis16475_chip_info[ADIS16477_1] }, |
1467 | { .compatible = "adi,adis16477-2" , |
1468 | .data = &adis16475_chip_info[ADIS16477_2] }, |
1469 | { .compatible = "adi,adis16477-3" , |
1470 | .data = &adis16475_chip_info[ADIS16477_3] }, |
1471 | { .compatible = "adi,adis16465-1" , |
1472 | .data = &adis16475_chip_info[ADIS16465_1] }, |
1473 | { .compatible = "adi,adis16465-2" , |
1474 | .data = &adis16475_chip_info[ADIS16465_2] }, |
1475 | { .compatible = "adi,adis16465-3" , |
1476 | .data = &adis16475_chip_info[ADIS16465_3] }, |
1477 | { .compatible = "adi,adis16467-1" , |
1478 | .data = &adis16475_chip_info[ADIS16467_1] }, |
1479 | { .compatible = "adi,adis16467-2" , |
1480 | .data = &adis16475_chip_info[ADIS16467_2] }, |
1481 | { .compatible = "adi,adis16467-3" , |
1482 | .data = &adis16475_chip_info[ADIS16467_3] }, |
1483 | { .compatible = "adi,adis16500" , |
1484 | .data = &adis16475_chip_info[ADIS16500] }, |
1485 | { .compatible = "adi,adis16505-1" , |
1486 | .data = &adis16475_chip_info[ADIS16505_1] }, |
1487 | { .compatible = "adi,adis16505-2" , |
1488 | .data = &adis16475_chip_info[ADIS16505_2] }, |
1489 | { .compatible = "adi,adis16505-3" , |
1490 | .data = &adis16475_chip_info[ADIS16505_3] }, |
1491 | { .compatible = "adi,adis16507-1" , |
1492 | .data = &adis16475_chip_info[ADIS16507_1] }, |
1493 | { .compatible = "adi,adis16507-2" , |
1494 | .data = &adis16475_chip_info[ADIS16507_2] }, |
1495 | { .compatible = "adi,adis16507-3" , |
1496 | .data = &adis16475_chip_info[ADIS16507_3] }, |
1497 | { }, |
1498 | }; |
1499 | MODULE_DEVICE_TABLE(of, adis16475_of_match); |
1500 | |
1501 | static const struct spi_device_id adis16475_ids[] = { |
1502 | { "adis16470" , (kernel_ulong_t)&adis16475_chip_info[ADIS16470] }, |
1503 | { "adis16475-1" , (kernel_ulong_t)&adis16475_chip_info[ADIS16475_1] }, |
1504 | { "adis16475-2" , (kernel_ulong_t)&adis16475_chip_info[ADIS16475_2] }, |
1505 | { "adis16475-3" , (kernel_ulong_t)&adis16475_chip_info[ADIS16475_3] }, |
1506 | { "adis16477-1" , (kernel_ulong_t)&adis16475_chip_info[ADIS16477_1] }, |
1507 | { "adis16477-2" , (kernel_ulong_t)&adis16475_chip_info[ADIS16477_2] }, |
1508 | { "adis16477-3" , (kernel_ulong_t)&adis16475_chip_info[ADIS16477_3] }, |
1509 | { "adis16465-1" , (kernel_ulong_t)&adis16475_chip_info[ADIS16465_1] }, |
1510 | { "adis16465-2" , (kernel_ulong_t)&adis16475_chip_info[ADIS16465_2] }, |
1511 | { "adis16465-3" , (kernel_ulong_t)&adis16475_chip_info[ADIS16465_3] }, |
1512 | { "adis16467-1" , (kernel_ulong_t)&adis16475_chip_info[ADIS16467_1] }, |
1513 | { "adis16467-2" , (kernel_ulong_t)&adis16475_chip_info[ADIS16467_2] }, |
1514 | { "adis16467-3" , (kernel_ulong_t)&adis16475_chip_info[ADIS16467_3] }, |
1515 | { "adis16500" , (kernel_ulong_t)&adis16475_chip_info[ADIS16500] }, |
1516 | { "adis16505-1" , (kernel_ulong_t)&adis16475_chip_info[ADIS16505_1] }, |
1517 | { "adis16505-2" , (kernel_ulong_t)&adis16475_chip_info[ADIS16505_2] }, |
1518 | { "adis16505-3" , (kernel_ulong_t)&adis16475_chip_info[ADIS16505_3] }, |
1519 | { "adis16507-1" , (kernel_ulong_t)&adis16475_chip_info[ADIS16507_1] }, |
1520 | { "adis16507-2" , (kernel_ulong_t)&adis16475_chip_info[ADIS16507_2] }, |
1521 | { "adis16507-3" , (kernel_ulong_t)&adis16475_chip_info[ADIS16507_3] }, |
1522 | { } |
1523 | }; |
1524 | MODULE_DEVICE_TABLE(spi, adis16475_ids); |
1525 | |
1526 | static struct spi_driver adis16475_driver = { |
1527 | .driver = { |
1528 | .name = "adis16475" , |
1529 | .of_match_table = adis16475_of_match, |
1530 | }, |
1531 | .probe = adis16475_probe, |
1532 | .id_table = adis16475_ids, |
1533 | }; |
1534 | module_spi_driver(adis16475_driver); |
1535 | |
1536 | MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>" ); |
1537 | MODULE_DESCRIPTION("Analog Devices ADIS16475 IMU driver" ); |
1538 | MODULE_LICENSE("GPL" ); |
1539 | MODULE_IMPORT_NS(IIO_ADISLIB); |
1540 | |