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:
18f7d5c18aSSean Nyekjaer  *   - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 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:
24f7d5c18aSSean Nyekjaer  *   - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 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  *
29186b9e38SLorenzo Bianconi  * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/
303a042fdaSLorenzo Bianconi  *   LSM6DSTX/LSM6DSO16IS/ISM330IS:
31f7d5c18aSSean Nyekjaer  *   - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416,
328f9a5249SLorenzo Bianconi  *     833
33801a6e0aSLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
34801a6e0aSLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
35801a6e0aSLorenzo Bianconi  *   - FIFO size: 3KB
36801a6e0aSLorenzo Bianconi  *
37d94fbd92SLorenzo Bianconi  * - LSM6DSV/LSM6DSV16X:
38d94fbd92SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 7.5, 15, 30, 60, 120, 240,
39d94fbd92SLorenzo Bianconi  *     480, 960
40d94fbd92SLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
41d94fbd92SLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-250/+-500/+-1000/+-2000
42d94fbd92SLorenzo Bianconi  *   - FIFO size: 3KB
43d94fbd92SLorenzo Bianconi  *
44fa060a3dSLorenzo Bianconi  * - LSM9DS1/LSM6DS0:
4552f4b1f1SMartin Kepplinger  *   - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
4652f4b1f1SMartin Kepplinger  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
4752f4b1f1SMartin Kepplinger  *   - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
4852f4b1f1SMartin Kepplinger  *   - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
4952f4b1f1SMartin Kepplinger  *   - FIFO size: 32
5052f4b1f1SMartin Kepplinger  *
51290a6ce1SLorenzo Bianconi  * Copyright 2016 STMicroelectronics Inc.
52290a6ce1SLorenzo Bianconi  *
53290a6ce1SLorenzo Bianconi  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
54290a6ce1SLorenzo Bianconi  * Denis Ciocca <denis.ciocca@st.com>
55290a6ce1SLorenzo Bianconi  */
56290a6ce1SLorenzo Bianconi 
57290a6ce1SLorenzo Bianconi #include <linux/kernel.h>
58290a6ce1SLorenzo Bianconi #include <linux/module.h>
59dc3d25f2SJonathan Cameron #include <linux/acpi.h>
60290a6ce1SLorenzo Bianconi #include <linux/delay.h>
611aabad1fSSean Nyekjaer #include <linux/iio/events.h>
62290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h>
63290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h>
642cfb2180SLorenzo Bianconi #include <linux/iio/triggered_buffer.h>
652cfb2180SLorenzo Bianconi #include <linux/iio/trigger_consumer.h>
666ee6a368SSean Nyekjaer #include <linux/interrupt.h>
676ee6a368SSean Nyekjaer #include <linux/irq.h>
689e5b4cd2SPaul Cercueil #include <linux/minmax.h>
69d3f77058SLorenzo Bianconi #include <linux/pm.h>
7003d4c566SAndy Shevchenko #include <linux/property.h>
7151a8b707SLorenzo Bianconi #include <linux/regmap.h>
7251a8b707SLorenzo Bianconi #include <linux/bitfield.h>
73290a6ce1SLorenzo Bianconi 
74dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h>
75dba32904SLorenzo Bianconi 
76290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h"
77290a6ce1SLorenzo Bianconi 
78290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
79290a6ce1SLorenzo Bianconi 
80cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
81cb3b6b8eSMario Tesi 
82f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
83b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
84b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
85b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
86f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
87f48bc49bSLorenzo Bianconi };
88f48bc49bSLorenzo Bianconi 
89f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
90f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
91f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
92f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
93f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
94f48bc49bSLorenzo Bianconi };
95f48bc49bSLorenzo Bianconi 
9652f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
9752f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
9852f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
9952f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
10052f4b1f1SMartin Kepplinger 	IIO_CHAN_SOFT_TIMESTAMP(3),
10152f4b1f1SMartin Kepplinger };
10252f4b1f1SMartin Kepplinger 
103290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
104290a6ce1SLorenzo Bianconi 	{
10566b662a1SLorenzo Bianconi 		.reset = {
10666b662a1SLorenzo Bianconi 			.addr = 0x22,
10766b662a1SLorenzo Bianconi 			.mask = BIT(0),
10866b662a1SLorenzo Bianconi 		},
10966b662a1SLorenzo Bianconi 		.boot = {
11066b662a1SLorenzo Bianconi 			.addr = 0x22,
11166b662a1SLorenzo Bianconi 			.mask = BIT(7),
11266b662a1SLorenzo Bianconi 		},
11366b662a1SLorenzo Bianconi 		.bdu = {
11466b662a1SLorenzo Bianconi 			.addr = 0x22,
11566b662a1SLorenzo Bianconi 			.mask = BIT(6),
11666b662a1SLorenzo Bianconi 		},
11752f4b1f1SMartin Kepplinger 		.id = {
11852f4b1f1SMartin Kepplinger 			{
11952f4b1f1SMartin Kepplinger 				.hw_id = ST_LSM9DS1_ID,
12052f4b1f1SMartin Kepplinger 				.name = ST_LSM9DS1_DEV_NAME,
12198c3544aSLorenzo Bianconi 				.wai = 0x68,
122fa060a3dSLorenzo Bianconi 			}, {
123fa060a3dSLorenzo Bianconi 				.hw_id = ST_LSM6DS0_ID,
124fa060a3dSLorenzo Bianconi 				.name = ST_LSM6DS0_DEV_NAME,
12598c3544aSLorenzo Bianconi 				.wai = 0x68,
12652f4b1f1SMartin Kepplinger 			},
12752f4b1f1SMartin Kepplinger 		},
12852f4b1f1SMartin Kepplinger 		.channels = {
12952f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
13052f4b1f1SMartin Kepplinger 				.chan = st_lsm6dsx_acc_channels,
13152f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
13252f4b1f1SMartin Kepplinger 			},
13352f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
13452f4b1f1SMartin Kepplinger 				.chan = st_lsm6ds0_gyro_channels,
13552f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
13652f4b1f1SMartin Kepplinger 			},
13752f4b1f1SMartin Kepplinger 		},
13852f4b1f1SMartin Kepplinger 		.odr_table = {
13952f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
14052f4b1f1SMartin Kepplinger 				.reg = {
14152f4b1f1SMartin Kepplinger 					.addr = 0x20,
14252f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
14352f4b1f1SMartin Kepplinger 				},
144f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  10000, 0x01 },
145f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  50000, 0x02 },
146f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
147f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
148f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
149f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
15059af4e20SLorenzo Bianconi 				.odr_len = 6,
15152f4b1f1SMartin Kepplinger 			},
15252f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
15352f4b1f1SMartin Kepplinger 				.reg = {
15452f4b1f1SMartin Kepplinger 					.addr = 0x10,
15552f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
15652f4b1f1SMartin Kepplinger 				},
157f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  14900, 0x01 },
158f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  59500, 0x02 },
159f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
160f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
161f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
162f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
16359af4e20SLorenzo Bianconi 				.odr_len = 6,
16452f4b1f1SMartin Kepplinger 			},
16552f4b1f1SMartin Kepplinger 		},
16652f4b1f1SMartin Kepplinger 		.fs_table = {
16752f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
16852f4b1f1SMartin Kepplinger 				.reg = {
16952f4b1f1SMartin Kepplinger 					.addr = 0x20,
17052f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
17152f4b1f1SMartin Kepplinger 				},
17244a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
17344a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
17444a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
17544a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 },
17685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
17752f4b1f1SMartin Kepplinger 			},
17852f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
17952f4b1f1SMartin Kepplinger 				.reg = {
18052f4b1f1SMartin Kepplinger 					.addr = 0x10,
18152f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
18252f4b1f1SMartin Kepplinger 				},
1831b375101SLorenzo Bianconi 
18444a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
18544a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
18644a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
18785ae3aeeSLorenzo Bianconi 				.fs_len = 3,
18852f4b1f1SMartin Kepplinger 			},
18952f4b1f1SMartin Kepplinger 		},
1907e906103SLorenzo Bianconi 		.irq_config = {
1917e906103SLorenzo Bianconi 			.irq1 = {
1927e906103SLorenzo Bianconi 				.addr = 0x0c,
1937e906103SLorenzo Bianconi 				.mask = BIT(3),
1947e906103SLorenzo Bianconi 			},
1957e906103SLorenzo Bianconi 			.irq2 = {
1967e906103SLorenzo Bianconi 				.addr = 0x0d,
1977e906103SLorenzo Bianconi 				.mask = BIT(3),
1987e906103SLorenzo Bianconi 			},
19931fe8d4eSLorenzo Bianconi 			.hla = {
20031fe8d4eSLorenzo Bianconi 				.addr = 0x22,
20131fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
20231fe8d4eSLorenzo Bianconi 			},
20331fe8d4eSLorenzo Bianconi 			.od = {
20431fe8d4eSLorenzo Bianconi 				.addr = 0x22,
20531fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
20631fe8d4eSLorenzo Bianconi 			},
2077e906103SLorenzo Bianconi 		},
2081b7da2faSLorenzo Bianconi 		.fifo_ops = {
2091b7da2faSLorenzo Bianconi 			.max_size = 32,
2101b7da2faSLorenzo Bianconi 		},
21152f4b1f1SMartin Kepplinger 	},
21252f4b1f1SMartin Kepplinger 	{
21366b662a1SLorenzo Bianconi 		.reset = {
21466b662a1SLorenzo Bianconi 			.addr = 0x12,
21566b662a1SLorenzo Bianconi 			.mask = BIT(0),
21666b662a1SLorenzo Bianconi 		},
21766b662a1SLorenzo Bianconi 		.boot = {
21866b662a1SLorenzo Bianconi 			.addr = 0x12,
21966b662a1SLorenzo Bianconi 			.mask = BIT(7),
22066b662a1SLorenzo Bianconi 		},
22166b662a1SLorenzo Bianconi 		.bdu = {
22266b662a1SLorenzo Bianconi 			.addr = 0x12,
22366b662a1SLorenzo Bianconi 			.mask = BIT(6),
22466b662a1SLorenzo Bianconi 		},
225d068e4a0SLorenzo Bianconi 		.id = {
22681956a93SLorenzo Bianconi 			{
22781956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3_ID,
22881956a93SLorenzo Bianconi 				.name = ST_LSM6DS3_DEV_NAME,
22998c3544aSLorenzo Bianconi 				.wai = 0x69,
23081956a93SLorenzo Bianconi 			},
231d068e4a0SLorenzo Bianconi 		},
232f48bc49bSLorenzo Bianconi 		.channels = {
233f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
234f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
235f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
236f48bc49bSLorenzo Bianconi 			},
237f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
238f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
239f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
240f48bc49bSLorenzo Bianconi 			},
241f48bc49bSLorenzo Bianconi 		},
24240dd7343SLorenzo Bianconi 		.odr_table = {
24340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
24440dd7343SLorenzo Bianconi 				.reg = {
24540dd7343SLorenzo Bianconi 					.addr = 0x10,
24640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
24740dd7343SLorenzo Bianconi 				},
248f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
249f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
250f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
251f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
252f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
253f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
25459af4e20SLorenzo Bianconi 				.odr_len = 6,
25540dd7343SLorenzo Bianconi 			},
25640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
25740dd7343SLorenzo Bianconi 				.reg = {
25840dd7343SLorenzo Bianconi 					.addr = 0x11,
25940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
26040dd7343SLorenzo Bianconi 				},
261f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
262f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
263f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
264f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
265f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
266f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
26759af4e20SLorenzo Bianconi 				.odr_len = 6,
26840dd7343SLorenzo Bianconi 			},
26940dd7343SLorenzo Bianconi 		},
270640aca3fSLorenzo Bianconi 		.fs_table = {
271640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
272640aca3fSLorenzo Bianconi 				.reg = {
273640aca3fSLorenzo Bianconi 					.addr = 0x10,
274640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
275640aca3fSLorenzo Bianconi 				},
27644a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
27744a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
27844a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
27944a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
28085ae3aeeSLorenzo Bianconi 				.fs_len = 4,
281640aca3fSLorenzo Bianconi 			},
282640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
283640aca3fSLorenzo Bianconi 				.reg = {
284640aca3fSLorenzo Bianconi 					.addr = 0x11,
285640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
286640aca3fSLorenzo Bianconi 				},
28744a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
28844a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
28944a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
29044a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
29185ae3aeeSLorenzo Bianconi 				.fs_len = 4,
292640aca3fSLorenzo Bianconi 			},
293640aca3fSLorenzo Bianconi 		},
2947e906103SLorenzo Bianconi 		.irq_config = {
2957e906103SLorenzo Bianconi 			.irq1 = {
2967e906103SLorenzo Bianconi 				.addr = 0x0d,
2977e906103SLorenzo Bianconi 				.mask = BIT(3),
2987e906103SLorenzo Bianconi 			},
2997e906103SLorenzo Bianconi 			.irq2 = {
3007e906103SLorenzo Bianconi 				.addr = 0x0e,
3017e906103SLorenzo Bianconi 				.mask = BIT(3),
3027e906103SLorenzo Bianconi 			},
3037e906103SLorenzo Bianconi 			.lir = {
3047e906103SLorenzo Bianconi 				.addr = 0x58,
3057e906103SLorenzo Bianconi 				.mask = BIT(0),
3067e906103SLorenzo Bianconi 			},
3077e906103SLorenzo Bianconi 			.irq1_func = {
3087e906103SLorenzo Bianconi 				.addr = 0x5e,
3097e906103SLorenzo Bianconi 				.mask = BIT(5),
3107e906103SLorenzo Bianconi 			},
3117e906103SLorenzo Bianconi 			.irq2_func = {
3127e906103SLorenzo Bianconi 				.addr = 0x5f,
3137e906103SLorenzo Bianconi 				.mask = BIT(5),
3147e906103SLorenzo Bianconi 			},
31531fe8d4eSLorenzo Bianconi 			.hla = {
31631fe8d4eSLorenzo Bianconi 				.addr = 0x12,
31731fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
31831fe8d4eSLorenzo Bianconi 			},
31931fe8d4eSLorenzo Bianconi 			.od = {
32031fe8d4eSLorenzo Bianconi 				.addr = 0x12,
32131fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
32231fe8d4eSLorenzo Bianconi 			},
3237e906103SLorenzo Bianconi 		},
3247ca3ac9eSLorenzo Bianconi 		.decimator = {
3257ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
3267ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3277ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
3287ca3ac9eSLorenzo Bianconi 			},
3297ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
3307ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3317ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
3327ca3ac9eSLorenzo Bianconi 			},
3337ca3ac9eSLorenzo Bianconi 		},
33492617c15SLorenzo Bianconi 		.fifo_ops = {
3353b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
33650ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
33792617c15SLorenzo Bianconi 			.fifo_th = {
33892617c15SLorenzo Bianconi 				.addr = 0x06,
33992617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
34092617c15SLorenzo Bianconi 			},
34192617c15SLorenzo Bianconi 			.fifo_diff = {
34292617c15SLorenzo Bianconi 				.addr = 0x3a,
34392617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
34492617c15SLorenzo Bianconi 			},
3451b7da2faSLorenzo Bianconi 			.max_size = 1365,
34692617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
34792617c15SLorenzo Bianconi 		},
34821345107SLorenzo Bianconi 		.ts_settings = {
34921345107SLorenzo Bianconi 			.timer_en = {
35021345107SLorenzo Bianconi 				.addr = 0x58,
35121345107SLorenzo Bianconi 				.mask = BIT(7),
35221345107SLorenzo Bianconi 			},
35321345107SLorenzo Bianconi 			.hr_timer = {
35421345107SLorenzo Bianconi 				.addr = 0x5c,
35521345107SLorenzo Bianconi 				.mask = BIT(4),
35621345107SLorenzo Bianconi 			},
35721345107SLorenzo Bianconi 			.fifo_en = {
35821345107SLorenzo Bianconi 				.addr = 0x07,
35921345107SLorenzo Bianconi 				.mask = BIT(7),
36021345107SLorenzo Bianconi 			},
36121345107SLorenzo Bianconi 			.decimator = {
36221345107SLorenzo Bianconi 				.addr = 0x09,
36321345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
36421345107SLorenzo Bianconi 			},
36521345107SLorenzo Bianconi 		},
366b5969abfSSean Nyekjaer 		.event_settings = {
367b5969abfSSean Nyekjaer 			.wakeup_reg = {
368b5969abfSSean Nyekjaer 				.addr = 0x5B,
369b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
370b5969abfSSean Nyekjaer 			},
3711aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
3721aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
3731aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
3741aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
3751aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
376b5969abfSSean Nyekjaer 		},
377290a6ce1SLorenzo Bianconi 	},
378290a6ce1SLorenzo Bianconi 	{
37966b662a1SLorenzo Bianconi 		.reset = {
38066b662a1SLorenzo Bianconi 			.addr = 0x12,
38166b662a1SLorenzo Bianconi 			.mask = BIT(0),
38266b662a1SLorenzo Bianconi 		},
38366b662a1SLorenzo Bianconi 		.boot = {
38466b662a1SLorenzo Bianconi 			.addr = 0x12,
38566b662a1SLorenzo Bianconi 			.mask = BIT(7),
38666b662a1SLorenzo Bianconi 		},
38766b662a1SLorenzo Bianconi 		.bdu = {
38866b662a1SLorenzo Bianconi 			.addr = 0x12,
38966b662a1SLorenzo Bianconi 			.mask = BIT(6),
39066b662a1SLorenzo Bianconi 		},
391df47710aSLorenzo Bianconi 		.id = {
39281956a93SLorenzo Bianconi 			{
39381956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3H_ID,
39481956a93SLorenzo Bianconi 				.name = ST_LSM6DS3H_DEV_NAME,
39598c3544aSLorenzo Bianconi 				.wai = 0x69,
39681956a93SLorenzo Bianconi 			},
397df47710aSLorenzo Bianconi 		},
398f48bc49bSLorenzo Bianconi 		.channels = {
399f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
400f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
401f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
402f48bc49bSLorenzo Bianconi 			},
403f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
404f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
405f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
406f48bc49bSLorenzo Bianconi 			},
407f48bc49bSLorenzo Bianconi 		},
40840dd7343SLorenzo Bianconi 		.odr_table = {
40940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
41040dd7343SLorenzo Bianconi 				.reg = {
41140dd7343SLorenzo Bianconi 					.addr = 0x10,
41240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
41340dd7343SLorenzo Bianconi 				},
414f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
415f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
416f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
417f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
418f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
419f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
42059af4e20SLorenzo Bianconi 				.odr_len = 6,
42140dd7343SLorenzo Bianconi 			},
42240dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
42340dd7343SLorenzo Bianconi 				.reg = {
42440dd7343SLorenzo Bianconi 					.addr = 0x11,
42540dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
42640dd7343SLorenzo Bianconi 				},
427f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
428f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
429f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
430f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
431f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
432f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
43359af4e20SLorenzo Bianconi 				.odr_len = 6,
43440dd7343SLorenzo Bianconi 			},
43540dd7343SLorenzo Bianconi 		},
436640aca3fSLorenzo Bianconi 		.fs_table = {
437640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
438640aca3fSLorenzo Bianconi 				.reg = {
439640aca3fSLorenzo Bianconi 					.addr = 0x10,
440640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
441640aca3fSLorenzo Bianconi 				},
44244a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
44344a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
44444a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
44544a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
44685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
447640aca3fSLorenzo Bianconi 			},
448640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
449640aca3fSLorenzo Bianconi 				.reg = {
450640aca3fSLorenzo Bianconi 					.addr = 0x11,
451640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
452640aca3fSLorenzo Bianconi 				},
45344a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
45444a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
45544a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
45644a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
45785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
458640aca3fSLorenzo Bianconi 			},
459640aca3fSLorenzo Bianconi 		},
4607e906103SLorenzo Bianconi 		.irq_config = {
4617e906103SLorenzo Bianconi 			.irq1 = {
4627e906103SLorenzo Bianconi 				.addr = 0x0d,
4637e906103SLorenzo Bianconi 				.mask = BIT(3),
4647e906103SLorenzo Bianconi 			},
4657e906103SLorenzo Bianconi 			.irq2 = {
4667e906103SLorenzo Bianconi 				.addr = 0x0e,
4677e906103SLorenzo Bianconi 				.mask = BIT(3),
4687e906103SLorenzo Bianconi 			},
4697e906103SLorenzo Bianconi 			.lir = {
4707e906103SLorenzo Bianconi 				.addr = 0x58,
4717e906103SLorenzo Bianconi 				.mask = BIT(0),
4727e906103SLorenzo Bianconi 			},
4737e906103SLorenzo Bianconi 			.irq1_func = {
4747e906103SLorenzo Bianconi 				.addr = 0x5e,
4757e906103SLorenzo Bianconi 				.mask = BIT(5),
4767e906103SLorenzo Bianconi 			},
4777e906103SLorenzo Bianconi 			.irq2_func = {
4787e906103SLorenzo Bianconi 				.addr = 0x5f,
4797e906103SLorenzo Bianconi 				.mask = BIT(5),
4807e906103SLorenzo Bianconi 			},
48131fe8d4eSLorenzo Bianconi 			.hla = {
48231fe8d4eSLorenzo Bianconi 				.addr = 0x12,
48331fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
48431fe8d4eSLorenzo Bianconi 			},
48531fe8d4eSLorenzo Bianconi 			.od = {
48631fe8d4eSLorenzo Bianconi 				.addr = 0x12,
48731fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
48831fe8d4eSLorenzo Bianconi 			},
4897e906103SLorenzo Bianconi 		},
4907ca3ac9eSLorenzo Bianconi 		.decimator = {
4917ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
4927ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4937ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
4947ca3ac9eSLorenzo Bianconi 			},
4957ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
4967ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4977ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
4987ca3ac9eSLorenzo Bianconi 			},
4997ca3ac9eSLorenzo Bianconi 		},
50092617c15SLorenzo Bianconi 		.fifo_ops = {
5013b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
50250ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
50392617c15SLorenzo Bianconi 			.fifo_th = {
50492617c15SLorenzo Bianconi 				.addr = 0x06,
50592617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
50692617c15SLorenzo Bianconi 			},
50792617c15SLorenzo Bianconi 			.fifo_diff = {
50892617c15SLorenzo Bianconi 				.addr = 0x3a,
50992617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
51092617c15SLorenzo Bianconi 			},
5111b7da2faSLorenzo Bianconi 			.max_size = 682,
51292617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
51392617c15SLorenzo Bianconi 		},
51421345107SLorenzo Bianconi 		.ts_settings = {
51521345107SLorenzo Bianconi 			.timer_en = {
51621345107SLorenzo Bianconi 				.addr = 0x58,
51721345107SLorenzo Bianconi 				.mask = BIT(7),
51821345107SLorenzo Bianconi 			},
51921345107SLorenzo Bianconi 			.hr_timer = {
52021345107SLorenzo Bianconi 				.addr = 0x5c,
52121345107SLorenzo Bianconi 				.mask = BIT(4),
52221345107SLorenzo Bianconi 			},
52321345107SLorenzo Bianconi 			.fifo_en = {
52421345107SLorenzo Bianconi 				.addr = 0x07,
52521345107SLorenzo Bianconi 				.mask = BIT(7),
52621345107SLorenzo Bianconi 			},
52721345107SLorenzo Bianconi 			.decimator = {
52821345107SLorenzo Bianconi 				.addr = 0x09,
52921345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
53021345107SLorenzo Bianconi 			},
53121345107SLorenzo Bianconi 		},
532b5969abfSSean Nyekjaer 		.event_settings = {
533b5969abfSSean Nyekjaer 			.wakeup_reg = {
534b5969abfSSean Nyekjaer 				.addr = 0x5B,
535b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
536b5969abfSSean Nyekjaer 			},
5371aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
5381aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
5391aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
5401aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
5411aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
542b5969abfSSean Nyekjaer 		},
543df47710aSLorenzo Bianconi 	},
544df47710aSLorenzo Bianconi 	{
54566b662a1SLorenzo Bianconi 		.reset = {
54666b662a1SLorenzo Bianconi 			.addr = 0x12,
54766b662a1SLorenzo Bianconi 			.mask = BIT(0),
54866b662a1SLorenzo Bianconi 		},
54966b662a1SLorenzo Bianconi 		.boot = {
55066b662a1SLorenzo Bianconi 			.addr = 0x12,
55166b662a1SLorenzo Bianconi 			.mask = BIT(7),
55266b662a1SLorenzo Bianconi 		},
55366b662a1SLorenzo Bianconi 		.bdu = {
55466b662a1SLorenzo Bianconi 			.addr = 0x12,
55566b662a1SLorenzo Bianconi 			.mask = BIT(6),
55666b662a1SLorenzo Bianconi 		},
557d068e4a0SLorenzo Bianconi 		.id = {
55881956a93SLorenzo Bianconi 			{
55981956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSL_ID,
56081956a93SLorenzo Bianconi 				.name = ST_LSM6DSL_DEV_NAME,
56198c3544aSLorenzo Bianconi 				.wai = 0x6a,
56281956a93SLorenzo Bianconi 			}, {
56381956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSM_ID,
56481956a93SLorenzo Bianconi 				.name = ST_LSM6DSM_DEV_NAME,
56598c3544aSLorenzo Bianconi 				.wai = 0x6a,
56681956a93SLorenzo Bianconi 			}, {
56781956a93SLorenzo Bianconi 				.hw_id = ST_ISM330DLC_ID,
56881956a93SLorenzo Bianconi 				.name = ST_ISM330DLC_DEV_NAME,
56998c3544aSLorenzo Bianconi 				.wai = 0x6a,
570dbcd2088SLorenzo Bianconi 			}, {
571dbcd2088SLorenzo Bianconi 				.hw_id = ST_LSM6DS3TRC_ID,
572dbcd2088SLorenzo Bianconi 				.name = ST_LSM6DS3TRC_DEV_NAME,
57398c3544aSLorenzo Bianconi 				.wai = 0x6a,
57481956a93SLorenzo Bianconi 			},
575d068e4a0SLorenzo Bianconi 		},
576f48bc49bSLorenzo Bianconi 		.channels = {
577f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
578f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
579f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
580f48bc49bSLorenzo Bianconi 			},
581f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
582f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
583f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
584f48bc49bSLorenzo Bianconi 			},
585f48bc49bSLorenzo Bianconi 		},
58640dd7343SLorenzo Bianconi 		.odr_table = {
58740dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
58840dd7343SLorenzo Bianconi 				.reg = {
58940dd7343SLorenzo Bianconi 					.addr = 0x10,
59040dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
59140dd7343SLorenzo Bianconi 				},
592f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
593f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
594f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
595f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
596f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
597f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
59859af4e20SLorenzo Bianconi 				.odr_len = 6,
59940dd7343SLorenzo Bianconi 			},
60040dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
60140dd7343SLorenzo Bianconi 				.reg = {
60240dd7343SLorenzo Bianconi 					.addr = 0x11,
60340dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
60440dd7343SLorenzo Bianconi 				},
605f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
606f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
607f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
608f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
609f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
610f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
61159af4e20SLorenzo Bianconi 				.odr_len = 6,
61240dd7343SLorenzo Bianconi 			},
61340dd7343SLorenzo Bianconi 		},
614640aca3fSLorenzo Bianconi 		.fs_table = {
615640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
616640aca3fSLorenzo Bianconi 				.reg = {
617640aca3fSLorenzo Bianconi 					.addr = 0x10,
618640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
619640aca3fSLorenzo Bianconi 				},
62044a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
62144a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
62244a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
62344a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
62485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
625640aca3fSLorenzo Bianconi 			},
626640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
627640aca3fSLorenzo Bianconi 				.reg = {
628640aca3fSLorenzo Bianconi 					.addr = 0x11,
629640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
630640aca3fSLorenzo Bianconi 				},
63144a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
63244a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
63344a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
63444a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
63585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
636640aca3fSLorenzo Bianconi 			},
637640aca3fSLorenzo Bianconi 		},
638db3c4905SLorenzo Bianconi 		.samples_to_discard = {
639db3c4905SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
640db3c4905SLorenzo Bianconi 				.val[0] = {  12500, 1 },
641db3c4905SLorenzo Bianconi 				.val[1] = {  26000, 1 },
642db3c4905SLorenzo Bianconi 				.val[2] = {  52000, 1 },
643db3c4905SLorenzo Bianconi 				.val[3] = { 104000, 2 },
644db3c4905SLorenzo Bianconi 				.val[4] = { 208000, 2 },
645db3c4905SLorenzo Bianconi 				.val[5] = { 416000, 2 },
646db3c4905SLorenzo Bianconi 			},
647db3c4905SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
648db3c4905SLorenzo Bianconi 				.val[0] = {  12500,  2 },
649db3c4905SLorenzo Bianconi 				.val[1] = {  26000,  5 },
650db3c4905SLorenzo Bianconi 				.val[2] = {  52000,  7 },
651db3c4905SLorenzo Bianconi 				.val[3] = { 104000, 12 },
652db3c4905SLorenzo Bianconi 				.val[4] = { 208000, 20 },
653db3c4905SLorenzo Bianconi 				.val[5] = { 416000, 36 },
654db3c4905SLorenzo Bianconi 			},
655db3c4905SLorenzo Bianconi 		},
6567e906103SLorenzo Bianconi 		.irq_config = {
6577e906103SLorenzo Bianconi 			.irq1 = {
6587e906103SLorenzo Bianconi 				.addr = 0x0d,
6597e906103SLorenzo Bianconi 				.mask = BIT(3),
6607e906103SLorenzo Bianconi 			},
6617e906103SLorenzo Bianconi 			.irq2 = {
6627e906103SLorenzo Bianconi 				.addr = 0x0e,
6637e906103SLorenzo Bianconi 				.mask = BIT(3),
6647e906103SLorenzo Bianconi 			},
6657e906103SLorenzo Bianconi 			.lir = {
6667e906103SLorenzo Bianconi 				.addr = 0x58,
6677e906103SLorenzo Bianconi 				.mask = BIT(0),
6687e906103SLorenzo Bianconi 			},
6697e906103SLorenzo Bianconi 			.irq1_func = {
6707e906103SLorenzo Bianconi 				.addr = 0x5e,
6717e906103SLorenzo Bianconi 				.mask = BIT(5),
6727e906103SLorenzo Bianconi 			},
6737e906103SLorenzo Bianconi 			.irq2_func = {
6747e906103SLorenzo Bianconi 				.addr = 0x5f,
6757e906103SLorenzo Bianconi 				.mask = BIT(5),
6767e906103SLorenzo Bianconi 			},
67731fe8d4eSLorenzo Bianconi 			.hla = {
67831fe8d4eSLorenzo Bianconi 				.addr = 0x12,
67931fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
68031fe8d4eSLorenzo Bianconi 			},
68131fe8d4eSLorenzo Bianconi 			.od = {
68231fe8d4eSLorenzo Bianconi 				.addr = 0x12,
68331fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
68431fe8d4eSLorenzo Bianconi 			},
6857e906103SLorenzo Bianconi 		},
6867ca3ac9eSLorenzo Bianconi 		.decimator = {
6877ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
6887ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6897ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
6907ca3ac9eSLorenzo Bianconi 			},
6917ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
6927ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6937ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
6947ca3ac9eSLorenzo Bianconi 			},
695e485e2a2SLorenzo Bianconi 			[ST_LSM6DSX_ID_EXT0] = {
696e485e2a2SLorenzo Bianconi 				.addr = 0x09,
697e485e2a2SLorenzo Bianconi 				.mask = GENMASK(2, 0),
698e485e2a2SLorenzo Bianconi 			},
6997ca3ac9eSLorenzo Bianconi 		},
70092617c15SLorenzo Bianconi 		.fifo_ops = {
7013b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
70250ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
70392617c15SLorenzo Bianconi 			.fifo_th = {
70492617c15SLorenzo Bianconi 				.addr = 0x06,
705be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
70692617c15SLorenzo Bianconi 			},
70792617c15SLorenzo Bianconi 			.fifo_diff = {
70892617c15SLorenzo Bianconi 				.addr = 0x3a,
709be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
71092617c15SLorenzo Bianconi 			},
7111b7da2faSLorenzo Bianconi 			.max_size = 682,
71292617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
71392617c15SLorenzo Bianconi 		},
71421345107SLorenzo Bianconi 		.ts_settings = {
71521345107SLorenzo Bianconi 			.timer_en = {
71621345107SLorenzo Bianconi 				.addr = 0x19,
71721345107SLorenzo Bianconi 				.mask = BIT(5),
71821345107SLorenzo Bianconi 			},
71921345107SLorenzo Bianconi 			.hr_timer = {
72021345107SLorenzo Bianconi 				.addr = 0x5c,
72121345107SLorenzo Bianconi 				.mask = BIT(4),
72221345107SLorenzo Bianconi 			},
72321345107SLorenzo Bianconi 			.fifo_en = {
72421345107SLorenzo Bianconi 				.addr = 0x07,
72521345107SLorenzo Bianconi 				.mask = BIT(7),
72621345107SLorenzo Bianconi 			},
72721345107SLorenzo Bianconi 			.decimator = {
72821345107SLorenzo Bianconi 				.addr = 0x09,
72921345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
73021345107SLorenzo Bianconi 			},
73121345107SLorenzo Bianconi 		},
732e485e2a2SLorenzo Bianconi 		.shub_settings = {
733e485e2a2SLorenzo Bianconi 			.page_mux = {
734e485e2a2SLorenzo Bianconi 				.addr = 0x01,
735e485e2a2SLorenzo Bianconi 				.mask = BIT(7),
736e485e2a2SLorenzo Bianconi 			},
737e485e2a2SLorenzo Bianconi 			.master_en = {
738e485e2a2SLorenzo Bianconi 				.addr = 0x1a,
739e485e2a2SLorenzo Bianconi 				.mask = BIT(0),
740e485e2a2SLorenzo Bianconi 			},
741e485e2a2SLorenzo Bianconi 			.pullup_en = {
742e485e2a2SLorenzo Bianconi 				.addr = 0x1a,
743e485e2a2SLorenzo Bianconi 				.mask = BIT(3),
744e485e2a2SLorenzo Bianconi 			},
745e485e2a2SLorenzo Bianconi 			.aux_sens = {
746e485e2a2SLorenzo Bianconi 				.addr = 0x04,
747e485e2a2SLorenzo Bianconi 				.mask = GENMASK(5, 4),
748e485e2a2SLorenzo Bianconi 			},
749e485e2a2SLorenzo Bianconi 			.wr_once = {
750e485e2a2SLorenzo Bianconi 				.addr = 0x07,
751e485e2a2SLorenzo Bianconi 				.mask = BIT(5),
752e485e2a2SLorenzo Bianconi 			},
753e485e2a2SLorenzo Bianconi 			.emb_func = {
754e485e2a2SLorenzo Bianconi 				.addr = 0x19,
755e485e2a2SLorenzo Bianconi 				.mask = BIT(2),
756e485e2a2SLorenzo Bianconi 			},
757e485e2a2SLorenzo Bianconi 			.num_ext_dev = 1,
758e485e2a2SLorenzo Bianconi 			.shub_out = {
759e485e2a2SLorenzo Bianconi 				.addr = 0x2e,
760e485e2a2SLorenzo Bianconi 			},
761e485e2a2SLorenzo Bianconi 			.slv0_addr = 0x02,
762e485e2a2SLorenzo Bianconi 			.dw_slv0_addr = 0x0e,
763e485e2a2SLorenzo Bianconi 			.pause = 0x7,
764e485e2a2SLorenzo Bianconi 		},
765b5969abfSSean Nyekjaer 		.event_settings = {
766b5969abfSSean Nyekjaer 			.enable_reg = {
767b5969abfSSean Nyekjaer 				.addr = 0x58,
768b5969abfSSean Nyekjaer 				.mask = BIT(7),
769b5969abfSSean Nyekjaer 			},
770b5969abfSSean Nyekjaer 			.wakeup_reg = {
771b5969abfSSean Nyekjaer 				.addr = 0x5B,
772b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
773b5969abfSSean Nyekjaer 			},
7741aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
7751aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
7761aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
7771aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
7781aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
779b5969abfSSean Nyekjaer 		},
780290a6ce1SLorenzo Bianconi 	},
781801a6e0aSLorenzo Bianconi 	{
78266b662a1SLorenzo Bianconi 		.reset = {
78366b662a1SLorenzo Bianconi 			.addr = 0x12,
78466b662a1SLorenzo Bianconi 			.mask = BIT(0),
78566b662a1SLorenzo Bianconi 		},
78666b662a1SLorenzo Bianconi 		.boot = {
78766b662a1SLorenzo Bianconi 			.addr = 0x12,
78866b662a1SLorenzo Bianconi 			.mask = BIT(7),
78966b662a1SLorenzo Bianconi 		},
79066b662a1SLorenzo Bianconi 		.bdu = {
79166b662a1SLorenzo Bianconi 			.addr = 0x12,
79266b662a1SLorenzo Bianconi 			.mask = BIT(6),
79366b662a1SLorenzo Bianconi 		},
79443901008SLorenzo Bianconi 		.id = {
79581956a93SLorenzo Bianconi 			{
79681956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSR_ID,
79781956a93SLorenzo Bianconi 				.name = ST_LSM6DSR_DEV_NAME,
79898c3544aSLorenzo Bianconi 				.wai = 0x6b,
799db947a79SLorenzo Bianconi 			}, {
800db947a79SLorenzo Bianconi 				.hw_id = ST_ISM330DHCX_ID,
801db947a79SLorenzo Bianconi 				.name = ST_ISM330DHCX_DEV_NAME,
80298c3544aSLorenzo Bianconi 				.wai = 0x6b,
803cf9c71b3SLorenzo Bianconi 			}, {
804cf9c71b3SLorenzo Bianconi 				.hw_id = ST_LSM6DSRX_ID,
805cf9c71b3SLorenzo Bianconi 				.name = ST_LSM6DSRX_DEV_NAME,
80698c3544aSLorenzo Bianconi 				.wai = 0x6b,
80798c3544aSLorenzo Bianconi 			}, {
80898c3544aSLorenzo Bianconi 				.hw_id = ST_LSM6DSO_ID,
80998c3544aSLorenzo Bianconi 				.name = ST_LSM6DSO_DEV_NAME,
81098c3544aSLorenzo Bianconi 				.wai = 0x6c,
81198c3544aSLorenzo Bianconi 			}, {
81298c3544aSLorenzo Bianconi 				.hw_id = ST_LSM6DSOX_ID,
81398c3544aSLorenzo Bianconi 				.name = ST_LSM6DSOX_DEV_NAME,
81498c3544aSLorenzo Bianconi 				.wai = 0x6c,
81598c3544aSLorenzo Bianconi 			}, {
8164393e4c5SLorenzo Bianconi 				.hw_id = ST_LSM6DST_ID,
8174393e4c5SLorenzo Bianconi 				.name = ST_LSM6DST_DEV_NAME,
81898c3544aSLorenzo Bianconi 				.wai = 0x6d,
819fdd70d7aSLorenzo Bianconi 			}, {
820fdd70d7aSLorenzo Bianconi 				.hw_id = ST_ASM330LHHX_ID,
821fdd70d7aSLorenzo Bianconi 				.name = ST_ASM330LHHX_DEV_NAME,
822fdd70d7aSLorenzo Bianconi 				.wai = 0x6b,
823186b9e38SLorenzo Bianconi 			}, {
824186b9e38SLorenzo Bianconi 				.hw_id = ST_LSM6DSTX_ID,
825186b9e38SLorenzo Bianconi 				.name = ST_LSM6DSTX_DEV_NAME,
826186b9e38SLorenzo Bianconi 				.wai = 0x6d,
8274393e4c5SLorenzo Bianconi 			},
8284393e4c5SLorenzo Bianconi 		},
8294393e4c5SLorenzo Bianconi 		.channels = {
8304393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
8314393e4c5SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
8324393e4c5SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
8334393e4c5SLorenzo Bianconi 			},
8344393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8354393e4c5SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
8364393e4c5SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
8374393e4c5SLorenzo Bianconi 			},
8384393e4c5SLorenzo Bianconi 		},
8394393e4c5SLorenzo Bianconi 		.drdy_mask = {
8404393e4c5SLorenzo Bianconi 			.addr = 0x13,
8414393e4c5SLorenzo Bianconi 			.mask = BIT(3),
8424393e4c5SLorenzo Bianconi 		},
8434393e4c5SLorenzo Bianconi 		.odr_table = {
8444393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
8454393e4c5SLorenzo Bianconi 				.reg = {
8464393e4c5SLorenzo Bianconi 					.addr = 0x10,
8474393e4c5SLorenzo Bianconi 					.mask = GENMASK(7, 4),
8484393e4c5SLorenzo Bianconi 				},
8494393e4c5SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
8504393e4c5SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
8514393e4c5SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
8524393e4c5SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
8534393e4c5SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
8544393e4c5SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
8554393e4c5SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
8564393e4c5SLorenzo Bianconi 				.odr_len = 7,
8574393e4c5SLorenzo Bianconi 			},
8584393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8594393e4c5SLorenzo Bianconi 				.reg = {
8604393e4c5SLorenzo Bianconi 					.addr = 0x11,
8614393e4c5SLorenzo Bianconi 					.mask = GENMASK(7, 4),
8624393e4c5SLorenzo Bianconi 				},
8634393e4c5SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
8644393e4c5SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
8654393e4c5SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
8664393e4c5SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
8674393e4c5SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
8684393e4c5SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
8694393e4c5SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
8704393e4c5SLorenzo Bianconi 				.odr_len = 7,
8714393e4c5SLorenzo Bianconi 			},
8724393e4c5SLorenzo Bianconi 		},
8734393e4c5SLorenzo Bianconi 		.fs_table = {
8744393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
8754393e4c5SLorenzo Bianconi 				.reg = {
8764393e4c5SLorenzo Bianconi 					.addr = 0x10,
8774393e4c5SLorenzo Bianconi 					.mask = GENMASK(3, 2),
8784393e4c5SLorenzo Bianconi 				},
8794393e4c5SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
8804393e4c5SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
8814393e4c5SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
8824393e4c5SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
8834393e4c5SLorenzo Bianconi 				.fs_len = 4,
8844393e4c5SLorenzo Bianconi 			},
8854393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8864393e4c5SLorenzo Bianconi 				.reg = {
8874393e4c5SLorenzo Bianconi 					.addr = 0x11,
8884393e4c5SLorenzo Bianconi 					.mask = GENMASK(3, 2),
8894393e4c5SLorenzo Bianconi 				},
8904393e4c5SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
8914393e4c5SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
8924393e4c5SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
8934393e4c5SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
8944393e4c5SLorenzo Bianconi 				.fs_len = 4,
8954393e4c5SLorenzo Bianconi 			},
8964393e4c5SLorenzo Bianconi 		},
8974393e4c5SLorenzo Bianconi 		.irq_config = {
8984393e4c5SLorenzo Bianconi 			.irq1 = {
8994393e4c5SLorenzo Bianconi 				.addr = 0x0d,
9004393e4c5SLorenzo Bianconi 				.mask = BIT(3),
9014393e4c5SLorenzo Bianconi 			},
9024393e4c5SLorenzo Bianconi 			.irq2 = {
9034393e4c5SLorenzo Bianconi 				.addr = 0x0e,
9044393e4c5SLorenzo Bianconi 				.mask = BIT(3),
9054393e4c5SLorenzo Bianconi 			},
9064393e4c5SLorenzo Bianconi 			.lir = {
9074393e4c5SLorenzo Bianconi 				.addr = 0x56,
9084393e4c5SLorenzo Bianconi 				.mask = BIT(0),
9094393e4c5SLorenzo Bianconi 			},
9104393e4c5SLorenzo Bianconi 			.clear_on_read = {
9114393e4c5SLorenzo Bianconi 				.addr = 0x56,
9124393e4c5SLorenzo Bianconi 				.mask = BIT(6),
9134393e4c5SLorenzo Bianconi 			},
9144393e4c5SLorenzo Bianconi 			.irq1_func = {
9154393e4c5SLorenzo Bianconi 				.addr = 0x5e,
9164393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9174393e4c5SLorenzo Bianconi 			},
9184393e4c5SLorenzo Bianconi 			.irq2_func = {
9194393e4c5SLorenzo Bianconi 				.addr = 0x5f,
9204393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9214393e4c5SLorenzo Bianconi 			},
9224393e4c5SLorenzo Bianconi 			.hla = {
9234393e4c5SLorenzo Bianconi 				.addr = 0x12,
9244393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9254393e4c5SLorenzo Bianconi 			},
9264393e4c5SLorenzo Bianconi 			.od = {
9274393e4c5SLorenzo Bianconi 				.addr = 0x12,
9284393e4c5SLorenzo Bianconi 				.mask = BIT(4),
9294393e4c5SLorenzo Bianconi 			},
9304393e4c5SLorenzo Bianconi 		},
9314393e4c5SLorenzo Bianconi 		.batch = {
9324393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
9334393e4c5SLorenzo Bianconi 				.addr = 0x09,
9344393e4c5SLorenzo Bianconi 				.mask = GENMASK(3, 0),
9354393e4c5SLorenzo Bianconi 			},
9364393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
9374393e4c5SLorenzo Bianconi 				.addr = 0x09,
9384393e4c5SLorenzo Bianconi 				.mask = GENMASK(7, 4),
9394393e4c5SLorenzo Bianconi 			},
9404393e4c5SLorenzo Bianconi 		},
9414393e4c5SLorenzo Bianconi 		.fifo_ops = {
9424393e4c5SLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
9434393e4c5SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
9444393e4c5SLorenzo Bianconi 			.fifo_th = {
9454393e4c5SLorenzo Bianconi 				.addr = 0x07,
9464393e4c5SLorenzo Bianconi 				.mask = GENMASK(8, 0),
9474393e4c5SLorenzo Bianconi 			},
9484393e4c5SLorenzo Bianconi 			.fifo_diff = {
9494393e4c5SLorenzo Bianconi 				.addr = 0x3a,
9504393e4c5SLorenzo Bianconi 				.mask = GENMASK(9, 0),
9514393e4c5SLorenzo Bianconi 			},
9521b7da2faSLorenzo Bianconi 			.max_size = 512,
9534393e4c5SLorenzo Bianconi 			.th_wl = 1,
9544393e4c5SLorenzo Bianconi 		},
9554393e4c5SLorenzo Bianconi 		.ts_settings = {
9564393e4c5SLorenzo Bianconi 			.timer_en = {
9574393e4c5SLorenzo Bianconi 				.addr = 0x19,
9584393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9594393e4c5SLorenzo Bianconi 			},
9604393e4c5SLorenzo Bianconi 			.decimator = {
9614393e4c5SLorenzo Bianconi 				.addr = 0x0a,
9624393e4c5SLorenzo Bianconi 				.mask = GENMASK(7, 6),
9634393e4c5SLorenzo Bianconi 			},
9644393e4c5SLorenzo Bianconi 			.freq_fine = 0x63,
9654393e4c5SLorenzo Bianconi 		},
9664393e4c5SLorenzo Bianconi 		.shub_settings = {
9674393e4c5SLorenzo Bianconi 			.page_mux = {
9684393e4c5SLorenzo Bianconi 				.addr = 0x01,
9694393e4c5SLorenzo Bianconi 				.mask = BIT(6),
9704393e4c5SLorenzo Bianconi 			},
9714393e4c5SLorenzo Bianconi 			.master_en = {
9724393e4c5SLorenzo Bianconi 				.sec_page = true,
9734393e4c5SLorenzo Bianconi 				.addr = 0x14,
9744393e4c5SLorenzo Bianconi 				.mask = BIT(2),
9754393e4c5SLorenzo Bianconi 			},
9764393e4c5SLorenzo Bianconi 			.pullup_en = {
9774393e4c5SLorenzo Bianconi 				.sec_page = true,
9784393e4c5SLorenzo Bianconi 				.addr = 0x14,
9794393e4c5SLorenzo Bianconi 				.mask = BIT(3),
9804393e4c5SLorenzo Bianconi 			},
9814393e4c5SLorenzo Bianconi 			.aux_sens = {
9824393e4c5SLorenzo Bianconi 				.addr = 0x14,
9834393e4c5SLorenzo Bianconi 				.mask = GENMASK(1, 0),
9844393e4c5SLorenzo Bianconi 			},
9854393e4c5SLorenzo Bianconi 			.wr_once = {
9864393e4c5SLorenzo Bianconi 				.addr = 0x14,
9874393e4c5SLorenzo Bianconi 				.mask = BIT(6),
9884393e4c5SLorenzo Bianconi 			},
9894393e4c5SLorenzo Bianconi 			.num_ext_dev = 3,
9904393e4c5SLorenzo Bianconi 			.shub_out = {
9914393e4c5SLorenzo Bianconi 				.sec_page = true,
9924393e4c5SLorenzo Bianconi 				.addr = 0x02,
9934393e4c5SLorenzo Bianconi 			},
9944393e4c5SLorenzo Bianconi 			.slv0_addr = 0x15,
9954393e4c5SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
9964393e4c5SLorenzo Bianconi 			.batch_en = BIT(3),
9974393e4c5SLorenzo Bianconi 		},
9984393e4c5SLorenzo Bianconi 		.event_settings = {
9994393e4c5SLorenzo Bianconi 			.enable_reg = {
10004393e4c5SLorenzo Bianconi 				.addr = 0x58,
10014393e4c5SLorenzo Bianconi 				.mask = BIT(7),
10024393e4c5SLorenzo Bianconi 			},
10034393e4c5SLorenzo Bianconi 			.wakeup_reg = {
10044393e4c5SLorenzo Bianconi 				.addr = 0x5b,
10054393e4c5SLorenzo Bianconi 				.mask = GENMASK(5, 0),
10064393e4c5SLorenzo Bianconi 			},
10074393e4c5SLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
10084393e4c5SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
10094393e4c5SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
10104393e4c5SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
10114393e4c5SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
10124393e4c5SLorenzo Bianconi 		},
10134393e4c5SLorenzo Bianconi 	},
101498c3544aSLorenzo Bianconi 	{
101598c3544aSLorenzo Bianconi 		.reset = {
101698c3544aSLorenzo Bianconi 			.addr = 0x12,
101798c3544aSLorenzo Bianconi 			.mask = BIT(0),
101898c3544aSLorenzo Bianconi 		},
101998c3544aSLorenzo Bianconi 		.boot = {
102098c3544aSLorenzo Bianconi 			.addr = 0x12,
102198c3544aSLorenzo Bianconi 			.mask = BIT(7),
102298c3544aSLorenzo Bianconi 		},
102398c3544aSLorenzo Bianconi 		.bdu = {
102498c3544aSLorenzo Bianconi 			.addr = 0x12,
102598c3544aSLorenzo Bianconi 			.mask = BIT(6),
102698c3544aSLorenzo Bianconi 		},
102798c3544aSLorenzo Bianconi 		.id = {
102898c3544aSLorenzo Bianconi 			{
102998c3544aSLorenzo Bianconi 				.hw_id = ST_ASM330LHH_ID,
103098c3544aSLorenzo Bianconi 				.name = ST_ASM330LHH_DEV_NAME,
103198c3544aSLorenzo Bianconi 				.wai = 0x6b,
10322c57d265SLorenzo Bianconi 			}, {
10332c57d265SLorenzo Bianconi 				.hw_id = ST_LSM6DSOP_ID,
10342c57d265SLorenzo Bianconi 				.name = ST_LSM6DSOP_DEV_NAME,
10352c57d265SLorenzo Bianconi 				.wai = 0x6c,
103618462d08SLorenzo Bianconi 			}, {
103718462d08SLorenzo Bianconi 				.hw_id = ST_ASM330LHB_ID,
103818462d08SLorenzo Bianconi 				.name = ST_ASM330LHB_DEV_NAME,
103918462d08SLorenzo Bianconi 				.wai = 0x6b,
104098c3544aSLorenzo Bianconi 			},
104198c3544aSLorenzo Bianconi 		},
104298c3544aSLorenzo Bianconi 		.channels = {
104398c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
104498c3544aSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
104598c3544aSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
104698c3544aSLorenzo Bianconi 			},
104798c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
104898c3544aSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
104998c3544aSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
105098c3544aSLorenzo Bianconi 			},
105198c3544aSLorenzo Bianconi 		},
105298c3544aSLorenzo Bianconi 		.drdy_mask = {
105398c3544aSLorenzo Bianconi 			.addr = 0x13,
105498c3544aSLorenzo Bianconi 			.mask = BIT(3),
105598c3544aSLorenzo Bianconi 		},
105698c3544aSLorenzo Bianconi 		.odr_table = {
105798c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
105898c3544aSLorenzo Bianconi 				.reg = {
105998c3544aSLorenzo Bianconi 					.addr = 0x10,
106098c3544aSLorenzo Bianconi 					.mask = GENMASK(7, 4),
106198c3544aSLorenzo Bianconi 				},
106298c3544aSLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
106398c3544aSLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
106498c3544aSLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
106598c3544aSLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
106698c3544aSLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
106798c3544aSLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
106898c3544aSLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
106998c3544aSLorenzo Bianconi 				.odr_len = 7,
107098c3544aSLorenzo Bianconi 			},
107198c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
107298c3544aSLorenzo Bianconi 				.reg = {
107398c3544aSLorenzo Bianconi 					.addr = 0x11,
107498c3544aSLorenzo Bianconi 					.mask = GENMASK(7, 4),
107598c3544aSLorenzo Bianconi 				},
107698c3544aSLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
107798c3544aSLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
107898c3544aSLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
107998c3544aSLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
108098c3544aSLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
108198c3544aSLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
108298c3544aSLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
108398c3544aSLorenzo Bianconi 				.odr_len = 7,
108498c3544aSLorenzo Bianconi 			},
108598c3544aSLorenzo Bianconi 		},
108698c3544aSLorenzo Bianconi 		.fs_table = {
108798c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
108898c3544aSLorenzo Bianconi 				.reg = {
108998c3544aSLorenzo Bianconi 					.addr = 0x10,
109098c3544aSLorenzo Bianconi 					.mask = GENMASK(3, 2),
109198c3544aSLorenzo Bianconi 				},
109298c3544aSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
109398c3544aSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
109498c3544aSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
109598c3544aSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
109698c3544aSLorenzo Bianconi 				.fs_len = 4,
109798c3544aSLorenzo Bianconi 			},
109898c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
109998c3544aSLorenzo Bianconi 				.reg = {
110098c3544aSLorenzo Bianconi 					.addr = 0x11,
110198c3544aSLorenzo Bianconi 					.mask = GENMASK(3, 2),
110298c3544aSLorenzo Bianconi 				},
110398c3544aSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
110498c3544aSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
110598c3544aSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
110698c3544aSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
110798c3544aSLorenzo Bianconi 				.fs_len = 4,
110898c3544aSLorenzo Bianconi 			},
110998c3544aSLorenzo Bianconi 		},
111098c3544aSLorenzo Bianconi 		.irq_config = {
111198c3544aSLorenzo Bianconi 			.irq1 = {
111298c3544aSLorenzo Bianconi 				.addr = 0x0d,
111398c3544aSLorenzo Bianconi 				.mask = BIT(3),
111498c3544aSLorenzo Bianconi 			},
111598c3544aSLorenzo Bianconi 			.irq2 = {
111698c3544aSLorenzo Bianconi 				.addr = 0x0e,
111798c3544aSLorenzo Bianconi 				.mask = BIT(3),
111898c3544aSLorenzo Bianconi 			},
111998c3544aSLorenzo Bianconi 			.lir = {
112098c3544aSLorenzo Bianconi 				.addr = 0x56,
112198c3544aSLorenzo Bianconi 				.mask = BIT(0),
112298c3544aSLorenzo Bianconi 			},
112398c3544aSLorenzo Bianconi 			.clear_on_read = {
112498c3544aSLorenzo Bianconi 				.addr = 0x56,
112598c3544aSLorenzo Bianconi 				.mask = BIT(6),
112698c3544aSLorenzo Bianconi 			},
112798c3544aSLorenzo Bianconi 			.irq1_func = {
112898c3544aSLorenzo Bianconi 				.addr = 0x5e,
112998c3544aSLorenzo Bianconi 				.mask = BIT(5),
113098c3544aSLorenzo Bianconi 			},
113198c3544aSLorenzo Bianconi 			.irq2_func = {
113298c3544aSLorenzo Bianconi 				.addr = 0x5f,
113398c3544aSLorenzo Bianconi 				.mask = BIT(5),
113498c3544aSLorenzo Bianconi 			},
113598c3544aSLorenzo Bianconi 			.hla = {
113698c3544aSLorenzo Bianconi 				.addr = 0x12,
113798c3544aSLorenzo Bianconi 				.mask = BIT(5),
113898c3544aSLorenzo Bianconi 			},
113998c3544aSLorenzo Bianconi 			.od = {
114098c3544aSLorenzo Bianconi 				.addr = 0x12,
114198c3544aSLorenzo Bianconi 				.mask = BIT(4),
114298c3544aSLorenzo Bianconi 			},
114398c3544aSLorenzo Bianconi 		},
114498c3544aSLorenzo Bianconi 		.batch = {
114598c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
114698c3544aSLorenzo Bianconi 				.addr = 0x09,
114798c3544aSLorenzo Bianconi 				.mask = GENMASK(3, 0),
114898c3544aSLorenzo Bianconi 			},
114998c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
115098c3544aSLorenzo Bianconi 				.addr = 0x09,
115198c3544aSLorenzo Bianconi 				.mask = GENMASK(7, 4),
115298c3544aSLorenzo Bianconi 			},
115398c3544aSLorenzo Bianconi 		},
115498c3544aSLorenzo Bianconi 		.fifo_ops = {
115598c3544aSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
115698c3544aSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
115798c3544aSLorenzo Bianconi 			.fifo_th = {
115898c3544aSLorenzo Bianconi 				.addr = 0x07,
115998c3544aSLorenzo Bianconi 				.mask = GENMASK(8, 0),
116098c3544aSLorenzo Bianconi 			},
116198c3544aSLorenzo Bianconi 			.fifo_diff = {
116298c3544aSLorenzo Bianconi 				.addr = 0x3a,
116398c3544aSLorenzo Bianconi 				.mask = GENMASK(9, 0),
116498c3544aSLorenzo Bianconi 			},
11651b7da2faSLorenzo Bianconi 			.max_size = 512,
116698c3544aSLorenzo Bianconi 			.th_wl = 1,
116798c3544aSLorenzo Bianconi 		},
116898c3544aSLorenzo Bianconi 		.ts_settings = {
116998c3544aSLorenzo Bianconi 			.timer_en = {
117098c3544aSLorenzo Bianconi 				.addr = 0x19,
117198c3544aSLorenzo Bianconi 				.mask = BIT(5),
117298c3544aSLorenzo Bianconi 			},
117398c3544aSLorenzo Bianconi 			.decimator = {
117498c3544aSLorenzo Bianconi 				.addr = 0x0a,
117598c3544aSLorenzo Bianconi 				.mask = GENMASK(7, 6),
117698c3544aSLorenzo Bianconi 			},
117798c3544aSLorenzo Bianconi 			.freq_fine = 0x63,
117898c3544aSLorenzo Bianconi 		},
117998c3544aSLorenzo Bianconi 		.event_settings = {
118098c3544aSLorenzo Bianconi 			.enable_reg = {
118198c3544aSLorenzo Bianconi 				.addr = 0x58,
118298c3544aSLorenzo Bianconi 				.mask = BIT(7),
118398c3544aSLorenzo Bianconi 			},
118498c3544aSLorenzo Bianconi 			.wakeup_reg = {
118598c3544aSLorenzo Bianconi 				.addr = 0x5B,
118698c3544aSLorenzo Bianconi 				.mask = GENMASK(5, 0),
118798c3544aSLorenzo Bianconi 			},
118898c3544aSLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
118998c3544aSLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
119098c3544aSLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
119198c3544aSLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
119298c3544aSLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
119398c3544aSLorenzo Bianconi 		},
119498c3544aSLorenzo Bianconi 	},
1195a1c6d631SLorenzo Bianconi 	{
1196a1c6d631SLorenzo Bianconi 		.reset = {
1197a1c6d631SLorenzo Bianconi 			.addr = 0x12,
1198a1c6d631SLorenzo Bianconi 			.mask = BIT(0),
1199a1c6d631SLorenzo Bianconi 		},
1200a1c6d631SLorenzo Bianconi 		.boot = {
1201a1c6d631SLorenzo Bianconi 			.addr = 0x12,
1202a1c6d631SLorenzo Bianconi 			.mask = BIT(7),
1203a1c6d631SLorenzo Bianconi 		},
1204a1c6d631SLorenzo Bianconi 		.bdu = {
1205a1c6d631SLorenzo Bianconi 			.addr = 0x12,
1206a1c6d631SLorenzo Bianconi 			.mask = BIT(6),
1207a1c6d631SLorenzo Bianconi 		},
1208a1c6d631SLorenzo Bianconi 		.id = {
1209a1c6d631SLorenzo Bianconi 			{
1210a1c6d631SLorenzo Bianconi 				.hw_id = ST_LSM6DSV_ID,
1211a1c6d631SLorenzo Bianconi 				.name = ST_LSM6DSV_DEV_NAME,
1212a1c6d631SLorenzo Bianconi 				.wai = 0x70,
121346975081SLorenzo Bianconi 			}, {
121446975081SLorenzo Bianconi 				.hw_id = ST_LSM6DSV16X_ID,
121546975081SLorenzo Bianconi 				.name = ST_LSM6DSV16X_DEV_NAME,
121646975081SLorenzo Bianconi 				.wai = 0x70,
1217a1c6d631SLorenzo Bianconi 			},
1218a1c6d631SLorenzo Bianconi 		},
1219a1c6d631SLorenzo Bianconi 		.channels = {
1220a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1221a1c6d631SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1222a1c6d631SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1223a1c6d631SLorenzo Bianconi 			},
1224a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1225a1c6d631SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1226a1c6d631SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1227a1c6d631SLorenzo Bianconi 			},
1228a1c6d631SLorenzo Bianconi 		},
1229a1c6d631SLorenzo Bianconi 		.drdy_mask = {
1230a1c6d631SLorenzo Bianconi 			.addr = 0x13,
1231a1c6d631SLorenzo Bianconi 			.mask = BIT(3),
1232a1c6d631SLorenzo Bianconi 		},
1233a1c6d631SLorenzo Bianconi 		.odr_table = {
1234a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1235a1c6d631SLorenzo Bianconi 				.reg = {
1236a1c6d631SLorenzo Bianconi 					.addr = 0x10,
1237a1c6d631SLorenzo Bianconi 					.mask = GENMASK(3, 0),
1238a1c6d631SLorenzo Bianconi 				},
1239a1c6d631SLorenzo Bianconi 				.odr_avl[0] = {   7500, 0x02 },
1240a1c6d631SLorenzo Bianconi 				.odr_avl[1] = {  15000, 0x03 },
1241a1c6d631SLorenzo Bianconi 				.odr_avl[2] = {  30000, 0x04 },
1242a1c6d631SLorenzo Bianconi 				.odr_avl[3] = {  60000, 0x05 },
1243a1c6d631SLorenzo Bianconi 				.odr_avl[4] = { 120000, 0x06 },
1244a1c6d631SLorenzo Bianconi 				.odr_avl[5] = { 240000, 0x07 },
1245a1c6d631SLorenzo Bianconi 				.odr_avl[6] = { 480000, 0x08 },
1246a1c6d631SLorenzo Bianconi 				.odr_avl[7] = { 960000, 0x09 },
1247a1c6d631SLorenzo Bianconi 				.odr_len = 8,
1248a1c6d631SLorenzo Bianconi 			},
1249a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1250a1c6d631SLorenzo Bianconi 				.reg = {
1251a1c6d631SLorenzo Bianconi 					.addr = 0x11,
1252a1c6d631SLorenzo Bianconi 					.mask = GENMASK(3, 0),
1253a1c6d631SLorenzo Bianconi 				},
1254a1c6d631SLorenzo Bianconi 				.odr_avl[0] = {   7500, 0x02 },
1255a1c6d631SLorenzo Bianconi 				.odr_avl[1] = {  15000, 0x03 },
1256a1c6d631SLorenzo Bianconi 				.odr_avl[2] = {  30000, 0x04 },
1257a1c6d631SLorenzo Bianconi 				.odr_avl[3] = {  60000, 0x05 },
1258a1c6d631SLorenzo Bianconi 				.odr_avl[4] = { 120000, 0x06 },
1259a1c6d631SLorenzo Bianconi 				.odr_avl[5] = { 240000, 0x07 },
1260a1c6d631SLorenzo Bianconi 				.odr_avl[6] = { 480000, 0x08 },
1261a1c6d631SLorenzo Bianconi 				.odr_avl[7] = { 960000, 0x09 },
1262a1c6d631SLorenzo Bianconi 				.odr_len = 8,
1263a1c6d631SLorenzo Bianconi 			},
1264a1c6d631SLorenzo Bianconi 		},
1265a1c6d631SLorenzo Bianconi 		.fs_table = {
1266a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1267a1c6d631SLorenzo Bianconi 				.reg = {
1268a1c6d631SLorenzo Bianconi 					.addr = 0x17,
1269a1c6d631SLorenzo Bianconi 					.mask = GENMASK(1, 0),
1270a1c6d631SLorenzo Bianconi 				},
1271a1c6d631SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
1272a1c6d631SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x1 },
1273a1c6d631SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x2 },
1274a1c6d631SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x3 },
1275a1c6d631SLorenzo Bianconi 				.fs_len = 4,
1276a1c6d631SLorenzo Bianconi 			},
1277a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1278a1c6d631SLorenzo Bianconi 				.reg = {
1279a1c6d631SLorenzo Bianconi 					.addr = 0x15,
1280a1c6d631SLorenzo Bianconi 					.mask = GENMASK(3, 0),
1281a1c6d631SLorenzo Bianconi 				},
1282a1c6d631SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x1 },
1283a1c6d631SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x2 },
1284a1c6d631SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x3 },
1285a1c6d631SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x4 },
1286a1c6d631SLorenzo Bianconi 				.fs_len = 4,
1287a1c6d631SLorenzo Bianconi 			},
1288a1c6d631SLorenzo Bianconi 		},
1289a1c6d631SLorenzo Bianconi 		.irq_config = {
1290a1c6d631SLorenzo Bianconi 			.irq1 = {
1291a1c6d631SLorenzo Bianconi 				.addr = 0x0d,
1292a1c6d631SLorenzo Bianconi 				.mask = BIT(3),
1293a1c6d631SLorenzo Bianconi 			},
1294a1c6d631SLorenzo Bianconi 			.irq2 = {
1295a1c6d631SLorenzo Bianconi 				.addr = 0x0e,
1296a1c6d631SLorenzo Bianconi 				.mask = BIT(3),
1297a1c6d631SLorenzo Bianconi 			},
1298a1c6d631SLorenzo Bianconi 			.lir = {
1299a1c6d631SLorenzo Bianconi 				.addr = 0x56,
1300a1c6d631SLorenzo Bianconi 				.mask = BIT(0),
1301a1c6d631SLorenzo Bianconi 			},
1302a1c6d631SLorenzo Bianconi 			.irq1_func = {
1303a1c6d631SLorenzo Bianconi 				.addr = 0x5e,
1304a1c6d631SLorenzo Bianconi 				.mask = BIT(5),
1305a1c6d631SLorenzo Bianconi 			},
1306a1c6d631SLorenzo Bianconi 			.irq2_func = {
1307a1c6d631SLorenzo Bianconi 				.addr = 0x5f,
1308a1c6d631SLorenzo Bianconi 				.mask = BIT(5),
1309a1c6d631SLorenzo Bianconi 			},
1310a1c6d631SLorenzo Bianconi 			.hla = {
1311a1c6d631SLorenzo Bianconi 				.addr = 0x03,
1312a1c6d631SLorenzo Bianconi 				.mask = BIT(4),
1313a1c6d631SLorenzo Bianconi 			},
1314a1c6d631SLorenzo Bianconi 			.od = {
1315a1c6d631SLorenzo Bianconi 				.addr = 0x03,
1316a1c6d631SLorenzo Bianconi 				.mask = BIT(3),
1317a1c6d631SLorenzo Bianconi 			},
1318a1c6d631SLorenzo Bianconi 		},
1319a1c6d631SLorenzo Bianconi 		.batch = {
1320a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1321a1c6d631SLorenzo Bianconi 				.addr = 0x09,
1322a1c6d631SLorenzo Bianconi 				.mask = GENMASK(3, 0),
1323a1c6d631SLorenzo Bianconi 			},
1324a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1325a1c6d631SLorenzo Bianconi 				.addr = 0x09,
1326a1c6d631SLorenzo Bianconi 				.mask = GENMASK(7, 4),
1327a1c6d631SLorenzo Bianconi 			},
1328a1c6d631SLorenzo Bianconi 		},
1329a1c6d631SLorenzo Bianconi 		.fifo_ops = {
1330a1c6d631SLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
1331a1c6d631SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
1332a1c6d631SLorenzo Bianconi 			.fifo_th = {
1333a1c6d631SLorenzo Bianconi 				.addr = 0x07,
1334a1c6d631SLorenzo Bianconi 				.mask = GENMASK(7, 0),
1335a1c6d631SLorenzo Bianconi 			},
1336a1c6d631SLorenzo Bianconi 			.fifo_diff = {
1337a1c6d631SLorenzo Bianconi 				.addr = 0x1b,
1338a1c6d631SLorenzo Bianconi 				.mask = GENMASK(8, 0),
1339a1c6d631SLorenzo Bianconi 			},
1340a1c6d631SLorenzo Bianconi 			.max_size = 512,
1341a1c6d631SLorenzo Bianconi 			.th_wl = 1,
1342a1c6d631SLorenzo Bianconi 		},
1343a1c6d631SLorenzo Bianconi 		.ts_settings = {
1344a1c6d631SLorenzo Bianconi 			.timer_en = {
1345a1c6d631SLorenzo Bianconi 				.addr = 0x50,
1346a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1347a1c6d631SLorenzo Bianconi 			},
1348a1c6d631SLorenzo Bianconi 			.decimator = {
1349a1c6d631SLorenzo Bianconi 				.addr = 0x0a,
1350a1c6d631SLorenzo Bianconi 				.mask = GENMASK(7, 6),
1351a1c6d631SLorenzo Bianconi 			},
1352a1c6d631SLorenzo Bianconi 			.freq_fine = 0x4f,
1353a1c6d631SLorenzo Bianconi 		},
1354a1c6d631SLorenzo Bianconi 		.shub_settings = {
1355a1c6d631SLorenzo Bianconi 			.page_mux = {
1356a1c6d631SLorenzo Bianconi 				.addr = 0x01,
1357a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1358a1c6d631SLorenzo Bianconi 			},
1359a1c6d631SLorenzo Bianconi 			.master_en = {
1360a1c6d631SLorenzo Bianconi 				.sec_page = true,
1361a1c6d631SLorenzo Bianconi 				.addr = 0x14,
1362a1c6d631SLorenzo Bianconi 				.mask = BIT(2),
1363a1c6d631SLorenzo Bianconi 			},
1364a1c6d631SLorenzo Bianconi 			.pullup_en = {
1365a1c6d631SLorenzo Bianconi 				.addr = 0x03,
1366a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1367a1c6d631SLorenzo Bianconi 			},
1368a1c6d631SLorenzo Bianconi 			.aux_sens = {
1369a1c6d631SLorenzo Bianconi 				.addr = 0x14,
1370a1c6d631SLorenzo Bianconi 				.mask = GENMASK(1, 0),
1371a1c6d631SLorenzo Bianconi 			},
1372a1c6d631SLorenzo Bianconi 			.wr_once = {
1373a1c6d631SLorenzo Bianconi 				.addr = 0x14,
1374a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1375a1c6d631SLorenzo Bianconi 			},
1376a1c6d631SLorenzo Bianconi 			.num_ext_dev = 3,
1377a1c6d631SLorenzo Bianconi 			.shub_out = {
1378a1c6d631SLorenzo Bianconi 				.sec_page = true,
1379a1c6d631SLorenzo Bianconi 				.addr = 0x02,
1380a1c6d631SLorenzo Bianconi 			},
1381a1c6d631SLorenzo Bianconi 			.slv0_addr = 0x15,
1382a1c6d631SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
1383a1c6d631SLorenzo Bianconi 			.batch_en = BIT(3),
1384a1c6d631SLorenzo Bianconi 		},
1385a1c6d631SLorenzo Bianconi 		.event_settings = {
1386a1c6d631SLorenzo Bianconi 			.enable_reg = {
1387a1c6d631SLorenzo Bianconi 				.addr = 0x50,
1388a1c6d631SLorenzo Bianconi 				.mask = BIT(7),
1389a1c6d631SLorenzo Bianconi 			},
1390a1c6d631SLorenzo Bianconi 			.wakeup_reg = {
1391a1c6d631SLorenzo Bianconi 				.addr = 0x5b,
1392a1c6d631SLorenzo Bianconi 				.mask = GENMASK(5, 0),
1393a1c6d631SLorenzo Bianconi 			},
1394a1c6d631SLorenzo Bianconi 			.wakeup_src_reg = 0x45,
1395a1c6d631SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
1396a1c6d631SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
1397a1c6d631SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
1398a1c6d631SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
1399a1c6d631SLorenzo Bianconi 		},
1400a1c6d631SLorenzo Bianconi 	},
1401f35e1ee9SLorenzo Bianconi 	{
1402f35e1ee9SLorenzo Bianconi 		.reset = {
1403f35e1ee9SLorenzo Bianconi 			.addr = 0x12,
1404f35e1ee9SLorenzo Bianconi 			.mask = BIT(0),
1405f35e1ee9SLorenzo Bianconi 		},
1406f35e1ee9SLorenzo Bianconi 		.boot = {
1407f35e1ee9SLorenzo Bianconi 			.addr = 0x12,
1408f35e1ee9SLorenzo Bianconi 			.mask = BIT(7),
1409f35e1ee9SLorenzo Bianconi 		},
1410f35e1ee9SLorenzo Bianconi 		.bdu = {
1411f35e1ee9SLorenzo Bianconi 			.addr = 0x12,
1412f35e1ee9SLorenzo Bianconi 			.mask = BIT(6),
1413f35e1ee9SLorenzo Bianconi 		},
1414f35e1ee9SLorenzo Bianconi 		.id = {
1415f35e1ee9SLorenzo Bianconi 			{
1416f35e1ee9SLorenzo Bianconi 				.hw_id = ST_LSM6DSO16IS_ID,
1417f35e1ee9SLorenzo Bianconi 				.name = ST_LSM6DSO16IS_DEV_NAME,
1418f35e1ee9SLorenzo Bianconi 				.wai = 0x22,
14193a042fdaSLorenzo Bianconi 			}, {
14203a042fdaSLorenzo Bianconi 				.hw_id = ST_ISM330IS_ID,
14213a042fdaSLorenzo Bianconi 				.name = ST_ISM330IS_DEV_NAME,
14223a042fdaSLorenzo Bianconi 				.wai = 0x22,
14233a042fdaSLorenzo Bianconi 			}
1424f35e1ee9SLorenzo Bianconi 		},
1425f35e1ee9SLorenzo Bianconi 		.channels = {
1426f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1427f35e1ee9SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1428f35e1ee9SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1429f35e1ee9SLorenzo Bianconi 			},
1430f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1431f35e1ee9SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1432f35e1ee9SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1433f35e1ee9SLorenzo Bianconi 			},
1434f35e1ee9SLorenzo Bianconi 		},
1435f35e1ee9SLorenzo Bianconi 		.odr_table = {
1436f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1437f35e1ee9SLorenzo Bianconi 				.reg = {
1438f35e1ee9SLorenzo Bianconi 					.addr = 0x10,
1439f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(7, 4),
1440f35e1ee9SLorenzo Bianconi 				},
1441f35e1ee9SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1442f35e1ee9SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1443f35e1ee9SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1444f35e1ee9SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1445f35e1ee9SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1446f35e1ee9SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
1447f35e1ee9SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
1448f35e1ee9SLorenzo Bianconi 				.odr_len = 7,
1449f35e1ee9SLorenzo Bianconi 			},
1450f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1451f35e1ee9SLorenzo Bianconi 				.reg = {
1452f35e1ee9SLorenzo Bianconi 					.addr = 0x11,
1453f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(7, 4),
1454f35e1ee9SLorenzo Bianconi 				},
1455f35e1ee9SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1456f35e1ee9SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1457f35e1ee9SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1458f35e1ee9SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1459f35e1ee9SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1460f35e1ee9SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
1461f35e1ee9SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
1462f35e1ee9SLorenzo Bianconi 				.odr_len = 7,
1463f35e1ee9SLorenzo Bianconi 			},
1464f35e1ee9SLorenzo Bianconi 		},
1465f35e1ee9SLorenzo Bianconi 		.fs_table = {
1466f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1467f35e1ee9SLorenzo Bianconi 				.reg = {
1468f35e1ee9SLorenzo Bianconi 					.addr = 0x10,
1469f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(3, 2),
1470f35e1ee9SLorenzo Bianconi 				},
1471f35e1ee9SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
1472f35e1ee9SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
1473f35e1ee9SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
1474f35e1ee9SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
1475f35e1ee9SLorenzo Bianconi 				.fs_len = 4,
1476f35e1ee9SLorenzo Bianconi 			},
1477f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1478f35e1ee9SLorenzo Bianconi 				.reg = {
1479f35e1ee9SLorenzo Bianconi 					.addr = 0x11,
1480f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(3, 2),
1481f35e1ee9SLorenzo Bianconi 				},
1482f35e1ee9SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
1483f35e1ee9SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
1484f35e1ee9SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
1485f35e1ee9SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
1486f35e1ee9SLorenzo Bianconi 				.fs_len = 4,
1487f35e1ee9SLorenzo Bianconi 			},
1488f35e1ee9SLorenzo Bianconi 		},
1489f35e1ee9SLorenzo Bianconi 		.irq_config = {
1490f35e1ee9SLorenzo Bianconi 			.hla = {
1491f35e1ee9SLorenzo Bianconi 				.addr = 0x12,
1492f35e1ee9SLorenzo Bianconi 				.mask = BIT(5),
1493f35e1ee9SLorenzo Bianconi 			},
1494f35e1ee9SLorenzo Bianconi 			.od = {
1495f35e1ee9SLorenzo Bianconi 				.addr = 0x12,
1496f35e1ee9SLorenzo Bianconi 				.mask = BIT(4),
1497f35e1ee9SLorenzo Bianconi 			},
1498f35e1ee9SLorenzo Bianconi 		},
1499f35e1ee9SLorenzo Bianconi 		.shub_settings = {
1500f35e1ee9SLorenzo Bianconi 			.page_mux = {
1501f35e1ee9SLorenzo Bianconi 				.addr = 0x01,
1502f35e1ee9SLorenzo Bianconi 				.mask = BIT(6),
1503f35e1ee9SLorenzo Bianconi 			},
1504f35e1ee9SLorenzo Bianconi 			.master_en = {
1505f35e1ee9SLorenzo Bianconi 				.sec_page = true,
1506f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1507f35e1ee9SLorenzo Bianconi 				.mask = BIT(2),
1508f35e1ee9SLorenzo Bianconi 			},
1509f35e1ee9SLorenzo Bianconi 			.pullup_en = {
1510f35e1ee9SLorenzo Bianconi 				.sec_page = true,
1511f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1512f35e1ee9SLorenzo Bianconi 				.mask = BIT(3),
1513f35e1ee9SLorenzo Bianconi 			},
1514f35e1ee9SLorenzo Bianconi 			.aux_sens = {
1515f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1516f35e1ee9SLorenzo Bianconi 				.mask = GENMASK(1, 0),
1517f35e1ee9SLorenzo Bianconi 			},
1518f35e1ee9SLorenzo Bianconi 			.wr_once = {
1519f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1520f35e1ee9SLorenzo Bianconi 				.mask = BIT(6),
1521f35e1ee9SLorenzo Bianconi 			},
1522f35e1ee9SLorenzo Bianconi 			.num_ext_dev = 3,
1523f35e1ee9SLorenzo Bianconi 			.shub_out = {
1524f35e1ee9SLorenzo Bianconi 				.sec_page = true,
1525f35e1ee9SLorenzo Bianconi 				.addr = 0x02,
1526f35e1ee9SLorenzo Bianconi 			},
1527f35e1ee9SLorenzo Bianconi 			.slv0_addr = 0x15,
1528f35e1ee9SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
1529f35e1ee9SLorenzo Bianconi 		},
1530f35e1ee9SLorenzo Bianconi 	},
1531290a6ce1SLorenzo Bianconi };
1532290a6ce1SLorenzo Bianconi 
st_lsm6dsx_set_page(struct st_lsm6dsx_hw * hw,bool enable)1533c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1534c91c1c84SLorenzo Bianconi {
1535c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1536c91c1c84SLorenzo Bianconi 	unsigned int data;
1537c91c1c84SLorenzo Bianconi 	int err;
1538c91c1c84SLorenzo Bianconi 
1539c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1540c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1541c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1542c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1543c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1544c91c1c84SLorenzo Bianconi 
1545c91c1c84SLorenzo Bianconi 	return err;
1546c91c1c84SLorenzo Bianconi }
1547c91c1c84SLorenzo Bianconi 
st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw * hw,int id,const char ** name)154881956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
154981956a93SLorenzo Bianconi 				   const char **name)
1550290a6ce1SLorenzo Bianconi {
155151a8b707SLorenzo Bianconi 	int err, i, j, data;
1552290a6ce1SLorenzo Bianconi 
1553290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1554d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
1555fb4fbc89SStephan Gerhold 			if (st_lsm6dsx_sensor_settings[i].id[j].name &&
1556fb4fbc89SStephan Gerhold 			    id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1557d068e4a0SLorenzo Bianconi 				break;
1558d068e4a0SLorenzo Bianconi 		}
1559d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1560290a6ce1SLorenzo Bianconi 			break;
1561290a6ce1SLorenzo Bianconi 	}
1562290a6ce1SLorenzo Bianconi 
1563290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1564290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1565290a6ce1SLorenzo Bianconi 		return -ENODEV;
1566290a6ce1SLorenzo Bianconi 	}
1567290a6ce1SLorenzo Bianconi 
156851a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1569290a6ce1SLorenzo Bianconi 	if (err < 0) {
1570290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1571290a6ce1SLorenzo Bianconi 		return err;
1572290a6ce1SLorenzo Bianconi 	}
1573290a6ce1SLorenzo Bianconi 
157498c3544aSLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].id[j].wai) {
1575290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1576290a6ce1SLorenzo Bianconi 		return -ENODEV;
1577290a6ce1SLorenzo Bianconi 	}
1578290a6ce1SLorenzo Bianconi 
157981956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1580290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1581290a6ce1SLorenzo Bianconi 
1582290a6ce1SLorenzo Bianconi 	return 0;
1583290a6ce1SLorenzo Bianconi }
1584290a6ce1SLorenzo Bianconi 
st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor * sensor,u32 gain)1585290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1586290a6ce1SLorenzo Bianconi 				     u32 gain)
1587290a6ce1SLorenzo Bianconi {
1588640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1589739aff87SLorenzo Bianconi 	unsigned int data;
1590290a6ce1SLorenzo Bianconi 	int i, err;
1591290a6ce1SLorenzo Bianconi 
1592640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
159385ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1594640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1595290a6ce1SLorenzo Bianconi 			break;
159685ae3aeeSLorenzo Bianconi 	}
1597290a6ce1SLorenzo Bianconi 
159885ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1599290a6ce1SLorenzo Bianconi 		return -EINVAL;
1600290a6ce1SLorenzo Bianconi 
1601640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1602640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1603640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1604640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1605290a6ce1SLorenzo Bianconi 	if (err < 0)
1606290a6ce1SLorenzo Bianconi 		return err;
1607290a6ce1SLorenzo Bianconi 
1608290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1609290a6ce1SLorenzo Bianconi 
1610290a6ce1SLorenzo Bianconi 	return 0;
1611290a6ce1SLorenzo Bianconi }
1612290a6ce1SLorenzo Bianconi 
st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor * sensor,u32 odr,u8 * val)1613f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val)
1614290a6ce1SLorenzo Bianconi {
161540dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
16162ccc1503SLorenzo Bianconi 	int i;
1617290a6ce1SLorenzo Bianconi 
161840dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
161959af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++) {
16206ffb55e5SLorenzo Bianconi 		/*
16216ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
16226ffb55e5SLorenzo Bianconi 		 * accel sensor
16236ffb55e5SLorenzo Bianconi 		 */
1624f8710f03SLorenzo Bianconi 		if (odr_table->odr_avl[i].milli_hz >= odr)
1625290a6ce1SLorenzo Bianconi 			break;
162659af4e20SLorenzo Bianconi 	}
1627290a6ce1SLorenzo Bianconi 
162859af4e20SLorenzo Bianconi 	if (i == odr_table->odr_len)
1629290a6ce1SLorenzo Bianconi 		return -EINVAL;
1630290a6ce1SLorenzo Bianconi 
163140dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1632f8710f03SLorenzo Bianconi 	return odr_table->odr_avl[i].milli_hz;
1633290a6ce1SLorenzo Bianconi }
1634290a6ce1SLorenzo Bianconi 
1635f8710f03SLorenzo Bianconi static int
st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw * hw,u32 odr,enum st_lsm6dsx_sensor_id id)1636f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr,
16376ffb55e5SLorenzo Bianconi 				enum st_lsm6dsx_sensor_id id)
16382ccc1503SLorenzo Bianconi {
16396ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
16406ffb55e5SLorenzo Bianconi 
16416ffb55e5SLorenzo Bianconi 	if (odr > 0) {
16426ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
1643f8710f03SLorenzo Bianconi 			return max_t(u32, ref->odr, odr);
16446ffb55e5SLorenzo Bianconi 		else
16456ffb55e5SLorenzo Bianconi 			return odr;
16466ffb55e5SLorenzo Bianconi 	} else {
16476ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
16486ffb55e5SLorenzo Bianconi 	}
16496ffb55e5SLorenzo Bianconi }
16506ffb55e5SLorenzo Bianconi 
1651f8710f03SLorenzo Bianconi static int
st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor * sensor,u32 req_odr)1652f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
16536ffb55e5SLorenzo Bianconi {
16546ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
165551a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
165651a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1657739aff87SLorenzo Bianconi 	unsigned int data;
16586ffb55e5SLorenzo Bianconi 	u8 val = 0;
16592ccc1503SLorenzo Bianconi 	int err;
16602ccc1503SLorenzo Bianconi 
16616ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
166294be878cSTeng Qi 	case ST_LSM6DSX_ID_GYRO:
166394be878cSTeng Qi 		break;
16646ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
16656ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
16666ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
16676ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
1668f8710f03SLorenzo Bianconi 		u32 odr;
16696ffb55e5SLorenzo Bianconi 		int i;
16706ffb55e5SLorenzo Bianconi 
16716ffb55e5SLorenzo Bianconi 		/*
16726ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
16736ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
16746ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
16756ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
16766ffb55e5SLorenzo Bianconi 		 */
16776ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
16786ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
16796ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
16806ffb55e5SLorenzo Bianconi 				continue;
16816ffb55e5SLorenzo Bianconi 
16826ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
16836ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
16846ffb55e5SLorenzo Bianconi 				/* device already configured */
16856ffb55e5SLorenzo Bianconi 				return 0;
16866ffb55e5SLorenzo Bianconi 		}
16876ffb55e5SLorenzo Bianconi 		break;
16886ffb55e5SLorenzo Bianconi 	}
168994be878cSTeng Qi 	default: /* should never occur */
169094be878cSTeng Qi 		return -EINVAL;
16916ffb55e5SLorenzo Bianconi 	}
16926ffb55e5SLorenzo Bianconi 
16936ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
16946ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
16952ccc1503SLorenzo Bianconi 		if (err < 0)
16962ccc1503SLorenzo Bianconi 			return err;
16976ffb55e5SLorenzo Bianconi 	}
16982ccc1503SLorenzo Bianconi 
169940dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1700739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1701739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
17022ccc1503SLorenzo Bianconi }
17032ccc1503SLorenzo Bianconi 
1704bd41c445SLorenzo Bianconi static int
__st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor * sensor,bool enable)1705bd41c445SLorenzo Bianconi __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
170617750443SLorenzo Bianconi 			       bool enable)
1707290a6ce1SLorenzo Bianconi {
170851a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1709f8710f03SLorenzo Bianconi 	u32 odr = enable ? sensor->odr : 0;
1710290a6ce1SLorenzo Bianconi 	int err;
1711290a6ce1SLorenzo Bianconi 
171217750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1713290a6ce1SLorenzo Bianconi 	if (err < 0)
1714290a6ce1SLorenzo Bianconi 		return err;
1715290a6ce1SLorenzo Bianconi 
171617750443SLorenzo Bianconi 	if (enable)
171717750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
171817750443SLorenzo Bianconi 	else
171917750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1720290a6ce1SLorenzo Bianconi 
1721290a6ce1SLorenzo Bianconi 	return 0;
1722290a6ce1SLorenzo Bianconi }
1723290a6ce1SLorenzo Bianconi 
1724bd41c445SLorenzo Bianconi static int
st_lsm6dsx_check_events(struct st_lsm6dsx_sensor * sensor,bool enable)1725bd41c445SLorenzo Bianconi st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable)
1726bd41c445SLorenzo Bianconi {
1727bd41c445SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1728bd41c445SLorenzo Bianconi 
1729bd41c445SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_GYRO || enable)
1730bd41c445SLorenzo Bianconi 		return 0;
1731bd41c445SLorenzo Bianconi 
1732bd41c445SLorenzo Bianconi 	return hw->enable_event;
1733bd41c445SLorenzo Bianconi }
1734bd41c445SLorenzo Bianconi 
st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor * sensor,bool enable)1735bd41c445SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1736bd41c445SLorenzo Bianconi 				 bool enable)
1737bd41c445SLorenzo Bianconi {
1738bd41c445SLorenzo Bianconi 	if (st_lsm6dsx_check_events(sensor, enable))
1739bd41c445SLorenzo Bianconi 		return 0;
1740bd41c445SLorenzo Bianconi 
1741bd41c445SLorenzo Bianconi 	return __st_lsm6dsx_sensor_set_enable(sensor, enable);
1742bd41c445SLorenzo Bianconi }
1743bd41c445SLorenzo Bianconi 
st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor * sensor,u8 addr,int * val)1744290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1745290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1746290a6ce1SLorenzo Bianconi {
174751a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1748290a6ce1SLorenzo Bianconi 	int err, delay;
1749290a6ce1SLorenzo Bianconi 	__le16 data;
1750290a6ce1SLorenzo Bianconi 
175117750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1752290a6ce1SLorenzo Bianconi 	if (err < 0)
1753290a6ce1SLorenzo Bianconi 		return err;
1754290a6ce1SLorenzo Bianconi 
1755ea85bf90SLorenzo Bianconi 	/*
1756ea85bf90SLorenzo Bianconi 	 * we need to wait for sensor settling time before
1757ea85bf90SLorenzo Bianconi 	 * reading data in order to avoid corrupted samples
1758ea85bf90SLorenzo Bianconi 	 */
1759f8710f03SLorenzo Bianconi 	delay = 1000000000 / sensor->odr;
1760ea85bf90SLorenzo Bianconi 	usleep_range(3 * delay, 4 * delay);
1761290a6ce1SLorenzo Bianconi 
1762739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1763290a6ce1SLorenzo Bianconi 	if (err < 0)
1764290a6ce1SLorenzo Bianconi 		return err;
1765290a6ce1SLorenzo Bianconi 
1766a2dd9bd9SLorenzo Bianconi 	if (!hw->enable_event) {
1767a2dd9bd9SLorenzo Bianconi 		err = st_lsm6dsx_sensor_set_enable(sensor, false);
1768a2dd9bd9SLorenzo Bianconi 		if (err < 0)
1769a2dd9bd9SLorenzo Bianconi 			return err;
1770a2dd9bd9SLorenzo Bianconi 	}
1771290a6ce1SLorenzo Bianconi 
17727b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1773290a6ce1SLorenzo Bianconi 
1774290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1775290a6ce1SLorenzo Bianconi }
1776290a6ce1SLorenzo Bianconi 
st_lsm6dsx_read_raw(struct iio_dev * iio_dev,struct iio_chan_spec const * ch,int * val,int * val2,long mask)1777290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1778290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1779290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1780290a6ce1SLorenzo Bianconi {
1781290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1782290a6ce1SLorenzo Bianconi 	int ret;
1783290a6ce1SLorenzo Bianconi 
1784290a6ce1SLorenzo Bianconi 	switch (mask) {
1785290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1786290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1787290a6ce1SLorenzo Bianconi 		if (ret)
1788290a6ce1SLorenzo Bianconi 			break;
1789290a6ce1SLorenzo Bianconi 
1790290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1791290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1792290a6ce1SLorenzo Bianconi 		break;
1793290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1794f8710f03SLorenzo Bianconi 		*val = sensor->odr / 1000;
1795f8710f03SLorenzo Bianconi 		*val2 = (sensor->odr % 1000) * 1000;
1796f8710f03SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1797290a6ce1SLorenzo Bianconi 		break;
1798290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1799290a6ce1SLorenzo Bianconi 		*val = 0;
1800290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
180144a76de8SMario Tesi 		ret = IIO_VAL_INT_PLUS_NANO;
1802290a6ce1SLorenzo Bianconi 		break;
1803290a6ce1SLorenzo Bianconi 	default:
1804290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1805290a6ce1SLorenzo Bianconi 		break;
1806290a6ce1SLorenzo Bianconi 	}
1807290a6ce1SLorenzo Bianconi 
1808290a6ce1SLorenzo Bianconi 	return ret;
1809290a6ce1SLorenzo Bianconi }
1810290a6ce1SLorenzo Bianconi 
st_lsm6dsx_write_raw(struct iio_dev * iio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)1811290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1812290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1813290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1814290a6ce1SLorenzo Bianconi {
1815290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1816290a6ce1SLorenzo Bianconi 	int err;
1817290a6ce1SLorenzo Bianconi 
1818290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1819290a6ce1SLorenzo Bianconi 	if (err)
1820290a6ce1SLorenzo Bianconi 		return err;
1821290a6ce1SLorenzo Bianconi 
1822290a6ce1SLorenzo Bianconi 	switch (mask) {
1823290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1824290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1825290a6ce1SLorenzo Bianconi 		break;
18262ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
18272ccc1503SLorenzo Bianconi 		u8 data;
18282ccc1503SLorenzo Bianconi 
1829f8710f03SLorenzo Bianconi 		val = val * 1000 + val2 / 1000;
1830fc3f6ad7SLorenzo Bianconi 		val = st_lsm6dsx_check_odr(sensor, val, &data);
1831fc3f6ad7SLorenzo Bianconi 		if (val < 0)
1832fc3f6ad7SLorenzo Bianconi 			err = val;
1833fc3f6ad7SLorenzo Bianconi 		else
18345e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1835290a6ce1SLorenzo Bianconi 		break;
18362ccc1503SLorenzo Bianconi 	}
1837290a6ce1SLorenzo Bianconi 	default:
1838290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1839290a6ce1SLorenzo Bianconi 		break;
1840290a6ce1SLorenzo Bianconi 	}
1841290a6ce1SLorenzo Bianconi 
1842290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1843290a6ce1SLorenzo Bianconi 
1844290a6ce1SLorenzo Bianconi 	return err;
1845290a6ce1SLorenzo Bianconi }
1846290a6ce1SLorenzo Bianconi 
st_lsm6dsx_event_setup(struct st_lsm6dsx_hw * hw,int state)1847b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1848b5969abfSSean Nyekjaer {
184984b2e7c3SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
185004ca37d5SLorenzo Bianconi 	unsigned int data;
1851b5969abfSSean Nyekjaer 	int err;
1852b5969abfSSean Nyekjaer 
18537e906103SLorenzo Bianconi 	if (!hw->settings->irq_config.irq1_func.addr)
1854b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1855b5969abfSSean Nyekjaer 
185684b2e7c3SLorenzo Bianconi 	reg = &hw->settings->event_settings.enable_reg;
185784b2e7c3SLorenzo Bianconi 	if (reg->addr) {
185804ca37d5SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
185904ca37d5SLorenzo Bianconi 		err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
186004ca37d5SLorenzo Bianconi 						    reg->mask, data);
1861b5969abfSSean Nyekjaer 		if (err < 0)
1862b5969abfSSean Nyekjaer 			return err;
186384b2e7c3SLorenzo Bianconi 	}
1864b5969abfSSean Nyekjaer 
1865b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
186604ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
186704ca37d5SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
186804ca37d5SLorenzo Bianconi 					     hw->irq_routing->mask, data);
1869b5969abfSSean Nyekjaer }
1870b5969abfSSean Nyekjaer 
st_lsm6dsx_read_event(struct iio_dev * iio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)1871b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1872b5969abfSSean Nyekjaer 				 const struct iio_chan_spec *chan,
1873b5969abfSSean Nyekjaer 				 enum iio_event_type type,
1874b5969abfSSean Nyekjaer 				 enum iio_event_direction dir,
1875b5969abfSSean Nyekjaer 				 enum iio_event_info info,
1876b5969abfSSean Nyekjaer 				 int *val, int *val2)
1877b5969abfSSean Nyekjaer {
1878b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1879b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1880b5969abfSSean Nyekjaer 
1881b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1882b5969abfSSean Nyekjaer 		return -EINVAL;
1883b5969abfSSean Nyekjaer 
1884b5969abfSSean Nyekjaer 	*val2 = 0;
1885b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1886b5969abfSSean Nyekjaer 
1887b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1888b5969abfSSean Nyekjaer }
1889b5969abfSSean Nyekjaer 
1890b307f495SLorenzo Bianconi static int
st_lsm6dsx_write_event(struct iio_dev * iio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)1891b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1892b5969abfSSean Nyekjaer 		       const struct iio_chan_spec *chan,
1893b5969abfSSean Nyekjaer 		       enum iio_event_type type,
1894b5969abfSSean Nyekjaer 		       enum iio_event_direction dir,
1895b5969abfSSean Nyekjaer 		       enum iio_event_info info,
1896b5969abfSSean Nyekjaer 		       int val, int val2)
1897b5969abfSSean Nyekjaer {
1898b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1899b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
190004ca37d5SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
190104ca37d5SLorenzo Bianconi 	unsigned int data;
1902b5969abfSSean Nyekjaer 	int err;
1903b5969abfSSean Nyekjaer 
1904b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1905b5969abfSSean Nyekjaer 		return -EINVAL;
1906b5969abfSSean Nyekjaer 
1907b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1908b5969abfSSean Nyekjaer 		return -EINVAL;
1909b5969abfSSean Nyekjaer 
191004ca37d5SLorenzo Bianconi 	reg = &hw->settings->event_settings.wakeup_reg;
191104ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
191204ca37d5SLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
191304ca37d5SLorenzo Bianconi 					    reg->mask, data);
191404ca37d5SLorenzo Bianconi 	if (err < 0)
1915b5969abfSSean Nyekjaer 		return -EINVAL;
1916b5969abfSSean Nyekjaer 
1917b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1918b5969abfSSean Nyekjaer 
1919b5969abfSSean Nyekjaer 	return 0;
1920b5969abfSSean Nyekjaer }
1921b5969abfSSean Nyekjaer 
1922b307f495SLorenzo Bianconi static int
st_lsm6dsx_read_event_config(struct iio_dev * iio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)1923b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1924b5969abfSSean Nyekjaer 			     const struct iio_chan_spec *chan,
1925b5969abfSSean Nyekjaer 			     enum iio_event_type type,
1926b5969abfSSean Nyekjaer 			     enum iio_event_direction dir)
1927b5969abfSSean Nyekjaer {
1928b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1929b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1930b5969abfSSean Nyekjaer 
1931b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1932b5969abfSSean Nyekjaer 		return -EINVAL;
1933b5969abfSSean Nyekjaer 
19341aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1935b5969abfSSean Nyekjaer }
1936b5969abfSSean Nyekjaer 
1937b307f495SLorenzo Bianconi static int
st_lsm6dsx_write_event_config(struct iio_dev * iio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,int state)1938b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1939b5969abfSSean Nyekjaer 			      const struct iio_chan_spec *chan,
1940b5969abfSSean Nyekjaer 			      enum iio_event_type type,
1941b307f495SLorenzo Bianconi 			      enum iio_event_direction dir, int state)
1942b5969abfSSean Nyekjaer {
1943b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1944b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
19451aabad1fSSean Nyekjaer 	u8 enable_event;
1946bd41c445SLorenzo Bianconi 	int err;
1947b5969abfSSean Nyekjaer 
1948b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1949b5969abfSSean Nyekjaer 		return -EINVAL;
1950b5969abfSSean Nyekjaer 
19511aabad1fSSean Nyekjaer 	if (state) {
19521aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
19531aabad1fSSean Nyekjaer 
1954b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
19551aabad1fSSean Nyekjaer 		if (hw->enable_event)
19561aabad1fSSean Nyekjaer 			goto out;
19571aabad1fSSean Nyekjaer 	} else {
19581aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
19591aabad1fSSean Nyekjaer 
19601aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
19611aabad1fSSean Nyekjaer 		if (enable_event)
19621aabad1fSSean Nyekjaer 			goto out;
19631aabad1fSSean Nyekjaer 	}
19641aabad1fSSean Nyekjaer 
19651aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
19661aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1967b5969abfSSean Nyekjaer 		return 0;
1968b5969abfSSean Nyekjaer 
1969b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1970b5969abfSSean Nyekjaer 	if (err < 0)
1971b5969abfSSean Nyekjaer 		return err;
1972b5969abfSSean Nyekjaer 
1973d278d447SLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1974bd41c445SLorenzo Bianconi 	if (enable_event || !(hw->fifo_mask & BIT(sensor->id)))
1975bd41c445SLorenzo Bianconi 		err = __st_lsm6dsx_sensor_set_enable(sensor, state);
1976d278d447SLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1977b5969abfSSean Nyekjaer 	if (err < 0)
1978b5969abfSSean Nyekjaer 		return err;
1979b5969abfSSean Nyekjaer 
19801aabad1fSSean Nyekjaer out:
19811aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1982b5969abfSSean Nyekjaer 
1983b5969abfSSean Nyekjaer 	return 0;
1984b5969abfSSean Nyekjaer }
1985b5969abfSSean Nyekjaer 
st_lsm6dsx_set_watermark(struct iio_dev * iio_dev,unsigned int val)1986d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1987290a6ce1SLorenzo Bianconi {
1988290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1989290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
19908f2a88a2SLorenzo Bianconi 	int err;
1991290a6ce1SLorenzo Bianconi 
19929e5b4cd2SPaul Cercueil 	val = clamp_val(val, 1, hw->settings->fifo_ops.max_size);
1993290a6ce1SLorenzo Bianconi 
1994335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1995335eaedcSLorenzo Bianconi 
1996290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
1997335eaedcSLorenzo Bianconi 
1998335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1999335eaedcSLorenzo Bianconi 
2000290a6ce1SLorenzo Bianconi 	if (err < 0)
2001290a6ce1SLorenzo Bianconi 		return err;
2002290a6ce1SLorenzo Bianconi 
2003290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
2004290a6ce1SLorenzo Bianconi 
2005290a6ce1SLorenzo Bianconi 	return 0;
2006290a6ce1SLorenzo Bianconi }
2007290a6ce1SLorenzo Bianconi 
2008290a6ce1SLorenzo Bianconi static ssize_t
st_lsm6dsx_sysfs_sampling_frequency_avail(struct device * dev,struct device_attribute * attr,char * buf)2009290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
2010290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
2011290a6ce1SLorenzo Bianconi 					  char *buf)
2012290a6ce1SLorenzo Bianconi {
20136270bf1fSHaibo Chen 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev));
201459af4e20SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
2015290a6ce1SLorenzo Bianconi 	int i, len = 0;
2016290a6ce1SLorenzo Bianconi 
201759af4e20SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
201859af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++)
2019f8710f03SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ",
2020f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz / 1000,
2021f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz % 1000);
2022290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
2023290a6ce1SLorenzo Bianconi 
2024290a6ce1SLorenzo Bianconi 	return len;
2025290a6ce1SLorenzo Bianconi }
2026290a6ce1SLorenzo Bianconi 
st_lsm6dsx_sysfs_scale_avail(struct device * dev,struct device_attribute * attr,char * buf)2027290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
2028290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
2029290a6ce1SLorenzo Bianconi 					    char *buf)
2030290a6ce1SLorenzo Bianconi {
20316270bf1fSHaibo Chen 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev));
20320f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
2033640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
2034290a6ce1SLorenzo Bianconi 	int i, len = 0;
2035290a6ce1SLorenzo Bianconi 
203685ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
203785ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
203844a76de8SMario Tesi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ",
20390f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
2040290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
2041290a6ce1SLorenzo Bianconi 
2042290a6ce1SLorenzo Bianconi 	return len;
2043290a6ce1SLorenzo Bianconi }
2044290a6ce1SLorenzo Bianconi 
st_lsm6dsx_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)204544a76de8SMario Tesi static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev,
204644a76de8SMario Tesi 					struct iio_chan_spec const *chan,
204744a76de8SMario Tesi 					long mask)
204844a76de8SMario Tesi {
204944a76de8SMario Tesi 	switch (mask) {
205044a76de8SMario Tesi 	case IIO_CHAN_INFO_SCALE:
205144a76de8SMario Tesi 		switch (chan->type) {
205244a76de8SMario Tesi 		case IIO_ANGL_VEL:
205344a76de8SMario Tesi 		case IIO_ACCEL:
205444a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_NANO;
205544a76de8SMario Tesi 		default:
205644a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_MICRO;
205744a76de8SMario Tesi 		}
205844a76de8SMario Tesi 	default:
205944a76de8SMario Tesi 		return IIO_VAL_INT_PLUS_MICRO;
206044a76de8SMario Tesi 	}
206144a76de8SMario Tesi }
206244a76de8SMario Tesi 
2063290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
2064290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
2065290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
2066290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
2067290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
2068290a6ce1SLorenzo Bianconi 
2069290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
2070290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
2071290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
2072290a6ce1SLorenzo Bianconi 	NULL,
2073290a6ce1SLorenzo Bianconi };
2074290a6ce1SLorenzo Bianconi 
2075290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
2076290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
2077290a6ce1SLorenzo Bianconi };
2078290a6ce1SLorenzo Bianconi 
2079290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
2080290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
2081290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
2082290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
2083b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
2084b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
2085b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
2086b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
2087290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
208844a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
2089290a6ce1SLorenzo Bianconi };
2090290a6ce1SLorenzo Bianconi 
2091290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
2092290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
2093290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
2094290a6ce1SLorenzo Bianconi 	NULL,
2095290a6ce1SLorenzo Bianconi };
2096290a6ce1SLorenzo Bianconi 
2097290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
2098290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
2099290a6ce1SLorenzo Bianconi };
2100290a6ce1SLorenzo Bianconi 
2101290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
2102290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
2103290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
2104290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
2105290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
210644a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
2107290a6ce1SLorenzo Bianconi };
2108290a6ce1SLorenzo Bianconi 
st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw * hw,int * drdy_pin)210903d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
2110dba32904SLorenzo Bianconi {
211103d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2112dba32904SLorenzo Bianconi 
211303d4c566SAndy Shevchenko 	if (!dev_fwnode(dev))
2114dba32904SLorenzo Bianconi 		return -EINVAL;
2115dba32904SLorenzo Bianconi 
211603d4c566SAndy Shevchenko 	return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
2117dba32904SLorenzo Bianconi }
2118dba32904SLorenzo Bianconi 
21197e906103SLorenzo Bianconi static int
st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw * hw,const struct st_lsm6dsx_reg ** drdy_reg)21207e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
21217e906103SLorenzo Bianconi 			const struct st_lsm6dsx_reg **drdy_reg)
2122dba32904SLorenzo Bianconi {
2123dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
2124dba32904SLorenzo Bianconi 
212503d4c566SAndy Shevchenko 	if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
2126dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
2127dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
2128dba32904SLorenzo Bianconi 
2129dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
2130dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
2131dba32904SLorenzo Bianconi 	}
2132dba32904SLorenzo Bianconi 
2133dba32904SLorenzo Bianconi 	switch (drdy_pin) {
2134dba32904SLorenzo Bianconi 	case 1:
21357e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq1_func;
21367e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq1;
2137dba32904SLorenzo Bianconi 		break;
2138dba32904SLorenzo Bianconi 	case 2:
21397e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq2_func;
21407e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq2;
2141dba32904SLorenzo Bianconi 		break;
2142dba32904SLorenzo Bianconi 	default:
2143dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
2144dba32904SLorenzo Bianconi 		err = -EINVAL;
2145dba32904SLorenzo Bianconi 		break;
2146dba32904SLorenzo Bianconi 	}
2147dba32904SLorenzo Bianconi 
2148dba32904SLorenzo Bianconi 	return err;
2149dba32904SLorenzo Bianconi }
2150dba32904SLorenzo Bianconi 
st_lsm6dsx_init_shub(struct st_lsm6dsx_hw * hw)2151c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
2152c91c1c84SLorenzo Bianconi {
2153c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2154c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
215503d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2156c91c1c84SLorenzo Bianconi 	unsigned int data;
2157c91c1c84SLorenzo Bianconi 	int err = 0;
2158c91c1c84SLorenzo Bianconi 
2159c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2160c91c1c84SLorenzo Bianconi 
216103d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
216203d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
2163c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
21643a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page) {
2165c91c1c84SLorenzo Bianconi 			err = st_lsm6dsx_set_page(hw, true);
2166c91c1c84SLorenzo Bianconi 			if (err < 0)
2167c91c1c84SLorenzo Bianconi 				return err;
21683a431957SLorenzo Bianconi 		}
2169c91c1c84SLorenzo Bianconi 
2170c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
2171c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2172c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
2173c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
2174c91c1c84SLorenzo Bianconi 
21753a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page)
2176c91c1c84SLorenzo Bianconi 			st_lsm6dsx_set_page(hw, false);
2177c91c1c84SLorenzo Bianconi 
2178c91c1c84SLorenzo Bianconi 		if (err < 0)
2179c91c1c84SLorenzo Bianconi 			return err;
2180c91c1c84SLorenzo Bianconi 	}
2181c91c1c84SLorenzo Bianconi 
2182c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
2183c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
2184c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
2185c91c1c84SLorenzo Bianconi 		if (err < 0)
2186c91c1c84SLorenzo Bianconi 			return err;
2187c91c1c84SLorenzo Bianconi 
2188c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
2189c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2190c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
2191c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
2192c91c1c84SLorenzo Bianconi 
2193c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
2194e485e2a2SLorenzo Bianconi 
2195e485e2a2SLorenzo Bianconi 		if (err < 0)
2196e485e2a2SLorenzo Bianconi 			return err;
2197e485e2a2SLorenzo Bianconi 	}
2198e485e2a2SLorenzo Bianconi 
2199e485e2a2SLorenzo Bianconi 	if (hub_settings->emb_func.addr) {
2200e485e2a2SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask);
2201e485e2a2SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2202e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.addr,
2203e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.mask, data);
2204c91c1c84SLorenzo Bianconi 	}
2205c91c1c84SLorenzo Bianconi 
2206c91c1c84SLorenzo Bianconi 	return err;
2207c91c1c84SLorenzo Bianconi }
2208c91c1c84SLorenzo Bianconi 
st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw * hw)220921345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
221021345107SLorenzo Bianconi {
221121345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
221221345107SLorenzo Bianconi 	int err, val;
221321345107SLorenzo Bianconi 
221421345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
221521345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
221621345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
221721345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
221821345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
221921345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
222021345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
222121345107SLorenzo Bianconi 		if (err < 0)
222221345107SLorenzo Bianconi 			return err;
222321345107SLorenzo Bianconi 	}
222421345107SLorenzo Bianconi 
222521345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
222621345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
222721345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
222821345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
222921345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
223021345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
223121345107SLorenzo Bianconi 		if (err < 0)
223221345107SLorenzo Bianconi 			return err;
223321345107SLorenzo Bianconi 	}
223421345107SLorenzo Bianconi 
223521345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
223621345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
223721345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
223821345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
223921345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
224021345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
224121345107SLorenzo Bianconi 		if (err < 0)
224221345107SLorenzo Bianconi 			return err;
224321345107SLorenzo Bianconi 	}
2244cb3b6b8eSMario Tesi 
2245cb3b6b8eSMario Tesi 	/* calibrate timestamp sensitivity */
2246cb3b6b8eSMario Tesi 	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
2247cb3b6b8eSMario Tesi 	if (ts_settings->freq_fine) {
2248cb3b6b8eSMario Tesi 		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
2249cb3b6b8eSMario Tesi 		if (err < 0)
2250cb3b6b8eSMario Tesi 			return err;
2251cb3b6b8eSMario Tesi 
2252cb3b6b8eSMario Tesi 		/*
2253cb3b6b8eSMario Tesi 		 * linearize the AN5192 formula:
2254cb3b6b8eSMario Tesi 		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
2255cb3b6b8eSMario Tesi 		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
2256cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - 37.5 * val
2257cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
2258cb3b6b8eSMario Tesi 		 */
2259cb3b6b8eSMario Tesi 		hw->ts_gain -= ((s8)val * 37500) / 1000;
2260cb3b6b8eSMario Tesi 	}
2261cb3b6b8eSMario Tesi 
226221345107SLorenzo Bianconi 	return 0;
226321345107SLorenzo Bianconi }
226421345107SLorenzo Bianconi 
st_lsm6dsx_reset_device(struct st_lsm6dsx_hw * hw)22653a63da26SLorenzo Bianconi static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
2266290a6ce1SLorenzo Bianconi {
22677e906103SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
2268290a6ce1SLorenzo Bianconi 	int err;
2269290a6ce1SLorenzo Bianconi 
22703a63da26SLorenzo Bianconi 	/*
22713a63da26SLorenzo Bianconi 	 * flush hw FIFO before device reset in order to avoid
22723a63da26SLorenzo Bianconi 	 * possible races on interrupt line 1. If the first interrupt
22733a63da26SLorenzo Bianconi 	 * line is asserted during hw reset the device will work in
22743a63da26SLorenzo Bianconi 	 * I3C-only mode (if it is supported)
22753a63da26SLorenzo Bianconi 	 */
22763a63da26SLorenzo Bianconi 	err = st_lsm6dsx_flush_fifo(hw);
22773a63da26SLorenzo Bianconi 	if (err < 0 && err != -ENOTSUPP)
22783a63da26SLorenzo Bianconi 		return err;
22793a63da26SLorenzo Bianconi 
228019435425SLorenzo Bianconi 	/* device sw reset */
228166b662a1SLorenzo Bianconi 	reg = &hw->settings->reset;
228266b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
228366b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2284290a6ce1SLorenzo Bianconi 	if (err < 0)
2285290a6ce1SLorenzo Bianconi 		return err;
2286290a6ce1SLorenzo Bianconi 
228719435425SLorenzo Bianconi 	msleep(50);
228819435425SLorenzo Bianconi 
228919435425SLorenzo Bianconi 	/* reload trimming parameter */
229066b662a1SLorenzo Bianconi 	reg = &hw->settings->boot;
229166b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
229266b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
229319435425SLorenzo Bianconi 	if (err < 0)
229419435425SLorenzo Bianconi 		return err;
229519435425SLorenzo Bianconi 
229619435425SLorenzo Bianconi 	msleep(50);
2297290a6ce1SLorenzo Bianconi 
22983a63da26SLorenzo Bianconi 	return 0;
22993a63da26SLorenzo Bianconi }
23003a63da26SLorenzo Bianconi 
st_lsm6dsx_init_device(struct st_lsm6dsx_hw * hw)23013a63da26SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
23023a63da26SLorenzo Bianconi {
23033a63da26SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
23043a63da26SLorenzo Bianconi 	int err;
23053a63da26SLorenzo Bianconi 
23063a63da26SLorenzo Bianconi 	err = st_lsm6dsx_reset_device(hw);
23073a63da26SLorenzo Bianconi 	if (err < 0)
23083a63da26SLorenzo Bianconi 		return err;
23093a63da26SLorenzo Bianconi 
2310290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
231166b662a1SLorenzo Bianconi 	reg = &hw->settings->bdu;
231266b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
231366b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2314290a6ce1SLorenzo Bianconi 	if (err < 0)
2315290a6ce1SLorenzo Bianconi 		return err;
2316290a6ce1SLorenzo Bianconi 
2317290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
23187e906103SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &reg);
2319290a6ce1SLorenzo Bianconi 	if (err < 0)
2320290a6ce1SLorenzo Bianconi 		return err;
2321290a6ce1SLorenzo Bianconi 
23227e906103SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
23237e906103SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
232421345107SLorenzo Bianconi 	if (err < 0)
232521345107SLorenzo Bianconi 		return err;
232621345107SLorenzo Bianconi 
23279db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
23287e906103SLorenzo Bianconi 	if (hw->settings->irq_config.lir.addr) {
23297e906103SLorenzo Bianconi 		reg = &hw->settings->irq_config.lir;
23307e906103SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
23317e906103SLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
23329db02d32SLorenzo Bianconi 		if (err < 0)
23339db02d32SLorenzo Bianconi 			return err;
233422ea5651SLorenzo Bianconi 
233522ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
23367e906103SLorenzo Bianconi 		if (hw->settings->irq_config.clear_on_read.addr) {
23377e906103SLorenzo Bianconi 			reg = &hw->settings->irq_config.clear_on_read;
233822ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
23397e906103SLorenzo Bianconi 					reg->addr, reg->mask,
23407e906103SLorenzo Bianconi 					ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
234122ea5651SLorenzo Bianconi 			if (err < 0)
234222ea5651SLorenzo Bianconi 				return err;
234322ea5651SLorenzo Bianconi 		}
23449db02d32SLorenzo Bianconi 	}
23459db02d32SLorenzo Bianconi 
2346960506edSLorenzo Bianconi 	/* enable drdy-mas if available */
2347960506edSLorenzo Bianconi 	if (hw->settings->drdy_mask.addr) {
2348960506edSLorenzo Bianconi 		reg = &hw->settings->drdy_mask;
2349960506edSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2350960506edSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2351960506edSLorenzo Bianconi 		if (err < 0)
2352960506edSLorenzo Bianconi 			return err;
2353960506edSLorenzo Bianconi 	}
2354960506edSLorenzo Bianconi 
2355c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
2356c91c1c84SLorenzo Bianconi 	if (err < 0)
2357c91c1c84SLorenzo Bianconi 		return err;
2358c91c1c84SLorenzo Bianconi 
235921345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
2360290a6ce1SLorenzo Bianconi }
2361290a6ce1SLorenzo Bianconi 
st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw * hw,enum st_lsm6dsx_sensor_id id,const char * name)2362290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
2363510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
2364510c0106SLorenzo Bianconi 					       const char *name)
2365290a6ce1SLorenzo Bianconi {
2366290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2367290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
2368290a6ce1SLorenzo Bianconi 
2369290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
2370290a6ce1SLorenzo Bianconi 	if (!iio_dev)
2371290a6ce1SLorenzo Bianconi 		return NULL;
2372290a6ce1SLorenzo Bianconi 
2373290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
2374290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2375f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
2376f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
2377290a6ce1SLorenzo Bianconi 
2378290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
2379290a6ce1SLorenzo Bianconi 	sensor->id = id;
2380290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
2381f8710f03SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz;
2382640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
2383290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
2384290a6ce1SLorenzo Bianconi 
2385290a6ce1SLorenzo Bianconi 	switch (id) {
2386290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
2387290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
2388510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
2389510c0106SLorenzo Bianconi 			  name);
2390290a6ce1SLorenzo Bianconi 		break;
2391290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
2392290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
2393510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
2394510c0106SLorenzo Bianconi 			  name);
2395290a6ce1SLorenzo Bianconi 		break;
2396290a6ce1SLorenzo Bianconi 	default:
2397290a6ce1SLorenzo Bianconi 		return NULL;
2398290a6ce1SLorenzo Bianconi 	}
2399510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
2400290a6ce1SLorenzo Bianconi 
2401290a6ce1SLorenzo Bianconi 	return iio_dev;
2402290a6ce1SLorenzo Bianconi }
2403290a6ce1SLorenzo Bianconi 
2404615bd378SLorenzo Bianconi static bool
st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw * hw)2405615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
24061aabad1fSSean Nyekjaer {
2407615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
2408615bd378SLorenzo Bianconi 	int err, data;
2409615bd378SLorenzo Bianconi 	s64 timestamp;
24101aabad1fSSean Nyekjaer 
2411615bd378SLorenzo Bianconi 	if (!hw->enable_event)
2412615bd378SLorenzo Bianconi 		return false;
2413615bd378SLorenzo Bianconi 
2414615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
2415615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2416615bd378SLorenzo Bianconi 				     &data, sizeof(data));
2417615bd378SLorenzo Bianconi 	if (err < 0)
2418615bd378SLorenzo Bianconi 		return false;
2419615bd378SLorenzo Bianconi 
2420615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
24211aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
24221aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
24231aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24241aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24251aabad1fSSean Nyekjaer 						  0,
24261aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
24271aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24281aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24291aabad1fSSean Nyekjaer 						  timestamp);
24301aabad1fSSean Nyekjaer 
24311aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
24321aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
24331aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24341aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24351aabad1fSSean Nyekjaer 						  0,
24361aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
24371aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24381aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24391aabad1fSSean Nyekjaer 						  timestamp);
24401aabad1fSSean Nyekjaer 
24411aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
24421aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
24431aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24441aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24451aabad1fSSean Nyekjaer 						  0,
24461aabad1fSSean Nyekjaer 						  IIO_MOD_X,
24471aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24481aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24491aabad1fSSean Nyekjaer 						  timestamp);
2450615bd378SLorenzo Bianconi 
2451615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
24521aabad1fSSean Nyekjaer }
24531aabad1fSSean Nyekjaer 
st_lsm6dsx_handler_thread(int irq,void * private)24546ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
24556ee6a368SSean Nyekjaer {
24566ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
24573f9bce7aSLorenzo Bianconi 	int fifo_len = 0, len;
2458615bd378SLorenzo Bianconi 	bool event;
24591aabad1fSSean Nyekjaer 
2460615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
24616ee6a368SSean Nyekjaer 
2462a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
2463a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
2464a912ee4cSLorenzo Bianconi 
24653f9bce7aSLorenzo Bianconi 	/*
24663f9bce7aSLorenzo Bianconi 	 * If we are using edge IRQs, new samples can arrive while
24673f9bce7aSLorenzo Bianconi 	 * processing current interrupt since there are no hw
24683f9bce7aSLorenzo Bianconi 	 * guarantees the irq line stays "low" long enough to properly
24693f9bce7aSLorenzo Bianconi 	 * detect the new interrupt. In this case the new sample will
24703f9bce7aSLorenzo Bianconi 	 * be missed.
24713f9bce7aSLorenzo Bianconi 	 * Polling FIFO status register allow us to read new
24723f9bce7aSLorenzo Bianconi 	 * samples even if the interrupt arrives while processing
24733f9bce7aSLorenzo Bianconi 	 * previous data and the timeslot where the line is "low" is
24743f9bce7aSLorenzo Bianconi 	 * too short to be properly detected.
24753f9bce7aSLorenzo Bianconi 	 */
24763f9bce7aSLorenzo Bianconi 	do {
24776ee6a368SSean Nyekjaer 		mutex_lock(&hw->fifo_lock);
24783f9bce7aSLorenzo Bianconi 		len = hw->settings->fifo_ops.read_fifo(hw);
24796ee6a368SSean Nyekjaer 		mutex_unlock(&hw->fifo_lock);
24806ee6a368SSean Nyekjaer 
24813f9bce7aSLorenzo Bianconi 		if (len > 0)
24823f9bce7aSLorenzo Bianconi 			fifo_len += len;
24833f9bce7aSLorenzo Bianconi 	} while (len > 0);
24843f9bce7aSLorenzo Bianconi 
24853f9bce7aSLorenzo Bianconi 	return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
24866ee6a368SSean Nyekjaer }
24876ee6a368SSean Nyekjaer 
st_lsm6dsx_sw_trigger_handler_thread(int irq,void * private)24882cfb2180SLorenzo Bianconi static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq,
24892cfb2180SLorenzo Bianconi 							void *private)
24902cfb2180SLorenzo Bianconi {
24912cfb2180SLorenzo Bianconi 	struct iio_poll_func *pf = private;
24922cfb2180SLorenzo Bianconi 	struct iio_dev *iio_dev = pf->indio_dev;
24932cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
24942cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
24952cfb2180SLorenzo Bianconi 
24962cfb2180SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
24972cfb2180SLorenzo Bianconi 	    sensor->id == ST_LSM6DSX_ID_EXT1 ||
24982cfb2180SLorenzo Bianconi 	    sensor->id == ST_LSM6DSX_ID_EXT2)
24992cfb2180SLorenzo Bianconi 		st_lsm6dsx_shub_read_output(hw,
25002cfb2180SLorenzo Bianconi 					    (u8 *)hw->scan[sensor->id].channels,
25012cfb2180SLorenzo Bianconi 					    sizeof(hw->scan[sensor->id].channels));
25022cfb2180SLorenzo Bianconi 	else
25032cfb2180SLorenzo Bianconi 		st_lsm6dsx_read_locked(hw, iio_dev->channels[0].address,
25042cfb2180SLorenzo Bianconi 				       hw->scan[sensor->id].channels,
25052cfb2180SLorenzo Bianconi 				       sizeof(hw->scan[sensor->id].channels));
25062cfb2180SLorenzo Bianconi 
25072cfb2180SLorenzo Bianconi 	iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan[sensor->id],
25082cfb2180SLorenzo Bianconi 					   iio_get_time_ns(iio_dev));
25092cfb2180SLorenzo Bianconi 	iio_trigger_notify_done(iio_dev->trig);
25102cfb2180SLorenzo Bianconi 
25112cfb2180SLorenzo Bianconi 	return IRQ_HANDLED;
25122cfb2180SLorenzo Bianconi }
25132cfb2180SLorenzo Bianconi 
st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw * hw)25146ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
25156ee6a368SSean Nyekjaer {
251631fe8d4eSLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
251731fe8d4eSLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
251803d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
25196ee6a368SSean Nyekjaer 	unsigned long irq_type;
25206ee6a368SSean Nyekjaer 	bool irq_active_low;
25216ee6a368SSean Nyekjaer 	int err;
25226ee6a368SSean Nyekjaer 
25236ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
25246ee6a368SSean Nyekjaer 
25256ee6a368SSean Nyekjaer 	switch (irq_type) {
25266ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
25276ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
25286ee6a368SSean Nyekjaer 		irq_active_low = false;
25296ee6a368SSean Nyekjaer 		break;
25306ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
25316ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
25326ee6a368SSean Nyekjaer 		irq_active_low = true;
25336ee6a368SSean Nyekjaer 		break;
25346ee6a368SSean Nyekjaer 	default:
25356ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
25366ee6a368SSean Nyekjaer 		return -EINVAL;
25376ee6a368SSean Nyekjaer 	}
25386ee6a368SSean Nyekjaer 
253931fe8d4eSLorenzo Bianconi 	reg = &hw->settings->irq_config.hla;
254031fe8d4eSLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
254131fe8d4eSLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(irq_active_low,
254231fe8d4eSLorenzo Bianconi 						      reg->mask));
25436ee6a368SSean Nyekjaer 	if (err < 0)
25446ee6a368SSean Nyekjaer 		return err;
25456ee6a368SSean Nyekjaer 
254603d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
254703d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
25486ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
254931fe8d4eSLorenzo Bianconi 		reg = &hw->settings->irq_config.od;
255031fe8d4eSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
255131fe8d4eSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
25526ee6a368SSean Nyekjaer 		if (err < 0)
25536ee6a368SSean Nyekjaer 			return err;
25546ee6a368SSean Nyekjaer 
25556ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
25566ee6a368SSean Nyekjaer 	}
25576ee6a368SSean Nyekjaer 
25586ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
2559a3aa17d4SSean Nyekjaer 					NULL,
25606ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
25616ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
25626ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
25636ee6a368SSean Nyekjaer 	if (err) {
25646ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
25656ee6a368SSean Nyekjaer 			hw->irq);
25666ee6a368SSean Nyekjaer 		return err;
25676ee6a368SSean Nyekjaer 	}
25686ee6a368SSean Nyekjaer 
25696ee6a368SSean Nyekjaer 	return 0;
25706ee6a368SSean Nyekjaer }
25716ee6a368SSean Nyekjaer 
st_lsm6dsx_sw_buffer_preenable(struct iio_dev * iio_dev)25722cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev)
25732cfb2180SLorenzo Bianconi {
25742cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
25752cfb2180SLorenzo Bianconi 
25762cfb2180SLorenzo Bianconi 	return st_lsm6dsx_device_set_enable(sensor, true);
25772cfb2180SLorenzo Bianconi }
25782cfb2180SLorenzo Bianconi 
st_lsm6dsx_sw_buffer_postdisable(struct iio_dev * iio_dev)25792cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev)
25802cfb2180SLorenzo Bianconi {
25812cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
25822cfb2180SLorenzo Bianconi 
25832cfb2180SLorenzo Bianconi 	return st_lsm6dsx_device_set_enable(sensor, false);
25842cfb2180SLorenzo Bianconi }
25852cfb2180SLorenzo Bianconi 
25862cfb2180SLorenzo Bianconi static const struct iio_buffer_setup_ops st_lsm6dsx_sw_buffer_ops = {
25872cfb2180SLorenzo Bianconi 	.preenable = st_lsm6dsx_sw_buffer_preenable,
25882cfb2180SLorenzo Bianconi 	.postdisable = st_lsm6dsx_sw_buffer_postdisable,
25892cfb2180SLorenzo Bianconi };
25902cfb2180SLorenzo Bianconi 
st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw * hw)25912cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw *hw)
25922cfb2180SLorenzo Bianconi {
25932cfb2180SLorenzo Bianconi 	int i;
25942cfb2180SLorenzo Bianconi 
25952cfb2180SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
25962cfb2180SLorenzo Bianconi 		int err;
25972cfb2180SLorenzo Bianconi 
25982cfb2180SLorenzo Bianconi 		if (!hw->iio_devs[i])
25992cfb2180SLorenzo Bianconi 			continue;
26002cfb2180SLorenzo Bianconi 
26012cfb2180SLorenzo Bianconi 		err = devm_iio_triggered_buffer_setup(hw->dev,
26022cfb2180SLorenzo Bianconi 					hw->iio_devs[i], NULL,
26032cfb2180SLorenzo Bianconi 					st_lsm6dsx_sw_trigger_handler_thread,
26042cfb2180SLorenzo Bianconi 					&st_lsm6dsx_sw_buffer_ops);
26052cfb2180SLorenzo Bianconi 		if (err)
26062cfb2180SLorenzo Bianconi 			return err;
26072cfb2180SLorenzo Bianconi 	}
26082cfb2180SLorenzo Bianconi 
26092cfb2180SLorenzo Bianconi 	return 0;
26102cfb2180SLorenzo Bianconi }
26112cfb2180SLorenzo Bianconi 
st_lsm6dsx_init_regulators(struct device * dev)2612f346b16fSLorenzo Bianconi static int st_lsm6dsx_init_regulators(struct device *dev)
2613f346b16fSLorenzo Bianconi {
26146900cdbfSMatti Vaittinen 	/* vdd-vddio power regulators */
26156900cdbfSMatti Vaittinen 	static const char * const regulators[] = { "vdd", "vddio" };
2616f346b16fSLorenzo Bianconi 	int err;
2617f346b16fSLorenzo Bianconi 
26186900cdbfSMatti Vaittinen 	err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),
26196900cdbfSMatti Vaittinen 					     regulators);
2620f346b16fSLorenzo Bianconi 	if (err)
26216900cdbfSMatti Vaittinen 		return dev_err_probe(dev, err, "failed to enable regulators\n");
2622f346b16fSLorenzo Bianconi 
2623f346b16fSLorenzo Bianconi 	msleep(50);
2624f346b16fSLorenzo Bianconi 
2625f346b16fSLorenzo Bianconi 	return 0;
2626f346b16fSLorenzo Bianconi }
2627f346b16fSLorenzo Bianconi 
2628dc3d25f2SJonathan Cameron #ifdef CONFIG_ACPI
2629dc3d25f2SJonathan Cameron 
lsm6dsx_get_acpi_mount_matrix(struct device * dev,struct iio_mount_matrix * orientation)2630dc3d25f2SJonathan Cameron static int lsm6dsx_get_acpi_mount_matrix(struct device *dev,
2631dc3d25f2SJonathan Cameron 					 struct iio_mount_matrix *orientation)
2632dc3d25f2SJonathan Cameron {
2633dc3d25f2SJonathan Cameron 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
2634dc3d25f2SJonathan Cameron 	struct acpi_device *adev = ACPI_COMPANION(dev);
2635dc3d25f2SJonathan Cameron 	union acpi_object *obj, *elements;
2636dc3d25f2SJonathan Cameron 	acpi_status status;
2637dc3d25f2SJonathan Cameron 	int i, j, val[3];
2638dc3d25f2SJonathan Cameron 	char *str;
2639dc3d25f2SJonathan Cameron 
2640dc3d25f2SJonathan Cameron 	if (!has_acpi_companion(dev))
2641dc3d25f2SJonathan Cameron 		return -EINVAL;
2642dc3d25f2SJonathan Cameron 
2643dc3d25f2SJonathan Cameron 	if (!acpi_has_method(adev->handle, "ROTM"))
2644dc3d25f2SJonathan Cameron 		return -EINVAL;
2645dc3d25f2SJonathan Cameron 
2646dc3d25f2SJonathan Cameron 	status = acpi_evaluate_object(adev->handle, "ROTM", NULL, &buffer);
2647dc3d25f2SJonathan Cameron 	if (ACPI_FAILURE(status)) {
2648dc3d25f2SJonathan Cameron 		dev_warn(dev, "Failed to get ACPI mount matrix: %d\n", status);
2649dc3d25f2SJonathan Cameron 		return -EINVAL;
2650dc3d25f2SJonathan Cameron 	}
2651dc3d25f2SJonathan Cameron 
2652dc3d25f2SJonathan Cameron 	obj = buffer.pointer;
2653dc3d25f2SJonathan Cameron 	if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 3)
2654dc3d25f2SJonathan Cameron 		goto unknown_format;
2655dc3d25f2SJonathan Cameron 
2656dc3d25f2SJonathan Cameron 	elements = obj->package.elements;
2657dc3d25f2SJonathan Cameron 	for (i = 0; i < 3; i++) {
2658dc3d25f2SJonathan Cameron 		if (elements[i].type != ACPI_TYPE_STRING)
2659dc3d25f2SJonathan Cameron 			goto unknown_format;
2660dc3d25f2SJonathan Cameron 
2661dc3d25f2SJonathan Cameron 		str = elements[i].string.pointer;
2662dc3d25f2SJonathan Cameron 		if (sscanf(str, "%d %d %d", &val[0], &val[1], &val[2]) != 3)
2663dc3d25f2SJonathan Cameron 			goto unknown_format;
2664dc3d25f2SJonathan Cameron 
2665dc3d25f2SJonathan Cameron 		for (j = 0; j < 3; j++) {
2666dc3d25f2SJonathan Cameron 			switch (val[j]) {
2667dc3d25f2SJonathan Cameron 			case -1: str = "-1"; break;
2668dc3d25f2SJonathan Cameron 			case 0:  str = "0";  break;
2669dc3d25f2SJonathan Cameron 			case 1:  str = "1";  break;
2670dc3d25f2SJonathan Cameron 			default: goto unknown_format;
2671dc3d25f2SJonathan Cameron 			}
2672dc3d25f2SJonathan Cameron 			orientation->rotation[i * 3 + j] = str;
2673dc3d25f2SJonathan Cameron 		}
2674dc3d25f2SJonathan Cameron 	}
2675dc3d25f2SJonathan Cameron 
2676dc3d25f2SJonathan Cameron 	kfree(buffer.pointer);
2677dc3d25f2SJonathan Cameron 	return 0;
2678dc3d25f2SJonathan Cameron 
2679dc3d25f2SJonathan Cameron unknown_format:
2680dc3d25f2SJonathan Cameron 	dev_warn(dev, "Unknown ACPI mount matrix format, ignoring\n");
2681dc3d25f2SJonathan Cameron 	kfree(buffer.pointer);
2682dc3d25f2SJonathan Cameron 	return -EINVAL;
2683dc3d25f2SJonathan Cameron }
2684dc3d25f2SJonathan Cameron 
2685dc3d25f2SJonathan Cameron #else
2686dc3d25f2SJonathan Cameron 
lsm6dsx_get_acpi_mount_matrix(struct device * dev,struct iio_mount_matrix * orientation)2687dc3d25f2SJonathan Cameron static int lsm6dsx_get_acpi_mount_matrix(struct device *dev,
2688dc3d25f2SJonathan Cameron 					  struct iio_mount_matrix *orientation)
2689dc3d25f2SJonathan Cameron {
2690*6811694eSAlejandro Tafalla 	return -EOPNOTSUPP;
2691dc3d25f2SJonathan Cameron }
2692dc3d25f2SJonathan Cameron 
2693dc3d25f2SJonathan Cameron #endif
2694dc3d25f2SJonathan Cameron 
st_lsm6dsx_probe(struct device * dev,int irq,int hw_id,struct regmap * regmap)269581956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
269651a8b707SLorenzo Bianconi 		     struct regmap *regmap)
2697290a6ce1SLorenzo Bianconi {
2698b7a73b33SLorenzo Bianconi 	struct st_sensors_platform_data *pdata = dev->platform_data;
2699c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2700290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
270181956a93SLorenzo Bianconi 	const char *name = NULL;
2702290a6ce1SLorenzo Bianconi 	int i, err;
2703290a6ce1SLorenzo Bianconi 
2704290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
2705290a6ce1SLorenzo Bianconi 	if (!hw)
2706290a6ce1SLorenzo Bianconi 		return -ENOMEM;
2707290a6ce1SLorenzo Bianconi 
2708290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
2709290a6ce1SLorenzo Bianconi 
2710290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
2711335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
2712739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
2713290a6ce1SLorenzo Bianconi 
2714f346b16fSLorenzo Bianconi 	err = st_lsm6dsx_init_regulators(dev);
2715f346b16fSLorenzo Bianconi 	if (err)
2716f346b16fSLorenzo Bianconi 		return err;
2717f346b16fSLorenzo Bianconi 
271891a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
271991a6b841SLorenzo Bianconi 	if (!hw->buff)
272091a6b841SLorenzo Bianconi 		return -ENOMEM;
272191a6b841SLorenzo Bianconi 
2722290a6ce1SLorenzo Bianconi 	hw->dev = dev;
2723290a6ce1SLorenzo Bianconi 	hw->irq = irq;
272451a8b707SLorenzo Bianconi 	hw->regmap = regmap;
2725290a6ce1SLorenzo Bianconi 
272681956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
2727290a6ce1SLorenzo Bianconi 	if (err < 0)
2728290a6ce1SLorenzo Bianconi 		return err;
2729290a6ce1SLorenzo Bianconi 
27306ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
2731510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
2732290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
2733290a6ce1SLorenzo Bianconi 			return -ENOMEM;
2734290a6ce1SLorenzo Bianconi 	}
2735290a6ce1SLorenzo Bianconi 
2736290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
2737290a6ce1SLorenzo Bianconi 	if (err < 0)
2738290a6ce1SLorenzo Bianconi 		return err;
2739290a6ce1SLorenzo Bianconi 
2740c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
274135619155SLorenzo Bianconi 	if (hub_settings->master_en.addr &&
274235619155SLorenzo Bianconi 	    (!dev_fwnode(dev) ||
274335619155SLorenzo Bianconi 	     !device_property_read_bool(dev, "st,disable-sensor-hub"))) {
2744c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
2745c91c1c84SLorenzo Bianconi 		if (err < 0)
2746c91c1c84SLorenzo Bianconi 			return err;
2747c91c1c84SLorenzo Bianconi 	}
2748c91c1c84SLorenzo Bianconi 
2749290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
27506ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
27516ee6a368SSean Nyekjaer 		if (err < 0)
27526ee6a368SSean Nyekjaer 			return err;
27536ee6a368SSean Nyekjaer 
2754290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
2755290a6ce1SLorenzo Bianconi 		if (err < 0)
2756290a6ce1SLorenzo Bianconi 			return err;
2757290a6ce1SLorenzo Bianconi 	}
2758290a6ce1SLorenzo Bianconi 
27592cfb2180SLorenzo Bianconi 	if (!hw->irq || !hw->settings->fifo_ops.read_fifo) {
27602cfb2180SLorenzo Bianconi 		/*
27612cfb2180SLorenzo Bianconi 		 * Rely on sw triggers (e.g. hr-timers) if irq pin is not
27622cfb2180SLorenzo Bianconi 		 * connected of if the device does not support HW FIFO
27632cfb2180SLorenzo Bianconi 		 */
27642cfb2180SLorenzo Bianconi 		err = st_lsm6dsx_sw_buffers_setup(hw);
27652cfb2180SLorenzo Bianconi 		if (err)
27662cfb2180SLorenzo Bianconi 			return err;
27672cfb2180SLorenzo Bianconi 	}
27682cfb2180SLorenzo Bianconi 
2769dc3d25f2SJonathan Cameron 	err = lsm6dsx_get_acpi_mount_matrix(hw->dev, &hw->orientation);
2770dc3d25f2SJonathan Cameron 	if (err) {
2771b892770aSAndy Shevchenko 		err = iio_read_mount_matrix(hw->dev, &hw->orientation);
277204e6fedbSMartin Kepplinger 		if (err)
277304e6fedbSMartin Kepplinger 			return err;
2774dc3d25f2SJonathan Cameron 	}
277504e6fedbSMartin Kepplinger 
2776290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
27776ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
27786ffb55e5SLorenzo Bianconi 			continue;
27796ffb55e5SLorenzo Bianconi 
2780290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
2781290a6ce1SLorenzo Bianconi 		if (err)
2782290a6ce1SLorenzo Bianconi 			return err;
2783290a6ce1SLorenzo Bianconi 	}
2784290a6ce1SLorenzo Bianconi 
278503d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
2786b7a73b33SLorenzo Bianconi 	    (pdata && pdata->wakeup_source))
27874c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
27884c997dfaSSean Nyekjaer 
2789290a6ce1SLorenzo Bianconi 	return 0;
2790290a6ce1SLorenzo Bianconi }
27912b059449SJonathan Cameron EXPORT_SYMBOL_NS(st_lsm6dsx_probe, IIO_LSM6DSX);
2792290a6ce1SLorenzo Bianconi 
st_lsm6dsx_suspend(struct device * dev)2793acc416ffSJonathan Cameron static int st_lsm6dsx_suspend(struct device *dev)
2794d3f77058SLorenzo Bianconi {
2795d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2796d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2797d3f77058SLorenzo Bianconi 	int i, err = 0;
2798d3f77058SLorenzo Bianconi 
2799d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
28006ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
28016ffb55e5SLorenzo Bianconi 			continue;
28026ffb55e5SLorenzo Bianconi 
2803d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
2804d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
2805d3f77058SLorenzo Bianconi 			continue;
2806d3f77058SLorenzo Bianconi 
28074c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
28084c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
28094c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
28104c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
28114c997dfaSSean Nyekjaer 			continue;
28124c997dfaSSean Nyekjaer 		}
28134c997dfaSSean Nyekjaer 
2814cd83c5c1SLorenzo Bianconi 		err = st_lsm6dsx_device_set_enable(sensor, false);
2815d3f77058SLorenzo Bianconi 		if (err < 0)
2816d3f77058SLorenzo Bianconi 			return err;
2817bce0d57dSLorenzo Bianconi 
2818bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2819d3f77058SLorenzo Bianconi 	}
2820d3f77058SLorenzo Bianconi 
2821c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2822d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2823d3f77058SLorenzo Bianconi 
2824d3f77058SLorenzo Bianconi 	return err;
2825d3f77058SLorenzo Bianconi }
2826d3f77058SLorenzo Bianconi 
st_lsm6dsx_resume(struct device * dev)2827acc416ffSJonathan Cameron static int st_lsm6dsx_resume(struct device *dev)
2828d3f77058SLorenzo Bianconi {
2829d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2830d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2831d3f77058SLorenzo Bianconi 	int i, err = 0;
2832d3f77058SLorenzo Bianconi 
2833d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
28346ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
28356ffb55e5SLorenzo Bianconi 			continue;
28366ffb55e5SLorenzo Bianconi 
2837d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
28384c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
28394c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
28404c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
28414c997dfaSSean Nyekjaer 
2842bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2843d3f77058SLorenzo Bianconi 			continue;
2844d3f77058SLorenzo Bianconi 
2845cd83c5c1SLorenzo Bianconi 		err = st_lsm6dsx_device_set_enable(sensor, true);
2846d3f77058SLorenzo Bianconi 		if (err < 0)
2847d3f77058SLorenzo Bianconi 			return err;
2848bce0d57dSLorenzo Bianconi 
2849bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2850d3f77058SLorenzo Bianconi 	}
2851d3f77058SLorenzo Bianconi 
2852c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2853a1bab939SLorenzo Bianconi 		err = st_lsm6dsx_resume_fifo(hw);
2854d3f77058SLorenzo Bianconi 
2855d3f77058SLorenzo Bianconi 	return err;
2856d3f77058SLorenzo Bianconi }
2857d3f77058SLorenzo Bianconi 
28582b059449SJonathan Cameron EXPORT_NS_SIMPLE_DEV_PM_OPS(st_lsm6dsx_pm_ops, st_lsm6dsx_suspend,
28592b059449SJonathan Cameron 			    st_lsm6dsx_resume, IIO_LSM6DSX);
2860d3f77058SLorenzo Bianconi 
2861290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2862290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2863290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2864290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2865