1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2290a6ce1SLorenzo Bianconi /*
3290a6ce1SLorenzo Bianconi  * STMicroelectronics st_lsm6dsx sensor driver
4290a6ce1SLorenzo Bianconi  *
5290a6ce1SLorenzo Bianconi  * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer
6290a6ce1SLorenzo Bianconi  * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial
7290a6ce1SLorenzo Bianconi  * interface standard output.
8290a6ce1SLorenzo Bianconi  * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale
9290a6ce1SLorenzo Bianconi  * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of
10290a6ce1SLorenzo Bianconi  * +-125/+-245/+-500/+-1000/+-2000 dps
11290a6ce1SLorenzo Bianconi  * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
12290a6ce1SLorenzo Bianconi  * allowing dynamic batching of sensor data.
1352f4b1f1SMartin Kepplinger  * LSM9DSx series is similar but includes an additional magnetometer, handled
1452f4b1f1SMartin Kepplinger  * by a different driver.
15290a6ce1SLorenzo Bianconi  *
16290a6ce1SLorenzo Bianconi  * Supported sensors:
17290a6ce1SLorenzo Bianconi  * - LSM6DS3:
18290a6ce1SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
19290a6ce1SLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
20290a6ce1SLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
21290a6ce1SLorenzo Bianconi  *   - FIFO size: 8KB
22290a6ce1SLorenzo Bianconi  *
23dbcd2088SLorenzo Bianconi  * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
24290a6ce1SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
25290a6ce1SLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
26290a6ce1SLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
27290a6ce1SLorenzo Bianconi  *   - FIFO size: 4KB
28290a6ce1SLorenzo Bianconi  *
29db947a79SLorenzo Bianconi  * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX:
30801a6e0aSLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
31801a6e0aSLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
32801a6e0aSLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
33801a6e0aSLorenzo Bianconi  *   - FIFO size: 3KB
34801a6e0aSLorenzo Bianconi  *
3552f4b1f1SMartin Kepplinger  * - LSM9DS1:
3652f4b1f1SMartin Kepplinger  *   - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
3752f4b1f1SMartin Kepplinger  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
3852f4b1f1SMartin Kepplinger  *   - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
3952f4b1f1SMartin Kepplinger  *   - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
4052f4b1f1SMartin Kepplinger  *   - FIFO size: 32
4152f4b1f1SMartin Kepplinger  *
42290a6ce1SLorenzo Bianconi  * Copyright 2016 STMicroelectronics Inc.
43290a6ce1SLorenzo Bianconi  *
44290a6ce1SLorenzo Bianconi  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
45290a6ce1SLorenzo Bianconi  * Denis Ciocca <denis.ciocca@st.com>
46290a6ce1SLorenzo Bianconi  */
47290a6ce1SLorenzo Bianconi 
48290a6ce1SLorenzo Bianconi #include <linux/kernel.h>
49290a6ce1SLorenzo Bianconi #include <linux/module.h>
50290a6ce1SLorenzo Bianconi #include <linux/delay.h>
511aabad1fSSean Nyekjaer #include <linux/iio/events.h>
52290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h>
53290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h>
546ee6a368SSean Nyekjaer #include <linux/interrupt.h>
556ee6a368SSean Nyekjaer #include <linux/irq.h>
56d3f77058SLorenzo Bianconi #include <linux/pm.h>
5751a8b707SLorenzo Bianconi #include <linux/regmap.h>
5851a8b707SLorenzo Bianconi #include <linux/bitfield.h>
59290a6ce1SLorenzo Bianconi 
60dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h>
61dba32904SLorenzo Bianconi 
62290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h"
63290a6ce1SLorenzo Bianconi 
64290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK	BIT(3)
65290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
66290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_RESET_MASK		BIT(0)
6719435425SLorenzo Bianconi #define ST_LSM6DSX_REG_BOOT_MASK		BIT(7)
68290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_BDU_ADDR			0x12
69290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_BDU_MASK			BIT(6)
70290a6ce1SLorenzo Bianconi 
716ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_HLACTIVE_ADDR		0x12
726ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_HLACTIVE_MASK		BIT(5)
736ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_PP_OD_ADDR		0x12
746ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_PP_OD_MASK		BIT(4)
756ee6a368SSean Nyekjaer 
76f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
77b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
78b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
79b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
80f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
81f48bc49bSLorenzo Bianconi };
82f48bc49bSLorenzo Bianconi 
83f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
84f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
85f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
86f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
87f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
88f48bc49bSLorenzo Bianconi };
89f48bc49bSLorenzo Bianconi 
9052f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
9152f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
9252f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
9352f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
9452f4b1f1SMartin Kepplinger 	IIO_CHAN_SOFT_TIMESTAMP(3),
9552f4b1f1SMartin Kepplinger };
9652f4b1f1SMartin Kepplinger 
97290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
98290a6ce1SLorenzo Bianconi 	{
9952f4b1f1SMartin Kepplinger 		.wai = 0x68,
10052f4b1f1SMartin Kepplinger 		.int1_addr = 0x0c,
10152f4b1f1SMartin Kepplinger 		.int2_addr = 0x0d,
10252f4b1f1SMartin Kepplinger 		.reset_addr = 0x22,
10352f4b1f1SMartin Kepplinger 		.max_fifo_size = 32,
10452f4b1f1SMartin Kepplinger 		.id = {
10552f4b1f1SMartin Kepplinger 			{
10652f4b1f1SMartin Kepplinger 				.hw_id = ST_LSM9DS1_ID,
10752f4b1f1SMartin Kepplinger 				.name = ST_LSM9DS1_DEV_NAME,
10852f4b1f1SMartin Kepplinger 			},
10952f4b1f1SMartin Kepplinger 		},
11052f4b1f1SMartin Kepplinger 		.channels = {
11152f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
11252f4b1f1SMartin Kepplinger 				.chan = st_lsm6dsx_acc_channels,
11352f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
11452f4b1f1SMartin Kepplinger 			},
11552f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
11652f4b1f1SMartin Kepplinger 				.chan = st_lsm6ds0_gyro_channels,
11752f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
11852f4b1f1SMartin Kepplinger 			},
11952f4b1f1SMartin Kepplinger 		},
12052f4b1f1SMartin Kepplinger 		.odr_table = {
12152f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
12252f4b1f1SMartin Kepplinger 				.reg = {
12352f4b1f1SMartin Kepplinger 					.addr = 0x20,
12452f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
12552f4b1f1SMartin Kepplinger 				},
12652f4b1f1SMartin Kepplinger 				.odr_avl[0] = {  10, 0x01 },
12752f4b1f1SMartin Kepplinger 				.odr_avl[1] = {  50, 0x02 },
12852f4b1f1SMartin Kepplinger 				.odr_avl[2] = { 119, 0x03 },
12952f4b1f1SMartin Kepplinger 				.odr_avl[3] = { 238, 0x04 },
13052f4b1f1SMartin Kepplinger 				.odr_avl[4] = { 476, 0x05 },
13152f4b1f1SMartin Kepplinger 				.odr_avl[5] = { 952, 0x06 },
13252f4b1f1SMartin Kepplinger 			},
13352f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
13452f4b1f1SMartin Kepplinger 				.reg = {
13552f4b1f1SMartin Kepplinger 					.addr = 0x10,
13652f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
13752f4b1f1SMartin Kepplinger 				},
13852f4b1f1SMartin Kepplinger 				.odr_avl[0] = {  15, 0x01 },
13952f4b1f1SMartin Kepplinger 				.odr_avl[1] = {  60, 0x02 },
14052f4b1f1SMartin Kepplinger 				.odr_avl[2] = { 119, 0x03 },
14152f4b1f1SMartin Kepplinger 				.odr_avl[3] = { 238, 0x04 },
14252f4b1f1SMartin Kepplinger 				.odr_avl[4] = { 476, 0x05 },
14352f4b1f1SMartin Kepplinger 				.odr_avl[5] = { 952, 0x06 },
14452f4b1f1SMartin Kepplinger 			},
14552f4b1f1SMartin Kepplinger 		},
14652f4b1f1SMartin Kepplinger 		.fs_table = {
14752f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
14852f4b1f1SMartin Kepplinger 				.reg = {
14952f4b1f1SMartin Kepplinger 					.addr = 0x20,
15052f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
15152f4b1f1SMartin Kepplinger 				},
1526fa02948SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
1536fa02948SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
1546fa02948SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
1556fa02948SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
15685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
15752f4b1f1SMartin Kepplinger 			},
15852f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
15952f4b1f1SMartin Kepplinger 				.reg = {
16052f4b1f1SMartin Kepplinger 					.addr = 0x10,
16152f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
16252f4b1f1SMartin Kepplinger 				},
16352f4b1f1SMartin Kepplinger 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(245), 0x0 },
16452f4b1f1SMartin Kepplinger 				.fs_avl[1] = {  IIO_DEGREE_TO_RAD(500), 0x1 },
1650f7e1728SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 },
16685ae3aeeSLorenzo Bianconi 				.fs_len = 3,
16752f4b1f1SMartin Kepplinger 			},
16852f4b1f1SMartin Kepplinger 		},
16952f4b1f1SMartin Kepplinger 	},
17052f4b1f1SMartin Kepplinger 	{
171d068e4a0SLorenzo Bianconi 		.wai = 0x69,
1725022c5a4SMartin Kepplinger 		.int1_addr = 0x0d,
1735022c5a4SMartin Kepplinger 		.int2_addr = 0x0e,
174b5969abfSSean Nyekjaer 		.int1_func_addr = 0x5e,
175b5969abfSSean Nyekjaer 		.int2_func_addr = 0x5f,
176b5969abfSSean Nyekjaer 		.int_func_mask = BIT(5),
1775022c5a4SMartin Kepplinger 		.reset_addr = 0x12,
1788f2a88a2SLorenzo Bianconi 		.max_fifo_size = 1365,
179d068e4a0SLorenzo Bianconi 		.id = {
18081956a93SLorenzo Bianconi 			{
18181956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3_ID,
18281956a93SLorenzo Bianconi 				.name = ST_LSM6DS3_DEV_NAME,
18381956a93SLorenzo Bianconi 			},
184d068e4a0SLorenzo Bianconi 		},
185f48bc49bSLorenzo Bianconi 		.channels = {
186f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
187f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
188f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
189f48bc49bSLorenzo Bianconi 			},
190f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
191f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
192f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
193f48bc49bSLorenzo Bianconi 			},
194f48bc49bSLorenzo Bianconi 		},
19540dd7343SLorenzo Bianconi 		.odr_table = {
19640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
19740dd7343SLorenzo Bianconi 				.reg = {
19840dd7343SLorenzo Bianconi 					.addr = 0x10,
19940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
20040dd7343SLorenzo Bianconi 				},
20140dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
20240dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
20340dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
20440dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
20540dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
20640dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
20740dd7343SLorenzo Bianconi 			},
20840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
20940dd7343SLorenzo Bianconi 				.reg = {
21040dd7343SLorenzo Bianconi 					.addr = 0x11,
21140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
21240dd7343SLorenzo Bianconi 				},
21340dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
21440dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
21540dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
21640dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
21740dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
21840dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
21940dd7343SLorenzo Bianconi 			},
22040dd7343SLorenzo Bianconi 		},
221640aca3fSLorenzo Bianconi 		.fs_table = {
222640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
223640aca3fSLorenzo Bianconi 				.reg = {
224640aca3fSLorenzo Bianconi 					.addr = 0x10,
225640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
226640aca3fSLorenzo Bianconi 				},
227640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
228640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
229640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
230640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
23185ae3aeeSLorenzo Bianconi 				.fs_len = 4,
232640aca3fSLorenzo Bianconi 			},
233640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
234640aca3fSLorenzo Bianconi 				.reg = {
235640aca3fSLorenzo Bianconi 					.addr = 0x11,
236640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
237640aca3fSLorenzo Bianconi 				},
238640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
239640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
240640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
241640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
24285ae3aeeSLorenzo Bianconi 				.fs_len = 4,
243640aca3fSLorenzo Bianconi 			},
244640aca3fSLorenzo Bianconi 		},
2457ca3ac9eSLorenzo Bianconi 		.decimator = {
2467ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
2477ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
2487ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
2497ca3ac9eSLorenzo Bianconi 			},
2507ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
2517ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
2527ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
2537ca3ac9eSLorenzo Bianconi 			},
2547ca3ac9eSLorenzo Bianconi 		},
2559db02d32SLorenzo Bianconi 		.lir = {
2569db02d32SLorenzo Bianconi 			.addr = 0x58,
2579db02d32SLorenzo Bianconi 			.mask = BIT(0),
2589db02d32SLorenzo Bianconi 		},
25992617c15SLorenzo Bianconi 		.fifo_ops = {
2603b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
26150ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
26292617c15SLorenzo Bianconi 			.fifo_th = {
26392617c15SLorenzo Bianconi 				.addr = 0x06,
26492617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
26592617c15SLorenzo Bianconi 			},
26692617c15SLorenzo Bianconi 			.fifo_diff = {
26792617c15SLorenzo Bianconi 				.addr = 0x3a,
26892617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
26992617c15SLorenzo Bianconi 			},
27092617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
27192617c15SLorenzo Bianconi 		},
27221345107SLorenzo Bianconi 		.ts_settings = {
27321345107SLorenzo Bianconi 			.timer_en = {
27421345107SLorenzo Bianconi 				.addr = 0x58,
27521345107SLorenzo Bianconi 				.mask = BIT(7),
27621345107SLorenzo Bianconi 			},
27721345107SLorenzo Bianconi 			.hr_timer = {
27821345107SLorenzo Bianconi 				.addr = 0x5c,
27921345107SLorenzo Bianconi 				.mask = BIT(4),
28021345107SLorenzo Bianconi 			},
28121345107SLorenzo Bianconi 			.fifo_en = {
28221345107SLorenzo Bianconi 				.addr = 0x07,
28321345107SLorenzo Bianconi 				.mask = BIT(7),
28421345107SLorenzo Bianconi 			},
28521345107SLorenzo Bianconi 			.decimator = {
28621345107SLorenzo Bianconi 				.addr = 0x09,
28721345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
28821345107SLorenzo Bianconi 			},
28921345107SLorenzo Bianconi 		},
290b5969abfSSean Nyekjaer 		.event_settings = {
291b5969abfSSean Nyekjaer 			.wakeup_reg = {
292b5969abfSSean Nyekjaer 				.addr = 0x5B,
293b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
294b5969abfSSean Nyekjaer 			},
2951aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
2961aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
2971aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
2981aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
2991aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
300b5969abfSSean Nyekjaer 		},
301290a6ce1SLorenzo Bianconi 	},
302290a6ce1SLorenzo Bianconi 	{
303df47710aSLorenzo Bianconi 		.wai = 0x69,
3045022c5a4SMartin Kepplinger 		.int1_addr = 0x0d,
3055022c5a4SMartin Kepplinger 		.int2_addr = 0x0e,
306b5969abfSSean Nyekjaer 		.int1_func_addr = 0x5e,
307b5969abfSSean Nyekjaer 		.int2_func_addr = 0x5f,
308b5969abfSSean Nyekjaer 		.int_func_mask = BIT(5),
3095022c5a4SMartin Kepplinger 		.reset_addr = 0x12,
3108f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
311df47710aSLorenzo Bianconi 		.id = {
31281956a93SLorenzo Bianconi 			{
31381956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3H_ID,
31481956a93SLorenzo Bianconi 				.name = ST_LSM6DS3H_DEV_NAME,
31581956a93SLorenzo Bianconi 			},
316df47710aSLorenzo Bianconi 		},
317f48bc49bSLorenzo Bianconi 		.channels = {
318f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
319f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
320f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
321f48bc49bSLorenzo Bianconi 			},
322f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
323f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
324f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
325f48bc49bSLorenzo Bianconi 			},
326f48bc49bSLorenzo Bianconi 		},
32740dd7343SLorenzo Bianconi 		.odr_table = {
32840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
32940dd7343SLorenzo Bianconi 				.reg = {
33040dd7343SLorenzo Bianconi 					.addr = 0x10,
33140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
33240dd7343SLorenzo Bianconi 				},
33340dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
33440dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
33540dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
33640dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
33740dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
33840dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
33940dd7343SLorenzo Bianconi 			},
34040dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
34140dd7343SLorenzo Bianconi 				.reg = {
34240dd7343SLorenzo Bianconi 					.addr = 0x11,
34340dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
34440dd7343SLorenzo Bianconi 				},
34540dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
34640dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
34740dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
34840dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
34940dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
35040dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
35140dd7343SLorenzo Bianconi 			},
35240dd7343SLorenzo Bianconi 		},
353640aca3fSLorenzo Bianconi 		.fs_table = {
354640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
355640aca3fSLorenzo Bianconi 				.reg = {
356640aca3fSLorenzo Bianconi 					.addr = 0x10,
357640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
358640aca3fSLorenzo Bianconi 				},
359640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
360640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
361640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
362640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
36385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
364640aca3fSLorenzo Bianconi 			},
365640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
366640aca3fSLorenzo Bianconi 				.reg = {
367640aca3fSLorenzo Bianconi 					.addr = 0x11,
368640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
369640aca3fSLorenzo Bianconi 				},
370640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
371640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
372640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
373640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
37485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
375640aca3fSLorenzo Bianconi 			},
376640aca3fSLorenzo Bianconi 		},
3777ca3ac9eSLorenzo Bianconi 		.decimator = {
3787ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
3797ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3807ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
3817ca3ac9eSLorenzo Bianconi 			},
3827ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
3837ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3847ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
3857ca3ac9eSLorenzo Bianconi 			},
3867ca3ac9eSLorenzo Bianconi 		},
3879db02d32SLorenzo Bianconi 		.lir = {
3889db02d32SLorenzo Bianconi 			.addr = 0x58,
3899db02d32SLorenzo Bianconi 			.mask = BIT(0),
3909db02d32SLorenzo Bianconi 		},
39192617c15SLorenzo Bianconi 		.fifo_ops = {
3923b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
39350ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
39492617c15SLorenzo Bianconi 			.fifo_th = {
39592617c15SLorenzo Bianconi 				.addr = 0x06,
39692617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
39792617c15SLorenzo Bianconi 			},
39892617c15SLorenzo Bianconi 			.fifo_diff = {
39992617c15SLorenzo Bianconi 				.addr = 0x3a,
40092617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
40192617c15SLorenzo Bianconi 			},
40292617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
40392617c15SLorenzo Bianconi 		},
40421345107SLorenzo Bianconi 		.ts_settings = {
40521345107SLorenzo Bianconi 			.timer_en = {
40621345107SLorenzo Bianconi 				.addr = 0x58,
40721345107SLorenzo Bianconi 				.mask = BIT(7),
40821345107SLorenzo Bianconi 			},
40921345107SLorenzo Bianconi 			.hr_timer = {
41021345107SLorenzo Bianconi 				.addr = 0x5c,
41121345107SLorenzo Bianconi 				.mask = BIT(4),
41221345107SLorenzo Bianconi 			},
41321345107SLorenzo Bianconi 			.fifo_en = {
41421345107SLorenzo Bianconi 				.addr = 0x07,
41521345107SLorenzo Bianconi 				.mask = BIT(7),
41621345107SLorenzo Bianconi 			},
41721345107SLorenzo Bianconi 			.decimator = {
41821345107SLorenzo Bianconi 				.addr = 0x09,
41921345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
42021345107SLorenzo Bianconi 			},
42121345107SLorenzo Bianconi 		},
422b5969abfSSean Nyekjaer 		.event_settings = {
423b5969abfSSean Nyekjaer 			.wakeup_reg = {
424b5969abfSSean Nyekjaer 				.addr = 0x5B,
425b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
426b5969abfSSean Nyekjaer 			},
4271aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
4281aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
4291aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
4301aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
4311aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
432b5969abfSSean Nyekjaer 		},
433df47710aSLorenzo Bianconi 	},
434df47710aSLorenzo Bianconi 	{
435d068e4a0SLorenzo Bianconi 		.wai = 0x6a,
4365022c5a4SMartin Kepplinger 		.int1_addr = 0x0d,
4375022c5a4SMartin Kepplinger 		.int2_addr = 0x0e,
438b5969abfSSean Nyekjaer 		.int1_func_addr = 0x5e,
439b5969abfSSean Nyekjaer 		.int2_func_addr = 0x5f,
440b5969abfSSean Nyekjaer 		.int_func_mask = BIT(5),
4415022c5a4SMartin Kepplinger 		.reset_addr = 0x12,
4428f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
443d068e4a0SLorenzo Bianconi 		.id = {
44481956a93SLorenzo Bianconi 			{
44581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSL_ID,
44681956a93SLorenzo Bianconi 				.name = ST_LSM6DSL_DEV_NAME,
44781956a93SLorenzo Bianconi 			}, {
44881956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSM_ID,
44981956a93SLorenzo Bianconi 				.name = ST_LSM6DSM_DEV_NAME,
45081956a93SLorenzo Bianconi 			}, {
45181956a93SLorenzo Bianconi 				.hw_id = ST_ISM330DLC_ID,
45281956a93SLorenzo Bianconi 				.name = ST_ISM330DLC_DEV_NAME,
453dbcd2088SLorenzo Bianconi 			}, {
454dbcd2088SLorenzo Bianconi 				.hw_id = ST_LSM6DS3TRC_ID,
455dbcd2088SLorenzo Bianconi 				.name = ST_LSM6DS3TRC_DEV_NAME,
45681956a93SLorenzo Bianconi 			},
457d068e4a0SLorenzo Bianconi 		},
458f48bc49bSLorenzo Bianconi 		.channels = {
459f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
460f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
461f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
462f48bc49bSLorenzo Bianconi 			},
463f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
464f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
465f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
466f48bc49bSLorenzo Bianconi 			},
467f48bc49bSLorenzo Bianconi 		},
46840dd7343SLorenzo Bianconi 		.odr_table = {
46940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
47040dd7343SLorenzo Bianconi 				.reg = {
47140dd7343SLorenzo Bianconi 					.addr = 0x10,
47240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
47340dd7343SLorenzo Bianconi 				},
47440dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
47540dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
47640dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
47740dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
47840dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
47940dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
48040dd7343SLorenzo Bianconi 			},
48140dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
48240dd7343SLorenzo Bianconi 				.reg = {
48340dd7343SLorenzo Bianconi 					.addr = 0x11,
48440dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
48540dd7343SLorenzo Bianconi 				},
48640dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
48740dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
48840dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
48940dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
49040dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
49140dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
49240dd7343SLorenzo Bianconi 			},
49340dd7343SLorenzo Bianconi 		},
494640aca3fSLorenzo Bianconi 		.fs_table = {
495640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
496640aca3fSLorenzo Bianconi 				.reg = {
497640aca3fSLorenzo Bianconi 					.addr = 0x10,
498640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
499640aca3fSLorenzo Bianconi 				},
500640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
501640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
502640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
503640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
50485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
505640aca3fSLorenzo Bianconi 			},
506640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
507640aca3fSLorenzo Bianconi 				.reg = {
508640aca3fSLorenzo Bianconi 					.addr = 0x11,
509640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
510640aca3fSLorenzo Bianconi 				},
511640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
512640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
513640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
514640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
51585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
516640aca3fSLorenzo Bianconi 			},
517640aca3fSLorenzo Bianconi 		},
5187ca3ac9eSLorenzo Bianconi 		.decimator = {
5197ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
5207ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
5217ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
5227ca3ac9eSLorenzo Bianconi 			},
5237ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
5247ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
5257ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
5267ca3ac9eSLorenzo Bianconi 			},
5277ca3ac9eSLorenzo Bianconi 		},
5289db02d32SLorenzo Bianconi 		.lir = {
5299db02d32SLorenzo Bianconi 			.addr = 0x58,
5309db02d32SLorenzo Bianconi 			.mask = BIT(0),
5319db02d32SLorenzo Bianconi 		},
53292617c15SLorenzo Bianconi 		.fifo_ops = {
5333b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
53450ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
53592617c15SLorenzo Bianconi 			.fifo_th = {
53692617c15SLorenzo Bianconi 				.addr = 0x06,
537be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
53892617c15SLorenzo Bianconi 			},
53992617c15SLorenzo Bianconi 			.fifo_diff = {
54092617c15SLorenzo Bianconi 				.addr = 0x3a,
541be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
54292617c15SLorenzo Bianconi 			},
54392617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
54492617c15SLorenzo Bianconi 		},
54521345107SLorenzo Bianconi 		.ts_settings = {
54621345107SLorenzo Bianconi 			.timer_en = {
54721345107SLorenzo Bianconi 				.addr = 0x19,
54821345107SLorenzo Bianconi 				.mask = BIT(5),
54921345107SLorenzo Bianconi 			},
55021345107SLorenzo Bianconi 			.hr_timer = {
55121345107SLorenzo Bianconi 				.addr = 0x5c,
55221345107SLorenzo Bianconi 				.mask = BIT(4),
55321345107SLorenzo Bianconi 			},
55421345107SLorenzo Bianconi 			.fifo_en = {
55521345107SLorenzo Bianconi 				.addr = 0x07,
55621345107SLorenzo Bianconi 				.mask = BIT(7),
55721345107SLorenzo Bianconi 			},
55821345107SLorenzo Bianconi 			.decimator = {
55921345107SLorenzo Bianconi 				.addr = 0x09,
56021345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
56121345107SLorenzo Bianconi 			},
56221345107SLorenzo Bianconi 		},
563b5969abfSSean Nyekjaer 		.event_settings = {
564b5969abfSSean Nyekjaer 			.enable_reg = {
565b5969abfSSean Nyekjaer 				.addr = 0x58,
566b5969abfSSean Nyekjaer 				.mask = BIT(7),
567b5969abfSSean Nyekjaer 			},
568b5969abfSSean Nyekjaer 			.wakeup_reg = {
569b5969abfSSean Nyekjaer 				.addr = 0x5B,
570b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
571b5969abfSSean Nyekjaer 			},
5721aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
5731aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
5741aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
5751aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
5761aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
577b5969abfSSean Nyekjaer 		},
578290a6ce1SLorenzo Bianconi 	},
579801a6e0aSLorenzo Bianconi 	{
580801a6e0aSLorenzo Bianconi 		.wai = 0x6c,
5815022c5a4SMartin Kepplinger 		.int1_addr = 0x0d,
5825022c5a4SMartin Kepplinger 		.int2_addr = 0x0e,
5835022c5a4SMartin Kepplinger 		.reset_addr = 0x12,
584801a6e0aSLorenzo Bianconi 		.max_fifo_size = 512,
585801a6e0aSLorenzo Bianconi 		.id = {
58681956a93SLorenzo Bianconi 			{
58781956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSO_ID,
58881956a93SLorenzo Bianconi 				.name = ST_LSM6DSO_DEV_NAME,
58981956a93SLorenzo Bianconi 			}, {
59081956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSOX_ID,
59181956a93SLorenzo Bianconi 				.name = ST_LSM6DSOX_DEV_NAME,
59281956a93SLorenzo Bianconi 			},
593801a6e0aSLorenzo Bianconi 		},
594f48bc49bSLorenzo Bianconi 		.channels = {
595f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
596f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
597f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
598f48bc49bSLorenzo Bianconi 			},
599f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
600f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
601f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
602f48bc49bSLorenzo Bianconi 			},
603f48bc49bSLorenzo Bianconi 		},
60440dd7343SLorenzo Bianconi 		.odr_table = {
60540dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
60640dd7343SLorenzo Bianconi 				.reg = {
60740dd7343SLorenzo Bianconi 					.addr = 0x10,
60840dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
60940dd7343SLorenzo Bianconi 				},
61040dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
61140dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
61240dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
61340dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
61440dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
61540dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
61640dd7343SLorenzo Bianconi 			},
61740dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
61840dd7343SLorenzo Bianconi 				.reg = {
61940dd7343SLorenzo Bianconi 					.addr = 0x11,
62040dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
62140dd7343SLorenzo Bianconi 				},
62240dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
62340dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
62440dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
62540dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
62640dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
62740dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
62840dd7343SLorenzo Bianconi 			},
62940dd7343SLorenzo Bianconi 		},
630640aca3fSLorenzo Bianconi 		.fs_table = {
631640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
632640aca3fSLorenzo Bianconi 				.reg = {
633640aca3fSLorenzo Bianconi 					.addr = 0x10,
634640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
635640aca3fSLorenzo Bianconi 				},
636640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
637640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
638640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
639640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
64085ae3aeeSLorenzo Bianconi 				.fs_len = 4,
641640aca3fSLorenzo Bianconi 			},
642640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
643640aca3fSLorenzo Bianconi 				.reg = {
644640aca3fSLorenzo Bianconi 					.addr = 0x11,
645640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
646640aca3fSLorenzo Bianconi 				},
647640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
648640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
649640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
650640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
65185ae3aeeSLorenzo Bianconi 				.fs_len = 4,
652640aca3fSLorenzo Bianconi 			},
653640aca3fSLorenzo Bianconi 		},
654801a6e0aSLorenzo Bianconi 		.batch = {
655801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
656801a6e0aSLorenzo Bianconi 				.addr = 0x09,
657801a6e0aSLorenzo Bianconi 				.mask = GENMASK(3, 0),
658801a6e0aSLorenzo Bianconi 			},
659801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
660801a6e0aSLorenzo Bianconi 				.addr = 0x09,
661801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 4),
662801a6e0aSLorenzo Bianconi 			},
663801a6e0aSLorenzo Bianconi 		},
6649db02d32SLorenzo Bianconi 		.lir = {
6659db02d32SLorenzo Bianconi 			.addr = 0x56,
6669db02d32SLorenzo Bianconi 			.mask = BIT(0),
6679db02d32SLorenzo Bianconi 		},
66822ea5651SLorenzo Bianconi 		.clear_on_read = {
66922ea5651SLorenzo Bianconi 			.addr = 0x56,
67022ea5651SLorenzo Bianconi 			.mask = BIT(6),
67122ea5651SLorenzo Bianconi 		},
672801a6e0aSLorenzo Bianconi 		.fifo_ops = {
6733b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
674801a6e0aSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
675801a6e0aSLorenzo Bianconi 			.fifo_th = {
676801a6e0aSLorenzo Bianconi 				.addr = 0x07,
677801a6e0aSLorenzo Bianconi 				.mask = GENMASK(8, 0),
678801a6e0aSLorenzo Bianconi 			},
679801a6e0aSLorenzo Bianconi 			.fifo_diff = {
680801a6e0aSLorenzo Bianconi 				.addr = 0x3a,
68170575abeSmario tesi 				.mask = GENMASK(9, 0),
682801a6e0aSLorenzo Bianconi 			},
683801a6e0aSLorenzo Bianconi 			.th_wl = 1,
684801a6e0aSLorenzo Bianconi 		},
685801a6e0aSLorenzo Bianconi 		.ts_settings = {
686801a6e0aSLorenzo Bianconi 			.timer_en = {
687801a6e0aSLorenzo Bianconi 				.addr = 0x19,
688801a6e0aSLorenzo Bianconi 				.mask = BIT(5),
689801a6e0aSLorenzo Bianconi 			},
690801a6e0aSLorenzo Bianconi 			.decimator = {
691801a6e0aSLorenzo Bianconi 				.addr = 0x0a,
692801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 6),
693801a6e0aSLorenzo Bianconi 			},
694801a6e0aSLorenzo Bianconi 		},
695c91c1c84SLorenzo Bianconi 		.shub_settings = {
696c91c1c84SLorenzo Bianconi 			.page_mux = {
697c91c1c84SLorenzo Bianconi 				.addr = 0x01,
698c91c1c84SLorenzo Bianconi 				.mask = BIT(6),
699c91c1c84SLorenzo Bianconi 			},
700c91c1c84SLorenzo Bianconi 			.master_en = {
701c91c1c84SLorenzo Bianconi 				.addr = 0x14,
702c91c1c84SLorenzo Bianconi 				.mask = BIT(2),
703c91c1c84SLorenzo Bianconi 			},
704c91c1c84SLorenzo Bianconi 			.pullup_en = {
705c91c1c84SLorenzo Bianconi 				.addr = 0x14,
706c91c1c84SLorenzo Bianconi 				.mask = BIT(3),
707c91c1c84SLorenzo Bianconi 			},
708c91c1c84SLorenzo Bianconi 			.aux_sens = {
709c91c1c84SLorenzo Bianconi 				.addr = 0x14,
710c91c1c84SLorenzo Bianconi 				.mask = GENMASK(1, 0),
711c91c1c84SLorenzo Bianconi 			},
7126d0205fdSLorenzo Bianconi 			.wr_once = {
7136d0205fdSLorenzo Bianconi 				.addr = 0x14,
7146d0205fdSLorenzo Bianconi 				.mask = BIT(6),
7156d0205fdSLorenzo Bianconi 			},
716c91c1c84SLorenzo Bianconi 			.shub_out = 0x02,
717c91c1c84SLorenzo Bianconi 			.slv0_addr = 0x15,
718c91c1c84SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
7196d0205fdSLorenzo Bianconi 			.batch_en = BIT(3),
720c91c1c84SLorenzo Bianconi 		}
721801a6e0aSLorenzo Bianconi 	},
7223054c4ffSLorenzo Bianconi 	{
7233054c4ffSLorenzo Bianconi 		.wai = 0x6b,
7245022c5a4SMartin Kepplinger 		.int1_addr = 0x0d,
7255022c5a4SMartin Kepplinger 		.int2_addr = 0x0e,
726b5969abfSSean Nyekjaer 		.int1_func_addr = 0x5e,
727b5969abfSSean Nyekjaer 		.int2_func_addr = 0x5f,
728b5969abfSSean Nyekjaer 		.int_func_mask = BIT(5),
7295022c5a4SMartin Kepplinger 		.reset_addr = 0x12,
7303054c4ffSLorenzo Bianconi 		.max_fifo_size = 512,
7313054c4ffSLorenzo Bianconi 		.id = {
73281956a93SLorenzo Bianconi 			{
73381956a93SLorenzo Bianconi 				.hw_id = ST_ASM330LHH_ID,
73481956a93SLorenzo Bianconi 				.name = ST_ASM330LHH_DEV_NAME,
73581956a93SLorenzo Bianconi 			},
7363054c4ffSLorenzo Bianconi 		},
737f48bc49bSLorenzo Bianconi 		.channels = {
738f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
739f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
740f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
741f48bc49bSLorenzo Bianconi 			},
742f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
743f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
744f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
745f48bc49bSLorenzo Bianconi 			},
746f48bc49bSLorenzo Bianconi 		},
74740dd7343SLorenzo Bianconi 		.odr_table = {
74840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
74940dd7343SLorenzo Bianconi 				.reg = {
75040dd7343SLorenzo Bianconi 					.addr = 0x10,
75140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
75240dd7343SLorenzo Bianconi 				},
75340dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
75440dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
75540dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
75640dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
75740dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
75840dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
75940dd7343SLorenzo Bianconi 			},
76040dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
76140dd7343SLorenzo Bianconi 				.reg = {
76240dd7343SLorenzo Bianconi 					.addr = 0x11,
76340dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
76440dd7343SLorenzo Bianconi 				},
76540dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
76640dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
76740dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
76840dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
76940dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
77040dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
77140dd7343SLorenzo Bianconi 			},
77240dd7343SLorenzo Bianconi 		},
773640aca3fSLorenzo Bianconi 		.fs_table = {
774640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
775640aca3fSLorenzo Bianconi 				.reg = {
776640aca3fSLorenzo Bianconi 					.addr = 0x10,
777640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
778640aca3fSLorenzo Bianconi 				},
779640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
780640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
781640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
782640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
78385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
784640aca3fSLorenzo Bianconi 			},
785640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
786640aca3fSLorenzo Bianconi 				.reg = {
787640aca3fSLorenzo Bianconi 					.addr = 0x11,
788640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
789640aca3fSLorenzo Bianconi 				},
790640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
791640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
792640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
793640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
79485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
795640aca3fSLorenzo Bianconi 			},
796640aca3fSLorenzo Bianconi 		},
7973054c4ffSLorenzo Bianconi 		.batch = {
7983054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
7993054c4ffSLorenzo Bianconi 				.addr = 0x09,
8003054c4ffSLorenzo Bianconi 				.mask = GENMASK(3, 0),
8013054c4ffSLorenzo Bianconi 			},
8023054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8033054c4ffSLorenzo Bianconi 				.addr = 0x09,
8043054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 4),
8053054c4ffSLorenzo Bianconi 			},
8063054c4ffSLorenzo Bianconi 		},
8079db02d32SLorenzo Bianconi 		.lir = {
8089db02d32SLorenzo Bianconi 			.addr = 0x56,
8099db02d32SLorenzo Bianconi 			.mask = BIT(0),
8109db02d32SLorenzo Bianconi 		},
81122ea5651SLorenzo Bianconi 		.clear_on_read = {
81222ea5651SLorenzo Bianconi 			.addr = 0x56,
81322ea5651SLorenzo Bianconi 			.mask = BIT(6),
81422ea5651SLorenzo Bianconi 		},
8153054c4ffSLorenzo Bianconi 		.fifo_ops = {
8163b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
8173054c4ffSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
8183054c4ffSLorenzo Bianconi 			.fifo_th = {
8193054c4ffSLorenzo Bianconi 				.addr = 0x07,
8203054c4ffSLorenzo Bianconi 				.mask = GENMASK(8, 0),
8213054c4ffSLorenzo Bianconi 			},
8223054c4ffSLorenzo Bianconi 			.fifo_diff = {
8233054c4ffSLorenzo Bianconi 				.addr = 0x3a,
82470575abeSmario tesi 				.mask = GENMASK(9, 0),
8253054c4ffSLorenzo Bianconi 			},
8263054c4ffSLorenzo Bianconi 			.th_wl = 1,
8273054c4ffSLorenzo Bianconi 		},
8283054c4ffSLorenzo Bianconi 		.ts_settings = {
8293054c4ffSLorenzo Bianconi 			.timer_en = {
8303054c4ffSLorenzo Bianconi 				.addr = 0x19,
8313054c4ffSLorenzo Bianconi 				.mask = BIT(5),
8323054c4ffSLorenzo Bianconi 			},
8333054c4ffSLorenzo Bianconi 			.decimator = {
8343054c4ffSLorenzo Bianconi 				.addr = 0x0a,
8353054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 6),
8363054c4ffSLorenzo Bianconi 			},
8373054c4ffSLorenzo Bianconi 		},
838b5969abfSSean Nyekjaer 		.event_settings = {
839b5969abfSSean Nyekjaer 			.enable_reg = {
840b5969abfSSean Nyekjaer 				.addr = 0x58,
841b5969abfSSean Nyekjaer 				.mask = BIT(7),
842b5969abfSSean Nyekjaer 			},
843b5969abfSSean Nyekjaer 			.wakeup_reg = {
844b5969abfSSean Nyekjaer 				.addr = 0x5B,
845b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
846b5969abfSSean Nyekjaer 			},
8471aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
8481aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
8491aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
8501aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
8511aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
852b5969abfSSean Nyekjaer 		},
8533054c4ffSLorenzo Bianconi 	},
85443901008SLorenzo Bianconi 	{
85543901008SLorenzo Bianconi 		.wai = 0x6b,
8565022c5a4SMartin Kepplinger 		.int1_addr = 0x0d,
8575022c5a4SMartin Kepplinger 		.int2_addr = 0x0e,
858b5969abfSSean Nyekjaer 		.int1_func_addr = 0x5e,
859b5969abfSSean Nyekjaer 		.int2_func_addr = 0x5f,
860b5969abfSSean Nyekjaer 		.int_func_mask = BIT(5),
8615022c5a4SMartin Kepplinger 		.reset_addr = 0x12,
86243901008SLorenzo Bianconi 		.max_fifo_size = 512,
86343901008SLorenzo Bianconi 		.id = {
86481956a93SLorenzo Bianconi 			{
86581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSR_ID,
86681956a93SLorenzo Bianconi 				.name = ST_LSM6DSR_DEV_NAME,
867db947a79SLorenzo Bianconi 			}, {
868db947a79SLorenzo Bianconi 				.hw_id = ST_ISM330DHCX_ID,
869db947a79SLorenzo Bianconi 				.name = ST_ISM330DHCX_DEV_NAME,
87081956a93SLorenzo Bianconi 			},
87143901008SLorenzo Bianconi 		},
872f48bc49bSLorenzo Bianconi 		.channels = {
873f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
874f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
875f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
876f48bc49bSLorenzo Bianconi 			},
877f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
878f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
879f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
880f48bc49bSLorenzo Bianconi 			},
881f48bc49bSLorenzo Bianconi 		},
88240dd7343SLorenzo Bianconi 		.odr_table = {
88340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
88440dd7343SLorenzo Bianconi 				.reg = {
88540dd7343SLorenzo Bianconi 					.addr = 0x10,
88640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
88740dd7343SLorenzo Bianconi 				},
88840dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
88940dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
89040dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
89140dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
89240dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
89340dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
89440dd7343SLorenzo Bianconi 			},
89540dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
89640dd7343SLorenzo Bianconi 				.reg = {
89740dd7343SLorenzo Bianconi 					.addr = 0x11,
89840dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
89940dd7343SLorenzo Bianconi 				},
90040dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
90140dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
90240dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
90340dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
90440dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
90540dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
90640dd7343SLorenzo Bianconi 			},
90740dd7343SLorenzo Bianconi 		},
908640aca3fSLorenzo Bianconi 		.fs_table = {
909640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
910640aca3fSLorenzo Bianconi 				.reg = {
911640aca3fSLorenzo Bianconi 					.addr = 0x10,
912640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
913640aca3fSLorenzo Bianconi 				},
914640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
915640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
916640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
917640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
91885ae3aeeSLorenzo Bianconi 				.fs_len = 4,
919640aca3fSLorenzo Bianconi 			},
920640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
921640aca3fSLorenzo Bianconi 				.reg = {
922640aca3fSLorenzo Bianconi 					.addr = 0x11,
923640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
924640aca3fSLorenzo Bianconi 				},
925640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
926640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
927640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
928640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
92985ae3aeeSLorenzo Bianconi 				.fs_len = 4,
930640aca3fSLorenzo Bianconi 			},
931640aca3fSLorenzo Bianconi 		},
93243901008SLorenzo Bianconi 		.batch = {
93343901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
93443901008SLorenzo Bianconi 				.addr = 0x09,
93543901008SLorenzo Bianconi 				.mask = GENMASK(3, 0),
93643901008SLorenzo Bianconi 			},
93743901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
93843901008SLorenzo Bianconi 				.addr = 0x09,
93943901008SLorenzo Bianconi 				.mask = GENMASK(7, 4),
94043901008SLorenzo Bianconi 			},
94143901008SLorenzo Bianconi 		},
9429db02d32SLorenzo Bianconi 		.lir = {
9439db02d32SLorenzo Bianconi 			.addr = 0x56,
9449db02d32SLorenzo Bianconi 			.mask = BIT(0),
9459db02d32SLorenzo Bianconi 		},
94622ea5651SLorenzo Bianconi 		.clear_on_read = {
94722ea5651SLorenzo Bianconi 			.addr = 0x56,
94822ea5651SLorenzo Bianconi 			.mask = BIT(6),
94922ea5651SLorenzo Bianconi 		},
95043901008SLorenzo Bianconi 		.fifo_ops = {
9513b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
95243901008SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
95343901008SLorenzo Bianconi 			.fifo_th = {
95443901008SLorenzo Bianconi 				.addr = 0x07,
95543901008SLorenzo Bianconi 				.mask = GENMASK(8, 0),
95643901008SLorenzo Bianconi 			},
95743901008SLorenzo Bianconi 			.fifo_diff = {
95843901008SLorenzo Bianconi 				.addr = 0x3a,
95970575abeSmario tesi 				.mask = GENMASK(9, 0),
96043901008SLorenzo Bianconi 			},
96143901008SLorenzo Bianconi 			.th_wl = 1,
96243901008SLorenzo Bianconi 		},
96343901008SLorenzo Bianconi 		.ts_settings = {
96443901008SLorenzo Bianconi 			.timer_en = {
96543901008SLorenzo Bianconi 				.addr = 0x19,
96643901008SLorenzo Bianconi 				.mask = BIT(5),
96743901008SLorenzo Bianconi 			},
96843901008SLorenzo Bianconi 			.decimator = {
96943901008SLorenzo Bianconi 				.addr = 0x0a,
97043901008SLorenzo Bianconi 				.mask = GENMASK(7, 6),
97143901008SLorenzo Bianconi 			},
97243901008SLorenzo Bianconi 		},
97343901008SLorenzo Bianconi 		.shub_settings = {
97443901008SLorenzo Bianconi 			.page_mux = {
97543901008SLorenzo Bianconi 				.addr = 0x01,
97643901008SLorenzo Bianconi 				.mask = BIT(6),
97743901008SLorenzo Bianconi 			},
97843901008SLorenzo Bianconi 			.master_en = {
97943901008SLorenzo Bianconi 				.addr = 0x14,
98043901008SLorenzo Bianconi 				.mask = BIT(2),
98143901008SLorenzo Bianconi 			},
98243901008SLorenzo Bianconi 			.pullup_en = {
98343901008SLorenzo Bianconi 				.addr = 0x14,
98443901008SLorenzo Bianconi 				.mask = BIT(3),
98543901008SLorenzo Bianconi 			},
98643901008SLorenzo Bianconi 			.aux_sens = {
98743901008SLorenzo Bianconi 				.addr = 0x14,
98843901008SLorenzo Bianconi 				.mask = GENMASK(1, 0),
98943901008SLorenzo Bianconi 			},
99043901008SLorenzo Bianconi 			.wr_once = {
99143901008SLorenzo Bianconi 				.addr = 0x14,
99243901008SLorenzo Bianconi 				.mask = BIT(6),
99343901008SLorenzo Bianconi 			},
99443901008SLorenzo Bianconi 			.shub_out = 0x02,
99543901008SLorenzo Bianconi 			.slv0_addr = 0x15,
99643901008SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
99743901008SLorenzo Bianconi 			.batch_en = BIT(3),
998b5969abfSSean Nyekjaer 		},
999b5969abfSSean Nyekjaer 		.event_settings = {
1000b5969abfSSean Nyekjaer 			.enable_reg = {
1001b5969abfSSean Nyekjaer 				.addr = 0x58,
1002b5969abfSSean Nyekjaer 				.mask = BIT(7),
1003b5969abfSSean Nyekjaer 			},
1004b5969abfSSean Nyekjaer 			.wakeup_reg = {
1005b5969abfSSean Nyekjaer 				.addr = 0x5B,
1006b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1007b5969abfSSean Nyekjaer 			},
10081aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
10091aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
10101aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
10111aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
10121aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
101343901008SLorenzo Bianconi 		}
101443901008SLorenzo Bianconi 	},
1015290a6ce1SLorenzo Bianconi };
1016290a6ce1SLorenzo Bianconi 
1017c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1018c91c1c84SLorenzo Bianconi {
1019c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1020c91c1c84SLorenzo Bianconi 	unsigned int data;
1021c91c1c84SLorenzo Bianconi 	int err;
1022c91c1c84SLorenzo Bianconi 
1023c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1024c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1025c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1026c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1027c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1028c91c1c84SLorenzo Bianconi 
1029c91c1c84SLorenzo Bianconi 	return err;
1030c91c1c84SLorenzo Bianconi }
1031c91c1c84SLorenzo Bianconi 
103281956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
103381956a93SLorenzo Bianconi 				   const char **name)
1034290a6ce1SLorenzo Bianconi {
103551a8b707SLorenzo Bianconi 	int err, i, j, data;
1036290a6ce1SLorenzo Bianconi 
1037290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1038d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
103981956a93SLorenzo Bianconi 			if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1040d068e4a0SLorenzo Bianconi 				break;
1041d068e4a0SLorenzo Bianconi 		}
1042d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1043290a6ce1SLorenzo Bianconi 			break;
1044290a6ce1SLorenzo Bianconi 	}
1045290a6ce1SLorenzo Bianconi 
1046290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1047290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1048290a6ce1SLorenzo Bianconi 		return -ENODEV;
1049290a6ce1SLorenzo Bianconi 	}
1050290a6ce1SLorenzo Bianconi 
105151a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1052290a6ce1SLorenzo Bianconi 	if (err < 0) {
1053290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1054290a6ce1SLorenzo Bianconi 		return err;
1055290a6ce1SLorenzo Bianconi 	}
1056290a6ce1SLorenzo Bianconi 
1057290a6ce1SLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].wai) {
1058290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1059290a6ce1SLorenzo Bianconi 		return -ENODEV;
1060290a6ce1SLorenzo Bianconi 	}
1061290a6ce1SLorenzo Bianconi 
106281956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1063290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1064290a6ce1SLorenzo Bianconi 
1065290a6ce1SLorenzo Bianconi 	return 0;
1066290a6ce1SLorenzo Bianconi }
1067290a6ce1SLorenzo Bianconi 
1068290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1069290a6ce1SLorenzo Bianconi 				     u32 gain)
1070290a6ce1SLorenzo Bianconi {
1071640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1072739aff87SLorenzo Bianconi 	unsigned int data;
1073290a6ce1SLorenzo Bianconi 	int i, err;
1074290a6ce1SLorenzo Bianconi 
1075640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
107685ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1077640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1078290a6ce1SLorenzo Bianconi 			break;
107985ae3aeeSLorenzo Bianconi 	}
1080290a6ce1SLorenzo Bianconi 
108185ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1082290a6ce1SLorenzo Bianconi 		return -EINVAL;
1083290a6ce1SLorenzo Bianconi 
1084640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1085640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1086640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1087640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1088290a6ce1SLorenzo Bianconi 	if (err < 0)
1089290a6ce1SLorenzo Bianconi 		return err;
1090290a6ce1SLorenzo Bianconi 
1091290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1092290a6ce1SLorenzo Bianconi 
1093290a6ce1SLorenzo Bianconi 	return 0;
1094290a6ce1SLorenzo Bianconi }
1095290a6ce1SLorenzo Bianconi 
109654a6d0c6SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
1097290a6ce1SLorenzo Bianconi {
109840dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
10992ccc1503SLorenzo Bianconi 	int i;
1100290a6ce1SLorenzo Bianconi 
110140dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
1102290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
11036ffb55e5SLorenzo Bianconi 		/*
11046ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
11056ffb55e5SLorenzo Bianconi 		 * accel sensor
11066ffb55e5SLorenzo Bianconi 		 */
110740dd7343SLorenzo Bianconi 		if (odr_table->odr_avl[i].hz >= odr)
1108290a6ce1SLorenzo Bianconi 			break;
1109290a6ce1SLorenzo Bianconi 
1110290a6ce1SLorenzo Bianconi 	if (i == ST_LSM6DSX_ODR_LIST_SIZE)
1111290a6ce1SLorenzo Bianconi 		return -EINVAL;
1112290a6ce1SLorenzo Bianconi 
111340dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1114290a6ce1SLorenzo Bianconi 
1115290a6ce1SLorenzo Bianconi 	return 0;
1116290a6ce1SLorenzo Bianconi }
1117290a6ce1SLorenzo Bianconi 
11186ffb55e5SLorenzo Bianconi static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr,
11196ffb55e5SLorenzo Bianconi 					   enum st_lsm6dsx_sensor_id id)
11202ccc1503SLorenzo Bianconi {
11216ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
11226ffb55e5SLorenzo Bianconi 
11236ffb55e5SLorenzo Bianconi 	if (odr > 0) {
11246ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
11256ffb55e5SLorenzo Bianconi 			return max_t(u16, ref->odr, odr);
11266ffb55e5SLorenzo Bianconi 		else
11276ffb55e5SLorenzo Bianconi 			return odr;
11286ffb55e5SLorenzo Bianconi 	} else {
11296ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
11306ffb55e5SLorenzo Bianconi 	}
11316ffb55e5SLorenzo Bianconi }
11326ffb55e5SLorenzo Bianconi 
11336ffb55e5SLorenzo Bianconi static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)
11346ffb55e5SLorenzo Bianconi {
11356ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
113651a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
113751a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1138739aff87SLorenzo Bianconi 	unsigned int data;
11396ffb55e5SLorenzo Bianconi 	u8 val = 0;
11402ccc1503SLorenzo Bianconi 	int err;
11412ccc1503SLorenzo Bianconi 
11426ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
11436ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
11446ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
11456ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
11466ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
11476ffb55e5SLorenzo Bianconi 		u16 odr;
11486ffb55e5SLorenzo Bianconi 		int i;
11496ffb55e5SLorenzo Bianconi 
11506ffb55e5SLorenzo Bianconi 		/*
11516ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
11526ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
11536ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
11546ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
11556ffb55e5SLorenzo Bianconi 		 */
11566ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
11576ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
11586ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
11596ffb55e5SLorenzo Bianconi 				continue;
11606ffb55e5SLorenzo Bianconi 
11616ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
11626ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
11636ffb55e5SLorenzo Bianconi 				/* device already configured */
11646ffb55e5SLorenzo Bianconi 				return 0;
11656ffb55e5SLorenzo Bianconi 		}
11666ffb55e5SLorenzo Bianconi 		break;
11676ffb55e5SLorenzo Bianconi 	}
11686ffb55e5SLorenzo Bianconi 	default:
11696ffb55e5SLorenzo Bianconi 		break;
11706ffb55e5SLorenzo Bianconi 	}
11716ffb55e5SLorenzo Bianconi 
11726ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
11736ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
11742ccc1503SLorenzo Bianconi 		if (err < 0)
11752ccc1503SLorenzo Bianconi 			return err;
11766ffb55e5SLorenzo Bianconi 	}
11772ccc1503SLorenzo Bianconi 
117840dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1179739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1180739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
11812ccc1503SLorenzo Bianconi }
11822ccc1503SLorenzo Bianconi 
118317750443SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
118417750443SLorenzo Bianconi 				 bool enable)
1185290a6ce1SLorenzo Bianconi {
118651a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
118717750443SLorenzo Bianconi 	u16 odr = enable ? sensor->odr : 0;
1188290a6ce1SLorenzo Bianconi 	int err;
1189290a6ce1SLorenzo Bianconi 
119017750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1191290a6ce1SLorenzo Bianconi 	if (err < 0)
1192290a6ce1SLorenzo Bianconi 		return err;
1193290a6ce1SLorenzo Bianconi 
119417750443SLorenzo Bianconi 	if (enable)
119517750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
119617750443SLorenzo Bianconi 	else
119717750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1198290a6ce1SLorenzo Bianconi 
1199290a6ce1SLorenzo Bianconi 	return 0;
1200290a6ce1SLorenzo Bianconi }
1201290a6ce1SLorenzo Bianconi 
1202290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1203290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1204290a6ce1SLorenzo Bianconi {
120551a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1206290a6ce1SLorenzo Bianconi 	int err, delay;
1207290a6ce1SLorenzo Bianconi 	__le16 data;
1208290a6ce1SLorenzo Bianconi 
120917750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1210290a6ce1SLorenzo Bianconi 	if (err < 0)
1211290a6ce1SLorenzo Bianconi 		return err;
1212290a6ce1SLorenzo Bianconi 
1213290a6ce1SLorenzo Bianconi 	delay = 1000000 / sensor->odr;
1214290a6ce1SLorenzo Bianconi 	usleep_range(delay, 2 * delay);
1215290a6ce1SLorenzo Bianconi 
1216739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1217290a6ce1SLorenzo Bianconi 	if (err < 0)
1218290a6ce1SLorenzo Bianconi 		return err;
1219290a6ce1SLorenzo Bianconi 
1220b5969abfSSean Nyekjaer 	if (!hw->enable_event)
122117750443SLorenzo Bianconi 		st_lsm6dsx_sensor_set_enable(sensor, false);
1222290a6ce1SLorenzo Bianconi 
12237b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1224290a6ce1SLorenzo Bianconi 
1225290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1226290a6ce1SLorenzo Bianconi }
1227290a6ce1SLorenzo Bianconi 
1228290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1229290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1230290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1231290a6ce1SLorenzo Bianconi {
1232290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1233290a6ce1SLorenzo Bianconi 	int ret;
1234290a6ce1SLorenzo Bianconi 
1235290a6ce1SLorenzo Bianconi 	switch (mask) {
1236290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1237290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1238290a6ce1SLorenzo Bianconi 		if (ret)
1239290a6ce1SLorenzo Bianconi 			break;
1240290a6ce1SLorenzo Bianconi 
1241290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1242290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1243290a6ce1SLorenzo Bianconi 		break;
1244290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1245290a6ce1SLorenzo Bianconi 		*val = sensor->odr;
1246290a6ce1SLorenzo Bianconi 		ret = IIO_VAL_INT;
1247290a6ce1SLorenzo Bianconi 		break;
1248290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1249290a6ce1SLorenzo Bianconi 		*val = 0;
1250290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
1251290a6ce1SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1252290a6ce1SLorenzo Bianconi 		break;
1253290a6ce1SLorenzo Bianconi 	default:
1254290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1255290a6ce1SLorenzo Bianconi 		break;
1256290a6ce1SLorenzo Bianconi 	}
1257290a6ce1SLorenzo Bianconi 
1258290a6ce1SLorenzo Bianconi 	return ret;
1259290a6ce1SLorenzo Bianconi }
1260290a6ce1SLorenzo Bianconi 
1261290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1262290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1263290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1264290a6ce1SLorenzo Bianconi {
1265290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1266290a6ce1SLorenzo Bianconi 	int err;
1267290a6ce1SLorenzo Bianconi 
1268290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1269290a6ce1SLorenzo Bianconi 	if (err)
1270290a6ce1SLorenzo Bianconi 		return err;
1271290a6ce1SLorenzo Bianconi 
1272290a6ce1SLorenzo Bianconi 	switch (mask) {
1273290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1274290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1275290a6ce1SLorenzo Bianconi 		break;
12762ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
12772ccc1503SLorenzo Bianconi 		u8 data;
12782ccc1503SLorenzo Bianconi 
12792ccc1503SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(sensor, val, &data);
12805e3c3e33SLorenzo Bianconi 		if (!err)
12815e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1282290a6ce1SLorenzo Bianconi 		break;
12832ccc1503SLorenzo Bianconi 	}
1284290a6ce1SLorenzo Bianconi 	default:
1285290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1286290a6ce1SLorenzo Bianconi 		break;
1287290a6ce1SLorenzo Bianconi 	}
1288290a6ce1SLorenzo Bianconi 
1289290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1290290a6ce1SLorenzo Bianconi 
1291290a6ce1SLorenzo Bianconi 	return err;
1292290a6ce1SLorenzo Bianconi }
1293290a6ce1SLorenzo Bianconi 
1294b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1295b5969abfSSean Nyekjaer {
1296b5969abfSSean Nyekjaer 	int err;
1297b5969abfSSean Nyekjaer 	u8 enable = 0;
1298b5969abfSSean Nyekjaer 
1299b5969abfSSean Nyekjaer 	if (!hw->settings->int1_func_addr)
1300b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1301b5969abfSSean Nyekjaer 
1302b5969abfSSean Nyekjaer 	enable = state ? hw->settings->event_settings.enable_reg.mask : 0;
1303b5969abfSSean Nyekjaer 
1304b5969abfSSean Nyekjaer 	err = regmap_update_bits(hw->regmap,
1305b5969abfSSean Nyekjaer 				 hw->settings->event_settings.enable_reg.addr,
1306b5969abfSSean Nyekjaer 				 hw->settings->event_settings.enable_reg.mask,
1307b5969abfSSean Nyekjaer 				 enable);
1308b5969abfSSean Nyekjaer 	if (err < 0)
1309b5969abfSSean Nyekjaer 		return err;
1310b5969abfSSean Nyekjaer 
1311b5969abfSSean Nyekjaer 	enable = state ? hw->irq_routing.mask : 0;
1312b5969abfSSean Nyekjaer 
1313b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
1314b5969abfSSean Nyekjaer 	return regmap_update_bits(hw->regmap, hw->irq_routing.addr,
1315b5969abfSSean Nyekjaer 				  hw->irq_routing.mask,
1316b5969abfSSean Nyekjaer 				  enable);
1317b5969abfSSean Nyekjaer }
1318b5969abfSSean Nyekjaer 
1319b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1320b5969abfSSean Nyekjaer 				   const struct iio_chan_spec *chan,
1321b5969abfSSean Nyekjaer 				   enum iio_event_type type,
1322b5969abfSSean Nyekjaer 				   enum iio_event_direction dir,
1323b5969abfSSean Nyekjaer 				   enum iio_event_info info,
1324b5969abfSSean Nyekjaer 				   int *val, int *val2)
1325b5969abfSSean Nyekjaer {
1326b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1327b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1328b5969abfSSean Nyekjaer 
1329b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1330b5969abfSSean Nyekjaer 		return -EINVAL;
1331b5969abfSSean Nyekjaer 
1332b5969abfSSean Nyekjaer 	*val2 = 0;
1333b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1334b5969abfSSean Nyekjaer 
1335b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1336b5969abfSSean Nyekjaer }
1337b5969abfSSean Nyekjaer 
1338b5969abfSSean Nyekjaer static int st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1339b5969abfSSean Nyekjaer 				    const struct iio_chan_spec *chan,
1340b5969abfSSean Nyekjaer 				    enum iio_event_type type,
1341b5969abfSSean Nyekjaer 				    enum iio_event_direction dir,
1342b5969abfSSean Nyekjaer 				    enum iio_event_info info,
1343b5969abfSSean Nyekjaer 				    int val, int val2)
1344b5969abfSSean Nyekjaer {
1345b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1346b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1347b5969abfSSean Nyekjaer 	int err;
1348b5969abfSSean Nyekjaer 
1349b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1350b5969abfSSean Nyekjaer 		return -EINVAL;
1351b5969abfSSean Nyekjaer 
1352b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1353b5969abfSSean Nyekjaer 		return -EINVAL;
1354b5969abfSSean Nyekjaer 
1355b5969abfSSean Nyekjaer 	err = regmap_update_bits(hw->regmap,
1356b5969abfSSean Nyekjaer 				 hw->settings->event_settings.wakeup_reg.addr,
1357b5969abfSSean Nyekjaer 				 hw->settings->event_settings.wakeup_reg.mask,
1358b5969abfSSean Nyekjaer 				 val);
1359b5969abfSSean Nyekjaer 	if (err)
1360b5969abfSSean Nyekjaer 		return -EINVAL;
1361b5969abfSSean Nyekjaer 
1362b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1363b5969abfSSean Nyekjaer 
1364b5969abfSSean Nyekjaer 	return 0;
1365b5969abfSSean Nyekjaer }
1366b5969abfSSean Nyekjaer 
1367b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1368b5969abfSSean Nyekjaer 					  const struct iio_chan_spec *chan,
1369b5969abfSSean Nyekjaer 					  enum iio_event_type type,
1370b5969abfSSean Nyekjaer 					  enum iio_event_direction dir)
1371b5969abfSSean Nyekjaer {
1372b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1373b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1374b5969abfSSean Nyekjaer 
1375b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1376b5969abfSSean Nyekjaer 		return -EINVAL;
1377b5969abfSSean Nyekjaer 
13781aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1379b5969abfSSean Nyekjaer }
1380b5969abfSSean Nyekjaer 
1381b5969abfSSean Nyekjaer static int st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1382b5969abfSSean Nyekjaer 					   const struct iio_chan_spec *chan,
1383b5969abfSSean Nyekjaer 					   enum iio_event_type type,
1384b5969abfSSean Nyekjaer 					   enum iio_event_direction dir,
1385b5969abfSSean Nyekjaer 					   int state)
1386b5969abfSSean Nyekjaer {
1387b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1388b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
13891aabad1fSSean Nyekjaer 	u8 enable_event;
1390b5969abfSSean Nyekjaer 	int err = 0;
1391b5969abfSSean Nyekjaer 
1392b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1393b5969abfSSean Nyekjaer 		return -EINVAL;
1394b5969abfSSean Nyekjaer 
13951aabad1fSSean Nyekjaer 	if (state) {
13961aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
13971aabad1fSSean Nyekjaer 
1398b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
13991aabad1fSSean Nyekjaer 		if (hw->enable_event)
14001aabad1fSSean Nyekjaer 			goto out;
14011aabad1fSSean Nyekjaer 	} else {
14021aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
14031aabad1fSSean Nyekjaer 
14041aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
14051aabad1fSSean Nyekjaer 		if (enable_event)
14061aabad1fSSean Nyekjaer 			goto out;
14071aabad1fSSean Nyekjaer 	}
14081aabad1fSSean Nyekjaer 
14091aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
14101aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1411b5969abfSSean Nyekjaer 		return 0;
1412b5969abfSSean Nyekjaer 
1413b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1414b5969abfSSean Nyekjaer 	if (err < 0)
1415b5969abfSSean Nyekjaer 		return err;
1416b5969abfSSean Nyekjaer 
1417b5969abfSSean Nyekjaer 	err = st_lsm6dsx_sensor_set_enable(sensor, state);
1418b5969abfSSean Nyekjaer 	if (err < 0)
1419b5969abfSSean Nyekjaer 		return err;
1420b5969abfSSean Nyekjaer 
14211aabad1fSSean Nyekjaer out:
14221aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1423b5969abfSSean Nyekjaer 
1424b5969abfSSean Nyekjaer 	return 0;
1425b5969abfSSean Nyekjaer }
1426b5969abfSSean Nyekjaer 
1427d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1428290a6ce1SLorenzo Bianconi {
1429290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1430290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
14318f2a88a2SLorenzo Bianconi 	int err;
1432290a6ce1SLorenzo Bianconi 
14338f2a88a2SLorenzo Bianconi 	if (val < 1 || val > hw->settings->max_fifo_size)
1434290a6ce1SLorenzo Bianconi 		return -EINVAL;
1435290a6ce1SLorenzo Bianconi 
1436335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1437335eaedcSLorenzo Bianconi 
1438290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
1439335eaedcSLorenzo Bianconi 
1440335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1441335eaedcSLorenzo Bianconi 
1442290a6ce1SLorenzo Bianconi 	if (err < 0)
1443290a6ce1SLorenzo Bianconi 		return err;
1444290a6ce1SLorenzo Bianconi 
1445290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
1446290a6ce1SLorenzo Bianconi 
1447290a6ce1SLorenzo Bianconi 	return 0;
1448290a6ce1SLorenzo Bianconi }
1449290a6ce1SLorenzo Bianconi 
1450290a6ce1SLorenzo Bianconi static ssize_t
1451290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1452290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
1453290a6ce1SLorenzo Bianconi 					  char *buf)
1454290a6ce1SLorenzo Bianconi {
1455290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
1456290a6ce1SLorenzo Bianconi 	enum st_lsm6dsx_sensor_id id = sensor->id;
145740dd7343SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1458290a6ce1SLorenzo Bianconi 	int i, len = 0;
1459290a6ce1SLorenzo Bianconi 
1460290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
1461290a6ce1SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
146240dd7343SLorenzo Bianconi 				 hw->settings->odr_table[id].odr_avl[i].hz);
1463290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1464290a6ce1SLorenzo Bianconi 
1465290a6ce1SLorenzo Bianconi 	return len;
1466290a6ce1SLorenzo Bianconi }
1467290a6ce1SLorenzo Bianconi 
1468290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
1469290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
1470290a6ce1SLorenzo Bianconi 					    char *buf)
1471290a6ce1SLorenzo Bianconi {
1472290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
14730f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1474640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1475290a6ce1SLorenzo Bianconi 	int i, len = 0;
1476290a6ce1SLorenzo Bianconi 
147785ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
147885ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
1479290a6ce1SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
14800f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
1481290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1482290a6ce1SLorenzo Bianconi 
1483290a6ce1SLorenzo Bianconi 	return len;
1484290a6ce1SLorenzo Bianconi }
1485290a6ce1SLorenzo Bianconi 
1486290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
1487290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
1488290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1489290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
1490290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1491290a6ce1SLorenzo Bianconi 
1492290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
1493290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1494290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1495290a6ce1SLorenzo Bianconi 	NULL,
1496290a6ce1SLorenzo Bianconi };
1497290a6ce1SLorenzo Bianconi 
1498290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
1499290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
1500290a6ce1SLorenzo Bianconi };
1501290a6ce1SLorenzo Bianconi 
1502290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
1503290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
1504290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1505290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1506b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
1507b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
1508b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
1509b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
1510290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1511290a6ce1SLorenzo Bianconi };
1512290a6ce1SLorenzo Bianconi 
1513290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
1514290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1515290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
1516290a6ce1SLorenzo Bianconi 	NULL,
1517290a6ce1SLorenzo Bianconi };
1518290a6ce1SLorenzo Bianconi 
1519290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
1520290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
1521290a6ce1SLorenzo Bianconi };
1522290a6ce1SLorenzo Bianconi 
1523290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
1524290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
1525290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1526290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1527290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1528290a6ce1SLorenzo Bianconi };
1529290a6ce1SLorenzo Bianconi 
1530dba32904SLorenzo Bianconi static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1531dba32904SLorenzo Bianconi {
1532dba32904SLorenzo Bianconi 	struct device_node *np = hw->dev->of_node;
1533dba32904SLorenzo Bianconi 
1534dba32904SLorenzo Bianconi 	if (!np)
1535dba32904SLorenzo Bianconi 		return -EINVAL;
1536dba32904SLorenzo Bianconi 
1537bf235277SLorenzo Bianconi 	return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
1538dba32904SLorenzo Bianconi }
1539dba32904SLorenzo Bianconi 
1540dba32904SLorenzo Bianconi static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
1541dba32904SLorenzo Bianconi {
1542dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
1543dba32904SLorenzo Bianconi 
1544dba32904SLorenzo Bianconi 	if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
1545dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
1546dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
1547dba32904SLorenzo Bianconi 
1548dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
1549dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
1550dba32904SLorenzo Bianconi 	}
1551dba32904SLorenzo Bianconi 
1552dba32904SLorenzo Bianconi 	switch (drdy_pin) {
1553dba32904SLorenzo Bianconi 	case 1:
15545022c5a4SMartin Kepplinger 		*drdy_reg = hw->settings->int1_addr;
1555b5969abfSSean Nyekjaer 		hw->irq_routing.addr = hw->settings->int1_func_addr;
1556b5969abfSSean Nyekjaer 		hw->irq_routing.mask = hw->settings->int_func_mask;
1557dba32904SLorenzo Bianconi 		break;
1558dba32904SLorenzo Bianconi 	case 2:
15595022c5a4SMartin Kepplinger 		*drdy_reg = hw->settings->int2_addr;
1560b5969abfSSean Nyekjaer 		hw->irq_routing.addr = hw->settings->int2_func_addr;
1561b5969abfSSean Nyekjaer 		hw->irq_routing.mask = hw->settings->int_func_mask;
1562dba32904SLorenzo Bianconi 		break;
1563dba32904SLorenzo Bianconi 	default:
1564dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
1565dba32904SLorenzo Bianconi 		err = -EINVAL;
1566dba32904SLorenzo Bianconi 		break;
1567dba32904SLorenzo Bianconi 	}
1568dba32904SLorenzo Bianconi 
1569dba32904SLorenzo Bianconi 	return err;
1570dba32904SLorenzo Bianconi }
1571dba32904SLorenzo Bianconi 
1572c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1573c91c1c84SLorenzo Bianconi {
1574c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1575c91c1c84SLorenzo Bianconi 	struct device_node *np = hw->dev->of_node;
1576c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
1577c91c1c84SLorenzo Bianconi 	unsigned int data;
1578c91c1c84SLorenzo Bianconi 	int err = 0;
1579c91c1c84SLorenzo Bianconi 
1580c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1581c91c1c84SLorenzo Bianconi 
1582c91c1c84SLorenzo Bianconi 	pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
1583c91c1c84SLorenzo Bianconi 	if ((np && of_property_read_bool(np, "st,pullups")) ||
1584c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
1585c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
1586c91c1c84SLorenzo Bianconi 		if (err < 0)
1587c91c1c84SLorenzo Bianconi 			return err;
1588c91c1c84SLorenzo Bianconi 
1589c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
1590c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
1591c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
1592c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
1593c91c1c84SLorenzo Bianconi 
1594c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
1595c91c1c84SLorenzo Bianconi 
1596c91c1c84SLorenzo Bianconi 		if (err < 0)
1597c91c1c84SLorenzo Bianconi 			return err;
1598c91c1c84SLorenzo Bianconi 	}
1599c91c1c84SLorenzo Bianconi 
1600c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
1601c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
1602c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
1603c91c1c84SLorenzo Bianconi 		if (err < 0)
1604c91c1c84SLorenzo Bianconi 			return err;
1605c91c1c84SLorenzo Bianconi 
1606c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
1607c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
1608c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
1609c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
1610c91c1c84SLorenzo Bianconi 
1611c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
1612c91c1c84SLorenzo Bianconi 	}
1613c91c1c84SLorenzo Bianconi 
1614c91c1c84SLorenzo Bianconi 	return err;
1615c91c1c84SLorenzo Bianconi }
1616c91c1c84SLorenzo Bianconi 
161721345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
161821345107SLorenzo Bianconi {
161921345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
162021345107SLorenzo Bianconi 	int err, val;
162121345107SLorenzo Bianconi 
162221345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
162321345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
162421345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
162521345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
162621345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
162721345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
162821345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
162921345107SLorenzo Bianconi 		if (err < 0)
163021345107SLorenzo Bianconi 			return err;
163121345107SLorenzo Bianconi 	}
163221345107SLorenzo Bianconi 
163321345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
163421345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
163521345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
163621345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
163721345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
163821345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
163921345107SLorenzo Bianconi 		if (err < 0)
164021345107SLorenzo Bianconi 			return err;
164121345107SLorenzo Bianconi 	}
164221345107SLorenzo Bianconi 
164321345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
164421345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
164521345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
164621345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
164721345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
164821345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
164921345107SLorenzo Bianconi 		if (err < 0)
165021345107SLorenzo Bianconi 			return err;
165121345107SLorenzo Bianconi 	}
165221345107SLorenzo Bianconi 	return 0;
165321345107SLorenzo Bianconi }
165421345107SLorenzo Bianconi 
1655290a6ce1SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
1656290a6ce1SLorenzo Bianconi {
165751a8b707SLorenzo Bianconi 	u8 drdy_int_reg;
1658290a6ce1SLorenzo Bianconi 	int err;
1659290a6ce1SLorenzo Bianconi 
166019435425SLorenzo Bianconi 	/* device sw reset */
16615022c5a4SMartin Kepplinger 	err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
166219435425SLorenzo Bianconi 				 ST_LSM6DSX_REG_RESET_MASK,
166319435425SLorenzo Bianconi 				 FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1));
1664290a6ce1SLorenzo Bianconi 	if (err < 0)
1665290a6ce1SLorenzo Bianconi 		return err;
1666290a6ce1SLorenzo Bianconi 
166719435425SLorenzo Bianconi 	msleep(50);
166819435425SLorenzo Bianconi 
166919435425SLorenzo Bianconi 	/* reload trimming parameter */
16705022c5a4SMartin Kepplinger 	err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
167119435425SLorenzo Bianconi 				 ST_LSM6DSX_REG_BOOT_MASK,
167219435425SLorenzo Bianconi 				 FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1));
167319435425SLorenzo Bianconi 	if (err < 0)
167419435425SLorenzo Bianconi 		return err;
167519435425SLorenzo Bianconi 
167619435425SLorenzo Bianconi 	msleep(50);
1677290a6ce1SLorenzo Bianconi 
1678290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
167951a8b707SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR,
168051a8b707SLorenzo Bianconi 				 ST_LSM6DSX_REG_BDU_MASK,
168151a8b707SLorenzo Bianconi 				 FIELD_PREP(ST_LSM6DSX_REG_BDU_MASK, 1));
1682290a6ce1SLorenzo Bianconi 	if (err < 0)
1683290a6ce1SLorenzo Bianconi 		return err;
1684290a6ce1SLorenzo Bianconi 
1685290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
1686dba32904SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg);
1687290a6ce1SLorenzo Bianconi 	if (err < 0)
1688290a6ce1SLorenzo Bianconi 		return err;
1689290a6ce1SLorenzo Bianconi 
169021345107SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, drdy_int_reg,
169151a8b707SLorenzo Bianconi 				 ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
169251a8b707SLorenzo Bianconi 				 FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
169351a8b707SLorenzo Bianconi 					    1));
169421345107SLorenzo Bianconi 	if (err < 0)
169521345107SLorenzo Bianconi 		return err;
169621345107SLorenzo Bianconi 
16979db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
16989db02d32SLorenzo Bianconi 	if (hw->settings->lir.addr) {
16999db02d32SLorenzo Bianconi 		unsigned int data;
17009db02d32SLorenzo Bianconi 
17019db02d32SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hw->settings->lir.mask);
17029db02d32SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, hw->settings->lir.addr,
17039db02d32SLorenzo Bianconi 					 hw->settings->lir.mask, data);
17049db02d32SLorenzo Bianconi 		if (err < 0)
17059db02d32SLorenzo Bianconi 			return err;
170622ea5651SLorenzo Bianconi 
170722ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
170822ea5651SLorenzo Bianconi 		if (hw->settings->clear_on_read.addr) {
170922ea5651SLorenzo Bianconi 			data = ST_LSM6DSX_SHIFT_VAL(1,
171022ea5651SLorenzo Bianconi 					hw->settings->clear_on_read.mask);
171122ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
171222ea5651SLorenzo Bianconi 					hw->settings->clear_on_read.addr,
171322ea5651SLorenzo Bianconi 					hw->settings->clear_on_read.mask,
171422ea5651SLorenzo Bianconi 					data);
171522ea5651SLorenzo Bianconi 			if (err < 0)
171622ea5651SLorenzo Bianconi 				return err;
171722ea5651SLorenzo Bianconi 		}
17189db02d32SLorenzo Bianconi 	}
17199db02d32SLorenzo Bianconi 
1720c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
1721c91c1c84SLorenzo Bianconi 	if (err < 0)
1722c91c1c84SLorenzo Bianconi 		return err;
1723c91c1c84SLorenzo Bianconi 
172421345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
1725290a6ce1SLorenzo Bianconi }
1726290a6ce1SLorenzo Bianconi 
1727290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
1728510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
1729510c0106SLorenzo Bianconi 					       const char *name)
1730290a6ce1SLorenzo Bianconi {
1731290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
1732290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
1733290a6ce1SLorenzo Bianconi 
1734290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
1735290a6ce1SLorenzo Bianconi 	if (!iio_dev)
1736290a6ce1SLorenzo Bianconi 		return NULL;
1737290a6ce1SLorenzo Bianconi 
1738290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
1739290a6ce1SLorenzo Bianconi 	iio_dev->dev.parent = hw->dev;
1740290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
1741f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
1742f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
1743290a6ce1SLorenzo Bianconi 
1744290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
1745290a6ce1SLorenzo Bianconi 	sensor->id = id;
1746290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
174740dd7343SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
1748640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
1749290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
1750290a6ce1SLorenzo Bianconi 
1751290a6ce1SLorenzo Bianconi 	switch (id) {
1752290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
1753290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
1754510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
1755510c0106SLorenzo Bianconi 			  name);
1756290a6ce1SLorenzo Bianconi 		break;
1757290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
1758290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
1759510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
1760510c0106SLorenzo Bianconi 			  name);
1761290a6ce1SLorenzo Bianconi 		break;
1762290a6ce1SLorenzo Bianconi 	default:
1763290a6ce1SLorenzo Bianconi 		return NULL;
1764290a6ce1SLorenzo Bianconi 	}
1765510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
1766290a6ce1SLorenzo Bianconi 
1767290a6ce1SLorenzo Bianconi 	return iio_dev;
1768290a6ce1SLorenzo Bianconi }
1769290a6ce1SLorenzo Bianconi 
1770615bd378SLorenzo Bianconi static bool
1771615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
17721aabad1fSSean Nyekjaer {
1773615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
1774615bd378SLorenzo Bianconi 	int err, data;
1775615bd378SLorenzo Bianconi 	s64 timestamp;
17761aabad1fSSean Nyekjaer 
1777615bd378SLorenzo Bianconi 	if (!hw->enable_event)
1778615bd378SLorenzo Bianconi 		return false;
1779615bd378SLorenzo Bianconi 
1780615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
1781615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
1782615bd378SLorenzo Bianconi 				     &data, sizeof(data));
1783615bd378SLorenzo Bianconi 	if (err < 0)
1784615bd378SLorenzo Bianconi 		return false;
1785615bd378SLorenzo Bianconi 
1786615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
17871aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
17881aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
17891aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
17901aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
17911aabad1fSSean Nyekjaer 						  0,
17921aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
17931aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
17941aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
17951aabad1fSSean Nyekjaer 						  timestamp);
17961aabad1fSSean Nyekjaer 
17971aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
17981aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
17991aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
18001aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
18011aabad1fSSean Nyekjaer 						  0,
18021aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
18031aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
18041aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
18051aabad1fSSean Nyekjaer 						  timestamp);
18061aabad1fSSean Nyekjaer 
18071aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
18081aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
18091aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
18101aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
18111aabad1fSSean Nyekjaer 						  0,
18121aabad1fSSean Nyekjaer 						  IIO_MOD_X,
18131aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
18141aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
18151aabad1fSSean Nyekjaer 						  timestamp);
1816615bd378SLorenzo Bianconi 
1817615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
18181aabad1fSSean Nyekjaer }
18191aabad1fSSean Nyekjaer 
18206ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
18216ee6a368SSean Nyekjaer {
18226ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
1823615bd378SLorenzo Bianconi 	bool event;
18246ee6a368SSean Nyekjaer 	int count;
18251aabad1fSSean Nyekjaer 
1826615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
18276ee6a368SSean Nyekjaer 
1828a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
1829a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
1830a912ee4cSLorenzo Bianconi 
18316ee6a368SSean Nyekjaer 	mutex_lock(&hw->fifo_lock);
18326ee6a368SSean Nyekjaer 	count = hw->settings->fifo_ops.read_fifo(hw);
18336ee6a368SSean Nyekjaer 	mutex_unlock(&hw->fifo_lock);
18346ee6a368SSean Nyekjaer 
1835615bd378SLorenzo Bianconi 	return count || event ? IRQ_HANDLED : IRQ_NONE;
18366ee6a368SSean Nyekjaer }
18376ee6a368SSean Nyekjaer 
18386ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
18396ee6a368SSean Nyekjaer {
18406ee6a368SSean Nyekjaer 	struct st_sensors_platform_data *pdata;
18416ee6a368SSean Nyekjaer 	struct device_node *np = hw->dev->of_node;
18426ee6a368SSean Nyekjaer 	unsigned long irq_type;
18436ee6a368SSean Nyekjaer 	bool irq_active_low;
18446ee6a368SSean Nyekjaer 	int err;
18456ee6a368SSean Nyekjaer 
18466ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
18476ee6a368SSean Nyekjaer 
18486ee6a368SSean Nyekjaer 	switch (irq_type) {
18496ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
18506ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
18516ee6a368SSean Nyekjaer 		irq_active_low = false;
18526ee6a368SSean Nyekjaer 		break;
18536ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
18546ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
18556ee6a368SSean Nyekjaer 		irq_active_low = true;
18566ee6a368SSean Nyekjaer 		break;
18576ee6a368SSean Nyekjaer 	default:
18586ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
18596ee6a368SSean Nyekjaer 		return -EINVAL;
18606ee6a368SSean Nyekjaer 	}
18616ee6a368SSean Nyekjaer 
18626ee6a368SSean Nyekjaer 	err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_HLACTIVE_ADDR,
18636ee6a368SSean Nyekjaer 				 ST_LSM6DSX_REG_HLACTIVE_MASK,
18646ee6a368SSean Nyekjaer 				 FIELD_PREP(ST_LSM6DSX_REG_HLACTIVE_MASK,
18656ee6a368SSean Nyekjaer 					    irq_active_low));
18666ee6a368SSean Nyekjaer 	if (err < 0)
18676ee6a368SSean Nyekjaer 		return err;
18686ee6a368SSean Nyekjaer 
18696ee6a368SSean Nyekjaer 	pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
18706ee6a368SSean Nyekjaer 	if ((np && of_property_read_bool(np, "drive-open-drain")) ||
18716ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
18726ee6a368SSean Nyekjaer 		err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_PP_OD_ADDR,
18736ee6a368SSean Nyekjaer 					 ST_LSM6DSX_REG_PP_OD_MASK,
18746ee6a368SSean Nyekjaer 					 FIELD_PREP(ST_LSM6DSX_REG_PP_OD_MASK,
18756ee6a368SSean Nyekjaer 						    1));
18766ee6a368SSean Nyekjaer 		if (err < 0)
18776ee6a368SSean Nyekjaer 			return err;
18786ee6a368SSean Nyekjaer 
18796ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
18806ee6a368SSean Nyekjaer 	}
18816ee6a368SSean Nyekjaer 
18826ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
1883a3aa17d4SSean Nyekjaer 					NULL,
18846ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
18856ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
18866ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
18876ee6a368SSean Nyekjaer 	if (err) {
18886ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
18896ee6a368SSean Nyekjaer 			hw->irq);
18906ee6a368SSean Nyekjaer 		return err;
18916ee6a368SSean Nyekjaer 	}
18926ee6a368SSean Nyekjaer 
18936ee6a368SSean Nyekjaer 	return 0;
18946ee6a368SSean Nyekjaer }
18956ee6a368SSean Nyekjaer 
189681956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
189751a8b707SLorenzo Bianconi 		     struct regmap *regmap)
1898290a6ce1SLorenzo Bianconi {
1899c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1900290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
190181956a93SLorenzo Bianconi 	const char *name = NULL;
1902290a6ce1SLorenzo Bianconi 	int i, err;
1903290a6ce1SLorenzo Bianconi 
1904290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
1905290a6ce1SLorenzo Bianconi 	if (!hw)
1906290a6ce1SLorenzo Bianconi 		return -ENOMEM;
1907290a6ce1SLorenzo Bianconi 
1908290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
1909290a6ce1SLorenzo Bianconi 
1910290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
1911335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
1912739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
1913290a6ce1SLorenzo Bianconi 
191491a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
191591a6b841SLorenzo Bianconi 	if (!hw->buff)
191691a6b841SLorenzo Bianconi 		return -ENOMEM;
191791a6b841SLorenzo Bianconi 
1918290a6ce1SLorenzo Bianconi 	hw->dev = dev;
1919290a6ce1SLorenzo Bianconi 	hw->irq = irq;
192051a8b707SLorenzo Bianconi 	hw->regmap = regmap;
1921290a6ce1SLorenzo Bianconi 
192281956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
1923290a6ce1SLorenzo Bianconi 	if (err < 0)
1924290a6ce1SLorenzo Bianconi 		return err;
1925290a6ce1SLorenzo Bianconi 
19266ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
1927510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
1928290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
1929290a6ce1SLorenzo Bianconi 			return -ENOMEM;
1930290a6ce1SLorenzo Bianconi 	}
1931290a6ce1SLorenzo Bianconi 
1932290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
1933290a6ce1SLorenzo Bianconi 	if (err < 0)
1934290a6ce1SLorenzo Bianconi 		return err;
1935290a6ce1SLorenzo Bianconi 
1936c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1937c91c1c84SLorenzo Bianconi 	if (hub_settings->master_en.addr) {
1938c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
1939c91c1c84SLorenzo Bianconi 		if (err < 0)
1940c91c1c84SLorenzo Bianconi 			return err;
1941c91c1c84SLorenzo Bianconi 	}
1942c91c1c84SLorenzo Bianconi 
1943290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
19446ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
19456ee6a368SSean Nyekjaer 		if (err < 0)
19466ee6a368SSean Nyekjaer 			return err;
19476ee6a368SSean Nyekjaer 
1948290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
1949290a6ce1SLorenzo Bianconi 		if (err < 0)
1950290a6ce1SLorenzo Bianconi 			return err;
1951290a6ce1SLorenzo Bianconi 	}
1952290a6ce1SLorenzo Bianconi 
1953290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
19546ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
19556ffb55e5SLorenzo Bianconi 			continue;
19566ffb55e5SLorenzo Bianconi 
1957290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
1958290a6ce1SLorenzo Bianconi 		if (err)
1959290a6ce1SLorenzo Bianconi 			return err;
1960290a6ce1SLorenzo Bianconi 	}
1961290a6ce1SLorenzo Bianconi 
19624c997dfaSSean Nyekjaer 	if (dev->of_node && of_property_read_bool(dev->of_node, "wakeup-source"))
19634c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
19644c997dfaSSean Nyekjaer 
1965290a6ce1SLorenzo Bianconi 	return 0;
1966290a6ce1SLorenzo Bianconi }
1967290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe);
1968290a6ce1SLorenzo Bianconi 
19693cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
1970d3f77058SLorenzo Bianconi {
1971d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
1972d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
1973d3f77058SLorenzo Bianconi 	int i, err = 0;
1974d3f77058SLorenzo Bianconi 
1975d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
19766ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
19776ffb55e5SLorenzo Bianconi 			continue;
19786ffb55e5SLorenzo Bianconi 
1979d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
1980d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
1981d3f77058SLorenzo Bianconi 			continue;
1982d3f77058SLorenzo Bianconi 
19834c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
19844c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
19854c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
19864c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
19874c997dfaSSean Nyekjaer 			continue;
19884c997dfaSSean Nyekjaer 		}
19894c997dfaSSean Nyekjaer 
1990bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
1991bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
1992bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
1993bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, false);
1994bce0d57dSLorenzo Bianconi 		else
1995bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, false);
1996d3f77058SLorenzo Bianconi 		if (err < 0)
1997d3f77058SLorenzo Bianconi 			return err;
1998bce0d57dSLorenzo Bianconi 
1999bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2000d3f77058SLorenzo Bianconi 	}
2001d3f77058SLorenzo Bianconi 
2002d3f77058SLorenzo Bianconi 	if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
2003d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2004d3f77058SLorenzo Bianconi 
2005d3f77058SLorenzo Bianconi 	return err;
2006d3f77058SLorenzo Bianconi }
2007d3f77058SLorenzo Bianconi 
20083cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
2009d3f77058SLorenzo Bianconi {
2010d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2011d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2012d3f77058SLorenzo Bianconi 	int i, err = 0;
2013d3f77058SLorenzo Bianconi 
2014d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
20156ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
20166ffb55e5SLorenzo Bianconi 			continue;
20176ffb55e5SLorenzo Bianconi 
2018d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
20194c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
20204c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
20214c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
20224c997dfaSSean Nyekjaer 
2023bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2024d3f77058SLorenzo Bianconi 			continue;
2025d3f77058SLorenzo Bianconi 
2026bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2027bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2028bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2029bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, true);
2030bce0d57dSLorenzo Bianconi 		else
2031bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, true);
2032d3f77058SLorenzo Bianconi 		if (err < 0)
2033d3f77058SLorenzo Bianconi 			return err;
2034bce0d57dSLorenzo Bianconi 
2035bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2036d3f77058SLorenzo Bianconi 	}
2037d3f77058SLorenzo Bianconi 
2038d3f77058SLorenzo Bianconi 	if (hw->enable_mask)
2039d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
2040d3f77058SLorenzo Bianconi 
2041d3f77058SLorenzo Bianconi 	return err;
2042d3f77058SLorenzo Bianconi }
2043d3f77058SLorenzo Bianconi 
2044d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = {
2045d3f77058SLorenzo Bianconi 	SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
2046d3f77058SLorenzo Bianconi };
2047d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
2048d3f77058SLorenzo Bianconi 
2049290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2050290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2051290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2052290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2053