1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2020 Invensense, Inc.
6 #include <linux/kernel.h>
7 #include <linux/device.h>
8 #include <linux/mutex.h>
9 #include <linux/pm_runtime.h>
10 #include <linux/regmap.h>
11 #include <linux/delay.h>
12 #include <linux/math64.h>
14 #include <linux/iio/buffer.h>
15 #include <linux/iio/common/inv_sensors_timestamp.h>
16 #include <linux/iio/iio.h>
17 #include <linux/iio/kfifo_buf.h>
19 #include "inv_icm42600.h"
20 #include "inv_icm42600_temp.h"
21 #include "inv_icm42600_buffer.h"
23 #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \
27 .channel2 = _modifier, \
28 .info_mask_separate = \
29 BIT(IIO_CHAN_INFO_RAW) | \
30 BIT(IIO_CHAN_INFO_CALIBBIAS), \
31 .info_mask_shared_by_type = \
32 BIT(IIO_CHAN_INFO_SCALE), \
33 .info_mask_shared_by_type_available = \
34 BIT(IIO_CHAN_INFO_SCALE) | \
35 BIT(IIO_CHAN_INFO_CALIBBIAS), \
36 .info_mask_shared_by_all = \
37 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
38 .info_mask_shared_by_all_available = \
39 BIT(IIO_CHAN_INFO_SAMP_FREQ), \
40 .scan_index = _index, \
45 .endianness = IIO_BE, \
47 .ext_info = _ext_info, \
50 enum inv_icm42600_accel_scan
{
51 INV_ICM42600_ACCEL_SCAN_X
,
52 INV_ICM42600_ACCEL_SCAN_Y
,
53 INV_ICM42600_ACCEL_SCAN_Z
,
54 INV_ICM42600_ACCEL_SCAN_TEMP
,
55 INV_ICM42600_ACCEL_SCAN_TIMESTAMP
,
58 static const char * const inv_icm42600_accel_power_mode_items
[] = {
62 static const int inv_icm42600_accel_power_mode_values
[] = {
63 INV_ICM42600_SENSOR_MODE_LOW_NOISE
,
64 INV_ICM42600_SENSOR_MODE_LOW_POWER
,
66 static const int inv_icm42600_accel_filter_values
[] = {
67 INV_ICM42600_FILTER_BW_ODR_DIV_2
,
68 INV_ICM42600_FILTER_AVG_16X
,
71 static int inv_icm42600_accel_power_mode_set(struct iio_dev
*indio_dev
,
72 const struct iio_chan_spec
*chan
,
75 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
76 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
77 int power_mode
, filter
;
79 if (chan
->type
!= IIO_ACCEL
)
82 if (idx
>= ARRAY_SIZE(inv_icm42600_accel_power_mode_values
))
85 if (iio_buffer_enabled(indio_dev
))
88 power_mode
= inv_icm42600_accel_power_mode_values
[idx
];
89 filter
= inv_icm42600_accel_filter_values
[idx
];
91 guard(mutex
)(&st
->lock
);
93 /* prevent change if power mode is not supported by the ODR */
95 case INV_ICM42600_SENSOR_MODE_LOW_NOISE
:
96 if (st
->conf
.accel
.odr
>= INV_ICM42600_ODR_6_25HZ_LP
&&
97 st
->conf
.accel
.odr
<= INV_ICM42600_ODR_1_5625HZ_LP
)
100 case INV_ICM42600_SENSOR_MODE_LOW_POWER
:
102 if (st
->conf
.accel
.odr
<= INV_ICM42600_ODR_1KHZ_LN
)
107 accel_st
->power_mode
= power_mode
;
108 accel_st
->filter
= filter
;
113 static int inv_icm42600_accel_power_mode_get(struct iio_dev
*indio_dev
,
114 const struct iio_chan_spec
*chan
)
116 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
117 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
121 if (chan
->type
!= IIO_ACCEL
)
124 guard(mutex
)(&st
->lock
);
126 /* if sensor is on, returns actual power mode and not configured one */
127 switch (st
->conf
.accel
.mode
) {
128 case INV_ICM42600_SENSOR_MODE_LOW_POWER
:
129 case INV_ICM42600_SENSOR_MODE_LOW_NOISE
:
130 power_mode
= st
->conf
.accel
.mode
;
133 power_mode
= accel_st
->power_mode
;
137 for (idx
= 0; idx
< ARRAY_SIZE(inv_icm42600_accel_power_mode_values
); ++idx
) {
138 if (power_mode
== inv_icm42600_accel_power_mode_values
[idx
])
141 if (idx
>= ARRAY_SIZE(inv_icm42600_accel_power_mode_values
))
147 static const struct iio_enum inv_icm42600_accel_power_mode_enum
= {
148 .items
= inv_icm42600_accel_power_mode_items
,
149 .num_items
= ARRAY_SIZE(inv_icm42600_accel_power_mode_items
),
150 .set
= inv_icm42600_accel_power_mode_set
,
151 .get
= inv_icm42600_accel_power_mode_get
,
154 static const struct iio_chan_spec_ext_info inv_icm42600_accel_ext_infos
[] = {
155 IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL
, inv_icm42600_get_mount_matrix
),
156 IIO_ENUM_AVAILABLE("power_mode", IIO_SHARED_BY_TYPE
,
157 &inv_icm42600_accel_power_mode_enum
),
158 IIO_ENUM("power_mode", IIO_SHARED_BY_TYPE
,
159 &inv_icm42600_accel_power_mode_enum
),
163 static const struct iio_chan_spec inv_icm42600_accel_channels
[] = {
164 INV_ICM42600_ACCEL_CHAN(IIO_MOD_X
, INV_ICM42600_ACCEL_SCAN_X
,
165 inv_icm42600_accel_ext_infos
),
166 INV_ICM42600_ACCEL_CHAN(IIO_MOD_Y
, INV_ICM42600_ACCEL_SCAN_Y
,
167 inv_icm42600_accel_ext_infos
),
168 INV_ICM42600_ACCEL_CHAN(IIO_MOD_Z
, INV_ICM42600_ACCEL_SCAN_Z
,
169 inv_icm42600_accel_ext_infos
),
170 INV_ICM42600_TEMP_CHAN(INV_ICM42600_ACCEL_SCAN_TEMP
),
171 IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42600_ACCEL_SCAN_TIMESTAMP
),
175 * IIO buffer data: size must be a power of 2 and timestamp aligned
176 * 16 bytes: 6 bytes acceleration, 2 bytes temperature, 8 bytes timestamp
178 struct inv_icm42600_accel_buffer
{
179 struct inv_icm42600_fifo_sensor_data accel
;
181 int64_t timestamp
__aligned(8);
184 #define INV_ICM42600_SCAN_MASK_ACCEL_3AXIS \
185 (BIT(INV_ICM42600_ACCEL_SCAN_X) | \
186 BIT(INV_ICM42600_ACCEL_SCAN_Y) | \
187 BIT(INV_ICM42600_ACCEL_SCAN_Z))
189 #define INV_ICM42600_SCAN_MASK_TEMP BIT(INV_ICM42600_ACCEL_SCAN_TEMP)
191 static const unsigned long inv_icm42600_accel_scan_masks
[] = {
192 /* 3-axis accel + temperature */
193 INV_ICM42600_SCAN_MASK_ACCEL_3AXIS
| INV_ICM42600_SCAN_MASK_TEMP
,
197 /* enable accelerometer sensor and FIFO write */
198 static int inv_icm42600_accel_update_scan_mode(struct iio_dev
*indio_dev
,
199 const unsigned long *scan_mask
)
201 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
202 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
203 struct inv_sensors_timestamp
*ts
= &accel_st
->ts
;
204 struct inv_icm42600_sensor_conf conf
= INV_ICM42600_SENSOR_CONF_INIT
;
205 unsigned int fifo_en
= 0;
206 unsigned int sleep_temp
= 0;
207 unsigned int sleep_accel
= 0;
211 mutex_lock(&st
->lock
);
213 if (*scan_mask
& INV_ICM42600_SCAN_MASK_TEMP
) {
214 /* enable temp sensor */
215 ret
= inv_icm42600_set_temp_conf(st
, true, &sleep_temp
);
218 fifo_en
|= INV_ICM42600_SENSOR_TEMP
;
221 if (*scan_mask
& INV_ICM42600_SCAN_MASK_ACCEL_3AXIS
) {
222 /* enable accel sensor */
223 conf
.mode
= accel_st
->power_mode
;
224 conf
.filter
= accel_st
->filter
;
225 ret
= inv_icm42600_set_accel_conf(st
, &conf
, &sleep_accel
);
228 fifo_en
|= INV_ICM42600_SENSOR_ACCEL
;
231 /* update data FIFO write */
232 inv_sensors_timestamp_apply_odr(ts
, 0, 0, 0);
233 ret
= inv_icm42600_buffer_set_fifo_en(st
, fifo_en
| st
->fifo
.en
);
236 mutex_unlock(&st
->lock
);
237 /* sleep maximum required time */
238 sleep
= max(sleep_accel
, sleep_temp
);
244 static int inv_icm42600_accel_read_sensor(struct iio_dev
*indio_dev
,
245 struct iio_chan_spec
const *chan
,
248 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
249 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
250 struct device
*dev
= regmap_get_device(st
->map
);
251 struct inv_icm42600_sensor_conf conf
= INV_ICM42600_SENSOR_CONF_INIT
;
256 if (chan
->type
!= IIO_ACCEL
)
259 switch (chan
->channel2
) {
261 reg
= INV_ICM42600_REG_ACCEL_DATA_X
;
264 reg
= INV_ICM42600_REG_ACCEL_DATA_Y
;
267 reg
= INV_ICM42600_REG_ACCEL_DATA_Z
;
273 pm_runtime_get_sync(dev
);
274 mutex_lock(&st
->lock
);
276 /* enable accel sensor */
277 conf
.mode
= accel_st
->power_mode
;
278 conf
.filter
= accel_st
->filter
;
279 ret
= inv_icm42600_set_accel_conf(st
, &conf
, NULL
);
283 /* read accel register data */
284 data
= (__be16
*)&st
->buffer
[0];
285 ret
= regmap_bulk_read(st
->map
, reg
, data
, sizeof(*data
));
289 *val
= (int16_t)be16_to_cpup(data
);
290 if (*val
== INV_ICM42600_DATA_INVALID
)
293 mutex_unlock(&st
->lock
);
294 pm_runtime_mark_last_busy(dev
);
295 pm_runtime_put_autosuspend(dev
);
299 /* IIO format int + nano */
300 static const int inv_icm42600_accel_scale
[] = {
301 /* +/- 16G => 0.004788403 m/s-2 */
302 [2 * INV_ICM42600_ACCEL_FS_16G
] = 0,
303 [2 * INV_ICM42600_ACCEL_FS_16G
+ 1] = 4788403,
304 /* +/- 8G => 0.002394202 m/s-2 */
305 [2 * INV_ICM42600_ACCEL_FS_8G
] = 0,
306 [2 * INV_ICM42600_ACCEL_FS_8G
+ 1] = 2394202,
307 /* +/- 4G => 0.001197101 m/s-2 */
308 [2 * INV_ICM42600_ACCEL_FS_4G
] = 0,
309 [2 * INV_ICM42600_ACCEL_FS_4G
+ 1] = 1197101,
310 /* +/- 2G => 0.000598550 m/s-2 */
311 [2 * INV_ICM42600_ACCEL_FS_2G
] = 0,
312 [2 * INV_ICM42600_ACCEL_FS_2G
+ 1] = 598550,
314 static const int inv_icm42686_accel_scale
[] = {
315 /* +/- 32G => 0.009576807 m/s-2 */
316 [2 * INV_ICM42686_ACCEL_FS_32G
] = 0,
317 [2 * INV_ICM42686_ACCEL_FS_32G
+ 1] = 9576807,
318 /* +/- 16G => 0.004788403 m/s-2 */
319 [2 * INV_ICM42686_ACCEL_FS_16G
] = 0,
320 [2 * INV_ICM42686_ACCEL_FS_16G
+ 1] = 4788403,
321 /* +/- 8G => 0.002394202 m/s-2 */
322 [2 * INV_ICM42686_ACCEL_FS_8G
] = 0,
323 [2 * INV_ICM42686_ACCEL_FS_8G
+ 1] = 2394202,
324 /* +/- 4G => 0.001197101 m/s-2 */
325 [2 * INV_ICM42686_ACCEL_FS_4G
] = 0,
326 [2 * INV_ICM42686_ACCEL_FS_4G
+ 1] = 1197101,
327 /* +/- 2G => 0.000598550 m/s-2 */
328 [2 * INV_ICM42686_ACCEL_FS_2G
] = 0,
329 [2 * INV_ICM42686_ACCEL_FS_2G
+ 1] = 598550,
332 static int inv_icm42600_accel_read_scale(struct iio_dev
*indio_dev
,
335 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
336 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
339 idx
= st
->conf
.accel
.fs
;
341 *val
= accel_st
->scales
[2 * idx
];
342 *val2
= accel_st
->scales
[2 * idx
+ 1];
343 return IIO_VAL_INT_PLUS_NANO
;
346 static int inv_icm42600_accel_write_scale(struct iio_dev
*indio_dev
,
349 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
350 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
351 struct device
*dev
= regmap_get_device(st
->map
);
353 struct inv_icm42600_sensor_conf conf
= INV_ICM42600_SENSOR_CONF_INIT
;
356 for (idx
= 0; idx
< accel_st
->scales_len
; idx
+= 2) {
357 if (val
== accel_st
->scales
[idx
] &&
358 val2
== accel_st
->scales
[idx
+ 1])
361 if (idx
>= accel_st
->scales_len
)
366 pm_runtime_get_sync(dev
);
367 mutex_lock(&st
->lock
);
369 ret
= inv_icm42600_set_accel_conf(st
, &conf
, NULL
);
371 mutex_unlock(&st
->lock
);
372 pm_runtime_mark_last_busy(dev
);
373 pm_runtime_put_autosuspend(dev
);
378 /* IIO format int + micro */
379 static const int inv_icm42600_accel_odr
[] = {
404 static const int inv_icm42600_accel_odr_conv
[] = {
405 INV_ICM42600_ODR_1_5625HZ_LP
,
406 INV_ICM42600_ODR_3_125HZ_LP
,
407 INV_ICM42600_ODR_6_25HZ_LP
,
408 INV_ICM42600_ODR_12_5HZ
,
409 INV_ICM42600_ODR_25HZ
,
410 INV_ICM42600_ODR_50HZ
,
411 INV_ICM42600_ODR_100HZ
,
412 INV_ICM42600_ODR_200HZ
,
413 INV_ICM42600_ODR_1KHZ_LN
,
414 INV_ICM42600_ODR_2KHZ_LN
,
415 INV_ICM42600_ODR_4KHZ_LN
,
418 static int inv_icm42600_accel_read_odr(struct inv_icm42600_state
*st
,
424 odr
= st
->conf
.accel
.odr
;
426 for (i
= 0; i
< ARRAY_SIZE(inv_icm42600_accel_odr_conv
); ++i
) {
427 if (inv_icm42600_accel_odr_conv
[i
] == odr
)
430 if (i
>= ARRAY_SIZE(inv_icm42600_accel_odr_conv
))
433 *val
= inv_icm42600_accel_odr
[2 * i
];
434 *val2
= inv_icm42600_accel_odr
[2 * i
+ 1];
436 return IIO_VAL_INT_PLUS_MICRO
;
439 static int inv_icm42600_accel_write_odr(struct iio_dev
*indio_dev
,
442 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
443 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
444 struct inv_sensors_timestamp
*ts
= &accel_st
->ts
;
445 struct device
*dev
= regmap_get_device(st
->map
);
447 struct inv_icm42600_sensor_conf conf
= INV_ICM42600_SENSOR_CONF_INIT
;
450 for (idx
= 0; idx
< ARRAY_SIZE(inv_icm42600_accel_odr
); idx
+= 2) {
451 if (val
== inv_icm42600_accel_odr
[idx
] &&
452 val2
== inv_icm42600_accel_odr
[idx
+ 1])
455 if (idx
>= ARRAY_SIZE(inv_icm42600_accel_odr
))
458 conf
.odr
= inv_icm42600_accel_odr_conv
[idx
/ 2];
460 pm_runtime_get_sync(dev
);
461 mutex_lock(&st
->lock
);
463 ret
= inv_sensors_timestamp_update_odr(ts
, inv_icm42600_odr_to_period(conf
.odr
),
464 iio_buffer_enabled(indio_dev
));
468 ret
= inv_icm42600_set_accel_conf(st
, &conf
, NULL
);
471 inv_icm42600_buffer_update_fifo_period(st
);
472 inv_icm42600_buffer_update_watermark(st
);
475 mutex_unlock(&st
->lock
);
476 pm_runtime_mark_last_busy(dev
);
477 pm_runtime_put_autosuspend(dev
);
483 * Calibration bias values, IIO range format int + micro.
484 * Value is limited to +/-1g coded on 12 bits signed. Step is 0.5mg.
486 static int inv_icm42600_accel_calibbias
[] = {
487 -10, 42010, /* min: -10.042010 m/s² */
488 0, 4903, /* step: 0.004903 m/s² */
489 10, 37106, /* max: 10.037106 m/s² */
492 static int inv_icm42600_accel_read_offset(struct inv_icm42600_state
*st
,
493 struct iio_chan_spec
const *chan
,
496 struct device
*dev
= regmap_get_device(st
->map
);
504 if (chan
->type
!= IIO_ACCEL
)
507 switch (chan
->channel2
) {
509 reg
= INV_ICM42600_REG_OFFSET_USER4
;
512 reg
= INV_ICM42600_REG_OFFSET_USER6
;
515 reg
= INV_ICM42600_REG_OFFSET_USER7
;
521 pm_runtime_get_sync(dev
);
522 mutex_lock(&st
->lock
);
524 ret
= regmap_bulk_read(st
->map
, reg
, st
->buffer
, sizeof(data
));
525 memcpy(data
, st
->buffer
, sizeof(data
));
527 mutex_unlock(&st
->lock
);
528 pm_runtime_mark_last_busy(dev
);
529 pm_runtime_put_autosuspend(dev
);
533 /* 12 bits signed value */
534 switch (chan
->channel2
) {
536 offset
= sign_extend32(((data
[0] & 0xF0) << 4) | data
[1], 11);
539 offset
= sign_extend32(((data
[1] & 0x0F) << 8) | data
[0], 11);
542 offset
= sign_extend32(((data
[0] & 0xF0) << 4) | data
[1], 11);
549 * convert raw offset to g then to m/s²
550 * 12 bits signed raw step 0.5mg to g: 5 / 10000
551 * g to m/s²: 9.806650
552 * result in micro (1000000)
553 * (offset * 5 * 9.806650 * 1000000) / 10000
555 val64
= (int64_t)offset
* 5LL * 9806650LL;
556 /* for rounding, add + or - divisor (10000) divided by 2 */
558 val64
+= 10000LL / 2LL;
560 val64
-= 10000LL / 2LL;
561 bias
= div_s64(val64
, 10000L);
562 *val
= bias
/ 1000000L;
563 *val2
= bias
% 1000000L;
565 return IIO_VAL_INT_PLUS_MICRO
;
568 static int inv_icm42600_accel_write_offset(struct inv_icm42600_state
*st
,
569 struct iio_chan_spec
const *chan
,
572 struct device
*dev
= regmap_get_device(st
->map
);
575 unsigned int reg
, regval
;
579 if (chan
->type
!= IIO_ACCEL
)
582 switch (chan
->channel2
) {
584 reg
= INV_ICM42600_REG_OFFSET_USER4
;
587 reg
= INV_ICM42600_REG_OFFSET_USER6
;
590 reg
= INV_ICM42600_REG_OFFSET_USER7
;
596 /* inv_icm42600_accel_calibbias: min - step - max in micro */
597 min
= inv_icm42600_accel_calibbias
[0] * 1000000L +
598 inv_icm42600_accel_calibbias
[1];
599 max
= inv_icm42600_accel_calibbias
[4] * 1000000L +
600 inv_icm42600_accel_calibbias
[5];
601 val64
= (int64_t)val
* 1000000LL + (int64_t)val2
;
602 if (val64
< min
|| val64
> max
)
606 * convert m/s² to g then to raw value
607 * m/s² to g: 1 / 9.806650
608 * g to raw 12 bits signed, step 0.5mg: 10000 / 5
609 * val in micro (1000000)
610 * val * 10000 / (9.806650 * 1000000 * 5)
612 val64
= val64
* 10000LL;
613 /* for rounding, add + or - divisor (9806650 * 5) divided by 2 */
615 val64
+= 9806650 * 5 / 2;
617 val64
-= 9806650 * 5 / 2;
618 offset
= div_s64(val64
, 9806650 * 5);
620 /* clamp value limited to 12 bits signed */
623 else if (offset
> 2047)
626 pm_runtime_get_sync(dev
);
627 mutex_lock(&st
->lock
);
629 switch (chan
->channel2
) {
631 /* OFFSET_USER4 register is shared */
632 ret
= regmap_read(st
->map
, INV_ICM42600_REG_OFFSET_USER4
,
636 st
->buffer
[0] = ((offset
& 0xF00) >> 4) | (regval
& 0x0F);
637 st
->buffer
[1] = offset
& 0xFF;
640 /* OFFSET_USER7 register is shared */
641 ret
= regmap_read(st
->map
, INV_ICM42600_REG_OFFSET_USER7
,
645 st
->buffer
[0] = offset
& 0xFF;
646 st
->buffer
[1] = ((offset
& 0xF00) >> 8) | (regval
& 0xF0);
649 /* OFFSET_USER7 register is shared */
650 ret
= regmap_read(st
->map
, INV_ICM42600_REG_OFFSET_USER7
,
654 st
->buffer
[0] = ((offset
& 0xF00) >> 4) | (regval
& 0x0F);
655 st
->buffer
[1] = offset
& 0xFF;
662 ret
= regmap_bulk_write(st
->map
, reg
, st
->buffer
, 2);
665 mutex_unlock(&st
->lock
);
666 pm_runtime_mark_last_busy(dev
);
667 pm_runtime_put_autosuspend(dev
);
671 static int inv_icm42600_accel_read_raw(struct iio_dev
*indio_dev
,
672 struct iio_chan_spec
const *chan
,
673 int *val
, int *val2
, long mask
)
675 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
679 switch (chan
->type
) {
683 return inv_icm42600_temp_read_raw(indio_dev
, chan
, val
, val2
, mask
);
689 case IIO_CHAN_INFO_RAW
:
690 ret
= iio_device_claim_direct_mode(indio_dev
);
693 ret
= inv_icm42600_accel_read_sensor(indio_dev
, chan
, &data
);
694 iio_device_release_direct_mode(indio_dev
);
699 case IIO_CHAN_INFO_SCALE
:
700 return inv_icm42600_accel_read_scale(indio_dev
, val
, val2
);
701 case IIO_CHAN_INFO_SAMP_FREQ
:
702 return inv_icm42600_accel_read_odr(st
, val
, val2
);
703 case IIO_CHAN_INFO_CALIBBIAS
:
704 return inv_icm42600_accel_read_offset(st
, chan
, val
, val2
);
710 static int inv_icm42600_accel_read_avail(struct iio_dev
*indio_dev
,
711 struct iio_chan_spec
const *chan
,
713 int *type
, int *length
, long mask
)
715 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
717 if (chan
->type
!= IIO_ACCEL
)
721 case IIO_CHAN_INFO_SCALE
:
722 *vals
= accel_st
->scales
;
723 *type
= IIO_VAL_INT_PLUS_NANO
;
724 *length
= accel_st
->scales_len
;
725 return IIO_AVAIL_LIST
;
726 case IIO_CHAN_INFO_SAMP_FREQ
:
727 *vals
= inv_icm42600_accel_odr
;
728 *type
= IIO_VAL_INT_PLUS_MICRO
;
729 *length
= ARRAY_SIZE(inv_icm42600_accel_odr
);
730 return IIO_AVAIL_LIST
;
731 case IIO_CHAN_INFO_CALIBBIAS
:
732 *vals
= inv_icm42600_accel_calibbias
;
733 *type
= IIO_VAL_INT_PLUS_MICRO
;
734 return IIO_AVAIL_RANGE
;
740 static int inv_icm42600_accel_write_raw(struct iio_dev
*indio_dev
,
741 struct iio_chan_spec
const *chan
,
742 int val
, int val2
, long mask
)
744 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
747 if (chan
->type
!= IIO_ACCEL
)
751 case IIO_CHAN_INFO_SCALE
:
752 ret
= iio_device_claim_direct_mode(indio_dev
);
755 ret
= inv_icm42600_accel_write_scale(indio_dev
, val
, val2
);
756 iio_device_release_direct_mode(indio_dev
);
758 case IIO_CHAN_INFO_SAMP_FREQ
:
759 return inv_icm42600_accel_write_odr(indio_dev
, val
, val2
);
760 case IIO_CHAN_INFO_CALIBBIAS
:
761 ret
= iio_device_claim_direct_mode(indio_dev
);
764 ret
= inv_icm42600_accel_write_offset(st
, chan
, val
, val2
);
765 iio_device_release_direct_mode(indio_dev
);
772 static int inv_icm42600_accel_write_raw_get_fmt(struct iio_dev
*indio_dev
,
773 struct iio_chan_spec
const *chan
,
776 if (chan
->type
!= IIO_ACCEL
)
780 case IIO_CHAN_INFO_SCALE
:
781 return IIO_VAL_INT_PLUS_NANO
;
782 case IIO_CHAN_INFO_SAMP_FREQ
:
783 return IIO_VAL_INT_PLUS_MICRO
;
784 case IIO_CHAN_INFO_CALIBBIAS
:
785 return IIO_VAL_INT_PLUS_MICRO
;
791 static int inv_icm42600_accel_hwfifo_set_watermark(struct iio_dev
*indio_dev
,
794 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
797 mutex_lock(&st
->lock
);
799 st
->fifo
.watermark
.accel
= val
;
800 ret
= inv_icm42600_buffer_update_watermark(st
);
802 mutex_unlock(&st
->lock
);
807 static int inv_icm42600_accel_hwfifo_flush(struct iio_dev
*indio_dev
,
810 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
816 mutex_lock(&st
->lock
);
818 ret
= inv_icm42600_buffer_hwfifo_flush(st
, count
);
820 ret
= st
->fifo
.nb
.accel
;
822 mutex_unlock(&st
->lock
);
827 static const struct iio_info inv_icm42600_accel_info
= {
828 .read_raw
= inv_icm42600_accel_read_raw
,
829 .read_avail
= inv_icm42600_accel_read_avail
,
830 .write_raw
= inv_icm42600_accel_write_raw
,
831 .write_raw_get_fmt
= inv_icm42600_accel_write_raw_get_fmt
,
832 .debugfs_reg_access
= inv_icm42600_debugfs_reg
,
833 .update_scan_mode
= inv_icm42600_accel_update_scan_mode
,
834 .hwfifo_set_watermark
= inv_icm42600_accel_hwfifo_set_watermark
,
835 .hwfifo_flush_to_buffer
= inv_icm42600_accel_hwfifo_flush
,
838 struct iio_dev
*inv_icm42600_accel_init(struct inv_icm42600_state
*st
)
840 struct device
*dev
= regmap_get_device(st
->map
);
842 struct inv_icm42600_sensor_state
*accel_st
;
843 struct inv_sensors_timestamp_chip ts_chip
;
844 struct iio_dev
*indio_dev
;
847 name
= devm_kasprintf(dev
, GFP_KERNEL
, "%s-accel", st
->name
);
849 return ERR_PTR(-ENOMEM
);
851 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*accel_st
));
853 return ERR_PTR(-ENOMEM
);
854 accel_st
= iio_priv(indio_dev
);
857 case INV_CHIP_ICM42686
:
858 accel_st
->scales
= inv_icm42686_accel_scale
;
859 accel_st
->scales_len
= ARRAY_SIZE(inv_icm42686_accel_scale
);
862 accel_st
->scales
= inv_icm42600_accel_scale
;
863 accel_st
->scales_len
= ARRAY_SIZE(inv_icm42600_accel_scale
);
866 /* low-power by default at init */
867 accel_st
->power_mode
= INV_ICM42600_SENSOR_MODE_LOW_POWER
;
868 accel_st
->filter
= INV_ICM42600_FILTER_AVG_16X
;
871 * clock period is 32kHz (31250ns)
872 * jitter is +/- 2% (20 per mille)
874 ts_chip
.clock_period
= 31250;
876 ts_chip
.init_period
= inv_icm42600_odr_to_period(st
->conf
.accel
.odr
);
877 inv_sensors_timestamp_init(&accel_st
->ts
, &ts_chip
);
879 iio_device_set_drvdata(indio_dev
, st
);
880 indio_dev
->name
= name
;
881 indio_dev
->info
= &inv_icm42600_accel_info
;
882 indio_dev
->modes
= INDIO_DIRECT_MODE
;
883 indio_dev
->channels
= inv_icm42600_accel_channels
;
884 indio_dev
->num_channels
= ARRAY_SIZE(inv_icm42600_accel_channels
);
885 indio_dev
->available_scan_masks
= inv_icm42600_accel_scan_masks
;
887 ret
= devm_iio_kfifo_buffer_setup(dev
, indio_dev
,
888 &inv_icm42600_buffer_ops
);
892 ret
= devm_iio_device_register(dev
, indio_dev
);
899 int inv_icm42600_accel_parse_fifo(struct iio_dev
*indio_dev
)
901 struct inv_icm42600_state
*st
= iio_device_get_drvdata(indio_dev
);
902 struct inv_icm42600_sensor_state
*accel_st
= iio_priv(indio_dev
);
903 struct inv_sensors_timestamp
*ts
= &accel_st
->ts
;
906 const void *accel
, *gyro
, *timestamp
;
910 struct inv_icm42600_accel_buffer buffer
;
912 /* parse all fifo packets */
913 for (i
= 0, no
= 0; i
< st
->fifo
.count
; i
+= size
, ++no
) {
914 size
= inv_icm42600_fifo_decode_packet(&st
->fifo
.data
[i
],
915 &accel
, &gyro
, &temp
, ×tamp
, &odr
);
916 /* quit if error or FIFO is empty */
920 /* skip packet if no accel data or data is invalid */
921 if (accel
== NULL
|| !inv_icm42600_fifo_is_data_valid(accel
))
925 if (odr
& INV_ICM42600_SENSOR_ACCEL
)
926 inv_sensors_timestamp_apply_odr(ts
, st
->fifo
.period
,
927 st
->fifo
.nb
.total
, no
);
929 /* buffer is copied to userspace, zeroing it to avoid any data leak */
930 memset(&buffer
, 0, sizeof(buffer
));
931 memcpy(&buffer
.accel
, accel
, sizeof(buffer
.accel
));
932 /* convert 8 bits FIFO temperature in high resolution format */
933 buffer
.temp
= temp
? (*temp
* 64) : 0;
934 ts_val
= inv_sensors_timestamp_pop(ts
);
935 iio_push_to_buffers_with_timestamp(indio_dev
, &buffer
, ts_val
);