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  *
29*4393e4c5SLorenzo Bianconi  * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX/LSM6DST:
308f9a5249SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416,
318f9a5249SLorenzo Bianconi  *     833
32801a6e0aSLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
33801a6e0aSLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
34801a6e0aSLorenzo Bianconi  *   - FIFO size: 3KB
35801a6e0aSLorenzo Bianconi  *
36fa060a3dSLorenzo Bianconi  * - LSM9DS1/LSM6DS0:
3752f4b1f1SMartin Kepplinger  *   - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
3852f4b1f1SMartin Kepplinger  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
3952f4b1f1SMartin Kepplinger  *   - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
4052f4b1f1SMartin Kepplinger  *   - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
4152f4b1f1SMartin Kepplinger  *   - FIFO size: 32
4252f4b1f1SMartin Kepplinger  *
43290a6ce1SLorenzo Bianconi  * Copyright 2016 STMicroelectronics Inc.
44290a6ce1SLorenzo Bianconi  *
45290a6ce1SLorenzo Bianconi  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
46290a6ce1SLorenzo Bianconi  * Denis Ciocca <denis.ciocca@st.com>
47290a6ce1SLorenzo Bianconi  */
48290a6ce1SLorenzo Bianconi 
49290a6ce1SLorenzo Bianconi #include <linux/kernel.h>
50290a6ce1SLorenzo Bianconi #include <linux/module.h>
51290a6ce1SLorenzo Bianconi #include <linux/delay.h>
521aabad1fSSean Nyekjaer #include <linux/iio/events.h>
53290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h>
54290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h>
556ee6a368SSean Nyekjaer #include <linux/interrupt.h>
566ee6a368SSean Nyekjaer #include <linux/irq.h>
57d3f77058SLorenzo Bianconi #include <linux/pm.h>
5803d4c566SAndy Shevchenko #include <linux/property.h>
5951a8b707SLorenzo Bianconi #include <linux/regmap.h>
6051a8b707SLorenzo Bianconi #include <linux/bitfield.h>
61290a6ce1SLorenzo Bianconi 
62dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h>
63dba32904SLorenzo Bianconi 
64290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h"
65290a6ce1SLorenzo Bianconi 
66290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
67290a6ce1SLorenzo Bianconi 
68cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
69cb3b6b8eSMario Tesi 
70f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
71b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
72b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
73b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
74f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
75f48bc49bSLorenzo Bianconi };
76f48bc49bSLorenzo Bianconi 
77f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
78f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
79f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
80f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
81f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
82f48bc49bSLorenzo Bianconi };
83f48bc49bSLorenzo Bianconi 
8452f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
8552f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
8652f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
8752f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
8852f4b1f1SMartin Kepplinger 	IIO_CHAN_SOFT_TIMESTAMP(3),
8952f4b1f1SMartin Kepplinger };
9052f4b1f1SMartin Kepplinger 
91290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
92290a6ce1SLorenzo Bianconi 	{
9352f4b1f1SMartin Kepplinger 		.wai = 0x68,
9466b662a1SLorenzo Bianconi 		.reset = {
9566b662a1SLorenzo Bianconi 			.addr = 0x22,
9666b662a1SLorenzo Bianconi 			.mask = BIT(0),
9766b662a1SLorenzo Bianconi 		},
9866b662a1SLorenzo Bianconi 		.boot = {
9966b662a1SLorenzo Bianconi 			.addr = 0x22,
10066b662a1SLorenzo Bianconi 			.mask = BIT(7),
10166b662a1SLorenzo Bianconi 		},
10266b662a1SLorenzo Bianconi 		.bdu = {
10366b662a1SLorenzo Bianconi 			.addr = 0x22,
10466b662a1SLorenzo Bianconi 			.mask = BIT(6),
10566b662a1SLorenzo Bianconi 		},
10652f4b1f1SMartin Kepplinger 		.max_fifo_size = 32,
10752f4b1f1SMartin Kepplinger 		.id = {
10852f4b1f1SMartin Kepplinger 			{
10952f4b1f1SMartin Kepplinger 				.hw_id = ST_LSM9DS1_ID,
11052f4b1f1SMartin Kepplinger 				.name = ST_LSM9DS1_DEV_NAME,
111fa060a3dSLorenzo Bianconi 			}, {
112fa060a3dSLorenzo Bianconi 				.hw_id = ST_LSM6DS0_ID,
113fa060a3dSLorenzo Bianconi 				.name = ST_LSM6DS0_DEV_NAME,
11452f4b1f1SMartin Kepplinger 			},
11552f4b1f1SMartin Kepplinger 		},
11652f4b1f1SMartin Kepplinger 		.channels = {
11752f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
11852f4b1f1SMartin Kepplinger 				.chan = st_lsm6dsx_acc_channels,
11952f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
12052f4b1f1SMartin Kepplinger 			},
12152f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
12252f4b1f1SMartin Kepplinger 				.chan = st_lsm6ds0_gyro_channels,
12352f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
12452f4b1f1SMartin Kepplinger 			},
12552f4b1f1SMartin Kepplinger 		},
12652f4b1f1SMartin Kepplinger 		.odr_table = {
12752f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
12852f4b1f1SMartin Kepplinger 				.reg = {
12952f4b1f1SMartin Kepplinger 					.addr = 0x20,
13052f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
13152f4b1f1SMartin Kepplinger 				},
132f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  10000, 0x01 },
133f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  50000, 0x02 },
134f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
135f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
136f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
137f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
13859af4e20SLorenzo Bianconi 				.odr_len = 6,
13952f4b1f1SMartin Kepplinger 			},
14052f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
14152f4b1f1SMartin Kepplinger 				.reg = {
14252f4b1f1SMartin Kepplinger 					.addr = 0x10,
14352f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
14452f4b1f1SMartin Kepplinger 				},
145f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  14900, 0x01 },
146f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  59500, 0x02 },
147f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
148f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
149f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
150f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
15159af4e20SLorenzo Bianconi 				.odr_len = 6,
15252f4b1f1SMartin Kepplinger 			},
15352f4b1f1SMartin Kepplinger 		},
15452f4b1f1SMartin Kepplinger 		.fs_table = {
15552f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
15652f4b1f1SMartin Kepplinger 				.reg = {
15752f4b1f1SMartin Kepplinger 					.addr = 0x20,
15852f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
15952f4b1f1SMartin Kepplinger 				},
16044a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
16144a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
16244a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
16344a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 },
16485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
16552f4b1f1SMartin Kepplinger 			},
16652f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
16752f4b1f1SMartin Kepplinger 				.reg = {
16852f4b1f1SMartin Kepplinger 					.addr = 0x10,
16952f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
17052f4b1f1SMartin Kepplinger 				},
1711b375101SLorenzo Bianconi 
17244a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
17344a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
17444a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
17585ae3aeeSLorenzo Bianconi 				.fs_len = 3,
17652f4b1f1SMartin Kepplinger 			},
17752f4b1f1SMartin Kepplinger 		},
1787e906103SLorenzo Bianconi 		.irq_config = {
1797e906103SLorenzo Bianconi 			.irq1 = {
1807e906103SLorenzo Bianconi 				.addr = 0x0c,
1817e906103SLorenzo Bianconi 				.mask = BIT(3),
1827e906103SLorenzo Bianconi 			},
1837e906103SLorenzo Bianconi 			.irq2 = {
1847e906103SLorenzo Bianconi 				.addr = 0x0d,
1857e906103SLorenzo Bianconi 				.mask = BIT(3),
1867e906103SLorenzo Bianconi 			},
18731fe8d4eSLorenzo Bianconi 			.hla = {
18831fe8d4eSLorenzo Bianconi 				.addr = 0x22,
18931fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
19031fe8d4eSLorenzo Bianconi 			},
19131fe8d4eSLorenzo Bianconi 			.od = {
19231fe8d4eSLorenzo Bianconi 				.addr = 0x22,
19331fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
19431fe8d4eSLorenzo Bianconi 			},
1957e906103SLorenzo Bianconi 		},
19652f4b1f1SMartin Kepplinger 	},
19752f4b1f1SMartin Kepplinger 	{
198d068e4a0SLorenzo Bianconi 		.wai = 0x69,
19966b662a1SLorenzo Bianconi 		.reset = {
20066b662a1SLorenzo Bianconi 			.addr = 0x12,
20166b662a1SLorenzo Bianconi 			.mask = BIT(0),
20266b662a1SLorenzo Bianconi 		},
20366b662a1SLorenzo Bianconi 		.boot = {
20466b662a1SLorenzo Bianconi 			.addr = 0x12,
20566b662a1SLorenzo Bianconi 			.mask = BIT(7),
20666b662a1SLorenzo Bianconi 		},
20766b662a1SLorenzo Bianconi 		.bdu = {
20866b662a1SLorenzo Bianconi 			.addr = 0x12,
20966b662a1SLorenzo Bianconi 			.mask = BIT(6),
21066b662a1SLorenzo Bianconi 		},
2118f2a88a2SLorenzo Bianconi 		.max_fifo_size = 1365,
212d068e4a0SLorenzo Bianconi 		.id = {
21381956a93SLorenzo Bianconi 			{
21481956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3_ID,
21581956a93SLorenzo Bianconi 				.name = ST_LSM6DS3_DEV_NAME,
21681956a93SLorenzo Bianconi 			},
217d068e4a0SLorenzo Bianconi 		},
218f48bc49bSLorenzo Bianconi 		.channels = {
219f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
220f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
221f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
222f48bc49bSLorenzo Bianconi 			},
223f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
224f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
225f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
226f48bc49bSLorenzo Bianconi 			},
227f48bc49bSLorenzo Bianconi 		},
22840dd7343SLorenzo Bianconi 		.odr_table = {
22940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
23040dd7343SLorenzo Bianconi 				.reg = {
23140dd7343SLorenzo Bianconi 					.addr = 0x10,
23240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
23340dd7343SLorenzo Bianconi 				},
234f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
235f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
236f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
237f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
238f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
239f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
24059af4e20SLorenzo Bianconi 				.odr_len = 6,
24140dd7343SLorenzo Bianconi 			},
24240dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
24340dd7343SLorenzo Bianconi 				.reg = {
24440dd7343SLorenzo Bianconi 					.addr = 0x11,
24540dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
24640dd7343SLorenzo Bianconi 				},
247f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
248f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
249f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
250f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
251f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
252f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
25359af4e20SLorenzo Bianconi 				.odr_len = 6,
25440dd7343SLorenzo Bianconi 			},
25540dd7343SLorenzo Bianconi 		},
256640aca3fSLorenzo Bianconi 		.fs_table = {
257640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
258640aca3fSLorenzo Bianconi 				.reg = {
259640aca3fSLorenzo Bianconi 					.addr = 0x10,
260640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
261640aca3fSLorenzo Bianconi 				},
26244a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
26344a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
26444a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
26544a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
26685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
267640aca3fSLorenzo Bianconi 			},
268640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
269640aca3fSLorenzo Bianconi 				.reg = {
270640aca3fSLorenzo Bianconi 					.addr = 0x11,
271640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
272640aca3fSLorenzo Bianconi 				},
27344a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
27444a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
27544a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
27644a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
27785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
278640aca3fSLorenzo Bianconi 			},
279640aca3fSLorenzo Bianconi 		},
2807e906103SLorenzo Bianconi 		.irq_config = {
2817e906103SLorenzo Bianconi 			.irq1 = {
2827e906103SLorenzo Bianconi 				.addr = 0x0d,
2837e906103SLorenzo Bianconi 				.mask = BIT(3),
2847e906103SLorenzo Bianconi 			},
2857e906103SLorenzo Bianconi 			.irq2 = {
2867e906103SLorenzo Bianconi 				.addr = 0x0e,
2877e906103SLorenzo Bianconi 				.mask = BIT(3),
2887e906103SLorenzo Bianconi 			},
2897e906103SLorenzo Bianconi 			.lir = {
2907e906103SLorenzo Bianconi 				.addr = 0x58,
2917e906103SLorenzo Bianconi 				.mask = BIT(0),
2927e906103SLorenzo Bianconi 			},
2937e906103SLorenzo Bianconi 			.irq1_func = {
2947e906103SLorenzo Bianconi 				.addr = 0x5e,
2957e906103SLorenzo Bianconi 				.mask = BIT(5),
2967e906103SLorenzo Bianconi 			},
2977e906103SLorenzo Bianconi 			.irq2_func = {
2987e906103SLorenzo Bianconi 				.addr = 0x5f,
2997e906103SLorenzo Bianconi 				.mask = BIT(5),
3007e906103SLorenzo Bianconi 			},
30131fe8d4eSLorenzo Bianconi 			.hla = {
30231fe8d4eSLorenzo Bianconi 				.addr = 0x12,
30331fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
30431fe8d4eSLorenzo Bianconi 			},
30531fe8d4eSLorenzo Bianconi 			.od = {
30631fe8d4eSLorenzo Bianconi 				.addr = 0x12,
30731fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
30831fe8d4eSLorenzo Bianconi 			},
3097e906103SLorenzo Bianconi 		},
3107ca3ac9eSLorenzo Bianconi 		.decimator = {
3117ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
3127ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3137ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
3147ca3ac9eSLorenzo Bianconi 			},
3157ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
3167ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3177ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
3187ca3ac9eSLorenzo Bianconi 			},
3197ca3ac9eSLorenzo Bianconi 		},
32092617c15SLorenzo Bianconi 		.fifo_ops = {
3213b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
32250ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
32392617c15SLorenzo Bianconi 			.fifo_th = {
32492617c15SLorenzo Bianconi 				.addr = 0x06,
32592617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
32692617c15SLorenzo Bianconi 			},
32792617c15SLorenzo Bianconi 			.fifo_diff = {
32892617c15SLorenzo Bianconi 				.addr = 0x3a,
32992617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
33092617c15SLorenzo Bianconi 			},
33192617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
33292617c15SLorenzo Bianconi 		},
33321345107SLorenzo Bianconi 		.ts_settings = {
33421345107SLorenzo Bianconi 			.timer_en = {
33521345107SLorenzo Bianconi 				.addr = 0x58,
33621345107SLorenzo Bianconi 				.mask = BIT(7),
33721345107SLorenzo Bianconi 			},
33821345107SLorenzo Bianconi 			.hr_timer = {
33921345107SLorenzo Bianconi 				.addr = 0x5c,
34021345107SLorenzo Bianconi 				.mask = BIT(4),
34121345107SLorenzo Bianconi 			},
34221345107SLorenzo Bianconi 			.fifo_en = {
34321345107SLorenzo Bianconi 				.addr = 0x07,
34421345107SLorenzo Bianconi 				.mask = BIT(7),
34521345107SLorenzo Bianconi 			},
34621345107SLorenzo Bianconi 			.decimator = {
34721345107SLorenzo Bianconi 				.addr = 0x09,
34821345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
34921345107SLorenzo Bianconi 			},
35021345107SLorenzo Bianconi 		},
351b5969abfSSean Nyekjaer 		.event_settings = {
352b5969abfSSean Nyekjaer 			.wakeup_reg = {
353b5969abfSSean Nyekjaer 				.addr = 0x5B,
354b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
355b5969abfSSean Nyekjaer 			},
3561aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
3571aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
3581aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
3591aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
3601aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
361b5969abfSSean Nyekjaer 		},
362290a6ce1SLorenzo Bianconi 	},
363290a6ce1SLorenzo Bianconi 	{
364df47710aSLorenzo Bianconi 		.wai = 0x69,
36566b662a1SLorenzo Bianconi 		.reset = {
36666b662a1SLorenzo Bianconi 			.addr = 0x12,
36766b662a1SLorenzo Bianconi 			.mask = BIT(0),
36866b662a1SLorenzo Bianconi 		},
36966b662a1SLorenzo Bianconi 		.boot = {
37066b662a1SLorenzo Bianconi 			.addr = 0x12,
37166b662a1SLorenzo Bianconi 			.mask = BIT(7),
37266b662a1SLorenzo Bianconi 		},
37366b662a1SLorenzo Bianconi 		.bdu = {
37466b662a1SLorenzo Bianconi 			.addr = 0x12,
37566b662a1SLorenzo Bianconi 			.mask = BIT(6),
37666b662a1SLorenzo Bianconi 		},
3778f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
378df47710aSLorenzo Bianconi 		.id = {
37981956a93SLorenzo Bianconi 			{
38081956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3H_ID,
38181956a93SLorenzo Bianconi 				.name = ST_LSM6DS3H_DEV_NAME,
38281956a93SLorenzo Bianconi 			},
383df47710aSLorenzo Bianconi 		},
384f48bc49bSLorenzo Bianconi 		.channels = {
385f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
386f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
387f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
388f48bc49bSLorenzo Bianconi 			},
389f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
390f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
391f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
392f48bc49bSLorenzo Bianconi 			},
393f48bc49bSLorenzo Bianconi 		},
39440dd7343SLorenzo Bianconi 		.odr_table = {
39540dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
39640dd7343SLorenzo Bianconi 				.reg = {
39740dd7343SLorenzo Bianconi 					.addr = 0x10,
39840dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
39940dd7343SLorenzo Bianconi 				},
400f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
401f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
402f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
403f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
404f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
405f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
40659af4e20SLorenzo Bianconi 				.odr_len = 6,
40740dd7343SLorenzo Bianconi 			},
40840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
40940dd7343SLorenzo Bianconi 				.reg = {
41040dd7343SLorenzo Bianconi 					.addr = 0x11,
41140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
41240dd7343SLorenzo Bianconi 				},
413f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
414f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
415f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
416f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
417f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
418f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
41959af4e20SLorenzo Bianconi 				.odr_len = 6,
42040dd7343SLorenzo Bianconi 			},
42140dd7343SLorenzo Bianconi 		},
422640aca3fSLorenzo Bianconi 		.fs_table = {
423640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
424640aca3fSLorenzo Bianconi 				.reg = {
425640aca3fSLorenzo Bianconi 					.addr = 0x10,
426640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
427640aca3fSLorenzo Bianconi 				},
42844a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
42944a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
43044a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
43144a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
43285ae3aeeSLorenzo Bianconi 				.fs_len = 4,
433640aca3fSLorenzo Bianconi 			},
434640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
435640aca3fSLorenzo Bianconi 				.reg = {
436640aca3fSLorenzo Bianconi 					.addr = 0x11,
437640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
438640aca3fSLorenzo Bianconi 				},
43944a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
44044a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
44144a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
44244a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
44385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
444640aca3fSLorenzo Bianconi 			},
445640aca3fSLorenzo Bianconi 		},
4467e906103SLorenzo Bianconi 		.irq_config = {
4477e906103SLorenzo Bianconi 			.irq1 = {
4487e906103SLorenzo Bianconi 				.addr = 0x0d,
4497e906103SLorenzo Bianconi 				.mask = BIT(3),
4507e906103SLorenzo Bianconi 			},
4517e906103SLorenzo Bianconi 			.irq2 = {
4527e906103SLorenzo Bianconi 				.addr = 0x0e,
4537e906103SLorenzo Bianconi 				.mask = BIT(3),
4547e906103SLorenzo Bianconi 			},
4557e906103SLorenzo Bianconi 			.lir = {
4567e906103SLorenzo Bianconi 				.addr = 0x58,
4577e906103SLorenzo Bianconi 				.mask = BIT(0),
4587e906103SLorenzo Bianconi 			},
4597e906103SLorenzo Bianconi 			.irq1_func = {
4607e906103SLorenzo Bianconi 				.addr = 0x5e,
4617e906103SLorenzo Bianconi 				.mask = BIT(5),
4627e906103SLorenzo Bianconi 			},
4637e906103SLorenzo Bianconi 			.irq2_func = {
4647e906103SLorenzo Bianconi 				.addr = 0x5f,
4657e906103SLorenzo Bianconi 				.mask = BIT(5),
4667e906103SLorenzo Bianconi 			},
46731fe8d4eSLorenzo Bianconi 			.hla = {
46831fe8d4eSLorenzo Bianconi 				.addr = 0x12,
46931fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
47031fe8d4eSLorenzo Bianconi 			},
47131fe8d4eSLorenzo Bianconi 			.od = {
47231fe8d4eSLorenzo Bianconi 				.addr = 0x12,
47331fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
47431fe8d4eSLorenzo Bianconi 			},
4757e906103SLorenzo Bianconi 		},
4767ca3ac9eSLorenzo Bianconi 		.decimator = {
4777ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
4787ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4797ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
4807ca3ac9eSLorenzo Bianconi 			},
4817ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
4827ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4837ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
4847ca3ac9eSLorenzo Bianconi 			},
4857ca3ac9eSLorenzo Bianconi 		},
48692617c15SLorenzo Bianconi 		.fifo_ops = {
4873b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
48850ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
48992617c15SLorenzo Bianconi 			.fifo_th = {
49092617c15SLorenzo Bianconi 				.addr = 0x06,
49192617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
49292617c15SLorenzo Bianconi 			},
49392617c15SLorenzo Bianconi 			.fifo_diff = {
49492617c15SLorenzo Bianconi 				.addr = 0x3a,
49592617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
49692617c15SLorenzo Bianconi 			},
49792617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
49892617c15SLorenzo Bianconi 		},
49921345107SLorenzo Bianconi 		.ts_settings = {
50021345107SLorenzo Bianconi 			.timer_en = {
50121345107SLorenzo Bianconi 				.addr = 0x58,
50221345107SLorenzo Bianconi 				.mask = BIT(7),
50321345107SLorenzo Bianconi 			},
50421345107SLorenzo Bianconi 			.hr_timer = {
50521345107SLorenzo Bianconi 				.addr = 0x5c,
50621345107SLorenzo Bianconi 				.mask = BIT(4),
50721345107SLorenzo Bianconi 			},
50821345107SLorenzo Bianconi 			.fifo_en = {
50921345107SLorenzo Bianconi 				.addr = 0x07,
51021345107SLorenzo Bianconi 				.mask = BIT(7),
51121345107SLorenzo Bianconi 			},
51221345107SLorenzo Bianconi 			.decimator = {
51321345107SLorenzo Bianconi 				.addr = 0x09,
51421345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
51521345107SLorenzo Bianconi 			},
51621345107SLorenzo Bianconi 		},
517b5969abfSSean Nyekjaer 		.event_settings = {
518b5969abfSSean Nyekjaer 			.wakeup_reg = {
519b5969abfSSean Nyekjaer 				.addr = 0x5B,
520b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
521b5969abfSSean Nyekjaer 			},
5221aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
5231aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
5241aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
5251aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
5261aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
527b5969abfSSean Nyekjaer 		},
528df47710aSLorenzo Bianconi 	},
529df47710aSLorenzo Bianconi 	{
530d068e4a0SLorenzo Bianconi 		.wai = 0x6a,
53166b662a1SLorenzo Bianconi 		.reset = {
53266b662a1SLorenzo Bianconi 			.addr = 0x12,
53366b662a1SLorenzo Bianconi 			.mask = BIT(0),
53466b662a1SLorenzo Bianconi 		},
53566b662a1SLorenzo Bianconi 		.boot = {
53666b662a1SLorenzo Bianconi 			.addr = 0x12,
53766b662a1SLorenzo Bianconi 			.mask = BIT(7),
53866b662a1SLorenzo Bianconi 		},
53966b662a1SLorenzo Bianconi 		.bdu = {
54066b662a1SLorenzo Bianconi 			.addr = 0x12,
54166b662a1SLorenzo Bianconi 			.mask = BIT(6),
54266b662a1SLorenzo Bianconi 		},
5438f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
544d068e4a0SLorenzo Bianconi 		.id = {
54581956a93SLorenzo Bianconi 			{
54681956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSL_ID,
54781956a93SLorenzo Bianconi 				.name = ST_LSM6DSL_DEV_NAME,
54881956a93SLorenzo Bianconi 			}, {
54981956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSM_ID,
55081956a93SLorenzo Bianconi 				.name = ST_LSM6DSM_DEV_NAME,
55181956a93SLorenzo Bianconi 			}, {
55281956a93SLorenzo Bianconi 				.hw_id = ST_ISM330DLC_ID,
55381956a93SLorenzo Bianconi 				.name = ST_ISM330DLC_DEV_NAME,
554dbcd2088SLorenzo Bianconi 			}, {
555dbcd2088SLorenzo Bianconi 				.hw_id = ST_LSM6DS3TRC_ID,
556dbcd2088SLorenzo Bianconi 				.name = ST_LSM6DS3TRC_DEV_NAME,
55781956a93SLorenzo Bianconi 			},
558d068e4a0SLorenzo Bianconi 		},
559f48bc49bSLorenzo Bianconi 		.channels = {
560f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
561f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
562f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
563f48bc49bSLorenzo Bianconi 			},
564f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
565f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
566f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
567f48bc49bSLorenzo Bianconi 			},
568f48bc49bSLorenzo Bianconi 		},
56940dd7343SLorenzo Bianconi 		.odr_table = {
57040dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
57140dd7343SLorenzo Bianconi 				.reg = {
57240dd7343SLorenzo Bianconi 					.addr = 0x10,
57340dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
57440dd7343SLorenzo Bianconi 				},
575f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
576f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
577f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
578f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
579f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
580f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
58159af4e20SLorenzo Bianconi 				.odr_len = 6,
58240dd7343SLorenzo Bianconi 			},
58340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
58440dd7343SLorenzo Bianconi 				.reg = {
58540dd7343SLorenzo Bianconi 					.addr = 0x11,
58640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
58740dd7343SLorenzo Bianconi 				},
588f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
589f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
590f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
591f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
592f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
593f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
59459af4e20SLorenzo Bianconi 				.odr_len = 6,
59540dd7343SLorenzo Bianconi 			},
59640dd7343SLorenzo Bianconi 		},
597640aca3fSLorenzo Bianconi 		.fs_table = {
598640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
599640aca3fSLorenzo Bianconi 				.reg = {
600640aca3fSLorenzo Bianconi 					.addr = 0x10,
601640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
602640aca3fSLorenzo Bianconi 				},
60344a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
60444a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
60544a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
60644a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
60785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
608640aca3fSLorenzo Bianconi 			},
609640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
610640aca3fSLorenzo Bianconi 				.reg = {
611640aca3fSLorenzo Bianconi 					.addr = 0x11,
612640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
613640aca3fSLorenzo Bianconi 				},
61444a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
61544a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
61644a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
61744a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
61885ae3aeeSLorenzo Bianconi 				.fs_len = 4,
619640aca3fSLorenzo Bianconi 			},
620640aca3fSLorenzo Bianconi 		},
6217e906103SLorenzo Bianconi 		.irq_config = {
6227e906103SLorenzo Bianconi 			.irq1 = {
6237e906103SLorenzo Bianconi 				.addr = 0x0d,
6247e906103SLorenzo Bianconi 				.mask = BIT(3),
6257e906103SLorenzo Bianconi 			},
6267e906103SLorenzo Bianconi 			.irq2 = {
6277e906103SLorenzo Bianconi 				.addr = 0x0e,
6287e906103SLorenzo Bianconi 				.mask = BIT(3),
6297e906103SLorenzo Bianconi 			},
6307e906103SLorenzo Bianconi 			.lir = {
6317e906103SLorenzo Bianconi 				.addr = 0x58,
6327e906103SLorenzo Bianconi 				.mask = BIT(0),
6337e906103SLorenzo Bianconi 			},
6347e906103SLorenzo Bianconi 			.irq1_func = {
6357e906103SLorenzo Bianconi 				.addr = 0x5e,
6367e906103SLorenzo Bianconi 				.mask = BIT(5),
6377e906103SLorenzo Bianconi 			},
6387e906103SLorenzo Bianconi 			.irq2_func = {
6397e906103SLorenzo Bianconi 				.addr = 0x5f,
6407e906103SLorenzo Bianconi 				.mask = BIT(5),
6417e906103SLorenzo Bianconi 			},
64231fe8d4eSLorenzo Bianconi 			.hla = {
64331fe8d4eSLorenzo Bianconi 				.addr = 0x12,
64431fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
64531fe8d4eSLorenzo Bianconi 			},
64631fe8d4eSLorenzo Bianconi 			.od = {
64731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
64831fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
64931fe8d4eSLorenzo Bianconi 			},
6507e906103SLorenzo Bianconi 		},
6517ca3ac9eSLorenzo Bianconi 		.decimator = {
6527ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
6537ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6547ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
6557ca3ac9eSLorenzo Bianconi 			},
6567ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
6577ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6587ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
6597ca3ac9eSLorenzo Bianconi 			},
660e485e2a2SLorenzo Bianconi 			[ST_LSM6DSX_ID_EXT0] = {
661e485e2a2SLorenzo Bianconi 				.addr = 0x09,
662e485e2a2SLorenzo Bianconi 				.mask = GENMASK(2, 0),
663e485e2a2SLorenzo Bianconi 			},
6647ca3ac9eSLorenzo Bianconi 		},
66592617c15SLorenzo Bianconi 		.fifo_ops = {
6663b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
66750ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
66892617c15SLorenzo Bianconi 			.fifo_th = {
66992617c15SLorenzo Bianconi 				.addr = 0x06,
670be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
67192617c15SLorenzo Bianconi 			},
67292617c15SLorenzo Bianconi 			.fifo_diff = {
67392617c15SLorenzo Bianconi 				.addr = 0x3a,
674be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
67592617c15SLorenzo Bianconi 			},
67692617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
67792617c15SLorenzo Bianconi 		},
67821345107SLorenzo Bianconi 		.ts_settings = {
67921345107SLorenzo Bianconi 			.timer_en = {
68021345107SLorenzo Bianconi 				.addr = 0x19,
68121345107SLorenzo Bianconi 				.mask = BIT(5),
68221345107SLorenzo Bianconi 			},
68321345107SLorenzo Bianconi 			.hr_timer = {
68421345107SLorenzo Bianconi 				.addr = 0x5c,
68521345107SLorenzo Bianconi 				.mask = BIT(4),
68621345107SLorenzo Bianconi 			},
68721345107SLorenzo Bianconi 			.fifo_en = {
68821345107SLorenzo Bianconi 				.addr = 0x07,
68921345107SLorenzo Bianconi 				.mask = BIT(7),
69021345107SLorenzo Bianconi 			},
69121345107SLorenzo Bianconi 			.decimator = {
69221345107SLorenzo Bianconi 				.addr = 0x09,
69321345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
69421345107SLorenzo Bianconi 			},
69521345107SLorenzo Bianconi 		},
696e485e2a2SLorenzo Bianconi 		.shub_settings = {
697e485e2a2SLorenzo Bianconi 			.page_mux = {
698e485e2a2SLorenzo Bianconi 				.addr = 0x01,
699e485e2a2SLorenzo Bianconi 				.mask = BIT(7),
700e485e2a2SLorenzo Bianconi 			},
701e485e2a2SLorenzo Bianconi 			.master_en = {
702e485e2a2SLorenzo Bianconi 				.addr = 0x1a,
703e485e2a2SLorenzo Bianconi 				.mask = BIT(0),
704e485e2a2SLorenzo Bianconi 			},
705e485e2a2SLorenzo Bianconi 			.pullup_en = {
706e485e2a2SLorenzo Bianconi 				.addr = 0x1a,
707e485e2a2SLorenzo Bianconi 				.mask = BIT(3),
708e485e2a2SLorenzo Bianconi 			},
709e485e2a2SLorenzo Bianconi 			.aux_sens = {
710e485e2a2SLorenzo Bianconi 				.addr = 0x04,
711e485e2a2SLorenzo Bianconi 				.mask = GENMASK(5, 4),
712e485e2a2SLorenzo Bianconi 			},
713e485e2a2SLorenzo Bianconi 			.wr_once = {
714e485e2a2SLorenzo Bianconi 				.addr = 0x07,
715e485e2a2SLorenzo Bianconi 				.mask = BIT(5),
716e485e2a2SLorenzo Bianconi 			},
717e485e2a2SLorenzo Bianconi 			.emb_func = {
718e485e2a2SLorenzo Bianconi 				.addr = 0x19,
719e485e2a2SLorenzo Bianconi 				.mask = BIT(2),
720e485e2a2SLorenzo Bianconi 			},
721e485e2a2SLorenzo Bianconi 			.num_ext_dev = 1,
722e485e2a2SLorenzo Bianconi 			.shub_out = {
723e485e2a2SLorenzo Bianconi 				.addr = 0x2e,
724e485e2a2SLorenzo Bianconi 			},
725e485e2a2SLorenzo Bianconi 			.slv0_addr = 0x02,
726e485e2a2SLorenzo Bianconi 			.dw_slv0_addr = 0x0e,
727e485e2a2SLorenzo Bianconi 			.pause = 0x7,
728e485e2a2SLorenzo Bianconi 		},
729b5969abfSSean Nyekjaer 		.event_settings = {
730b5969abfSSean Nyekjaer 			.enable_reg = {
731b5969abfSSean Nyekjaer 				.addr = 0x58,
732b5969abfSSean Nyekjaer 				.mask = BIT(7),
733b5969abfSSean Nyekjaer 			},
734b5969abfSSean Nyekjaer 			.wakeup_reg = {
735b5969abfSSean Nyekjaer 				.addr = 0x5B,
736b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
737b5969abfSSean Nyekjaer 			},
7381aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
7391aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
7401aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
7411aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
7421aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
743b5969abfSSean Nyekjaer 		},
744290a6ce1SLorenzo Bianconi 	},
745801a6e0aSLorenzo Bianconi 	{
746801a6e0aSLorenzo Bianconi 		.wai = 0x6c,
74766b662a1SLorenzo Bianconi 		.reset = {
74866b662a1SLorenzo Bianconi 			.addr = 0x12,
74966b662a1SLorenzo Bianconi 			.mask = BIT(0),
75066b662a1SLorenzo Bianconi 		},
75166b662a1SLorenzo Bianconi 		.boot = {
75266b662a1SLorenzo Bianconi 			.addr = 0x12,
75366b662a1SLorenzo Bianconi 			.mask = BIT(7),
75466b662a1SLorenzo Bianconi 		},
75566b662a1SLorenzo Bianconi 		.bdu = {
75666b662a1SLorenzo Bianconi 			.addr = 0x12,
75766b662a1SLorenzo Bianconi 			.mask = BIT(6),
75866b662a1SLorenzo Bianconi 		},
759801a6e0aSLorenzo Bianconi 		.max_fifo_size = 512,
760801a6e0aSLorenzo Bianconi 		.id = {
76181956a93SLorenzo Bianconi 			{
76281956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSO_ID,
76381956a93SLorenzo Bianconi 				.name = ST_LSM6DSO_DEV_NAME,
76481956a93SLorenzo Bianconi 			}, {
76581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSOX_ID,
76681956a93SLorenzo Bianconi 				.name = ST_LSM6DSOX_DEV_NAME,
76781956a93SLorenzo Bianconi 			},
768801a6e0aSLorenzo Bianconi 		},
769f48bc49bSLorenzo Bianconi 		.channels = {
770f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
771f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
772f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
773f48bc49bSLorenzo Bianconi 			},
774f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
775f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
776f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
777f48bc49bSLorenzo Bianconi 			},
778f48bc49bSLorenzo Bianconi 		},
779960506edSLorenzo Bianconi 		.drdy_mask = {
780960506edSLorenzo Bianconi 			.addr = 0x13,
781960506edSLorenzo Bianconi 			.mask = BIT(3),
782960506edSLorenzo Bianconi 		},
78340dd7343SLorenzo Bianconi 		.odr_table = {
78440dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
78540dd7343SLorenzo Bianconi 				.reg = {
78640dd7343SLorenzo Bianconi 					.addr = 0x10,
78740dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
78840dd7343SLorenzo Bianconi 				},
789f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
790f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
791f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
792f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
793f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
794f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
7958f9a5249SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
7968f9a5249SLorenzo Bianconi 				.odr_len = 7,
79740dd7343SLorenzo Bianconi 			},
79840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
79940dd7343SLorenzo Bianconi 				.reg = {
80040dd7343SLorenzo Bianconi 					.addr = 0x11,
80140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
80240dd7343SLorenzo Bianconi 				},
803f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
804f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
805f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
806f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
807f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
808f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
8098f9a5249SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
8108f9a5249SLorenzo Bianconi 				.odr_len = 7,
81140dd7343SLorenzo Bianconi 			},
81240dd7343SLorenzo Bianconi 		},
813640aca3fSLorenzo Bianconi 		.fs_table = {
814640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
815640aca3fSLorenzo Bianconi 				.reg = {
816640aca3fSLorenzo Bianconi 					.addr = 0x10,
817640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
818640aca3fSLorenzo Bianconi 				},
81944a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
82044a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
82144a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
82244a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
82385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
824640aca3fSLorenzo Bianconi 			},
825640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
826640aca3fSLorenzo Bianconi 				.reg = {
827640aca3fSLorenzo Bianconi 					.addr = 0x11,
828640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
829640aca3fSLorenzo Bianconi 				},
83044a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
83144a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
83244a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
83344a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
83485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
835640aca3fSLorenzo Bianconi 			},
836640aca3fSLorenzo Bianconi 		},
8377e906103SLorenzo Bianconi 		.irq_config = {
8387e906103SLorenzo Bianconi 			.irq1 = {
8397e906103SLorenzo Bianconi 				.addr = 0x0d,
8407e906103SLorenzo Bianconi 				.mask = BIT(3),
8417e906103SLorenzo Bianconi 			},
8427e906103SLorenzo Bianconi 			.irq2 = {
8437e906103SLorenzo Bianconi 				.addr = 0x0e,
8447e906103SLorenzo Bianconi 				.mask = BIT(3),
8457e906103SLorenzo Bianconi 			},
8467e906103SLorenzo Bianconi 			.lir = {
8477e906103SLorenzo Bianconi 				.addr = 0x56,
8487e906103SLorenzo Bianconi 				.mask = BIT(0),
8497e906103SLorenzo Bianconi 			},
8507e906103SLorenzo Bianconi 			.clear_on_read = {
8517e906103SLorenzo Bianconi 				.addr = 0x56,
8527e906103SLorenzo Bianconi 				.mask = BIT(6),
8537e906103SLorenzo Bianconi 			},
8543ea39d61SLorenzo Bianconi 			.irq1_func = {
8553ea39d61SLorenzo Bianconi 				.addr = 0x5e,
8563ea39d61SLorenzo Bianconi 				.mask = BIT(5),
8573ea39d61SLorenzo Bianconi 			},
8583ea39d61SLorenzo Bianconi 			.irq2_func = {
8593ea39d61SLorenzo Bianconi 				.addr = 0x5f,
8603ea39d61SLorenzo Bianconi 				.mask = BIT(5),
8613ea39d61SLorenzo Bianconi 			},
86231fe8d4eSLorenzo Bianconi 			.hla = {
86331fe8d4eSLorenzo Bianconi 				.addr = 0x12,
86431fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
86531fe8d4eSLorenzo Bianconi 			},
86631fe8d4eSLorenzo Bianconi 			.od = {
86731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
86831fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
86931fe8d4eSLorenzo Bianconi 			},
8707e906103SLorenzo Bianconi 		},
871801a6e0aSLorenzo Bianconi 		.batch = {
872801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
873801a6e0aSLorenzo Bianconi 				.addr = 0x09,
874801a6e0aSLorenzo Bianconi 				.mask = GENMASK(3, 0),
875801a6e0aSLorenzo Bianconi 			},
876801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
877801a6e0aSLorenzo Bianconi 				.addr = 0x09,
878801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 4),
879801a6e0aSLorenzo Bianconi 			},
880801a6e0aSLorenzo Bianconi 		},
881801a6e0aSLorenzo Bianconi 		.fifo_ops = {
8823b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
883801a6e0aSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
884801a6e0aSLorenzo Bianconi 			.fifo_th = {
885801a6e0aSLorenzo Bianconi 				.addr = 0x07,
886801a6e0aSLorenzo Bianconi 				.mask = GENMASK(8, 0),
887801a6e0aSLorenzo Bianconi 			},
888801a6e0aSLorenzo Bianconi 			.fifo_diff = {
889801a6e0aSLorenzo Bianconi 				.addr = 0x3a,
89070575abeSmario tesi 				.mask = GENMASK(9, 0),
891801a6e0aSLorenzo Bianconi 			},
892801a6e0aSLorenzo Bianconi 			.th_wl = 1,
893801a6e0aSLorenzo Bianconi 		},
894801a6e0aSLorenzo Bianconi 		.ts_settings = {
895801a6e0aSLorenzo Bianconi 			.timer_en = {
896801a6e0aSLorenzo Bianconi 				.addr = 0x19,
897801a6e0aSLorenzo Bianconi 				.mask = BIT(5),
898801a6e0aSLorenzo Bianconi 			},
899801a6e0aSLorenzo Bianconi 			.decimator = {
900801a6e0aSLorenzo Bianconi 				.addr = 0x0a,
901801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 6),
902801a6e0aSLorenzo Bianconi 			},
903cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
904801a6e0aSLorenzo Bianconi 		},
905c91c1c84SLorenzo Bianconi 		.shub_settings = {
906c91c1c84SLorenzo Bianconi 			.page_mux = {
907c91c1c84SLorenzo Bianconi 				.addr = 0x01,
908c91c1c84SLorenzo Bianconi 				.mask = BIT(6),
909c91c1c84SLorenzo Bianconi 			},
910c91c1c84SLorenzo Bianconi 			.master_en = {
911007f2ebbSLorenzo Bianconi 				.sec_page = true,
912c91c1c84SLorenzo Bianconi 				.addr = 0x14,
913c91c1c84SLorenzo Bianconi 				.mask = BIT(2),
914c91c1c84SLorenzo Bianconi 			},
915c91c1c84SLorenzo Bianconi 			.pullup_en = {
9163a431957SLorenzo Bianconi 				.sec_page = true,
917c91c1c84SLorenzo Bianconi 				.addr = 0x14,
918c91c1c84SLorenzo Bianconi 				.mask = BIT(3),
919c91c1c84SLorenzo Bianconi 			},
920c91c1c84SLorenzo Bianconi 			.aux_sens = {
921c91c1c84SLorenzo Bianconi 				.addr = 0x14,
922c91c1c84SLorenzo Bianconi 				.mask = GENMASK(1, 0),
923c91c1c84SLorenzo Bianconi 			},
9246d0205fdSLorenzo Bianconi 			.wr_once = {
9256d0205fdSLorenzo Bianconi 				.addr = 0x14,
9266d0205fdSLorenzo Bianconi 				.mask = BIT(6),
9276d0205fdSLorenzo Bianconi 			},
928ee978bb8SLorenzo Bianconi 			.num_ext_dev = 3,
9295b8343e0SLorenzo Bianconi 			.shub_out = {
9305b8343e0SLorenzo Bianconi 				.sec_page = true,
9315b8343e0SLorenzo Bianconi 				.addr = 0x02,
9325b8343e0SLorenzo Bianconi 			},
933c91c1c84SLorenzo Bianconi 			.slv0_addr = 0x15,
934c91c1c84SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
9356d0205fdSLorenzo Bianconi 			.batch_en = BIT(3),
9363ea39d61SLorenzo Bianconi 		},
9373ea39d61SLorenzo Bianconi 		.event_settings = {
9383ea39d61SLorenzo Bianconi 			.enable_reg = {
9393ea39d61SLorenzo Bianconi 				.addr = 0x58,
9403ea39d61SLorenzo Bianconi 				.mask = BIT(7),
9413ea39d61SLorenzo Bianconi 			},
9423ea39d61SLorenzo Bianconi 			.wakeup_reg = {
9433ea39d61SLorenzo Bianconi 				.addr = 0x5b,
9443ea39d61SLorenzo Bianconi 				.mask = GENMASK(5, 0),
9453ea39d61SLorenzo Bianconi 			},
9463ea39d61SLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
9473ea39d61SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
9483ea39d61SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
9493ea39d61SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
9503ea39d61SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
9513ea39d61SLorenzo Bianconi 		},
952801a6e0aSLorenzo Bianconi 	},
9533054c4ffSLorenzo Bianconi 	{
9543054c4ffSLorenzo Bianconi 		.wai = 0x6b,
95566b662a1SLorenzo Bianconi 		.reset = {
95666b662a1SLorenzo Bianconi 			.addr = 0x12,
95766b662a1SLorenzo Bianconi 			.mask = BIT(0),
95866b662a1SLorenzo Bianconi 		},
95966b662a1SLorenzo Bianconi 		.boot = {
96066b662a1SLorenzo Bianconi 			.addr = 0x12,
96166b662a1SLorenzo Bianconi 			.mask = BIT(7),
96266b662a1SLorenzo Bianconi 		},
96366b662a1SLorenzo Bianconi 		.bdu = {
96466b662a1SLorenzo Bianconi 			.addr = 0x12,
96566b662a1SLorenzo Bianconi 			.mask = BIT(6),
96666b662a1SLorenzo Bianconi 		},
9673054c4ffSLorenzo Bianconi 		.max_fifo_size = 512,
9683054c4ffSLorenzo Bianconi 		.id = {
96981956a93SLorenzo Bianconi 			{
97081956a93SLorenzo Bianconi 				.hw_id = ST_ASM330LHH_ID,
97181956a93SLorenzo Bianconi 				.name = ST_ASM330LHH_DEV_NAME,
97281956a93SLorenzo Bianconi 			},
9733054c4ffSLorenzo Bianconi 		},
974f48bc49bSLorenzo Bianconi 		.channels = {
975f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
976f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
977f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
978f48bc49bSLorenzo Bianconi 			},
979f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
980f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
981f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
982f48bc49bSLorenzo Bianconi 			},
983f48bc49bSLorenzo Bianconi 		},
984960506edSLorenzo Bianconi 		.drdy_mask = {
985960506edSLorenzo Bianconi 			.addr = 0x13,
986960506edSLorenzo Bianconi 			.mask = BIT(3),
987960506edSLorenzo Bianconi 		},
98840dd7343SLorenzo Bianconi 		.odr_table = {
98940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
99040dd7343SLorenzo Bianconi 				.reg = {
99140dd7343SLorenzo Bianconi 					.addr = 0x10,
99240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
99340dd7343SLorenzo Bianconi 				},
994f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
995f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
996f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
997f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
998f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
999f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
10008f9a5249SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
10018f9a5249SLorenzo Bianconi 				.odr_len = 7,
100240dd7343SLorenzo Bianconi 			},
100340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
100440dd7343SLorenzo Bianconi 				.reg = {
100540dd7343SLorenzo Bianconi 					.addr = 0x11,
100640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
100740dd7343SLorenzo Bianconi 				},
1008f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1009f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1010f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1011f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1012f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1013f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
10148f9a5249SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
10158f9a5249SLorenzo Bianconi 				.odr_len = 7,
101640dd7343SLorenzo Bianconi 			},
101740dd7343SLorenzo Bianconi 		},
1018640aca3fSLorenzo Bianconi 		.fs_table = {
1019640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1020640aca3fSLorenzo Bianconi 				.reg = {
1021640aca3fSLorenzo Bianconi 					.addr = 0x10,
1022640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1023640aca3fSLorenzo Bianconi 				},
102444a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
102544a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
102644a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
102744a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
102885ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1029640aca3fSLorenzo Bianconi 			},
1030640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1031640aca3fSLorenzo Bianconi 				.reg = {
1032640aca3fSLorenzo Bianconi 					.addr = 0x11,
1033640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1034640aca3fSLorenzo Bianconi 				},
103544a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
103644a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
103744a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
103844a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
103985ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1040640aca3fSLorenzo Bianconi 			},
1041640aca3fSLorenzo Bianconi 		},
10427e906103SLorenzo Bianconi 		.irq_config = {
10437e906103SLorenzo Bianconi 			.irq1 = {
10447e906103SLorenzo Bianconi 				.addr = 0x0d,
10457e906103SLorenzo Bianconi 				.mask = BIT(3),
10467e906103SLorenzo Bianconi 			},
10477e906103SLorenzo Bianconi 			.irq2 = {
10487e906103SLorenzo Bianconi 				.addr = 0x0e,
10497e906103SLorenzo Bianconi 				.mask = BIT(3),
10507e906103SLorenzo Bianconi 			},
10517e906103SLorenzo Bianconi 			.lir = {
10527e906103SLorenzo Bianconi 				.addr = 0x56,
10537e906103SLorenzo Bianconi 				.mask = BIT(0),
10547e906103SLorenzo Bianconi 			},
10557e906103SLorenzo Bianconi 			.clear_on_read = {
10567e906103SLorenzo Bianconi 				.addr = 0x56,
10577e906103SLorenzo Bianconi 				.mask = BIT(6),
10587e906103SLorenzo Bianconi 			},
10597e906103SLorenzo Bianconi 			.irq1_func = {
10607e906103SLorenzo Bianconi 				.addr = 0x5e,
10617e906103SLorenzo Bianconi 				.mask = BIT(5),
10627e906103SLorenzo Bianconi 			},
10637e906103SLorenzo Bianconi 			.irq2_func = {
10647e906103SLorenzo Bianconi 				.addr = 0x5f,
10657e906103SLorenzo Bianconi 				.mask = BIT(5),
10667e906103SLorenzo Bianconi 			},
106731fe8d4eSLorenzo Bianconi 			.hla = {
106831fe8d4eSLorenzo Bianconi 				.addr = 0x12,
106931fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
107031fe8d4eSLorenzo Bianconi 			},
107131fe8d4eSLorenzo Bianconi 			.od = {
107231fe8d4eSLorenzo Bianconi 				.addr = 0x12,
107331fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
107431fe8d4eSLorenzo Bianconi 			},
10757e906103SLorenzo Bianconi 		},
10763054c4ffSLorenzo Bianconi 		.batch = {
10773054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
10783054c4ffSLorenzo Bianconi 				.addr = 0x09,
10793054c4ffSLorenzo Bianconi 				.mask = GENMASK(3, 0),
10803054c4ffSLorenzo Bianconi 			},
10813054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
10823054c4ffSLorenzo Bianconi 				.addr = 0x09,
10833054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 4),
10843054c4ffSLorenzo Bianconi 			},
10853054c4ffSLorenzo Bianconi 		},
10863054c4ffSLorenzo Bianconi 		.fifo_ops = {
10873b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
10883054c4ffSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
10893054c4ffSLorenzo Bianconi 			.fifo_th = {
10903054c4ffSLorenzo Bianconi 				.addr = 0x07,
10913054c4ffSLorenzo Bianconi 				.mask = GENMASK(8, 0),
10923054c4ffSLorenzo Bianconi 			},
10933054c4ffSLorenzo Bianconi 			.fifo_diff = {
10943054c4ffSLorenzo Bianconi 				.addr = 0x3a,
109570575abeSmario tesi 				.mask = GENMASK(9, 0),
10963054c4ffSLorenzo Bianconi 			},
10973054c4ffSLorenzo Bianconi 			.th_wl = 1,
10983054c4ffSLorenzo Bianconi 		},
10993054c4ffSLorenzo Bianconi 		.ts_settings = {
11003054c4ffSLorenzo Bianconi 			.timer_en = {
11013054c4ffSLorenzo Bianconi 				.addr = 0x19,
11023054c4ffSLorenzo Bianconi 				.mask = BIT(5),
11033054c4ffSLorenzo Bianconi 			},
11043054c4ffSLorenzo Bianconi 			.decimator = {
11053054c4ffSLorenzo Bianconi 				.addr = 0x0a,
11063054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 6),
11073054c4ffSLorenzo Bianconi 			},
1108cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
11093054c4ffSLorenzo Bianconi 		},
1110b5969abfSSean Nyekjaer 		.event_settings = {
1111b5969abfSSean Nyekjaer 			.enable_reg = {
1112b5969abfSSean Nyekjaer 				.addr = 0x58,
1113b5969abfSSean Nyekjaer 				.mask = BIT(7),
1114b5969abfSSean Nyekjaer 			},
1115b5969abfSSean Nyekjaer 			.wakeup_reg = {
1116b5969abfSSean Nyekjaer 				.addr = 0x5B,
1117b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1118b5969abfSSean Nyekjaer 			},
11191aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
11201aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
11211aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
11221aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
11231aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
1124b5969abfSSean Nyekjaer 		},
11253054c4ffSLorenzo Bianconi 	},
112643901008SLorenzo Bianconi 	{
112743901008SLorenzo Bianconi 		.wai = 0x6b,
112866b662a1SLorenzo Bianconi 		.reset = {
112966b662a1SLorenzo Bianconi 			.addr = 0x12,
113066b662a1SLorenzo Bianconi 			.mask = BIT(0),
113166b662a1SLorenzo Bianconi 		},
113266b662a1SLorenzo Bianconi 		.boot = {
113366b662a1SLorenzo Bianconi 			.addr = 0x12,
113466b662a1SLorenzo Bianconi 			.mask = BIT(7),
113566b662a1SLorenzo Bianconi 		},
113666b662a1SLorenzo Bianconi 		.bdu = {
113766b662a1SLorenzo Bianconi 			.addr = 0x12,
113866b662a1SLorenzo Bianconi 			.mask = BIT(6),
113966b662a1SLorenzo Bianconi 		},
114043901008SLorenzo Bianconi 		.max_fifo_size = 512,
114143901008SLorenzo Bianconi 		.id = {
114281956a93SLorenzo Bianconi 			{
114381956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSR_ID,
114481956a93SLorenzo Bianconi 				.name = ST_LSM6DSR_DEV_NAME,
1145db947a79SLorenzo Bianconi 			}, {
1146db947a79SLorenzo Bianconi 				.hw_id = ST_ISM330DHCX_ID,
1147db947a79SLorenzo Bianconi 				.name = ST_ISM330DHCX_DEV_NAME,
1148cf9c71b3SLorenzo Bianconi 			}, {
1149cf9c71b3SLorenzo Bianconi 				.hw_id = ST_LSM6DSRX_ID,
1150cf9c71b3SLorenzo Bianconi 				.name = ST_LSM6DSRX_DEV_NAME,
115181956a93SLorenzo Bianconi 			},
115243901008SLorenzo Bianconi 		},
1153f48bc49bSLorenzo Bianconi 		.channels = {
1154f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1155f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1156f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1157f48bc49bSLorenzo Bianconi 			},
1158f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1159f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1160f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1161f48bc49bSLorenzo Bianconi 			},
1162f48bc49bSLorenzo Bianconi 		},
1163960506edSLorenzo Bianconi 		.drdy_mask = {
1164960506edSLorenzo Bianconi 			.addr = 0x13,
1165960506edSLorenzo Bianconi 			.mask = BIT(3),
1166960506edSLorenzo Bianconi 		},
116740dd7343SLorenzo Bianconi 		.odr_table = {
116840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
116940dd7343SLorenzo Bianconi 				.reg = {
117040dd7343SLorenzo Bianconi 					.addr = 0x10,
117140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
117240dd7343SLorenzo Bianconi 				},
1173f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1174f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1175f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1176f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1177f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1178f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
11798f9a5249SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
11808f9a5249SLorenzo Bianconi 				.odr_len = 7,
118140dd7343SLorenzo Bianconi 			},
118240dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
118340dd7343SLorenzo Bianconi 				.reg = {
118440dd7343SLorenzo Bianconi 					.addr = 0x11,
118540dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
118640dd7343SLorenzo Bianconi 				},
1187f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1188f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1189f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1190f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1191f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1192f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
11938f9a5249SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
11948f9a5249SLorenzo Bianconi 				.odr_len = 7,
119540dd7343SLorenzo Bianconi 			},
119640dd7343SLorenzo Bianconi 		},
1197640aca3fSLorenzo Bianconi 		.fs_table = {
1198640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1199640aca3fSLorenzo Bianconi 				.reg = {
1200640aca3fSLorenzo Bianconi 					.addr = 0x10,
1201640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1202640aca3fSLorenzo Bianconi 				},
120344a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
120444a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
120544a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
120644a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
120785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1208640aca3fSLorenzo Bianconi 			},
1209640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1210640aca3fSLorenzo Bianconi 				.reg = {
1211640aca3fSLorenzo Bianconi 					.addr = 0x11,
1212640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1213640aca3fSLorenzo Bianconi 				},
121444a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
121544a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
121644a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
121744a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
121885ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1219640aca3fSLorenzo Bianconi 			},
1220640aca3fSLorenzo Bianconi 		},
12217e906103SLorenzo Bianconi 		.irq_config = {
12227e906103SLorenzo Bianconi 			.irq1 = {
12237e906103SLorenzo Bianconi 				.addr = 0x0d,
12247e906103SLorenzo Bianconi 				.mask = BIT(3),
12257e906103SLorenzo Bianconi 			},
12267e906103SLorenzo Bianconi 			.irq2 = {
12277e906103SLorenzo Bianconi 				.addr = 0x0e,
12287e906103SLorenzo Bianconi 				.mask = BIT(3),
12297e906103SLorenzo Bianconi 			},
12307e906103SLorenzo Bianconi 			.lir = {
12317e906103SLorenzo Bianconi 				.addr = 0x56,
12327e906103SLorenzo Bianconi 				.mask = BIT(0),
12337e906103SLorenzo Bianconi 			},
12347e906103SLorenzo Bianconi 			.clear_on_read = {
12357e906103SLorenzo Bianconi 				.addr = 0x56,
12367e906103SLorenzo Bianconi 				.mask = BIT(6),
12377e906103SLorenzo Bianconi 			},
12387e906103SLorenzo Bianconi 			.irq1_func = {
12397e906103SLorenzo Bianconi 				.addr = 0x5e,
12407e906103SLorenzo Bianconi 				.mask = BIT(5),
12417e906103SLorenzo Bianconi 			},
12427e906103SLorenzo Bianconi 			.irq2_func = {
12437e906103SLorenzo Bianconi 				.addr = 0x5f,
12447e906103SLorenzo Bianconi 				.mask = BIT(5),
12457e906103SLorenzo Bianconi 			},
124631fe8d4eSLorenzo Bianconi 			.hla = {
124731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
124831fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
124931fe8d4eSLorenzo Bianconi 			},
125031fe8d4eSLorenzo Bianconi 			.od = {
125131fe8d4eSLorenzo Bianconi 				.addr = 0x12,
125231fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
125331fe8d4eSLorenzo Bianconi 			},
12547e906103SLorenzo Bianconi 		},
125543901008SLorenzo Bianconi 		.batch = {
125643901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
125743901008SLorenzo Bianconi 				.addr = 0x09,
125843901008SLorenzo Bianconi 				.mask = GENMASK(3, 0),
125943901008SLorenzo Bianconi 			},
126043901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
126143901008SLorenzo Bianconi 				.addr = 0x09,
126243901008SLorenzo Bianconi 				.mask = GENMASK(7, 4),
126343901008SLorenzo Bianconi 			},
126443901008SLorenzo Bianconi 		},
126543901008SLorenzo Bianconi 		.fifo_ops = {
12663b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
126743901008SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
126843901008SLorenzo Bianconi 			.fifo_th = {
126943901008SLorenzo Bianconi 				.addr = 0x07,
127043901008SLorenzo Bianconi 				.mask = GENMASK(8, 0),
127143901008SLorenzo Bianconi 			},
127243901008SLorenzo Bianconi 			.fifo_diff = {
127343901008SLorenzo Bianconi 				.addr = 0x3a,
127470575abeSmario tesi 				.mask = GENMASK(9, 0),
127543901008SLorenzo Bianconi 			},
127643901008SLorenzo Bianconi 			.th_wl = 1,
127743901008SLorenzo Bianconi 		},
127843901008SLorenzo Bianconi 		.ts_settings = {
127943901008SLorenzo Bianconi 			.timer_en = {
128043901008SLorenzo Bianconi 				.addr = 0x19,
128143901008SLorenzo Bianconi 				.mask = BIT(5),
128243901008SLorenzo Bianconi 			},
128343901008SLorenzo Bianconi 			.decimator = {
128443901008SLorenzo Bianconi 				.addr = 0x0a,
128543901008SLorenzo Bianconi 				.mask = GENMASK(7, 6),
128643901008SLorenzo Bianconi 			},
1287cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
128843901008SLorenzo Bianconi 		},
128943901008SLorenzo Bianconi 		.shub_settings = {
129043901008SLorenzo Bianconi 			.page_mux = {
129143901008SLorenzo Bianconi 				.addr = 0x01,
129243901008SLorenzo Bianconi 				.mask = BIT(6),
129343901008SLorenzo Bianconi 			},
129443901008SLorenzo Bianconi 			.master_en = {
1295007f2ebbSLorenzo Bianconi 				.sec_page = true,
129643901008SLorenzo Bianconi 				.addr = 0x14,
129743901008SLorenzo Bianconi 				.mask = BIT(2),
129843901008SLorenzo Bianconi 			},
129943901008SLorenzo Bianconi 			.pullup_en = {
13003a431957SLorenzo Bianconi 				.sec_page = true,
130143901008SLorenzo Bianconi 				.addr = 0x14,
130243901008SLorenzo Bianconi 				.mask = BIT(3),
130343901008SLorenzo Bianconi 			},
130443901008SLorenzo Bianconi 			.aux_sens = {
130543901008SLorenzo Bianconi 				.addr = 0x14,
130643901008SLorenzo Bianconi 				.mask = GENMASK(1, 0),
130743901008SLorenzo Bianconi 			},
130843901008SLorenzo Bianconi 			.wr_once = {
130943901008SLorenzo Bianconi 				.addr = 0x14,
131043901008SLorenzo Bianconi 				.mask = BIT(6),
131143901008SLorenzo Bianconi 			},
1312ee978bb8SLorenzo Bianconi 			.num_ext_dev = 3,
13135b8343e0SLorenzo Bianconi 			.shub_out = {
13145b8343e0SLorenzo Bianconi 				.sec_page = true,
13155b8343e0SLorenzo Bianconi 				.addr = 0x02,
13165b8343e0SLorenzo Bianconi 			},
131743901008SLorenzo Bianconi 			.slv0_addr = 0x15,
131843901008SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
131943901008SLorenzo Bianconi 			.batch_en = BIT(3),
1320b5969abfSSean Nyekjaer 		},
1321b5969abfSSean Nyekjaer 		.event_settings = {
1322b5969abfSSean Nyekjaer 			.enable_reg = {
1323b5969abfSSean Nyekjaer 				.addr = 0x58,
1324b5969abfSSean Nyekjaer 				.mask = BIT(7),
1325b5969abfSSean Nyekjaer 			},
1326b5969abfSSean Nyekjaer 			.wakeup_reg = {
1327b5969abfSSean Nyekjaer 				.addr = 0x5B,
1328b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1329b5969abfSSean Nyekjaer 			},
13301aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
13311aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
13321aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
13331aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
13341aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
133543901008SLorenzo Bianconi 		}
133643901008SLorenzo Bianconi 	},
1337*4393e4c5SLorenzo Bianconi 	{
1338*4393e4c5SLorenzo Bianconi 		.wai = 0x6d,
1339*4393e4c5SLorenzo Bianconi 		.reset = {
1340*4393e4c5SLorenzo Bianconi 			.addr = 0x12,
1341*4393e4c5SLorenzo Bianconi 			.mask = BIT(0),
1342*4393e4c5SLorenzo Bianconi 		},
1343*4393e4c5SLorenzo Bianconi 		.boot = {
1344*4393e4c5SLorenzo Bianconi 			.addr = 0x12,
1345*4393e4c5SLorenzo Bianconi 			.mask = BIT(7),
1346*4393e4c5SLorenzo Bianconi 		},
1347*4393e4c5SLorenzo Bianconi 		.bdu = {
1348*4393e4c5SLorenzo Bianconi 			.addr = 0x12,
1349*4393e4c5SLorenzo Bianconi 			.mask = BIT(6),
1350*4393e4c5SLorenzo Bianconi 		},
1351*4393e4c5SLorenzo Bianconi 		.max_fifo_size = 512,
1352*4393e4c5SLorenzo Bianconi 		.id = {
1353*4393e4c5SLorenzo Bianconi 			{
1354*4393e4c5SLorenzo Bianconi 				.hw_id = ST_LSM6DST_ID,
1355*4393e4c5SLorenzo Bianconi 				.name = ST_LSM6DST_DEV_NAME,
1356*4393e4c5SLorenzo Bianconi 			},
1357*4393e4c5SLorenzo Bianconi 		},
1358*4393e4c5SLorenzo Bianconi 		.channels = {
1359*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1360*4393e4c5SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1361*4393e4c5SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1362*4393e4c5SLorenzo Bianconi 			},
1363*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1364*4393e4c5SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1365*4393e4c5SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1366*4393e4c5SLorenzo Bianconi 			},
1367*4393e4c5SLorenzo Bianconi 		},
1368*4393e4c5SLorenzo Bianconi 		.drdy_mask = {
1369*4393e4c5SLorenzo Bianconi 			.addr = 0x13,
1370*4393e4c5SLorenzo Bianconi 			.mask = BIT(3),
1371*4393e4c5SLorenzo Bianconi 		},
1372*4393e4c5SLorenzo Bianconi 		.odr_table = {
1373*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1374*4393e4c5SLorenzo Bianconi 				.reg = {
1375*4393e4c5SLorenzo Bianconi 					.addr = 0x10,
1376*4393e4c5SLorenzo Bianconi 					.mask = GENMASK(7, 4),
1377*4393e4c5SLorenzo Bianconi 				},
1378*4393e4c5SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1379*4393e4c5SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1380*4393e4c5SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1381*4393e4c5SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1382*4393e4c5SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1383*4393e4c5SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
1384*4393e4c5SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
1385*4393e4c5SLorenzo Bianconi 				.odr_len = 7,
1386*4393e4c5SLorenzo Bianconi 			},
1387*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1388*4393e4c5SLorenzo Bianconi 				.reg = {
1389*4393e4c5SLorenzo Bianconi 					.addr = 0x11,
1390*4393e4c5SLorenzo Bianconi 					.mask = GENMASK(7, 4),
1391*4393e4c5SLorenzo Bianconi 				},
1392*4393e4c5SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1393*4393e4c5SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1394*4393e4c5SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1395*4393e4c5SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1396*4393e4c5SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1397*4393e4c5SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
1398*4393e4c5SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
1399*4393e4c5SLorenzo Bianconi 				.odr_len = 7,
1400*4393e4c5SLorenzo Bianconi 			},
1401*4393e4c5SLorenzo Bianconi 		},
1402*4393e4c5SLorenzo Bianconi 		.fs_table = {
1403*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1404*4393e4c5SLorenzo Bianconi 				.reg = {
1405*4393e4c5SLorenzo Bianconi 					.addr = 0x10,
1406*4393e4c5SLorenzo Bianconi 					.mask = GENMASK(3, 2),
1407*4393e4c5SLorenzo Bianconi 				},
1408*4393e4c5SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
1409*4393e4c5SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
1410*4393e4c5SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
1411*4393e4c5SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
1412*4393e4c5SLorenzo Bianconi 				.fs_len = 4,
1413*4393e4c5SLorenzo Bianconi 			},
1414*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1415*4393e4c5SLorenzo Bianconi 				.reg = {
1416*4393e4c5SLorenzo Bianconi 					.addr = 0x11,
1417*4393e4c5SLorenzo Bianconi 					.mask = GENMASK(3, 2),
1418*4393e4c5SLorenzo Bianconi 				},
1419*4393e4c5SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
1420*4393e4c5SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
1421*4393e4c5SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
1422*4393e4c5SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
1423*4393e4c5SLorenzo Bianconi 				.fs_len = 4,
1424*4393e4c5SLorenzo Bianconi 			},
1425*4393e4c5SLorenzo Bianconi 		},
1426*4393e4c5SLorenzo Bianconi 		.irq_config = {
1427*4393e4c5SLorenzo Bianconi 			.irq1 = {
1428*4393e4c5SLorenzo Bianconi 				.addr = 0x0d,
1429*4393e4c5SLorenzo Bianconi 				.mask = BIT(3),
1430*4393e4c5SLorenzo Bianconi 			},
1431*4393e4c5SLorenzo Bianconi 			.irq2 = {
1432*4393e4c5SLorenzo Bianconi 				.addr = 0x0e,
1433*4393e4c5SLorenzo Bianconi 				.mask = BIT(3),
1434*4393e4c5SLorenzo Bianconi 			},
1435*4393e4c5SLorenzo Bianconi 			.lir = {
1436*4393e4c5SLorenzo Bianconi 				.addr = 0x56,
1437*4393e4c5SLorenzo Bianconi 				.mask = BIT(0),
1438*4393e4c5SLorenzo Bianconi 			},
1439*4393e4c5SLorenzo Bianconi 			.clear_on_read = {
1440*4393e4c5SLorenzo Bianconi 				.addr = 0x56,
1441*4393e4c5SLorenzo Bianconi 				.mask = BIT(6),
1442*4393e4c5SLorenzo Bianconi 			},
1443*4393e4c5SLorenzo Bianconi 			.irq1_func = {
1444*4393e4c5SLorenzo Bianconi 				.addr = 0x5e,
1445*4393e4c5SLorenzo Bianconi 				.mask = BIT(5),
1446*4393e4c5SLorenzo Bianconi 			},
1447*4393e4c5SLorenzo Bianconi 			.irq2_func = {
1448*4393e4c5SLorenzo Bianconi 				.addr = 0x5f,
1449*4393e4c5SLorenzo Bianconi 				.mask = BIT(5),
1450*4393e4c5SLorenzo Bianconi 			},
1451*4393e4c5SLorenzo Bianconi 			.hla = {
1452*4393e4c5SLorenzo Bianconi 				.addr = 0x12,
1453*4393e4c5SLorenzo Bianconi 				.mask = BIT(5),
1454*4393e4c5SLorenzo Bianconi 			},
1455*4393e4c5SLorenzo Bianconi 			.od = {
1456*4393e4c5SLorenzo Bianconi 				.addr = 0x12,
1457*4393e4c5SLorenzo Bianconi 				.mask = BIT(4),
1458*4393e4c5SLorenzo Bianconi 			},
1459*4393e4c5SLorenzo Bianconi 		},
1460*4393e4c5SLorenzo Bianconi 		.batch = {
1461*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1462*4393e4c5SLorenzo Bianconi 				.addr = 0x09,
1463*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(3, 0),
1464*4393e4c5SLorenzo Bianconi 			},
1465*4393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1466*4393e4c5SLorenzo Bianconi 				.addr = 0x09,
1467*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(7, 4),
1468*4393e4c5SLorenzo Bianconi 			},
1469*4393e4c5SLorenzo Bianconi 		},
1470*4393e4c5SLorenzo Bianconi 		.fifo_ops = {
1471*4393e4c5SLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
1472*4393e4c5SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
1473*4393e4c5SLorenzo Bianconi 			.fifo_th = {
1474*4393e4c5SLorenzo Bianconi 				.addr = 0x07,
1475*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(8, 0),
1476*4393e4c5SLorenzo Bianconi 			},
1477*4393e4c5SLorenzo Bianconi 			.fifo_diff = {
1478*4393e4c5SLorenzo Bianconi 				.addr = 0x3a,
1479*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(9, 0),
1480*4393e4c5SLorenzo Bianconi 			},
1481*4393e4c5SLorenzo Bianconi 			.th_wl = 1,
1482*4393e4c5SLorenzo Bianconi 		},
1483*4393e4c5SLorenzo Bianconi 		.ts_settings = {
1484*4393e4c5SLorenzo Bianconi 			.timer_en = {
1485*4393e4c5SLorenzo Bianconi 				.addr = 0x19,
1486*4393e4c5SLorenzo Bianconi 				.mask = BIT(5),
1487*4393e4c5SLorenzo Bianconi 			},
1488*4393e4c5SLorenzo Bianconi 			.decimator = {
1489*4393e4c5SLorenzo Bianconi 				.addr = 0x0a,
1490*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(7, 6),
1491*4393e4c5SLorenzo Bianconi 			},
1492*4393e4c5SLorenzo Bianconi 			.freq_fine = 0x63,
1493*4393e4c5SLorenzo Bianconi 		},
1494*4393e4c5SLorenzo Bianconi 		.shub_settings = {
1495*4393e4c5SLorenzo Bianconi 			.page_mux = {
1496*4393e4c5SLorenzo Bianconi 				.addr = 0x01,
1497*4393e4c5SLorenzo Bianconi 				.mask = BIT(6),
1498*4393e4c5SLorenzo Bianconi 			},
1499*4393e4c5SLorenzo Bianconi 			.master_en = {
1500*4393e4c5SLorenzo Bianconi 				.sec_page = true,
1501*4393e4c5SLorenzo Bianconi 				.addr = 0x14,
1502*4393e4c5SLorenzo Bianconi 				.mask = BIT(2),
1503*4393e4c5SLorenzo Bianconi 			},
1504*4393e4c5SLorenzo Bianconi 			.pullup_en = {
1505*4393e4c5SLorenzo Bianconi 				.sec_page = true,
1506*4393e4c5SLorenzo Bianconi 				.addr = 0x14,
1507*4393e4c5SLorenzo Bianconi 				.mask = BIT(3),
1508*4393e4c5SLorenzo Bianconi 			},
1509*4393e4c5SLorenzo Bianconi 			.aux_sens = {
1510*4393e4c5SLorenzo Bianconi 				.addr = 0x14,
1511*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(1, 0),
1512*4393e4c5SLorenzo Bianconi 			},
1513*4393e4c5SLorenzo Bianconi 			.wr_once = {
1514*4393e4c5SLorenzo Bianconi 				.addr = 0x14,
1515*4393e4c5SLorenzo Bianconi 				.mask = BIT(6),
1516*4393e4c5SLorenzo Bianconi 			},
1517*4393e4c5SLorenzo Bianconi 			.num_ext_dev = 3,
1518*4393e4c5SLorenzo Bianconi 			.shub_out = {
1519*4393e4c5SLorenzo Bianconi 				.sec_page = true,
1520*4393e4c5SLorenzo Bianconi 				.addr = 0x02,
1521*4393e4c5SLorenzo Bianconi 			},
1522*4393e4c5SLorenzo Bianconi 			.slv0_addr = 0x15,
1523*4393e4c5SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
1524*4393e4c5SLorenzo Bianconi 			.batch_en = BIT(3),
1525*4393e4c5SLorenzo Bianconi 		},
1526*4393e4c5SLorenzo Bianconi 		.event_settings = {
1527*4393e4c5SLorenzo Bianconi 			.enable_reg = {
1528*4393e4c5SLorenzo Bianconi 				.addr = 0x58,
1529*4393e4c5SLorenzo Bianconi 				.mask = BIT(7),
1530*4393e4c5SLorenzo Bianconi 			},
1531*4393e4c5SLorenzo Bianconi 			.wakeup_reg = {
1532*4393e4c5SLorenzo Bianconi 				.addr = 0x5b,
1533*4393e4c5SLorenzo Bianconi 				.mask = GENMASK(5, 0),
1534*4393e4c5SLorenzo Bianconi 			},
1535*4393e4c5SLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
1536*4393e4c5SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
1537*4393e4c5SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
1538*4393e4c5SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
1539*4393e4c5SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
1540*4393e4c5SLorenzo Bianconi 		},
1541*4393e4c5SLorenzo Bianconi 	},
1542290a6ce1SLorenzo Bianconi };
1543290a6ce1SLorenzo Bianconi 
1544c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1545c91c1c84SLorenzo Bianconi {
1546c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1547c91c1c84SLorenzo Bianconi 	unsigned int data;
1548c91c1c84SLorenzo Bianconi 	int err;
1549c91c1c84SLorenzo Bianconi 
1550c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1551c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1552c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1553c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1554c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1555c91c1c84SLorenzo Bianconi 
1556c91c1c84SLorenzo Bianconi 	return err;
1557c91c1c84SLorenzo Bianconi }
1558c91c1c84SLorenzo Bianconi 
155981956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
156081956a93SLorenzo Bianconi 				   const char **name)
1561290a6ce1SLorenzo Bianconi {
156251a8b707SLorenzo Bianconi 	int err, i, j, data;
1563290a6ce1SLorenzo Bianconi 
1564290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1565d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
1566fb4fbc89SStephan Gerhold 			if (st_lsm6dsx_sensor_settings[i].id[j].name &&
1567fb4fbc89SStephan Gerhold 			    id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1568d068e4a0SLorenzo Bianconi 				break;
1569d068e4a0SLorenzo Bianconi 		}
1570d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1571290a6ce1SLorenzo Bianconi 			break;
1572290a6ce1SLorenzo Bianconi 	}
1573290a6ce1SLorenzo Bianconi 
1574290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1575290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1576290a6ce1SLorenzo Bianconi 		return -ENODEV;
1577290a6ce1SLorenzo Bianconi 	}
1578290a6ce1SLorenzo Bianconi 
157951a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1580290a6ce1SLorenzo Bianconi 	if (err < 0) {
1581290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1582290a6ce1SLorenzo Bianconi 		return err;
1583290a6ce1SLorenzo Bianconi 	}
1584290a6ce1SLorenzo Bianconi 
1585290a6ce1SLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].wai) {
1586290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1587290a6ce1SLorenzo Bianconi 		return -ENODEV;
1588290a6ce1SLorenzo Bianconi 	}
1589290a6ce1SLorenzo Bianconi 
159081956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1591290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1592290a6ce1SLorenzo Bianconi 
1593290a6ce1SLorenzo Bianconi 	return 0;
1594290a6ce1SLorenzo Bianconi }
1595290a6ce1SLorenzo Bianconi 
1596290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1597290a6ce1SLorenzo Bianconi 				     u32 gain)
1598290a6ce1SLorenzo Bianconi {
1599640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1600739aff87SLorenzo Bianconi 	unsigned int data;
1601290a6ce1SLorenzo Bianconi 	int i, err;
1602290a6ce1SLorenzo Bianconi 
1603640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
160485ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1605640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1606290a6ce1SLorenzo Bianconi 			break;
160785ae3aeeSLorenzo Bianconi 	}
1608290a6ce1SLorenzo Bianconi 
160985ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1610290a6ce1SLorenzo Bianconi 		return -EINVAL;
1611290a6ce1SLorenzo Bianconi 
1612640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1613640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1614640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1615640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1616290a6ce1SLorenzo Bianconi 	if (err < 0)
1617290a6ce1SLorenzo Bianconi 		return err;
1618290a6ce1SLorenzo Bianconi 
1619290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1620290a6ce1SLorenzo Bianconi 
1621290a6ce1SLorenzo Bianconi 	return 0;
1622290a6ce1SLorenzo Bianconi }
1623290a6ce1SLorenzo Bianconi 
1624f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val)
1625290a6ce1SLorenzo Bianconi {
162640dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
16272ccc1503SLorenzo Bianconi 	int i;
1628290a6ce1SLorenzo Bianconi 
162940dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
163059af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++) {
16316ffb55e5SLorenzo Bianconi 		/*
16326ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
16336ffb55e5SLorenzo Bianconi 		 * accel sensor
16346ffb55e5SLorenzo Bianconi 		 */
1635f8710f03SLorenzo Bianconi 		if (odr_table->odr_avl[i].milli_hz >= odr)
1636290a6ce1SLorenzo Bianconi 			break;
163759af4e20SLorenzo Bianconi 	}
1638290a6ce1SLorenzo Bianconi 
163959af4e20SLorenzo Bianconi 	if (i == odr_table->odr_len)
1640290a6ce1SLorenzo Bianconi 		return -EINVAL;
1641290a6ce1SLorenzo Bianconi 
164240dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1643f8710f03SLorenzo Bianconi 	return odr_table->odr_avl[i].milli_hz;
1644290a6ce1SLorenzo Bianconi }
1645290a6ce1SLorenzo Bianconi 
1646f8710f03SLorenzo Bianconi static int
1647f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr,
16486ffb55e5SLorenzo Bianconi 				enum st_lsm6dsx_sensor_id id)
16492ccc1503SLorenzo Bianconi {
16506ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
16516ffb55e5SLorenzo Bianconi 
16526ffb55e5SLorenzo Bianconi 	if (odr > 0) {
16536ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
1654f8710f03SLorenzo Bianconi 			return max_t(u32, ref->odr, odr);
16556ffb55e5SLorenzo Bianconi 		else
16566ffb55e5SLorenzo Bianconi 			return odr;
16576ffb55e5SLorenzo Bianconi 	} else {
16586ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
16596ffb55e5SLorenzo Bianconi 	}
16606ffb55e5SLorenzo Bianconi }
16616ffb55e5SLorenzo Bianconi 
1662f8710f03SLorenzo Bianconi static int
1663f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
16646ffb55e5SLorenzo Bianconi {
16656ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
166651a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
166751a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1668739aff87SLorenzo Bianconi 	unsigned int data;
16696ffb55e5SLorenzo Bianconi 	u8 val = 0;
16702ccc1503SLorenzo Bianconi 	int err;
16712ccc1503SLorenzo Bianconi 
16726ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
16736ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
16746ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
16756ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
16766ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
1677f8710f03SLorenzo Bianconi 		u32 odr;
16786ffb55e5SLorenzo Bianconi 		int i;
16796ffb55e5SLorenzo Bianconi 
16806ffb55e5SLorenzo Bianconi 		/*
16816ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
16826ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
16836ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
16846ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
16856ffb55e5SLorenzo Bianconi 		 */
16866ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
16876ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
16886ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
16896ffb55e5SLorenzo Bianconi 				continue;
16906ffb55e5SLorenzo Bianconi 
16916ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
16926ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
16936ffb55e5SLorenzo Bianconi 				/* device already configured */
16946ffb55e5SLorenzo Bianconi 				return 0;
16956ffb55e5SLorenzo Bianconi 		}
16966ffb55e5SLorenzo Bianconi 		break;
16976ffb55e5SLorenzo Bianconi 	}
16986ffb55e5SLorenzo Bianconi 	default:
16996ffb55e5SLorenzo Bianconi 		break;
17006ffb55e5SLorenzo Bianconi 	}
17016ffb55e5SLorenzo Bianconi 
17026ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
17036ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
17042ccc1503SLorenzo Bianconi 		if (err < 0)
17052ccc1503SLorenzo Bianconi 			return err;
17066ffb55e5SLorenzo Bianconi 	}
17072ccc1503SLorenzo Bianconi 
170840dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1709739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1710739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
17112ccc1503SLorenzo Bianconi }
17122ccc1503SLorenzo Bianconi 
1713bd41c445SLorenzo Bianconi static int
1714bd41c445SLorenzo Bianconi __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
171517750443SLorenzo Bianconi 			       bool enable)
1716290a6ce1SLorenzo Bianconi {
171751a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1718f8710f03SLorenzo Bianconi 	u32 odr = enable ? sensor->odr : 0;
1719290a6ce1SLorenzo Bianconi 	int err;
1720290a6ce1SLorenzo Bianconi 
172117750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1722290a6ce1SLorenzo Bianconi 	if (err < 0)
1723290a6ce1SLorenzo Bianconi 		return err;
1724290a6ce1SLorenzo Bianconi 
172517750443SLorenzo Bianconi 	if (enable)
172617750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
172717750443SLorenzo Bianconi 	else
172817750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1729290a6ce1SLorenzo Bianconi 
1730290a6ce1SLorenzo Bianconi 	return 0;
1731290a6ce1SLorenzo Bianconi }
1732290a6ce1SLorenzo Bianconi 
1733bd41c445SLorenzo Bianconi static int
1734bd41c445SLorenzo Bianconi st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable)
1735bd41c445SLorenzo Bianconi {
1736bd41c445SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1737bd41c445SLorenzo Bianconi 
1738bd41c445SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_GYRO || enable)
1739bd41c445SLorenzo Bianconi 		return 0;
1740bd41c445SLorenzo Bianconi 
1741bd41c445SLorenzo Bianconi 	return hw->enable_event;
1742bd41c445SLorenzo Bianconi }
1743bd41c445SLorenzo Bianconi 
1744bd41c445SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1745bd41c445SLorenzo Bianconi 				 bool enable)
1746bd41c445SLorenzo Bianconi {
1747bd41c445SLorenzo Bianconi 	if (st_lsm6dsx_check_events(sensor, enable))
1748bd41c445SLorenzo Bianconi 		return 0;
1749bd41c445SLorenzo Bianconi 
1750bd41c445SLorenzo Bianconi 	return __st_lsm6dsx_sensor_set_enable(sensor, enable);
1751bd41c445SLorenzo Bianconi }
1752bd41c445SLorenzo Bianconi 
1753290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1754290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1755290a6ce1SLorenzo Bianconi {
175651a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1757290a6ce1SLorenzo Bianconi 	int err, delay;
1758290a6ce1SLorenzo Bianconi 	__le16 data;
1759290a6ce1SLorenzo Bianconi 
176017750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1761290a6ce1SLorenzo Bianconi 	if (err < 0)
1762290a6ce1SLorenzo Bianconi 		return err;
1763290a6ce1SLorenzo Bianconi 
1764f8710f03SLorenzo Bianconi 	delay = 1000000000 / sensor->odr;
1765290a6ce1SLorenzo Bianconi 	usleep_range(delay, 2 * delay);
1766290a6ce1SLorenzo Bianconi 
1767739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1768290a6ce1SLorenzo Bianconi 	if (err < 0)
1769290a6ce1SLorenzo Bianconi 		return err;
1770290a6ce1SLorenzo Bianconi 
1771a2dd9bd9SLorenzo Bianconi 	if (!hw->enable_event) {
1772a2dd9bd9SLorenzo Bianconi 		err = st_lsm6dsx_sensor_set_enable(sensor, false);
1773a2dd9bd9SLorenzo Bianconi 		if (err < 0)
1774a2dd9bd9SLorenzo Bianconi 			return err;
1775a2dd9bd9SLorenzo Bianconi 	}
1776290a6ce1SLorenzo Bianconi 
17777b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1778290a6ce1SLorenzo Bianconi 
1779290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1780290a6ce1SLorenzo Bianconi }
1781290a6ce1SLorenzo Bianconi 
1782290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1783290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1784290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1785290a6ce1SLorenzo Bianconi {
1786290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1787290a6ce1SLorenzo Bianconi 	int ret;
1788290a6ce1SLorenzo Bianconi 
1789290a6ce1SLorenzo Bianconi 	switch (mask) {
1790290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1791290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1792290a6ce1SLorenzo Bianconi 		if (ret)
1793290a6ce1SLorenzo Bianconi 			break;
1794290a6ce1SLorenzo Bianconi 
1795290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1796290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1797290a6ce1SLorenzo Bianconi 		break;
1798290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1799f8710f03SLorenzo Bianconi 		*val = sensor->odr / 1000;
1800f8710f03SLorenzo Bianconi 		*val2 = (sensor->odr % 1000) * 1000;
1801f8710f03SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1802290a6ce1SLorenzo Bianconi 		break;
1803290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1804290a6ce1SLorenzo Bianconi 		*val = 0;
1805290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
180644a76de8SMario Tesi 		ret = IIO_VAL_INT_PLUS_NANO;
1807290a6ce1SLorenzo Bianconi 		break;
1808290a6ce1SLorenzo Bianconi 	default:
1809290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1810290a6ce1SLorenzo Bianconi 		break;
1811290a6ce1SLorenzo Bianconi 	}
1812290a6ce1SLorenzo Bianconi 
1813290a6ce1SLorenzo Bianconi 	return ret;
1814290a6ce1SLorenzo Bianconi }
1815290a6ce1SLorenzo Bianconi 
1816290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1817290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1818290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1819290a6ce1SLorenzo Bianconi {
1820290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1821290a6ce1SLorenzo Bianconi 	int err;
1822290a6ce1SLorenzo Bianconi 
1823290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1824290a6ce1SLorenzo Bianconi 	if (err)
1825290a6ce1SLorenzo Bianconi 		return err;
1826290a6ce1SLorenzo Bianconi 
1827290a6ce1SLorenzo Bianconi 	switch (mask) {
1828290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1829290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1830290a6ce1SLorenzo Bianconi 		break;
18312ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
18322ccc1503SLorenzo Bianconi 		u8 data;
18332ccc1503SLorenzo Bianconi 
1834f8710f03SLorenzo Bianconi 		val = val * 1000 + val2 / 1000;
1835fc3f6ad7SLorenzo Bianconi 		val = st_lsm6dsx_check_odr(sensor, val, &data);
1836fc3f6ad7SLorenzo Bianconi 		if (val < 0)
1837fc3f6ad7SLorenzo Bianconi 			err = val;
1838fc3f6ad7SLorenzo Bianconi 		else
18395e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1840290a6ce1SLorenzo Bianconi 		break;
18412ccc1503SLorenzo Bianconi 	}
1842290a6ce1SLorenzo Bianconi 	default:
1843290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1844290a6ce1SLorenzo Bianconi 		break;
1845290a6ce1SLorenzo Bianconi 	}
1846290a6ce1SLorenzo Bianconi 
1847290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1848290a6ce1SLorenzo Bianconi 
1849290a6ce1SLorenzo Bianconi 	return err;
1850290a6ce1SLorenzo Bianconi }
1851290a6ce1SLorenzo Bianconi 
1852b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1853b5969abfSSean Nyekjaer {
185484b2e7c3SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
185504ca37d5SLorenzo Bianconi 	unsigned int data;
1856b5969abfSSean Nyekjaer 	int err;
1857b5969abfSSean Nyekjaer 
18587e906103SLorenzo Bianconi 	if (!hw->settings->irq_config.irq1_func.addr)
1859b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1860b5969abfSSean Nyekjaer 
186184b2e7c3SLorenzo Bianconi 	reg = &hw->settings->event_settings.enable_reg;
186284b2e7c3SLorenzo Bianconi 	if (reg->addr) {
186304ca37d5SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
186404ca37d5SLorenzo Bianconi 		err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
186504ca37d5SLorenzo Bianconi 						    reg->mask, data);
1866b5969abfSSean Nyekjaer 		if (err < 0)
1867b5969abfSSean Nyekjaer 			return err;
186884b2e7c3SLorenzo Bianconi 	}
1869b5969abfSSean Nyekjaer 
1870b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
187104ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
187204ca37d5SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
187304ca37d5SLorenzo Bianconi 					     hw->irq_routing->mask, data);
1874b5969abfSSean Nyekjaer }
1875b5969abfSSean Nyekjaer 
1876b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1877b5969abfSSean Nyekjaer 				 const struct iio_chan_spec *chan,
1878b5969abfSSean Nyekjaer 				 enum iio_event_type type,
1879b5969abfSSean Nyekjaer 				 enum iio_event_direction dir,
1880b5969abfSSean Nyekjaer 				 enum iio_event_info info,
1881b5969abfSSean Nyekjaer 				 int *val, int *val2)
1882b5969abfSSean Nyekjaer {
1883b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1884b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1885b5969abfSSean Nyekjaer 
1886b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1887b5969abfSSean Nyekjaer 		return -EINVAL;
1888b5969abfSSean Nyekjaer 
1889b5969abfSSean Nyekjaer 	*val2 = 0;
1890b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1891b5969abfSSean Nyekjaer 
1892b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1893b5969abfSSean Nyekjaer }
1894b5969abfSSean Nyekjaer 
1895b307f495SLorenzo Bianconi static int
1896b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1897b5969abfSSean Nyekjaer 		       const struct iio_chan_spec *chan,
1898b5969abfSSean Nyekjaer 		       enum iio_event_type type,
1899b5969abfSSean Nyekjaer 		       enum iio_event_direction dir,
1900b5969abfSSean Nyekjaer 		       enum iio_event_info info,
1901b5969abfSSean Nyekjaer 		       int val, int val2)
1902b5969abfSSean Nyekjaer {
1903b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1904b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
190504ca37d5SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
190604ca37d5SLorenzo Bianconi 	unsigned int data;
1907b5969abfSSean Nyekjaer 	int err;
1908b5969abfSSean Nyekjaer 
1909b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1910b5969abfSSean Nyekjaer 		return -EINVAL;
1911b5969abfSSean Nyekjaer 
1912b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1913b5969abfSSean Nyekjaer 		return -EINVAL;
1914b5969abfSSean Nyekjaer 
191504ca37d5SLorenzo Bianconi 	reg = &hw->settings->event_settings.wakeup_reg;
191604ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
191704ca37d5SLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
191804ca37d5SLorenzo Bianconi 					    reg->mask, data);
191904ca37d5SLorenzo Bianconi 	if (err < 0)
1920b5969abfSSean Nyekjaer 		return -EINVAL;
1921b5969abfSSean Nyekjaer 
1922b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1923b5969abfSSean Nyekjaer 
1924b5969abfSSean Nyekjaer 	return 0;
1925b5969abfSSean Nyekjaer }
1926b5969abfSSean Nyekjaer 
1927b307f495SLorenzo Bianconi static int
1928b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1929b5969abfSSean Nyekjaer 			     const struct iio_chan_spec *chan,
1930b5969abfSSean Nyekjaer 			     enum iio_event_type type,
1931b5969abfSSean Nyekjaer 			     enum iio_event_direction dir)
1932b5969abfSSean Nyekjaer {
1933b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1934b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1935b5969abfSSean Nyekjaer 
1936b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1937b5969abfSSean Nyekjaer 		return -EINVAL;
1938b5969abfSSean Nyekjaer 
19391aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1940b5969abfSSean Nyekjaer }
1941b5969abfSSean Nyekjaer 
1942b307f495SLorenzo Bianconi static int
1943b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1944b5969abfSSean Nyekjaer 			      const struct iio_chan_spec *chan,
1945b5969abfSSean Nyekjaer 			      enum iio_event_type type,
1946b307f495SLorenzo Bianconi 			      enum iio_event_direction dir, int state)
1947b5969abfSSean Nyekjaer {
1948b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1949b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
19501aabad1fSSean Nyekjaer 	u8 enable_event;
1951bd41c445SLorenzo Bianconi 	int err;
1952b5969abfSSean Nyekjaer 
1953b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1954b5969abfSSean Nyekjaer 		return -EINVAL;
1955b5969abfSSean Nyekjaer 
19561aabad1fSSean Nyekjaer 	if (state) {
19571aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
19581aabad1fSSean Nyekjaer 
1959b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
19601aabad1fSSean Nyekjaer 		if (hw->enable_event)
19611aabad1fSSean Nyekjaer 			goto out;
19621aabad1fSSean Nyekjaer 	} else {
19631aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
19641aabad1fSSean Nyekjaer 
19651aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
19661aabad1fSSean Nyekjaer 		if (enable_event)
19671aabad1fSSean Nyekjaer 			goto out;
19681aabad1fSSean Nyekjaer 	}
19691aabad1fSSean Nyekjaer 
19701aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
19711aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1972b5969abfSSean Nyekjaer 		return 0;
1973b5969abfSSean Nyekjaer 
1974b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1975b5969abfSSean Nyekjaer 	if (err < 0)
1976b5969abfSSean Nyekjaer 		return err;
1977b5969abfSSean Nyekjaer 
1978d278d447SLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1979bd41c445SLorenzo Bianconi 	if (enable_event || !(hw->fifo_mask & BIT(sensor->id)))
1980bd41c445SLorenzo Bianconi 		err = __st_lsm6dsx_sensor_set_enable(sensor, state);
1981d278d447SLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1982b5969abfSSean Nyekjaer 	if (err < 0)
1983b5969abfSSean Nyekjaer 		return err;
1984b5969abfSSean Nyekjaer 
19851aabad1fSSean Nyekjaer out:
19861aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1987b5969abfSSean Nyekjaer 
1988b5969abfSSean Nyekjaer 	return 0;
1989b5969abfSSean Nyekjaer }
1990b5969abfSSean Nyekjaer 
1991d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1992290a6ce1SLorenzo Bianconi {
1993290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1994290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
19958f2a88a2SLorenzo Bianconi 	int err;
1996290a6ce1SLorenzo Bianconi 
19978f2a88a2SLorenzo Bianconi 	if (val < 1 || val > hw->settings->max_fifo_size)
1998290a6ce1SLorenzo Bianconi 		return -EINVAL;
1999290a6ce1SLorenzo Bianconi 
2000335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
2001335eaedcSLorenzo Bianconi 
2002290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
2003335eaedcSLorenzo Bianconi 
2004335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
2005335eaedcSLorenzo Bianconi 
2006290a6ce1SLorenzo Bianconi 	if (err < 0)
2007290a6ce1SLorenzo Bianconi 		return err;
2008290a6ce1SLorenzo Bianconi 
2009290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
2010290a6ce1SLorenzo Bianconi 
2011290a6ce1SLorenzo Bianconi 	return 0;
2012290a6ce1SLorenzo Bianconi }
2013290a6ce1SLorenzo Bianconi 
2014290a6ce1SLorenzo Bianconi static ssize_t
2015290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
2016290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
2017290a6ce1SLorenzo Bianconi 					  char *buf)
2018290a6ce1SLorenzo Bianconi {
2019290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
202059af4e20SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
2021290a6ce1SLorenzo Bianconi 	int i, len = 0;
2022290a6ce1SLorenzo Bianconi 
202359af4e20SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
202459af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++)
2025f8710f03SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ",
2026f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz / 1000,
2027f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz % 1000);
2028290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
2029290a6ce1SLorenzo Bianconi 
2030290a6ce1SLorenzo Bianconi 	return len;
2031290a6ce1SLorenzo Bianconi }
2032290a6ce1SLorenzo Bianconi 
2033290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
2034290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
2035290a6ce1SLorenzo Bianconi 					    char *buf)
2036290a6ce1SLorenzo Bianconi {
2037290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
20380f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
2039640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
2040290a6ce1SLorenzo Bianconi 	int i, len = 0;
2041290a6ce1SLorenzo Bianconi 
204285ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
204385ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
204444a76de8SMario Tesi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ",
20450f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
2046290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
2047290a6ce1SLorenzo Bianconi 
2048290a6ce1SLorenzo Bianconi 	return len;
2049290a6ce1SLorenzo Bianconi }
2050290a6ce1SLorenzo Bianconi 
205144a76de8SMario Tesi static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev,
205244a76de8SMario Tesi 					struct iio_chan_spec const *chan,
205344a76de8SMario Tesi 					long mask)
205444a76de8SMario Tesi {
205544a76de8SMario Tesi 	switch (mask) {
205644a76de8SMario Tesi 	case IIO_CHAN_INFO_SCALE:
205744a76de8SMario Tesi 		switch (chan->type) {
205844a76de8SMario Tesi 		case IIO_ANGL_VEL:
205944a76de8SMario Tesi 		case IIO_ACCEL:
206044a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_NANO;
206144a76de8SMario Tesi 		default:
206244a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_MICRO;
206344a76de8SMario Tesi 		}
206444a76de8SMario Tesi 	default:
206544a76de8SMario Tesi 		return IIO_VAL_INT_PLUS_MICRO;
206644a76de8SMario Tesi 	}
206744a76de8SMario Tesi }
206844a76de8SMario Tesi 
2069290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
2070290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
2071290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
2072290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
2073290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
2074290a6ce1SLorenzo Bianconi 
2075290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
2076290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
2077290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
2078290a6ce1SLorenzo Bianconi 	NULL,
2079290a6ce1SLorenzo Bianconi };
2080290a6ce1SLorenzo Bianconi 
2081290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
2082290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
2083290a6ce1SLorenzo Bianconi };
2084290a6ce1SLorenzo Bianconi 
2085290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
2086290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
2087290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
2088290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
2089b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
2090b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
2091b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
2092b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
2093290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
209444a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
2095290a6ce1SLorenzo Bianconi };
2096290a6ce1SLorenzo Bianconi 
2097290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
2098290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
2099290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
2100290a6ce1SLorenzo Bianconi 	NULL,
2101290a6ce1SLorenzo Bianconi };
2102290a6ce1SLorenzo Bianconi 
2103290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
2104290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
2105290a6ce1SLorenzo Bianconi };
2106290a6ce1SLorenzo Bianconi 
2107290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
2108290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
2109290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
2110290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
2111290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
211244a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
2113290a6ce1SLorenzo Bianconi };
2114290a6ce1SLorenzo Bianconi 
211503d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
2116dba32904SLorenzo Bianconi {
211703d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2118dba32904SLorenzo Bianconi 
211903d4c566SAndy Shevchenko 	if (!dev_fwnode(dev))
2120dba32904SLorenzo Bianconi 		return -EINVAL;
2121dba32904SLorenzo Bianconi 
212203d4c566SAndy Shevchenko 	return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
2123dba32904SLorenzo Bianconi }
2124dba32904SLorenzo Bianconi 
21257e906103SLorenzo Bianconi static int
21267e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
21277e906103SLorenzo Bianconi 			const struct st_lsm6dsx_reg **drdy_reg)
2128dba32904SLorenzo Bianconi {
2129dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
2130dba32904SLorenzo Bianconi 
213103d4c566SAndy Shevchenko 	if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
2132dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
2133dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
2134dba32904SLorenzo Bianconi 
2135dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
2136dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
2137dba32904SLorenzo Bianconi 	}
2138dba32904SLorenzo Bianconi 
2139dba32904SLorenzo Bianconi 	switch (drdy_pin) {
2140dba32904SLorenzo Bianconi 	case 1:
21417e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq1_func;
21427e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq1;
2143dba32904SLorenzo Bianconi 		break;
2144dba32904SLorenzo Bianconi 	case 2:
21457e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq2_func;
21467e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq2;
2147dba32904SLorenzo Bianconi 		break;
2148dba32904SLorenzo Bianconi 	default:
2149dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
2150dba32904SLorenzo Bianconi 		err = -EINVAL;
2151dba32904SLorenzo Bianconi 		break;
2152dba32904SLorenzo Bianconi 	}
2153dba32904SLorenzo Bianconi 
2154dba32904SLorenzo Bianconi 	return err;
2155dba32904SLorenzo Bianconi }
2156dba32904SLorenzo Bianconi 
2157c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
2158c91c1c84SLorenzo Bianconi {
2159c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2160c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
216103d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2162c91c1c84SLorenzo Bianconi 	unsigned int data;
2163c91c1c84SLorenzo Bianconi 	int err = 0;
2164c91c1c84SLorenzo Bianconi 
2165c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2166c91c1c84SLorenzo Bianconi 
216703d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
216803d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
2169c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
21703a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page) {
2171c91c1c84SLorenzo Bianconi 			err = st_lsm6dsx_set_page(hw, true);
2172c91c1c84SLorenzo Bianconi 			if (err < 0)
2173c91c1c84SLorenzo Bianconi 				return err;
21743a431957SLorenzo Bianconi 		}
2175c91c1c84SLorenzo Bianconi 
2176c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
2177c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2178c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
2179c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
2180c91c1c84SLorenzo Bianconi 
21813a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page)
2182c91c1c84SLorenzo Bianconi 			st_lsm6dsx_set_page(hw, false);
2183c91c1c84SLorenzo Bianconi 
2184c91c1c84SLorenzo Bianconi 		if (err < 0)
2185c91c1c84SLorenzo Bianconi 			return err;
2186c91c1c84SLorenzo Bianconi 	}
2187c91c1c84SLorenzo Bianconi 
2188c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
2189c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
2190c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
2191c91c1c84SLorenzo Bianconi 		if (err < 0)
2192c91c1c84SLorenzo Bianconi 			return err;
2193c91c1c84SLorenzo Bianconi 
2194c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
2195c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2196c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
2197c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
2198c91c1c84SLorenzo Bianconi 
2199c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
2200e485e2a2SLorenzo Bianconi 
2201e485e2a2SLorenzo Bianconi 		if (err < 0)
2202e485e2a2SLorenzo Bianconi 			return err;
2203e485e2a2SLorenzo Bianconi 	}
2204e485e2a2SLorenzo Bianconi 
2205e485e2a2SLorenzo Bianconi 	if (hub_settings->emb_func.addr) {
2206e485e2a2SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask);
2207e485e2a2SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2208e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.addr,
2209e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.mask, data);
2210c91c1c84SLorenzo Bianconi 	}
2211c91c1c84SLorenzo Bianconi 
2212c91c1c84SLorenzo Bianconi 	return err;
2213c91c1c84SLorenzo Bianconi }
2214c91c1c84SLorenzo Bianconi 
221521345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
221621345107SLorenzo Bianconi {
221721345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
221821345107SLorenzo Bianconi 	int err, val;
221921345107SLorenzo Bianconi 
222021345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
222121345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
222221345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
222321345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
222421345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
222521345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
222621345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
222721345107SLorenzo Bianconi 		if (err < 0)
222821345107SLorenzo Bianconi 			return err;
222921345107SLorenzo Bianconi 	}
223021345107SLorenzo Bianconi 
223121345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
223221345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
223321345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
223421345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
223521345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
223621345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
223721345107SLorenzo Bianconi 		if (err < 0)
223821345107SLorenzo Bianconi 			return err;
223921345107SLorenzo Bianconi 	}
224021345107SLorenzo Bianconi 
224121345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
224221345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
224321345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
224421345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
224521345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
224621345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
224721345107SLorenzo Bianconi 		if (err < 0)
224821345107SLorenzo Bianconi 			return err;
224921345107SLorenzo Bianconi 	}
2250cb3b6b8eSMario Tesi 
2251cb3b6b8eSMario Tesi 	/* calibrate timestamp sensitivity */
2252cb3b6b8eSMario Tesi 	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
2253cb3b6b8eSMario Tesi 	if (ts_settings->freq_fine) {
2254cb3b6b8eSMario Tesi 		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
2255cb3b6b8eSMario Tesi 		if (err < 0)
2256cb3b6b8eSMario Tesi 			return err;
2257cb3b6b8eSMario Tesi 
2258cb3b6b8eSMario Tesi 		/*
2259cb3b6b8eSMario Tesi 		 * linearize the AN5192 formula:
2260cb3b6b8eSMario Tesi 		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
2261cb3b6b8eSMario Tesi 		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
2262cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - 37.5 * val
2263cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
2264cb3b6b8eSMario Tesi 		 */
2265cb3b6b8eSMario Tesi 		hw->ts_gain -= ((s8)val * 37500) / 1000;
2266cb3b6b8eSMario Tesi 	}
2267cb3b6b8eSMario Tesi 
226821345107SLorenzo Bianconi 	return 0;
226921345107SLorenzo Bianconi }
227021345107SLorenzo Bianconi 
22713a63da26SLorenzo Bianconi static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
2272290a6ce1SLorenzo Bianconi {
22737e906103SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
2274290a6ce1SLorenzo Bianconi 	int err;
2275290a6ce1SLorenzo Bianconi 
22763a63da26SLorenzo Bianconi 	/*
22773a63da26SLorenzo Bianconi 	 * flush hw FIFO before device reset in order to avoid
22783a63da26SLorenzo Bianconi 	 * possible races on interrupt line 1. If the first interrupt
22793a63da26SLorenzo Bianconi 	 * line is asserted during hw reset the device will work in
22803a63da26SLorenzo Bianconi 	 * I3C-only mode (if it is supported)
22813a63da26SLorenzo Bianconi 	 */
22823a63da26SLorenzo Bianconi 	err = st_lsm6dsx_flush_fifo(hw);
22833a63da26SLorenzo Bianconi 	if (err < 0 && err != -ENOTSUPP)
22843a63da26SLorenzo Bianconi 		return err;
22853a63da26SLorenzo Bianconi 
228619435425SLorenzo Bianconi 	/* device sw reset */
228766b662a1SLorenzo Bianconi 	reg = &hw->settings->reset;
228866b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
228966b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2290290a6ce1SLorenzo Bianconi 	if (err < 0)
2291290a6ce1SLorenzo Bianconi 		return err;
2292290a6ce1SLorenzo Bianconi 
229319435425SLorenzo Bianconi 	msleep(50);
229419435425SLorenzo Bianconi 
229519435425SLorenzo Bianconi 	/* reload trimming parameter */
229666b662a1SLorenzo Bianconi 	reg = &hw->settings->boot;
229766b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
229866b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
229919435425SLorenzo Bianconi 	if (err < 0)
230019435425SLorenzo Bianconi 		return err;
230119435425SLorenzo Bianconi 
230219435425SLorenzo Bianconi 	msleep(50);
2303290a6ce1SLorenzo Bianconi 
23043a63da26SLorenzo Bianconi 	return 0;
23053a63da26SLorenzo Bianconi }
23063a63da26SLorenzo Bianconi 
23073a63da26SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
23083a63da26SLorenzo Bianconi {
23093a63da26SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
23103a63da26SLorenzo Bianconi 	int err;
23113a63da26SLorenzo Bianconi 
23123a63da26SLorenzo Bianconi 	err = st_lsm6dsx_reset_device(hw);
23133a63da26SLorenzo Bianconi 	if (err < 0)
23143a63da26SLorenzo Bianconi 		return err;
23153a63da26SLorenzo Bianconi 
2316290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
231766b662a1SLorenzo Bianconi 	reg = &hw->settings->bdu;
231866b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
231966b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2320290a6ce1SLorenzo Bianconi 	if (err < 0)
2321290a6ce1SLorenzo Bianconi 		return err;
2322290a6ce1SLorenzo Bianconi 
2323290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
23247e906103SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &reg);
2325290a6ce1SLorenzo Bianconi 	if (err < 0)
2326290a6ce1SLorenzo Bianconi 		return err;
2327290a6ce1SLorenzo Bianconi 
23287e906103SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
23297e906103SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
233021345107SLorenzo Bianconi 	if (err < 0)
233121345107SLorenzo Bianconi 		return err;
233221345107SLorenzo Bianconi 
23339db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
23347e906103SLorenzo Bianconi 	if (hw->settings->irq_config.lir.addr) {
23357e906103SLorenzo Bianconi 		reg = &hw->settings->irq_config.lir;
23367e906103SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
23377e906103SLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
23389db02d32SLorenzo Bianconi 		if (err < 0)
23399db02d32SLorenzo Bianconi 			return err;
234022ea5651SLorenzo Bianconi 
234122ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
23427e906103SLorenzo Bianconi 		if (hw->settings->irq_config.clear_on_read.addr) {
23437e906103SLorenzo Bianconi 			reg = &hw->settings->irq_config.clear_on_read;
234422ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
23457e906103SLorenzo Bianconi 					reg->addr, reg->mask,
23467e906103SLorenzo Bianconi 					ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
234722ea5651SLorenzo Bianconi 			if (err < 0)
234822ea5651SLorenzo Bianconi 				return err;
234922ea5651SLorenzo Bianconi 		}
23509db02d32SLorenzo Bianconi 	}
23519db02d32SLorenzo Bianconi 
2352960506edSLorenzo Bianconi 	/* enable drdy-mas if available */
2353960506edSLorenzo Bianconi 	if (hw->settings->drdy_mask.addr) {
2354960506edSLorenzo Bianconi 		reg = &hw->settings->drdy_mask;
2355960506edSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2356960506edSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2357960506edSLorenzo Bianconi 		if (err < 0)
2358960506edSLorenzo Bianconi 			return err;
2359960506edSLorenzo Bianconi 	}
2360960506edSLorenzo Bianconi 
2361c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
2362c91c1c84SLorenzo Bianconi 	if (err < 0)
2363c91c1c84SLorenzo Bianconi 		return err;
2364c91c1c84SLorenzo Bianconi 
236521345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
2366290a6ce1SLorenzo Bianconi }
2367290a6ce1SLorenzo Bianconi 
2368290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
2369510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
2370510c0106SLorenzo Bianconi 					       const char *name)
2371290a6ce1SLorenzo Bianconi {
2372290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2373290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
2374290a6ce1SLorenzo Bianconi 
2375290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
2376290a6ce1SLorenzo Bianconi 	if (!iio_dev)
2377290a6ce1SLorenzo Bianconi 		return NULL;
2378290a6ce1SLorenzo Bianconi 
2379290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
2380290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2381f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
2382f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
2383290a6ce1SLorenzo Bianconi 
2384290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
2385290a6ce1SLorenzo Bianconi 	sensor->id = id;
2386290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
2387f8710f03SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz;
2388640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
2389290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
2390290a6ce1SLorenzo Bianconi 
2391290a6ce1SLorenzo Bianconi 	switch (id) {
2392290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
2393290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
2394510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
2395510c0106SLorenzo Bianconi 			  name);
2396290a6ce1SLorenzo Bianconi 		break;
2397290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
2398290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
2399510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
2400510c0106SLorenzo Bianconi 			  name);
2401290a6ce1SLorenzo Bianconi 		break;
2402290a6ce1SLorenzo Bianconi 	default:
2403290a6ce1SLorenzo Bianconi 		return NULL;
2404290a6ce1SLorenzo Bianconi 	}
2405510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
2406290a6ce1SLorenzo Bianconi 
2407290a6ce1SLorenzo Bianconi 	return iio_dev;
2408290a6ce1SLorenzo Bianconi }
2409290a6ce1SLorenzo Bianconi 
2410615bd378SLorenzo Bianconi static bool
2411615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
24121aabad1fSSean Nyekjaer {
2413615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
2414615bd378SLorenzo Bianconi 	int err, data;
2415615bd378SLorenzo Bianconi 	s64 timestamp;
24161aabad1fSSean Nyekjaer 
2417615bd378SLorenzo Bianconi 	if (!hw->enable_event)
2418615bd378SLorenzo Bianconi 		return false;
2419615bd378SLorenzo Bianconi 
2420615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
2421615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2422615bd378SLorenzo Bianconi 				     &data, sizeof(data));
2423615bd378SLorenzo Bianconi 	if (err < 0)
2424615bd378SLorenzo Bianconi 		return false;
2425615bd378SLorenzo Bianconi 
2426615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
24271aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
24281aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
24291aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24301aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24311aabad1fSSean Nyekjaer 						  0,
24321aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
24331aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24341aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24351aabad1fSSean Nyekjaer 						  timestamp);
24361aabad1fSSean Nyekjaer 
24371aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
24381aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
24391aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24401aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24411aabad1fSSean Nyekjaer 						  0,
24421aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
24431aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24441aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24451aabad1fSSean Nyekjaer 						  timestamp);
24461aabad1fSSean Nyekjaer 
24471aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
24481aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
24491aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24501aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24511aabad1fSSean Nyekjaer 						  0,
24521aabad1fSSean Nyekjaer 						  IIO_MOD_X,
24531aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24541aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24551aabad1fSSean Nyekjaer 						  timestamp);
2456615bd378SLorenzo Bianconi 
2457615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
24581aabad1fSSean Nyekjaer }
24591aabad1fSSean Nyekjaer 
24606ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
24616ee6a368SSean Nyekjaer {
24626ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
2463615bd378SLorenzo Bianconi 	bool event;
24646ee6a368SSean Nyekjaer 	int count;
24651aabad1fSSean Nyekjaer 
2466615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
24676ee6a368SSean Nyekjaer 
2468a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
2469a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
2470a912ee4cSLorenzo Bianconi 
24716ee6a368SSean Nyekjaer 	mutex_lock(&hw->fifo_lock);
24726ee6a368SSean Nyekjaer 	count = hw->settings->fifo_ops.read_fifo(hw);
24736ee6a368SSean Nyekjaer 	mutex_unlock(&hw->fifo_lock);
24746ee6a368SSean Nyekjaer 
2475615bd378SLorenzo Bianconi 	return count || event ? IRQ_HANDLED : IRQ_NONE;
24766ee6a368SSean Nyekjaer }
24776ee6a368SSean Nyekjaer 
24786ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
24796ee6a368SSean Nyekjaer {
248031fe8d4eSLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
248131fe8d4eSLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
248203d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
24836ee6a368SSean Nyekjaer 	unsigned long irq_type;
24846ee6a368SSean Nyekjaer 	bool irq_active_low;
24856ee6a368SSean Nyekjaer 	int err;
24866ee6a368SSean Nyekjaer 
24876ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
24886ee6a368SSean Nyekjaer 
24896ee6a368SSean Nyekjaer 	switch (irq_type) {
24906ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
24916ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
24926ee6a368SSean Nyekjaer 		irq_active_low = false;
24936ee6a368SSean Nyekjaer 		break;
24946ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
24956ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
24966ee6a368SSean Nyekjaer 		irq_active_low = true;
24976ee6a368SSean Nyekjaer 		break;
24986ee6a368SSean Nyekjaer 	default:
24996ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
25006ee6a368SSean Nyekjaer 		return -EINVAL;
25016ee6a368SSean Nyekjaer 	}
25026ee6a368SSean Nyekjaer 
250331fe8d4eSLorenzo Bianconi 	reg = &hw->settings->irq_config.hla;
250431fe8d4eSLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
250531fe8d4eSLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(irq_active_low,
250631fe8d4eSLorenzo Bianconi 						      reg->mask));
25076ee6a368SSean Nyekjaer 	if (err < 0)
25086ee6a368SSean Nyekjaer 		return err;
25096ee6a368SSean Nyekjaer 
251003d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
251103d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
25126ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
251331fe8d4eSLorenzo Bianconi 		reg = &hw->settings->irq_config.od;
251431fe8d4eSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
251531fe8d4eSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
25166ee6a368SSean Nyekjaer 		if (err < 0)
25176ee6a368SSean Nyekjaer 			return err;
25186ee6a368SSean Nyekjaer 
25196ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
25206ee6a368SSean Nyekjaer 	}
25216ee6a368SSean Nyekjaer 
25226ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
2523a3aa17d4SSean Nyekjaer 					NULL,
25246ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
25256ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
25266ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
25276ee6a368SSean Nyekjaer 	if (err) {
25286ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
25296ee6a368SSean Nyekjaer 			hw->irq);
25306ee6a368SSean Nyekjaer 		return err;
25316ee6a368SSean Nyekjaer 	}
25326ee6a368SSean Nyekjaer 
25336ee6a368SSean Nyekjaer 	return 0;
25346ee6a368SSean Nyekjaer }
25356ee6a368SSean Nyekjaer 
253681956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
253751a8b707SLorenzo Bianconi 		     struct regmap *regmap)
2538290a6ce1SLorenzo Bianconi {
2539b7a73b33SLorenzo Bianconi 	struct st_sensors_platform_data *pdata = dev->platform_data;
2540c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2541290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
254281956a93SLorenzo Bianconi 	const char *name = NULL;
2543290a6ce1SLorenzo Bianconi 	int i, err;
2544290a6ce1SLorenzo Bianconi 
2545290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
2546290a6ce1SLorenzo Bianconi 	if (!hw)
2547290a6ce1SLorenzo Bianconi 		return -ENOMEM;
2548290a6ce1SLorenzo Bianconi 
2549290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
2550290a6ce1SLorenzo Bianconi 
2551290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
2552335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
2553739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
2554290a6ce1SLorenzo Bianconi 
255591a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
255691a6b841SLorenzo Bianconi 	if (!hw->buff)
255791a6b841SLorenzo Bianconi 		return -ENOMEM;
255891a6b841SLorenzo Bianconi 
2559290a6ce1SLorenzo Bianconi 	hw->dev = dev;
2560290a6ce1SLorenzo Bianconi 	hw->irq = irq;
256151a8b707SLorenzo Bianconi 	hw->regmap = regmap;
2562290a6ce1SLorenzo Bianconi 
256381956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
2564290a6ce1SLorenzo Bianconi 	if (err < 0)
2565290a6ce1SLorenzo Bianconi 		return err;
2566290a6ce1SLorenzo Bianconi 
25676ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
2568510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
2569290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
2570290a6ce1SLorenzo Bianconi 			return -ENOMEM;
2571290a6ce1SLorenzo Bianconi 	}
2572290a6ce1SLorenzo Bianconi 
2573290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
2574290a6ce1SLorenzo Bianconi 	if (err < 0)
2575290a6ce1SLorenzo Bianconi 		return err;
2576290a6ce1SLorenzo Bianconi 
2577c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2578c91c1c84SLorenzo Bianconi 	if (hub_settings->master_en.addr) {
2579c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
2580c91c1c84SLorenzo Bianconi 		if (err < 0)
2581c91c1c84SLorenzo Bianconi 			return err;
2582c91c1c84SLorenzo Bianconi 	}
2583c91c1c84SLorenzo Bianconi 
2584290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
25856ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
25866ee6a368SSean Nyekjaer 		if (err < 0)
25876ee6a368SSean Nyekjaer 			return err;
25886ee6a368SSean Nyekjaer 
2589290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
2590290a6ce1SLorenzo Bianconi 		if (err < 0)
2591290a6ce1SLorenzo Bianconi 			return err;
2592290a6ce1SLorenzo Bianconi 	}
2593290a6ce1SLorenzo Bianconi 
259404e6fedbSMartin Kepplinger 	err = iio_read_mount_matrix(hw->dev, "mount-matrix", &hw->orientation);
259504e6fedbSMartin Kepplinger 	if (err)
259604e6fedbSMartin Kepplinger 		return err;
259704e6fedbSMartin Kepplinger 
2598290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
25996ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
26006ffb55e5SLorenzo Bianconi 			continue;
26016ffb55e5SLorenzo Bianconi 
2602290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
2603290a6ce1SLorenzo Bianconi 		if (err)
2604290a6ce1SLorenzo Bianconi 			return err;
2605290a6ce1SLorenzo Bianconi 	}
2606290a6ce1SLorenzo Bianconi 
260703d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
2608b7a73b33SLorenzo Bianconi 	    (pdata && pdata->wakeup_source))
26094c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
26104c997dfaSSean Nyekjaer 
2611290a6ce1SLorenzo Bianconi 	return 0;
2612290a6ce1SLorenzo Bianconi }
2613290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe);
2614290a6ce1SLorenzo Bianconi 
26153cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
2616d3f77058SLorenzo Bianconi {
2617d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2618d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2619d3f77058SLorenzo Bianconi 	int i, err = 0;
2620d3f77058SLorenzo Bianconi 
2621d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
26226ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
26236ffb55e5SLorenzo Bianconi 			continue;
26246ffb55e5SLorenzo Bianconi 
2625d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
2626d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
2627d3f77058SLorenzo Bianconi 			continue;
2628d3f77058SLorenzo Bianconi 
26294c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
26304c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
26314c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
26324c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
26334c997dfaSSean Nyekjaer 			continue;
26344c997dfaSSean Nyekjaer 		}
26354c997dfaSSean Nyekjaer 
2636bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2637bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2638bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2639bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, false);
2640bce0d57dSLorenzo Bianconi 		else
2641bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, false);
2642d3f77058SLorenzo Bianconi 		if (err < 0)
2643d3f77058SLorenzo Bianconi 			return err;
2644bce0d57dSLorenzo Bianconi 
2645bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2646d3f77058SLorenzo Bianconi 	}
2647d3f77058SLorenzo Bianconi 
2648c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2649d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2650d3f77058SLorenzo Bianconi 
2651d3f77058SLorenzo Bianconi 	return err;
2652d3f77058SLorenzo Bianconi }
2653d3f77058SLorenzo Bianconi 
26543cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
2655d3f77058SLorenzo Bianconi {
2656d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2657d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2658d3f77058SLorenzo Bianconi 	int i, err = 0;
2659d3f77058SLorenzo Bianconi 
2660d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
26616ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
26626ffb55e5SLorenzo Bianconi 			continue;
26636ffb55e5SLorenzo Bianconi 
2664d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
26654c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
26664c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
26674c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
26684c997dfaSSean Nyekjaer 
2669bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2670d3f77058SLorenzo Bianconi 			continue;
2671d3f77058SLorenzo Bianconi 
2672bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2673bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2674bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2675bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, true);
2676bce0d57dSLorenzo Bianconi 		else
2677bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, true);
2678d3f77058SLorenzo Bianconi 		if (err < 0)
2679d3f77058SLorenzo Bianconi 			return err;
2680bce0d57dSLorenzo Bianconi 
2681bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2682d3f77058SLorenzo Bianconi 	}
2683d3f77058SLorenzo Bianconi 
2684c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2685a1bab939SLorenzo Bianconi 		err = st_lsm6dsx_resume_fifo(hw);
2686d3f77058SLorenzo Bianconi 
2687d3f77058SLorenzo Bianconi 	return err;
2688d3f77058SLorenzo Bianconi }
2689d3f77058SLorenzo Bianconi 
2690d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = {
2691d3f77058SLorenzo Bianconi 	SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
2692d3f77058SLorenzo Bianconi };
2693d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
2694d3f77058SLorenzo Bianconi 
2695290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2696290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2697290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2698290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2699