1 // SPDX-License-Identifier: GPL-2.0-only
3 * STMicroelectronics st_lsm6dsx sensor driver
5 * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer
6 * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial
7 * interface standard output.
8 * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale
9 * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of
10 * +-125/+-245/+-500/+-1000/+-2000 dps
11 * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
12 * allowing dynamic batching of sensor data.
13 * LSM9DSx series is similar but includes an additional magnetometer, handled
14 * by a different driver.
18 * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
19 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
20 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
23 * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
24 * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
25 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
26 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
29 * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX:
30 * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
31 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
32 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
36 * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
37 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
38 * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
39 * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
42 * Copyright 2016 STMicroelectronics Inc.
44 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
45 * Denis Ciocca <denis.ciocca@st.com>
48 #include <linux/kernel.h>
49 #include <linux/module.h>
50 #include <linux/delay.h>
51 #include <linux/iio/iio.h>
52 #include <linux/iio/sysfs.h>
54 #include <linux/regmap.h>
55 #include <linux/bitfield.h>
57 #include <linux/platform_data/st_sensors_pdata.h>
59 #include "st_lsm6dsx.h"
61 #define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
62 #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
63 #define ST_LSM6DSX_REG_RESET_MASK BIT(0)
64 #define ST_LSM6DSX_REG_BOOT_MASK BIT(7)
65 #define ST_LSM6DSX_REG_BDU_ADDR 0x12
66 #define ST_LSM6DSX_REG_BDU_MASK BIT(6)
68 static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
69 ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
70 ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
71 ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
72 IIO_CHAN_SOFT_TIMESTAMP(3),
75 static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
76 ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
77 ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
78 ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
79 IIO_CHAN_SOFT_TIMESTAMP(3),
82 static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
83 ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
84 ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
85 ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
86 IIO_CHAN_SOFT_TIMESTAMP(3),
89 static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
98 .hw_id = ST_LSM9DS1_ID,
99 .name = ST_LSM9DS1_DEV_NAME,
103 [ST_LSM6DSX_ID_ACC] = {
104 .chan = st_lsm6dsx_acc_channels,
105 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
107 [ST_LSM6DSX_ID_GYRO] = {
108 .chan = st_lsm6ds0_gyro_channels,
109 .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
113 [ST_LSM6DSX_ID_ACC] = {
116 .mask = GENMASK(7, 5),
118 .odr_avl[0] = { 10, 0x01 },
119 .odr_avl[1] = { 50, 0x02 },
120 .odr_avl[2] = { 119, 0x03 },
121 .odr_avl[3] = { 238, 0x04 },
122 .odr_avl[4] = { 476, 0x05 },
123 .odr_avl[5] = { 952, 0x06 },
125 [ST_LSM6DSX_ID_GYRO] = {
128 .mask = GENMASK(7, 5),
130 .odr_avl[0] = { 15, 0x01 },
131 .odr_avl[1] = { 60, 0x02 },
132 .odr_avl[2] = { 119, 0x03 },
133 .odr_avl[3] = { 238, 0x04 },
134 .odr_avl[4] = { 476, 0x05 },
135 .odr_avl[5] = { 952, 0x06 },
139 [ST_LSM6DSX_ID_ACC] = {
142 .mask = GENMASK(4, 3),
144 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
145 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
146 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
147 .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
149 [ST_LSM6DSX_ID_GYRO] = {
152 .mask = GENMASK(4, 3),
154 .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 },
155 .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 },
156 .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
165 .max_fifo_size = 1365,
168 .hw_id = ST_LSM6DS3_ID,
169 .name = ST_LSM6DS3_DEV_NAME,
173 [ST_LSM6DSX_ID_ACC] = {
174 .chan = st_lsm6dsx_acc_channels,
175 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
177 [ST_LSM6DSX_ID_GYRO] = {
178 .chan = st_lsm6dsx_gyro_channels,
179 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
183 [ST_LSM6DSX_ID_ACC] = {
186 .mask = GENMASK(7, 4),
188 .odr_avl[0] = { 13, 0x01 },
189 .odr_avl[1] = { 26, 0x02 },
190 .odr_avl[2] = { 52, 0x03 },
191 .odr_avl[3] = { 104, 0x04 },
192 .odr_avl[4] = { 208, 0x05 },
193 .odr_avl[5] = { 416, 0x06 },
195 [ST_LSM6DSX_ID_GYRO] = {
198 .mask = GENMASK(7, 4),
200 .odr_avl[0] = { 13, 0x01 },
201 .odr_avl[1] = { 26, 0x02 },
202 .odr_avl[2] = { 52, 0x03 },
203 .odr_avl[3] = { 104, 0x04 },
204 .odr_avl[4] = { 208, 0x05 },
205 .odr_avl[5] = { 416, 0x06 },
209 [ST_LSM6DSX_ID_ACC] = {
212 .mask = GENMASK(3, 2),
214 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
215 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
216 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
217 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
219 [ST_LSM6DSX_ID_GYRO] = {
222 .mask = GENMASK(3, 2),
224 .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
225 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
226 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
227 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
231 [ST_LSM6DSX_ID_ACC] = {
233 .mask = GENMASK(2, 0),
235 [ST_LSM6DSX_ID_GYRO] = {
237 .mask = GENMASK(5, 3),
241 .update_fifo = st_lsm6dsx_update_fifo,
242 .read_fifo = st_lsm6dsx_read_fifo,
245 .mask = GENMASK(11, 0),
249 .mask = GENMASK(11, 0),
251 .th_wl = 3, /* 1LSB = 2B */
268 .mask = GENMASK(5, 3),
277 .max_fifo_size = 682,
280 .hw_id = ST_LSM6DS3H_ID,
281 .name = ST_LSM6DS3H_DEV_NAME,
285 [ST_LSM6DSX_ID_ACC] = {
286 .chan = st_lsm6dsx_acc_channels,
287 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
289 [ST_LSM6DSX_ID_GYRO] = {
290 .chan = st_lsm6dsx_gyro_channels,
291 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
295 [ST_LSM6DSX_ID_ACC] = {
298 .mask = GENMASK(7, 4),
300 .odr_avl[0] = { 13, 0x01 },
301 .odr_avl[1] = { 26, 0x02 },
302 .odr_avl[2] = { 52, 0x03 },
303 .odr_avl[3] = { 104, 0x04 },
304 .odr_avl[4] = { 208, 0x05 },
305 .odr_avl[5] = { 416, 0x06 },
307 [ST_LSM6DSX_ID_GYRO] = {
310 .mask = GENMASK(7, 4),
312 .odr_avl[0] = { 13, 0x01 },
313 .odr_avl[1] = { 26, 0x02 },
314 .odr_avl[2] = { 52, 0x03 },
315 .odr_avl[3] = { 104, 0x04 },
316 .odr_avl[4] = { 208, 0x05 },
317 .odr_avl[5] = { 416, 0x06 },
321 [ST_LSM6DSX_ID_ACC] = {
324 .mask = GENMASK(3, 2),
326 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
327 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
328 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
329 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
331 [ST_LSM6DSX_ID_GYRO] = {
334 .mask = GENMASK(3, 2),
336 .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
337 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
338 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
339 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
343 [ST_LSM6DSX_ID_ACC] = {
345 .mask = GENMASK(2, 0),
347 [ST_LSM6DSX_ID_GYRO] = {
349 .mask = GENMASK(5, 3),
353 .update_fifo = st_lsm6dsx_update_fifo,
354 .read_fifo = st_lsm6dsx_read_fifo,
357 .mask = GENMASK(11, 0),
361 .mask = GENMASK(11, 0),
363 .th_wl = 3, /* 1LSB = 2B */
380 .mask = GENMASK(5, 3),
389 .max_fifo_size = 682,
392 .hw_id = ST_LSM6DSL_ID,
393 .name = ST_LSM6DSL_DEV_NAME,
395 .hw_id = ST_LSM6DSM_ID,
396 .name = ST_LSM6DSM_DEV_NAME,
398 .hw_id = ST_ISM330DLC_ID,
399 .name = ST_ISM330DLC_DEV_NAME,
401 .hw_id = ST_LSM6DS3TRC_ID,
402 .name = ST_LSM6DS3TRC_DEV_NAME,
406 [ST_LSM6DSX_ID_ACC] = {
407 .chan = st_lsm6dsx_acc_channels,
408 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
410 [ST_LSM6DSX_ID_GYRO] = {
411 .chan = st_lsm6dsx_gyro_channels,
412 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
416 [ST_LSM6DSX_ID_ACC] = {
419 .mask = GENMASK(7, 4),
421 .odr_avl[0] = { 13, 0x01 },
422 .odr_avl[1] = { 26, 0x02 },
423 .odr_avl[2] = { 52, 0x03 },
424 .odr_avl[3] = { 104, 0x04 },
425 .odr_avl[4] = { 208, 0x05 },
426 .odr_avl[5] = { 416, 0x06 },
428 [ST_LSM6DSX_ID_GYRO] = {
431 .mask = GENMASK(7, 4),
433 .odr_avl[0] = { 13, 0x01 },
434 .odr_avl[1] = { 26, 0x02 },
435 .odr_avl[2] = { 52, 0x03 },
436 .odr_avl[3] = { 104, 0x04 },
437 .odr_avl[4] = { 208, 0x05 },
438 .odr_avl[5] = { 416, 0x06 },
442 [ST_LSM6DSX_ID_ACC] = {
445 .mask = GENMASK(3, 2),
447 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
448 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
449 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
450 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
452 [ST_LSM6DSX_ID_GYRO] = {
455 .mask = GENMASK(3, 2),
457 .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
458 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
459 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
460 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
464 [ST_LSM6DSX_ID_ACC] = {
466 .mask = GENMASK(2, 0),
468 [ST_LSM6DSX_ID_GYRO] = {
470 .mask = GENMASK(5, 3),
474 .update_fifo = st_lsm6dsx_update_fifo,
475 .read_fifo = st_lsm6dsx_read_fifo,
478 .mask = GENMASK(10, 0),
482 .mask = GENMASK(10, 0),
484 .th_wl = 3, /* 1LSB = 2B */
501 .mask = GENMASK(5, 3),
510 .max_fifo_size = 512,
513 .hw_id = ST_LSM6DSO_ID,
514 .name = ST_LSM6DSO_DEV_NAME,
516 .hw_id = ST_LSM6DSOX_ID,
517 .name = ST_LSM6DSOX_DEV_NAME,
521 [ST_LSM6DSX_ID_ACC] = {
522 .chan = st_lsm6dsx_acc_channels,
523 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
525 [ST_LSM6DSX_ID_GYRO] = {
526 .chan = st_lsm6dsx_gyro_channels,
527 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
531 [ST_LSM6DSX_ID_ACC] = {
534 .mask = GENMASK(7, 4),
536 .odr_avl[0] = { 13, 0x01 },
537 .odr_avl[1] = { 26, 0x02 },
538 .odr_avl[2] = { 52, 0x03 },
539 .odr_avl[3] = { 104, 0x04 },
540 .odr_avl[4] = { 208, 0x05 },
541 .odr_avl[5] = { 416, 0x06 },
543 [ST_LSM6DSX_ID_GYRO] = {
546 .mask = GENMASK(7, 4),
548 .odr_avl[0] = { 13, 0x01 },
549 .odr_avl[1] = { 26, 0x02 },
550 .odr_avl[2] = { 52, 0x03 },
551 .odr_avl[3] = { 104, 0x04 },
552 .odr_avl[4] = { 208, 0x05 },
553 .odr_avl[5] = { 416, 0x06 },
557 [ST_LSM6DSX_ID_ACC] = {
560 .mask = GENMASK(3, 2),
562 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
563 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
564 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
565 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
567 [ST_LSM6DSX_ID_GYRO] = {
570 .mask = GENMASK(3, 2),
572 .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
573 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
574 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
575 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
579 [ST_LSM6DSX_ID_ACC] = {
581 .mask = GENMASK(3, 0),
583 [ST_LSM6DSX_ID_GYRO] = {
585 .mask = GENMASK(7, 4),
589 .update_fifo = st_lsm6dsx_update_fifo,
590 .read_fifo = st_lsm6dsx_read_tagged_fifo,
593 .mask = GENMASK(8, 0),
597 .mask = GENMASK(9, 0),
608 .mask = GENMASK(7, 6),
626 .mask = GENMASK(1, 0),
634 .dw_slv0_addr = 0x21,
643 .max_fifo_size = 512,
646 .hw_id = ST_ASM330LHH_ID,
647 .name = ST_ASM330LHH_DEV_NAME,
651 [ST_LSM6DSX_ID_ACC] = {
652 .chan = st_lsm6dsx_acc_channels,
653 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
655 [ST_LSM6DSX_ID_GYRO] = {
656 .chan = st_lsm6dsx_gyro_channels,
657 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
661 [ST_LSM6DSX_ID_ACC] = {
664 .mask = GENMASK(7, 4),
666 .odr_avl[0] = { 13, 0x01 },
667 .odr_avl[1] = { 26, 0x02 },
668 .odr_avl[2] = { 52, 0x03 },
669 .odr_avl[3] = { 104, 0x04 },
670 .odr_avl[4] = { 208, 0x05 },
671 .odr_avl[5] = { 416, 0x06 },
673 [ST_LSM6DSX_ID_GYRO] = {
676 .mask = GENMASK(7, 4),
678 .odr_avl[0] = { 13, 0x01 },
679 .odr_avl[1] = { 26, 0x02 },
680 .odr_avl[2] = { 52, 0x03 },
681 .odr_avl[3] = { 104, 0x04 },
682 .odr_avl[4] = { 208, 0x05 },
683 .odr_avl[5] = { 416, 0x06 },
687 [ST_LSM6DSX_ID_ACC] = {
690 .mask = GENMASK(3, 2),
692 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
693 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
694 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
695 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
697 [ST_LSM6DSX_ID_GYRO] = {
700 .mask = GENMASK(3, 2),
702 .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
703 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
704 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
705 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
709 [ST_LSM6DSX_ID_ACC] = {
711 .mask = GENMASK(3, 0),
713 [ST_LSM6DSX_ID_GYRO] = {
715 .mask = GENMASK(7, 4),
719 .update_fifo = st_lsm6dsx_update_fifo,
720 .read_fifo = st_lsm6dsx_read_tagged_fifo,
723 .mask = GENMASK(8, 0),
727 .mask = GENMASK(9, 0),
738 .mask = GENMASK(7, 6),
747 .max_fifo_size = 512,
750 .hw_id = ST_LSM6DSR_ID,
751 .name = ST_LSM6DSR_DEV_NAME,
753 .hw_id = ST_ISM330DHCX_ID,
754 .name = ST_ISM330DHCX_DEV_NAME,
758 [ST_LSM6DSX_ID_ACC] = {
759 .chan = st_lsm6dsx_acc_channels,
760 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
762 [ST_LSM6DSX_ID_GYRO] = {
763 .chan = st_lsm6dsx_gyro_channels,
764 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
768 [ST_LSM6DSX_ID_ACC] = {
771 .mask = GENMASK(7, 4),
773 .odr_avl[0] = { 13, 0x01 },
774 .odr_avl[1] = { 26, 0x02 },
775 .odr_avl[2] = { 52, 0x03 },
776 .odr_avl[3] = { 104, 0x04 },
777 .odr_avl[4] = { 208, 0x05 },
778 .odr_avl[5] = { 416, 0x06 },
780 [ST_LSM6DSX_ID_GYRO] = {
783 .mask = GENMASK(7, 4),
785 .odr_avl[0] = { 13, 0x01 },
786 .odr_avl[1] = { 26, 0x02 },
787 .odr_avl[2] = { 52, 0x03 },
788 .odr_avl[3] = { 104, 0x04 },
789 .odr_avl[4] = { 208, 0x05 },
790 .odr_avl[5] = { 416, 0x06 },
794 [ST_LSM6DSX_ID_ACC] = {
797 .mask = GENMASK(3, 2),
799 .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 },
800 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
801 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
802 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
804 [ST_LSM6DSX_ID_GYRO] = {
807 .mask = GENMASK(3, 2),
809 .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 },
810 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
811 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
812 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
816 [ST_LSM6DSX_ID_ACC] = {
818 .mask = GENMASK(3, 0),
820 [ST_LSM6DSX_ID_GYRO] = {
822 .mask = GENMASK(7, 4),
826 .update_fifo = st_lsm6dsx_update_fifo,
827 .read_fifo = st_lsm6dsx_read_tagged_fifo,
830 .mask = GENMASK(8, 0),
834 .mask = GENMASK(9, 0),
845 .mask = GENMASK(7, 6),
863 .mask = GENMASK(1, 0),
871 .dw_slv0_addr = 0x21,
877 int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
879 const struct st_lsm6dsx_shub_settings *hub_settings;
883 hub_settings = &hw->settings->shub_settings;
884 data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
885 err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
886 hub_settings->page_mux.mask, data);
887 usleep_range(100, 150);
892 static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
897 for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
898 for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
899 if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
902 if (j < ST_LSM6DSX_MAX_ID)
906 if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
907 dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
911 err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
913 dev_err(hw->dev, "failed to read whoami register\n");
917 if (data != st_lsm6dsx_sensor_settings[i].wai) {
918 dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
922 *name = st_lsm6dsx_sensor_settings[i].id[j].name;
923 hw->settings = &st_lsm6dsx_sensor_settings[i];
928 static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
931 const struct st_lsm6dsx_fs_table_entry *fs_table;
935 fs_table = &sensor->hw->settings->fs_table[sensor->id];
936 for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
937 if (fs_table->fs_avl[i].gain == gain)
940 if (i == ST_LSM6DSX_FS_LIST_SIZE)
943 data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
945 err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
946 fs_table->reg.mask, data);
955 int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
957 const struct st_lsm6dsx_odr_table_entry *odr_table;
960 odr_table = &sensor->hw->settings->odr_table[sensor->id];
961 for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
963 * ext devices can run at different odr respect to
966 if (odr_table->odr_avl[i].hz >= odr)
969 if (i == ST_LSM6DSX_ODR_LIST_SIZE)
972 *val = odr_table->odr_avl[i].val;
977 static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr,
978 enum st_lsm6dsx_sensor_id id)
980 struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
983 if (hw->enable_mask & BIT(id))
984 return max_t(u16, ref->odr, odr);
988 return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
992 static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)
994 struct st_lsm6dsx_sensor *ref_sensor = sensor;
995 struct st_lsm6dsx_hw *hw = sensor->hw;
996 const struct st_lsm6dsx_reg *reg;
1001 switch (sensor->id) {
1002 case ST_LSM6DSX_ID_EXT0:
1003 case ST_LSM6DSX_ID_EXT1:
1004 case ST_LSM6DSX_ID_EXT2:
1005 case ST_LSM6DSX_ID_ACC: {
1010 * i2c embedded controller relies on the accelerometer sensor as
1011 * bus read/write trigger so we need to enable accel device
1012 * at odr = max(accel_odr, ext_odr) in order to properly
1013 * communicate with i2c slave devices
1015 ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
1016 for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
1017 if (!hw->iio_devs[i] || i == sensor->id)
1020 odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
1022 /* device already configured */
1032 err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
1037 reg = &hw->settings->odr_table[ref_sensor->id].reg;
1038 data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1039 return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
1042 int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1045 struct st_lsm6dsx_hw *hw = sensor->hw;
1046 u16 odr = enable ? sensor->odr : 0;
1049 err = st_lsm6dsx_set_odr(sensor, odr);
1054 hw->enable_mask |= BIT(sensor->id);
1056 hw->enable_mask &= ~BIT(sensor->id);
1061 static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1064 struct st_lsm6dsx_hw *hw = sensor->hw;
1068 err = st_lsm6dsx_sensor_set_enable(sensor, true);
1072 delay = 1000000 / sensor->odr;
1073 usleep_range(delay, 2 * delay);
1075 err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1079 st_lsm6dsx_sensor_set_enable(sensor, false);
1081 *val = (s16)le16_to_cpu(data);
1086 static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1087 struct iio_chan_spec const *ch,
1088 int *val, int *val2, long mask)
1090 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1094 case IIO_CHAN_INFO_RAW:
1095 ret = iio_device_claim_direct_mode(iio_dev);
1099 ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1100 iio_device_release_direct_mode(iio_dev);
1102 case IIO_CHAN_INFO_SAMP_FREQ:
1106 case IIO_CHAN_INFO_SCALE:
1108 *val2 = sensor->gain;
1109 ret = IIO_VAL_INT_PLUS_MICRO;
1119 static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1120 struct iio_chan_spec const *chan,
1121 int val, int val2, long mask)
1123 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1126 err = iio_device_claim_direct_mode(iio_dev);
1131 case IIO_CHAN_INFO_SCALE:
1132 err = st_lsm6dsx_set_full_scale(sensor, val2);
1134 case IIO_CHAN_INFO_SAMP_FREQ: {
1137 err = st_lsm6dsx_check_odr(sensor, val, &data);
1147 iio_device_release_direct_mode(iio_dev);
1152 int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1154 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1155 struct st_lsm6dsx_hw *hw = sensor->hw;
1158 if (val < 1 || val > hw->settings->max_fifo_size)
1161 mutex_lock(&hw->conf_lock);
1163 err = st_lsm6dsx_update_watermark(sensor, val);
1165 mutex_unlock(&hw->conf_lock);
1170 sensor->watermark = val;
1176 st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1177 struct device_attribute *attr,
1180 struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
1181 enum st_lsm6dsx_sensor_id id = sensor->id;
1182 struct st_lsm6dsx_hw *hw = sensor->hw;
1185 for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
1186 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
1187 hw->settings->odr_table[id].odr_avl[i].hz);
1188 buf[len - 1] = '\n';
1193 static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
1194 struct device_attribute *attr,
1197 struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
1198 const struct st_lsm6dsx_fs_table_entry *fs_table;
1199 enum st_lsm6dsx_sensor_id id = sensor->id;
1200 struct st_lsm6dsx_hw *hw = sensor->hw;
1203 fs_table = &hw->settings->fs_table[id];
1204 for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) {
1205 if (!fs_table->fs_avl[i].gain)
1208 len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
1209 fs_table->fs_avl[i].gain);
1211 buf[len - 1] = '\n';
1216 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
1217 static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
1218 st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1219 static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
1220 st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1222 static struct attribute *st_lsm6dsx_acc_attributes[] = {
1223 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1224 &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1228 static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
1229 .attrs = st_lsm6dsx_acc_attributes,
1232 static const struct iio_info st_lsm6dsx_acc_info = {
1233 .attrs = &st_lsm6dsx_acc_attribute_group,
1234 .read_raw = st_lsm6dsx_read_raw,
1235 .write_raw = st_lsm6dsx_write_raw,
1236 .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1239 static struct attribute *st_lsm6dsx_gyro_attributes[] = {
1240 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1241 &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
1245 static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
1246 .attrs = st_lsm6dsx_gyro_attributes,
1249 static const struct iio_info st_lsm6dsx_gyro_info = {
1250 .attrs = &st_lsm6dsx_gyro_attribute_group,
1251 .read_raw = st_lsm6dsx_read_raw,
1252 .write_raw = st_lsm6dsx_write_raw,
1253 .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1256 static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1258 struct device_node *np = hw->dev->of_node;
1263 return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
1266 static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
1268 int err = 0, drdy_pin;
1270 if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
1271 struct st_sensors_platform_data *pdata;
1272 struct device *dev = hw->dev;
1274 pdata = (struct st_sensors_platform_data *)dev->platform_data;
1275 drdy_pin = pdata ? pdata->drdy_int_pin : 1;
1280 *drdy_reg = hw->settings->int1_addr;
1283 *drdy_reg = hw->settings->int2_addr;
1286 dev_err(hw->dev, "unsupported data ready pin\n");
1294 static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1296 const struct st_lsm6dsx_shub_settings *hub_settings;
1297 struct device_node *np = hw->dev->of_node;
1298 struct st_sensors_platform_data *pdata;
1302 hub_settings = &hw->settings->shub_settings;
1304 pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
1305 if ((np && of_property_read_bool(np, "st,pullups")) ||
1306 (pdata && pdata->pullups)) {
1307 err = st_lsm6dsx_set_page(hw, true);
1311 data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
1312 err = regmap_update_bits(hw->regmap,
1313 hub_settings->pullup_en.addr,
1314 hub_settings->pullup_en.mask, data);
1316 st_lsm6dsx_set_page(hw, false);
1322 if (hub_settings->aux_sens.addr) {
1323 /* configure aux sensors */
1324 err = st_lsm6dsx_set_page(hw, true);
1328 data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
1329 err = regmap_update_bits(hw->regmap,
1330 hub_settings->aux_sens.addr,
1331 hub_settings->aux_sens.mask, data);
1333 st_lsm6dsx_set_page(hw, false);
1339 static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
1341 const struct st_lsm6dsx_hw_ts_settings *ts_settings;
1344 ts_settings = &hw->settings->ts_settings;
1345 /* enable hw timestamp generation if necessary */
1346 if (ts_settings->timer_en.addr) {
1347 val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
1348 err = regmap_update_bits(hw->regmap,
1349 ts_settings->timer_en.addr,
1350 ts_settings->timer_en.mask, val);
1355 /* enable high resolution for hw ts timer if necessary */
1356 if (ts_settings->hr_timer.addr) {
1357 val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
1358 err = regmap_update_bits(hw->regmap,
1359 ts_settings->hr_timer.addr,
1360 ts_settings->hr_timer.mask, val);
1365 /* enable ts queueing in FIFO if necessary */
1366 if (ts_settings->fifo_en.addr) {
1367 val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
1368 err = regmap_update_bits(hw->regmap,
1369 ts_settings->fifo_en.addr,
1370 ts_settings->fifo_en.mask, val);
1377 static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
1382 /* device sw reset */
1383 err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
1384 ST_LSM6DSX_REG_RESET_MASK,
1385 FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1));
1391 /* reload trimming parameter */
1392 err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
1393 ST_LSM6DSX_REG_BOOT_MASK,
1394 FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1));
1400 /* enable Block Data Update */
1401 err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR,
1402 ST_LSM6DSX_REG_BDU_MASK,
1403 FIELD_PREP(ST_LSM6DSX_REG_BDU_MASK, 1));
1407 /* enable FIFO watermak interrupt */
1408 err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg);
1412 err = regmap_update_bits(hw->regmap, drdy_int_reg,
1413 ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
1414 FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
1419 err = st_lsm6dsx_init_shub(hw);
1423 return st_lsm6dsx_init_hw_timer(hw);
1426 static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
1427 enum st_lsm6dsx_sensor_id id,
1430 struct st_lsm6dsx_sensor *sensor;
1431 struct iio_dev *iio_dev;
1433 iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
1437 iio_dev->modes = INDIO_DIRECT_MODE;
1438 iio_dev->dev.parent = hw->dev;
1439 iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
1440 iio_dev->channels = hw->settings->channels[id].chan;
1441 iio_dev->num_channels = hw->settings->channels[id].len;
1443 sensor = iio_priv(iio_dev);
1446 sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
1447 sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
1448 sensor->watermark = 1;
1451 case ST_LSM6DSX_ID_ACC:
1452 iio_dev->info = &st_lsm6dsx_acc_info;
1453 scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
1456 case ST_LSM6DSX_ID_GYRO:
1457 iio_dev->info = &st_lsm6dsx_gyro_info;
1458 scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
1464 iio_dev->name = sensor->name;
1469 int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
1470 struct regmap *regmap)
1472 const struct st_lsm6dsx_shub_settings *hub_settings;
1473 struct st_lsm6dsx_hw *hw;
1474 const char *name = NULL;
1477 hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
1481 dev_set_drvdata(dev, (void *)hw);
1483 mutex_init(&hw->fifo_lock);
1484 mutex_init(&hw->conf_lock);
1485 mutex_init(&hw->page_lock);
1487 hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
1493 hw->regmap = regmap;
1495 err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
1499 for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
1500 hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
1501 if (!hw->iio_devs[i])
1505 err = st_lsm6dsx_init_device(hw);
1509 hub_settings = &hw->settings->shub_settings;
1510 if (hub_settings->master_en.addr) {
1511 err = st_lsm6dsx_shub_probe(hw, name);
1517 err = st_lsm6dsx_fifo_setup(hw);
1522 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
1523 if (!hw->iio_devs[i])
1526 err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
1533 EXPORT_SYMBOL(st_lsm6dsx_probe);
1535 static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
1537 struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
1538 struct st_lsm6dsx_sensor *sensor;
1541 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
1542 if (!hw->iio_devs[i])
1545 sensor = iio_priv(hw->iio_devs[i]);
1546 if (!(hw->enable_mask & BIT(sensor->id)))
1549 if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
1550 sensor->id == ST_LSM6DSX_ID_EXT1 ||
1551 sensor->id == ST_LSM6DSX_ID_EXT2)
1552 err = st_lsm6dsx_shub_set_enable(sensor, false);
1554 err = st_lsm6dsx_sensor_set_enable(sensor, false);
1558 hw->suspend_mask |= BIT(sensor->id);
1561 if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
1562 err = st_lsm6dsx_flush_fifo(hw);
1567 static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
1569 struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
1570 struct st_lsm6dsx_sensor *sensor;
1573 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
1574 if (!hw->iio_devs[i])
1577 sensor = iio_priv(hw->iio_devs[i]);
1578 if (!(hw->suspend_mask & BIT(sensor->id)))
1581 if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
1582 sensor->id == ST_LSM6DSX_ID_EXT1 ||
1583 sensor->id == ST_LSM6DSX_ID_EXT2)
1584 err = st_lsm6dsx_shub_set_enable(sensor, true);
1586 err = st_lsm6dsx_sensor_set_enable(sensor, true);
1590 hw->suspend_mask &= ~BIT(sensor->id);
1593 if (hw->enable_mask)
1594 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
1599 const struct dev_pm_ops st_lsm6dsx_pm_ops = {
1600 SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
1602 EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
1604 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
1605 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
1606 MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
1607 MODULE_LICENSE("GPL v2");