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/
30*f35e1ee9SLorenzo Bianconi  *   LSM6DSTX/LSM6DSO16IS:
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>
59290a6ce1SLorenzo Bianconi #include <linux/delay.h>
601aabad1fSSean Nyekjaer #include <linux/iio/events.h>
61290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h>
62290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h>
632cfb2180SLorenzo Bianconi #include <linux/iio/triggered_buffer.h>
642cfb2180SLorenzo Bianconi #include <linux/iio/trigger_consumer.h>
656ee6a368SSean Nyekjaer #include <linux/interrupt.h>
666ee6a368SSean Nyekjaer #include <linux/irq.h>
679e5b4cd2SPaul Cercueil #include <linux/minmax.h>
68d3f77058SLorenzo Bianconi #include <linux/pm.h>
6903d4c566SAndy Shevchenko #include <linux/property.h>
7051a8b707SLorenzo Bianconi #include <linux/regmap.h>
7151a8b707SLorenzo Bianconi #include <linux/bitfield.h>
72290a6ce1SLorenzo Bianconi 
73dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h>
74dba32904SLorenzo Bianconi 
75290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h"
76290a6ce1SLorenzo Bianconi 
77290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
78290a6ce1SLorenzo Bianconi 
79cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
80cb3b6b8eSMario Tesi 
81f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
82b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
83b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
84b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
85f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
86f48bc49bSLorenzo Bianconi };
87f48bc49bSLorenzo Bianconi 
88f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
89f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
90f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
91f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
92f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
93f48bc49bSLorenzo Bianconi };
94f48bc49bSLorenzo Bianconi 
9552f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
9652f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
9752f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
9852f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
9952f4b1f1SMartin Kepplinger 	IIO_CHAN_SOFT_TIMESTAMP(3),
10052f4b1f1SMartin Kepplinger };
10152f4b1f1SMartin Kepplinger 
102290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
103290a6ce1SLorenzo Bianconi 	{
10466b662a1SLorenzo Bianconi 		.reset = {
10566b662a1SLorenzo Bianconi 			.addr = 0x22,
10666b662a1SLorenzo Bianconi 			.mask = BIT(0),
10766b662a1SLorenzo Bianconi 		},
10866b662a1SLorenzo Bianconi 		.boot = {
10966b662a1SLorenzo Bianconi 			.addr = 0x22,
11066b662a1SLorenzo Bianconi 			.mask = BIT(7),
11166b662a1SLorenzo Bianconi 		},
11266b662a1SLorenzo Bianconi 		.bdu = {
11366b662a1SLorenzo Bianconi 			.addr = 0x22,
11466b662a1SLorenzo Bianconi 			.mask = BIT(6),
11566b662a1SLorenzo Bianconi 		},
11652f4b1f1SMartin Kepplinger 		.id = {
11752f4b1f1SMartin Kepplinger 			{
11852f4b1f1SMartin Kepplinger 				.hw_id = ST_LSM9DS1_ID,
11952f4b1f1SMartin Kepplinger 				.name = ST_LSM9DS1_DEV_NAME,
12098c3544aSLorenzo Bianconi 				.wai = 0x68,
121fa060a3dSLorenzo Bianconi 			}, {
122fa060a3dSLorenzo Bianconi 				.hw_id = ST_LSM6DS0_ID,
123fa060a3dSLorenzo Bianconi 				.name = ST_LSM6DS0_DEV_NAME,
12498c3544aSLorenzo Bianconi 				.wai = 0x68,
12552f4b1f1SMartin Kepplinger 			},
12652f4b1f1SMartin Kepplinger 		},
12752f4b1f1SMartin Kepplinger 		.channels = {
12852f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
12952f4b1f1SMartin Kepplinger 				.chan = st_lsm6dsx_acc_channels,
13052f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
13152f4b1f1SMartin Kepplinger 			},
13252f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
13352f4b1f1SMartin Kepplinger 				.chan = st_lsm6ds0_gyro_channels,
13452f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
13552f4b1f1SMartin Kepplinger 			},
13652f4b1f1SMartin Kepplinger 		},
13752f4b1f1SMartin Kepplinger 		.odr_table = {
13852f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
13952f4b1f1SMartin Kepplinger 				.reg = {
14052f4b1f1SMartin Kepplinger 					.addr = 0x20,
14152f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
14252f4b1f1SMartin Kepplinger 				},
143f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  10000, 0x01 },
144f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  50000, 0x02 },
145f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
146f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
147f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
148f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
14959af4e20SLorenzo Bianconi 				.odr_len = 6,
15052f4b1f1SMartin Kepplinger 			},
15152f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
15252f4b1f1SMartin Kepplinger 				.reg = {
15352f4b1f1SMartin Kepplinger 					.addr = 0x10,
15452f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
15552f4b1f1SMartin Kepplinger 				},
156f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  14900, 0x01 },
157f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  59500, 0x02 },
158f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
159f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
160f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
161f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
16259af4e20SLorenzo Bianconi 				.odr_len = 6,
16352f4b1f1SMartin Kepplinger 			},
16452f4b1f1SMartin Kepplinger 		},
16552f4b1f1SMartin Kepplinger 		.fs_table = {
16652f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
16752f4b1f1SMartin Kepplinger 				.reg = {
16852f4b1f1SMartin Kepplinger 					.addr = 0x20,
16952f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
17052f4b1f1SMartin Kepplinger 				},
17144a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
17244a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
17344a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
17444a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 },
17585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
17652f4b1f1SMartin Kepplinger 			},
17752f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
17852f4b1f1SMartin Kepplinger 				.reg = {
17952f4b1f1SMartin Kepplinger 					.addr = 0x10,
18052f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
18152f4b1f1SMartin Kepplinger 				},
1821b375101SLorenzo Bianconi 
18344a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
18444a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
18544a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
18685ae3aeeSLorenzo Bianconi 				.fs_len = 3,
18752f4b1f1SMartin Kepplinger 			},
18852f4b1f1SMartin Kepplinger 		},
1897e906103SLorenzo Bianconi 		.irq_config = {
1907e906103SLorenzo Bianconi 			.irq1 = {
1917e906103SLorenzo Bianconi 				.addr = 0x0c,
1927e906103SLorenzo Bianconi 				.mask = BIT(3),
1937e906103SLorenzo Bianconi 			},
1947e906103SLorenzo Bianconi 			.irq2 = {
1957e906103SLorenzo Bianconi 				.addr = 0x0d,
1967e906103SLorenzo Bianconi 				.mask = BIT(3),
1977e906103SLorenzo Bianconi 			},
19831fe8d4eSLorenzo Bianconi 			.hla = {
19931fe8d4eSLorenzo Bianconi 				.addr = 0x22,
20031fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
20131fe8d4eSLorenzo Bianconi 			},
20231fe8d4eSLorenzo Bianconi 			.od = {
20331fe8d4eSLorenzo Bianconi 				.addr = 0x22,
20431fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
20531fe8d4eSLorenzo Bianconi 			},
2067e906103SLorenzo Bianconi 		},
2071b7da2faSLorenzo Bianconi 		.fifo_ops = {
2081b7da2faSLorenzo Bianconi 			.max_size = 32,
2091b7da2faSLorenzo Bianconi 		},
21052f4b1f1SMartin Kepplinger 	},
21152f4b1f1SMartin Kepplinger 	{
21266b662a1SLorenzo Bianconi 		.reset = {
21366b662a1SLorenzo Bianconi 			.addr = 0x12,
21466b662a1SLorenzo Bianconi 			.mask = BIT(0),
21566b662a1SLorenzo Bianconi 		},
21666b662a1SLorenzo Bianconi 		.boot = {
21766b662a1SLorenzo Bianconi 			.addr = 0x12,
21866b662a1SLorenzo Bianconi 			.mask = BIT(7),
21966b662a1SLorenzo Bianconi 		},
22066b662a1SLorenzo Bianconi 		.bdu = {
22166b662a1SLorenzo Bianconi 			.addr = 0x12,
22266b662a1SLorenzo Bianconi 			.mask = BIT(6),
22366b662a1SLorenzo Bianconi 		},
224d068e4a0SLorenzo Bianconi 		.id = {
22581956a93SLorenzo Bianconi 			{
22681956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3_ID,
22781956a93SLorenzo Bianconi 				.name = ST_LSM6DS3_DEV_NAME,
22898c3544aSLorenzo Bianconi 				.wai = 0x69,
22981956a93SLorenzo Bianconi 			},
230d068e4a0SLorenzo Bianconi 		},
231f48bc49bSLorenzo Bianconi 		.channels = {
232f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
233f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
234f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
235f48bc49bSLorenzo Bianconi 			},
236f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
237f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
238f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
239f48bc49bSLorenzo Bianconi 			},
240f48bc49bSLorenzo Bianconi 		},
24140dd7343SLorenzo Bianconi 		.odr_table = {
24240dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
24340dd7343SLorenzo Bianconi 				.reg = {
24440dd7343SLorenzo Bianconi 					.addr = 0x10,
24540dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
24640dd7343SLorenzo Bianconi 				},
247f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
248f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
249f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
250f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
251f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
252f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
25359af4e20SLorenzo Bianconi 				.odr_len = 6,
25440dd7343SLorenzo Bianconi 			},
25540dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
25640dd7343SLorenzo Bianconi 				.reg = {
25740dd7343SLorenzo Bianconi 					.addr = 0x11,
25840dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
25940dd7343SLorenzo Bianconi 				},
260f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
261f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
262f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
263f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
264f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
265f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
26659af4e20SLorenzo Bianconi 				.odr_len = 6,
26740dd7343SLorenzo Bianconi 			},
26840dd7343SLorenzo Bianconi 		},
269640aca3fSLorenzo Bianconi 		.fs_table = {
270640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
271640aca3fSLorenzo Bianconi 				.reg = {
272640aca3fSLorenzo Bianconi 					.addr = 0x10,
273640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
274640aca3fSLorenzo Bianconi 				},
27544a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
27644a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
27744a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
27844a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
27985ae3aeeSLorenzo Bianconi 				.fs_len = 4,
280640aca3fSLorenzo Bianconi 			},
281640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
282640aca3fSLorenzo Bianconi 				.reg = {
283640aca3fSLorenzo Bianconi 					.addr = 0x11,
284640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
285640aca3fSLorenzo Bianconi 				},
28644a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
28744a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
28844a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
28944a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
29085ae3aeeSLorenzo Bianconi 				.fs_len = 4,
291640aca3fSLorenzo Bianconi 			},
292640aca3fSLorenzo Bianconi 		},
2937e906103SLorenzo Bianconi 		.irq_config = {
2947e906103SLorenzo Bianconi 			.irq1 = {
2957e906103SLorenzo Bianconi 				.addr = 0x0d,
2967e906103SLorenzo Bianconi 				.mask = BIT(3),
2977e906103SLorenzo Bianconi 			},
2987e906103SLorenzo Bianconi 			.irq2 = {
2997e906103SLorenzo Bianconi 				.addr = 0x0e,
3007e906103SLorenzo Bianconi 				.mask = BIT(3),
3017e906103SLorenzo Bianconi 			},
3027e906103SLorenzo Bianconi 			.lir = {
3037e906103SLorenzo Bianconi 				.addr = 0x58,
3047e906103SLorenzo Bianconi 				.mask = BIT(0),
3057e906103SLorenzo Bianconi 			},
3067e906103SLorenzo Bianconi 			.irq1_func = {
3077e906103SLorenzo Bianconi 				.addr = 0x5e,
3087e906103SLorenzo Bianconi 				.mask = BIT(5),
3097e906103SLorenzo Bianconi 			},
3107e906103SLorenzo Bianconi 			.irq2_func = {
3117e906103SLorenzo Bianconi 				.addr = 0x5f,
3127e906103SLorenzo Bianconi 				.mask = BIT(5),
3137e906103SLorenzo Bianconi 			},
31431fe8d4eSLorenzo Bianconi 			.hla = {
31531fe8d4eSLorenzo Bianconi 				.addr = 0x12,
31631fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
31731fe8d4eSLorenzo Bianconi 			},
31831fe8d4eSLorenzo Bianconi 			.od = {
31931fe8d4eSLorenzo Bianconi 				.addr = 0x12,
32031fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
32131fe8d4eSLorenzo Bianconi 			},
3227e906103SLorenzo Bianconi 		},
3237ca3ac9eSLorenzo Bianconi 		.decimator = {
3247ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
3257ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3267ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
3277ca3ac9eSLorenzo Bianconi 			},
3287ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
3297ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3307ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
3317ca3ac9eSLorenzo Bianconi 			},
3327ca3ac9eSLorenzo Bianconi 		},
33392617c15SLorenzo Bianconi 		.fifo_ops = {
3343b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
33550ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
33692617c15SLorenzo Bianconi 			.fifo_th = {
33792617c15SLorenzo Bianconi 				.addr = 0x06,
33892617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
33992617c15SLorenzo Bianconi 			},
34092617c15SLorenzo Bianconi 			.fifo_diff = {
34192617c15SLorenzo Bianconi 				.addr = 0x3a,
34292617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
34392617c15SLorenzo Bianconi 			},
3441b7da2faSLorenzo Bianconi 			.max_size = 1365,
34592617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
34692617c15SLorenzo Bianconi 		},
34721345107SLorenzo Bianconi 		.ts_settings = {
34821345107SLorenzo Bianconi 			.timer_en = {
34921345107SLorenzo Bianconi 				.addr = 0x58,
35021345107SLorenzo Bianconi 				.mask = BIT(7),
35121345107SLorenzo Bianconi 			},
35221345107SLorenzo Bianconi 			.hr_timer = {
35321345107SLorenzo Bianconi 				.addr = 0x5c,
35421345107SLorenzo Bianconi 				.mask = BIT(4),
35521345107SLorenzo Bianconi 			},
35621345107SLorenzo Bianconi 			.fifo_en = {
35721345107SLorenzo Bianconi 				.addr = 0x07,
35821345107SLorenzo Bianconi 				.mask = BIT(7),
35921345107SLorenzo Bianconi 			},
36021345107SLorenzo Bianconi 			.decimator = {
36121345107SLorenzo Bianconi 				.addr = 0x09,
36221345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
36321345107SLorenzo Bianconi 			},
36421345107SLorenzo Bianconi 		},
365b5969abfSSean Nyekjaer 		.event_settings = {
366b5969abfSSean Nyekjaer 			.wakeup_reg = {
367b5969abfSSean Nyekjaer 				.addr = 0x5B,
368b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
369b5969abfSSean Nyekjaer 			},
3701aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
3711aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
3721aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
3731aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
3741aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
375b5969abfSSean Nyekjaer 		},
376290a6ce1SLorenzo Bianconi 	},
377290a6ce1SLorenzo Bianconi 	{
37866b662a1SLorenzo Bianconi 		.reset = {
37966b662a1SLorenzo Bianconi 			.addr = 0x12,
38066b662a1SLorenzo Bianconi 			.mask = BIT(0),
38166b662a1SLorenzo Bianconi 		},
38266b662a1SLorenzo Bianconi 		.boot = {
38366b662a1SLorenzo Bianconi 			.addr = 0x12,
38466b662a1SLorenzo Bianconi 			.mask = BIT(7),
38566b662a1SLorenzo Bianconi 		},
38666b662a1SLorenzo Bianconi 		.bdu = {
38766b662a1SLorenzo Bianconi 			.addr = 0x12,
38866b662a1SLorenzo Bianconi 			.mask = BIT(6),
38966b662a1SLorenzo Bianconi 		},
390df47710aSLorenzo Bianconi 		.id = {
39181956a93SLorenzo Bianconi 			{
39281956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3H_ID,
39381956a93SLorenzo Bianconi 				.name = ST_LSM6DS3H_DEV_NAME,
39498c3544aSLorenzo Bianconi 				.wai = 0x69,
39581956a93SLorenzo Bianconi 			},
396df47710aSLorenzo Bianconi 		},
397f48bc49bSLorenzo Bianconi 		.channels = {
398f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
399f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
400f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
401f48bc49bSLorenzo Bianconi 			},
402f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
403f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
404f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
405f48bc49bSLorenzo Bianconi 			},
406f48bc49bSLorenzo Bianconi 		},
40740dd7343SLorenzo Bianconi 		.odr_table = {
40840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
40940dd7343SLorenzo Bianconi 				.reg = {
41040dd7343SLorenzo Bianconi 					.addr = 0x10,
41140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
41240dd7343SLorenzo Bianconi 				},
413f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
414f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
415f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
416f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
417f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
418f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
41959af4e20SLorenzo Bianconi 				.odr_len = 6,
42040dd7343SLorenzo Bianconi 			},
42140dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
42240dd7343SLorenzo Bianconi 				.reg = {
42340dd7343SLorenzo Bianconi 					.addr = 0x11,
42440dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
42540dd7343SLorenzo Bianconi 				},
426f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
427f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
428f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
429f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
430f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
431f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
43259af4e20SLorenzo Bianconi 				.odr_len = 6,
43340dd7343SLorenzo Bianconi 			},
43440dd7343SLorenzo Bianconi 		},
435640aca3fSLorenzo Bianconi 		.fs_table = {
436640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
437640aca3fSLorenzo Bianconi 				.reg = {
438640aca3fSLorenzo Bianconi 					.addr = 0x10,
439640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
440640aca3fSLorenzo Bianconi 				},
44144a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
44244a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
44344a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
44444a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
44585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
446640aca3fSLorenzo Bianconi 			},
447640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
448640aca3fSLorenzo Bianconi 				.reg = {
449640aca3fSLorenzo Bianconi 					.addr = 0x11,
450640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
451640aca3fSLorenzo Bianconi 				},
45244a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
45344a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
45444a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
45544a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
45685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
457640aca3fSLorenzo Bianconi 			},
458640aca3fSLorenzo Bianconi 		},
4597e906103SLorenzo Bianconi 		.irq_config = {
4607e906103SLorenzo Bianconi 			.irq1 = {
4617e906103SLorenzo Bianconi 				.addr = 0x0d,
4627e906103SLorenzo Bianconi 				.mask = BIT(3),
4637e906103SLorenzo Bianconi 			},
4647e906103SLorenzo Bianconi 			.irq2 = {
4657e906103SLorenzo Bianconi 				.addr = 0x0e,
4667e906103SLorenzo Bianconi 				.mask = BIT(3),
4677e906103SLorenzo Bianconi 			},
4687e906103SLorenzo Bianconi 			.lir = {
4697e906103SLorenzo Bianconi 				.addr = 0x58,
4707e906103SLorenzo Bianconi 				.mask = BIT(0),
4717e906103SLorenzo Bianconi 			},
4727e906103SLorenzo Bianconi 			.irq1_func = {
4737e906103SLorenzo Bianconi 				.addr = 0x5e,
4747e906103SLorenzo Bianconi 				.mask = BIT(5),
4757e906103SLorenzo Bianconi 			},
4767e906103SLorenzo Bianconi 			.irq2_func = {
4777e906103SLorenzo Bianconi 				.addr = 0x5f,
4787e906103SLorenzo Bianconi 				.mask = BIT(5),
4797e906103SLorenzo Bianconi 			},
48031fe8d4eSLorenzo Bianconi 			.hla = {
48131fe8d4eSLorenzo Bianconi 				.addr = 0x12,
48231fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
48331fe8d4eSLorenzo Bianconi 			},
48431fe8d4eSLorenzo Bianconi 			.od = {
48531fe8d4eSLorenzo Bianconi 				.addr = 0x12,
48631fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
48731fe8d4eSLorenzo Bianconi 			},
4887e906103SLorenzo Bianconi 		},
4897ca3ac9eSLorenzo Bianconi 		.decimator = {
4907ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
4917ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4927ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
4937ca3ac9eSLorenzo Bianconi 			},
4947ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
4957ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4967ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
4977ca3ac9eSLorenzo Bianconi 			},
4987ca3ac9eSLorenzo Bianconi 		},
49992617c15SLorenzo Bianconi 		.fifo_ops = {
5003b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
50150ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
50292617c15SLorenzo Bianconi 			.fifo_th = {
50392617c15SLorenzo Bianconi 				.addr = 0x06,
50492617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
50592617c15SLorenzo Bianconi 			},
50692617c15SLorenzo Bianconi 			.fifo_diff = {
50792617c15SLorenzo Bianconi 				.addr = 0x3a,
50892617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
50992617c15SLorenzo Bianconi 			},
5101b7da2faSLorenzo Bianconi 			.max_size = 682,
51192617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
51292617c15SLorenzo Bianconi 		},
51321345107SLorenzo Bianconi 		.ts_settings = {
51421345107SLorenzo Bianconi 			.timer_en = {
51521345107SLorenzo Bianconi 				.addr = 0x58,
51621345107SLorenzo Bianconi 				.mask = BIT(7),
51721345107SLorenzo Bianconi 			},
51821345107SLorenzo Bianconi 			.hr_timer = {
51921345107SLorenzo Bianconi 				.addr = 0x5c,
52021345107SLorenzo Bianconi 				.mask = BIT(4),
52121345107SLorenzo Bianconi 			},
52221345107SLorenzo Bianconi 			.fifo_en = {
52321345107SLorenzo Bianconi 				.addr = 0x07,
52421345107SLorenzo Bianconi 				.mask = BIT(7),
52521345107SLorenzo Bianconi 			},
52621345107SLorenzo Bianconi 			.decimator = {
52721345107SLorenzo Bianconi 				.addr = 0x09,
52821345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
52921345107SLorenzo Bianconi 			},
53021345107SLorenzo Bianconi 		},
531b5969abfSSean Nyekjaer 		.event_settings = {
532b5969abfSSean Nyekjaer 			.wakeup_reg = {
533b5969abfSSean Nyekjaer 				.addr = 0x5B,
534b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
535b5969abfSSean Nyekjaer 			},
5361aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
5371aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
5381aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
5391aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
5401aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
541b5969abfSSean Nyekjaer 		},
542df47710aSLorenzo Bianconi 	},
543df47710aSLorenzo Bianconi 	{
54466b662a1SLorenzo Bianconi 		.reset = {
54566b662a1SLorenzo Bianconi 			.addr = 0x12,
54666b662a1SLorenzo Bianconi 			.mask = BIT(0),
54766b662a1SLorenzo Bianconi 		},
54866b662a1SLorenzo Bianconi 		.boot = {
54966b662a1SLorenzo Bianconi 			.addr = 0x12,
55066b662a1SLorenzo Bianconi 			.mask = BIT(7),
55166b662a1SLorenzo Bianconi 		},
55266b662a1SLorenzo Bianconi 		.bdu = {
55366b662a1SLorenzo Bianconi 			.addr = 0x12,
55466b662a1SLorenzo Bianconi 			.mask = BIT(6),
55566b662a1SLorenzo Bianconi 		},
556d068e4a0SLorenzo Bianconi 		.id = {
55781956a93SLorenzo Bianconi 			{
55881956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSL_ID,
55981956a93SLorenzo Bianconi 				.name = ST_LSM6DSL_DEV_NAME,
56098c3544aSLorenzo Bianconi 				.wai = 0x6a,
56181956a93SLorenzo Bianconi 			}, {
56281956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSM_ID,
56381956a93SLorenzo Bianconi 				.name = ST_LSM6DSM_DEV_NAME,
56498c3544aSLorenzo Bianconi 				.wai = 0x6a,
56581956a93SLorenzo Bianconi 			}, {
56681956a93SLorenzo Bianconi 				.hw_id = ST_ISM330DLC_ID,
56781956a93SLorenzo Bianconi 				.name = ST_ISM330DLC_DEV_NAME,
56898c3544aSLorenzo Bianconi 				.wai = 0x6a,
569dbcd2088SLorenzo Bianconi 			}, {
570dbcd2088SLorenzo Bianconi 				.hw_id = ST_LSM6DS3TRC_ID,
571dbcd2088SLorenzo Bianconi 				.name = ST_LSM6DS3TRC_DEV_NAME,
57298c3544aSLorenzo Bianconi 				.wai = 0x6a,
57381956a93SLorenzo Bianconi 			},
574d068e4a0SLorenzo Bianconi 		},
575f48bc49bSLorenzo Bianconi 		.channels = {
576f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
577f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
578f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
579f48bc49bSLorenzo Bianconi 			},
580f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
581f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
582f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
583f48bc49bSLorenzo Bianconi 			},
584f48bc49bSLorenzo Bianconi 		},
58540dd7343SLorenzo Bianconi 		.odr_table = {
58640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
58740dd7343SLorenzo Bianconi 				.reg = {
58840dd7343SLorenzo Bianconi 					.addr = 0x10,
58940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
59040dd7343SLorenzo Bianconi 				},
591f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
592f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
593f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
594f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
595f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
596f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
59759af4e20SLorenzo Bianconi 				.odr_len = 6,
59840dd7343SLorenzo Bianconi 			},
59940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
60040dd7343SLorenzo Bianconi 				.reg = {
60140dd7343SLorenzo Bianconi 					.addr = 0x11,
60240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
60340dd7343SLorenzo Bianconi 				},
604f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
605f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
606f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
607f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
608f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
609f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
61059af4e20SLorenzo Bianconi 				.odr_len = 6,
61140dd7343SLorenzo Bianconi 			},
61240dd7343SLorenzo Bianconi 		},
613640aca3fSLorenzo Bianconi 		.fs_table = {
614640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
615640aca3fSLorenzo Bianconi 				.reg = {
616640aca3fSLorenzo Bianconi 					.addr = 0x10,
617640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
618640aca3fSLorenzo Bianconi 				},
61944a76de8SMario Tesi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
62044a76de8SMario Tesi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
62144a76de8SMario Tesi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
62244a76de8SMario Tesi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
62385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
624640aca3fSLorenzo Bianconi 			},
625640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
626640aca3fSLorenzo Bianconi 				.reg = {
627640aca3fSLorenzo Bianconi 					.addr = 0x11,
628640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
629640aca3fSLorenzo Bianconi 				},
63044a76de8SMario Tesi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
63144a76de8SMario Tesi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
63244a76de8SMario Tesi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
63344a76de8SMario Tesi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
63485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
635640aca3fSLorenzo Bianconi 			},
636640aca3fSLorenzo Bianconi 		},
6377e906103SLorenzo Bianconi 		.irq_config = {
6387e906103SLorenzo Bianconi 			.irq1 = {
6397e906103SLorenzo Bianconi 				.addr = 0x0d,
6407e906103SLorenzo Bianconi 				.mask = BIT(3),
6417e906103SLorenzo Bianconi 			},
6427e906103SLorenzo Bianconi 			.irq2 = {
6437e906103SLorenzo Bianconi 				.addr = 0x0e,
6447e906103SLorenzo Bianconi 				.mask = BIT(3),
6457e906103SLorenzo Bianconi 			},
6467e906103SLorenzo Bianconi 			.lir = {
6477e906103SLorenzo Bianconi 				.addr = 0x58,
6487e906103SLorenzo Bianconi 				.mask = BIT(0),
6497e906103SLorenzo Bianconi 			},
6507e906103SLorenzo Bianconi 			.irq1_func = {
6517e906103SLorenzo Bianconi 				.addr = 0x5e,
6527e906103SLorenzo Bianconi 				.mask = BIT(5),
6537e906103SLorenzo Bianconi 			},
6547e906103SLorenzo Bianconi 			.irq2_func = {
6557e906103SLorenzo Bianconi 				.addr = 0x5f,
6567e906103SLorenzo Bianconi 				.mask = BIT(5),
6577e906103SLorenzo Bianconi 			},
65831fe8d4eSLorenzo Bianconi 			.hla = {
65931fe8d4eSLorenzo Bianconi 				.addr = 0x12,
66031fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
66131fe8d4eSLorenzo Bianconi 			},
66231fe8d4eSLorenzo Bianconi 			.od = {
66331fe8d4eSLorenzo Bianconi 				.addr = 0x12,
66431fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
66531fe8d4eSLorenzo Bianconi 			},
6667e906103SLorenzo Bianconi 		},
6677ca3ac9eSLorenzo Bianconi 		.decimator = {
6687ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
6697ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6707ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
6717ca3ac9eSLorenzo Bianconi 			},
6727ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
6737ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6747ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
6757ca3ac9eSLorenzo Bianconi 			},
676e485e2a2SLorenzo Bianconi 			[ST_LSM6DSX_ID_EXT0] = {
677e485e2a2SLorenzo Bianconi 				.addr = 0x09,
678e485e2a2SLorenzo Bianconi 				.mask = GENMASK(2, 0),
679e485e2a2SLorenzo Bianconi 			},
6807ca3ac9eSLorenzo Bianconi 		},
68192617c15SLorenzo Bianconi 		.fifo_ops = {
6823b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
68350ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
68492617c15SLorenzo Bianconi 			.fifo_th = {
68592617c15SLorenzo Bianconi 				.addr = 0x06,
686be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
68792617c15SLorenzo Bianconi 			},
68892617c15SLorenzo Bianconi 			.fifo_diff = {
68992617c15SLorenzo Bianconi 				.addr = 0x3a,
690be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
69192617c15SLorenzo Bianconi 			},
6921b7da2faSLorenzo Bianconi 			.max_size = 682,
69392617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
69492617c15SLorenzo Bianconi 		},
69521345107SLorenzo Bianconi 		.ts_settings = {
69621345107SLorenzo Bianconi 			.timer_en = {
69721345107SLorenzo Bianconi 				.addr = 0x19,
69821345107SLorenzo Bianconi 				.mask = BIT(5),
69921345107SLorenzo Bianconi 			},
70021345107SLorenzo Bianconi 			.hr_timer = {
70121345107SLorenzo Bianconi 				.addr = 0x5c,
70221345107SLorenzo Bianconi 				.mask = BIT(4),
70321345107SLorenzo Bianconi 			},
70421345107SLorenzo Bianconi 			.fifo_en = {
70521345107SLorenzo Bianconi 				.addr = 0x07,
70621345107SLorenzo Bianconi 				.mask = BIT(7),
70721345107SLorenzo Bianconi 			},
70821345107SLorenzo Bianconi 			.decimator = {
70921345107SLorenzo Bianconi 				.addr = 0x09,
71021345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
71121345107SLorenzo Bianconi 			},
71221345107SLorenzo Bianconi 		},
713e485e2a2SLorenzo Bianconi 		.shub_settings = {
714e485e2a2SLorenzo Bianconi 			.page_mux = {
715e485e2a2SLorenzo Bianconi 				.addr = 0x01,
716e485e2a2SLorenzo Bianconi 				.mask = BIT(7),
717e485e2a2SLorenzo Bianconi 			},
718e485e2a2SLorenzo Bianconi 			.master_en = {
719e485e2a2SLorenzo Bianconi 				.addr = 0x1a,
720e485e2a2SLorenzo Bianconi 				.mask = BIT(0),
721e485e2a2SLorenzo Bianconi 			},
722e485e2a2SLorenzo Bianconi 			.pullup_en = {
723e485e2a2SLorenzo Bianconi 				.addr = 0x1a,
724e485e2a2SLorenzo Bianconi 				.mask = BIT(3),
725e485e2a2SLorenzo Bianconi 			},
726e485e2a2SLorenzo Bianconi 			.aux_sens = {
727e485e2a2SLorenzo Bianconi 				.addr = 0x04,
728e485e2a2SLorenzo Bianconi 				.mask = GENMASK(5, 4),
729e485e2a2SLorenzo Bianconi 			},
730e485e2a2SLorenzo Bianconi 			.wr_once = {
731e485e2a2SLorenzo Bianconi 				.addr = 0x07,
732e485e2a2SLorenzo Bianconi 				.mask = BIT(5),
733e485e2a2SLorenzo Bianconi 			},
734e485e2a2SLorenzo Bianconi 			.emb_func = {
735e485e2a2SLorenzo Bianconi 				.addr = 0x19,
736e485e2a2SLorenzo Bianconi 				.mask = BIT(2),
737e485e2a2SLorenzo Bianconi 			},
738e485e2a2SLorenzo Bianconi 			.num_ext_dev = 1,
739e485e2a2SLorenzo Bianconi 			.shub_out = {
740e485e2a2SLorenzo Bianconi 				.addr = 0x2e,
741e485e2a2SLorenzo Bianconi 			},
742e485e2a2SLorenzo Bianconi 			.slv0_addr = 0x02,
743e485e2a2SLorenzo Bianconi 			.dw_slv0_addr = 0x0e,
744e485e2a2SLorenzo Bianconi 			.pause = 0x7,
745e485e2a2SLorenzo Bianconi 		},
746b5969abfSSean Nyekjaer 		.event_settings = {
747b5969abfSSean Nyekjaer 			.enable_reg = {
748b5969abfSSean Nyekjaer 				.addr = 0x58,
749b5969abfSSean Nyekjaer 				.mask = BIT(7),
750b5969abfSSean Nyekjaer 			},
751b5969abfSSean Nyekjaer 			.wakeup_reg = {
752b5969abfSSean Nyekjaer 				.addr = 0x5B,
753b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
754b5969abfSSean Nyekjaer 			},
7551aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
7561aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
7571aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
7581aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
7591aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
760b5969abfSSean Nyekjaer 		},
761290a6ce1SLorenzo Bianconi 	},
762801a6e0aSLorenzo Bianconi 	{
76366b662a1SLorenzo Bianconi 		.reset = {
76466b662a1SLorenzo Bianconi 			.addr = 0x12,
76566b662a1SLorenzo Bianconi 			.mask = BIT(0),
76666b662a1SLorenzo Bianconi 		},
76766b662a1SLorenzo Bianconi 		.boot = {
76866b662a1SLorenzo Bianconi 			.addr = 0x12,
76966b662a1SLorenzo Bianconi 			.mask = BIT(7),
77066b662a1SLorenzo Bianconi 		},
77166b662a1SLorenzo Bianconi 		.bdu = {
77266b662a1SLorenzo Bianconi 			.addr = 0x12,
77366b662a1SLorenzo Bianconi 			.mask = BIT(6),
77466b662a1SLorenzo Bianconi 		},
77543901008SLorenzo Bianconi 		.id = {
77681956a93SLorenzo Bianconi 			{
77781956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSR_ID,
77881956a93SLorenzo Bianconi 				.name = ST_LSM6DSR_DEV_NAME,
77998c3544aSLorenzo Bianconi 				.wai = 0x6b,
780db947a79SLorenzo Bianconi 			}, {
781db947a79SLorenzo Bianconi 				.hw_id = ST_ISM330DHCX_ID,
782db947a79SLorenzo Bianconi 				.name = ST_ISM330DHCX_DEV_NAME,
78398c3544aSLorenzo Bianconi 				.wai = 0x6b,
784cf9c71b3SLorenzo Bianconi 			}, {
785cf9c71b3SLorenzo Bianconi 				.hw_id = ST_LSM6DSRX_ID,
786cf9c71b3SLorenzo Bianconi 				.name = ST_LSM6DSRX_DEV_NAME,
78798c3544aSLorenzo Bianconi 				.wai = 0x6b,
78898c3544aSLorenzo Bianconi 			}, {
78998c3544aSLorenzo Bianconi 				.hw_id = ST_LSM6DSO_ID,
79098c3544aSLorenzo Bianconi 				.name = ST_LSM6DSO_DEV_NAME,
79198c3544aSLorenzo Bianconi 				.wai = 0x6c,
79298c3544aSLorenzo Bianconi 			}, {
79398c3544aSLorenzo Bianconi 				.hw_id = ST_LSM6DSOX_ID,
79498c3544aSLorenzo Bianconi 				.name = ST_LSM6DSOX_DEV_NAME,
79598c3544aSLorenzo Bianconi 				.wai = 0x6c,
79698c3544aSLorenzo Bianconi 			}, {
7974393e4c5SLorenzo Bianconi 				.hw_id = ST_LSM6DST_ID,
7984393e4c5SLorenzo Bianconi 				.name = ST_LSM6DST_DEV_NAME,
79998c3544aSLorenzo Bianconi 				.wai = 0x6d,
800fdd70d7aSLorenzo Bianconi 			}, {
801fdd70d7aSLorenzo Bianconi 				.hw_id = ST_ASM330LHHX_ID,
802fdd70d7aSLorenzo Bianconi 				.name = ST_ASM330LHHX_DEV_NAME,
803fdd70d7aSLorenzo Bianconi 				.wai = 0x6b,
804186b9e38SLorenzo Bianconi 			}, {
805186b9e38SLorenzo Bianconi 				.hw_id = ST_LSM6DSTX_ID,
806186b9e38SLorenzo Bianconi 				.name = ST_LSM6DSTX_DEV_NAME,
807186b9e38SLorenzo Bianconi 				.wai = 0x6d,
8084393e4c5SLorenzo Bianconi 			},
8094393e4c5SLorenzo Bianconi 		},
8104393e4c5SLorenzo Bianconi 		.channels = {
8114393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
8124393e4c5SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
8134393e4c5SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
8144393e4c5SLorenzo Bianconi 			},
8154393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8164393e4c5SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
8174393e4c5SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
8184393e4c5SLorenzo Bianconi 			},
8194393e4c5SLorenzo Bianconi 		},
8204393e4c5SLorenzo Bianconi 		.drdy_mask = {
8214393e4c5SLorenzo Bianconi 			.addr = 0x13,
8224393e4c5SLorenzo Bianconi 			.mask = BIT(3),
8234393e4c5SLorenzo Bianconi 		},
8244393e4c5SLorenzo Bianconi 		.odr_table = {
8254393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
8264393e4c5SLorenzo Bianconi 				.reg = {
8274393e4c5SLorenzo Bianconi 					.addr = 0x10,
8284393e4c5SLorenzo Bianconi 					.mask = GENMASK(7, 4),
8294393e4c5SLorenzo Bianconi 				},
8304393e4c5SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
8314393e4c5SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
8324393e4c5SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
8334393e4c5SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
8344393e4c5SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
8354393e4c5SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
8364393e4c5SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
8374393e4c5SLorenzo Bianconi 				.odr_len = 7,
8384393e4c5SLorenzo Bianconi 			},
8394393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8404393e4c5SLorenzo Bianconi 				.reg = {
8414393e4c5SLorenzo Bianconi 					.addr = 0x11,
8424393e4c5SLorenzo Bianconi 					.mask = GENMASK(7, 4),
8434393e4c5SLorenzo Bianconi 				},
8444393e4c5SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
8454393e4c5SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
8464393e4c5SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
8474393e4c5SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
8484393e4c5SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
8494393e4c5SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
8504393e4c5SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
8514393e4c5SLorenzo Bianconi 				.odr_len = 7,
8524393e4c5SLorenzo Bianconi 			},
8534393e4c5SLorenzo Bianconi 		},
8544393e4c5SLorenzo Bianconi 		.fs_table = {
8554393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
8564393e4c5SLorenzo Bianconi 				.reg = {
8574393e4c5SLorenzo Bianconi 					.addr = 0x10,
8584393e4c5SLorenzo Bianconi 					.mask = GENMASK(3, 2),
8594393e4c5SLorenzo Bianconi 				},
8604393e4c5SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
8614393e4c5SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
8624393e4c5SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
8634393e4c5SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
8644393e4c5SLorenzo Bianconi 				.fs_len = 4,
8654393e4c5SLorenzo Bianconi 			},
8664393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
8674393e4c5SLorenzo Bianconi 				.reg = {
8684393e4c5SLorenzo Bianconi 					.addr = 0x11,
8694393e4c5SLorenzo Bianconi 					.mask = GENMASK(3, 2),
8704393e4c5SLorenzo Bianconi 				},
8714393e4c5SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
8724393e4c5SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
8734393e4c5SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
8744393e4c5SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
8754393e4c5SLorenzo Bianconi 				.fs_len = 4,
8764393e4c5SLorenzo Bianconi 			},
8774393e4c5SLorenzo Bianconi 		},
8784393e4c5SLorenzo Bianconi 		.irq_config = {
8794393e4c5SLorenzo Bianconi 			.irq1 = {
8804393e4c5SLorenzo Bianconi 				.addr = 0x0d,
8814393e4c5SLorenzo Bianconi 				.mask = BIT(3),
8824393e4c5SLorenzo Bianconi 			},
8834393e4c5SLorenzo Bianconi 			.irq2 = {
8844393e4c5SLorenzo Bianconi 				.addr = 0x0e,
8854393e4c5SLorenzo Bianconi 				.mask = BIT(3),
8864393e4c5SLorenzo Bianconi 			},
8874393e4c5SLorenzo Bianconi 			.lir = {
8884393e4c5SLorenzo Bianconi 				.addr = 0x56,
8894393e4c5SLorenzo Bianconi 				.mask = BIT(0),
8904393e4c5SLorenzo Bianconi 			},
8914393e4c5SLorenzo Bianconi 			.clear_on_read = {
8924393e4c5SLorenzo Bianconi 				.addr = 0x56,
8934393e4c5SLorenzo Bianconi 				.mask = BIT(6),
8944393e4c5SLorenzo Bianconi 			},
8954393e4c5SLorenzo Bianconi 			.irq1_func = {
8964393e4c5SLorenzo Bianconi 				.addr = 0x5e,
8974393e4c5SLorenzo Bianconi 				.mask = BIT(5),
8984393e4c5SLorenzo Bianconi 			},
8994393e4c5SLorenzo Bianconi 			.irq2_func = {
9004393e4c5SLorenzo Bianconi 				.addr = 0x5f,
9014393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9024393e4c5SLorenzo Bianconi 			},
9034393e4c5SLorenzo Bianconi 			.hla = {
9044393e4c5SLorenzo Bianconi 				.addr = 0x12,
9054393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9064393e4c5SLorenzo Bianconi 			},
9074393e4c5SLorenzo Bianconi 			.od = {
9084393e4c5SLorenzo Bianconi 				.addr = 0x12,
9094393e4c5SLorenzo Bianconi 				.mask = BIT(4),
9104393e4c5SLorenzo Bianconi 			},
9114393e4c5SLorenzo Bianconi 		},
9124393e4c5SLorenzo Bianconi 		.batch = {
9134393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
9144393e4c5SLorenzo Bianconi 				.addr = 0x09,
9154393e4c5SLorenzo Bianconi 				.mask = GENMASK(3, 0),
9164393e4c5SLorenzo Bianconi 			},
9174393e4c5SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
9184393e4c5SLorenzo Bianconi 				.addr = 0x09,
9194393e4c5SLorenzo Bianconi 				.mask = GENMASK(7, 4),
9204393e4c5SLorenzo Bianconi 			},
9214393e4c5SLorenzo Bianconi 		},
9224393e4c5SLorenzo Bianconi 		.fifo_ops = {
9234393e4c5SLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
9244393e4c5SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
9254393e4c5SLorenzo Bianconi 			.fifo_th = {
9264393e4c5SLorenzo Bianconi 				.addr = 0x07,
9274393e4c5SLorenzo Bianconi 				.mask = GENMASK(8, 0),
9284393e4c5SLorenzo Bianconi 			},
9294393e4c5SLorenzo Bianconi 			.fifo_diff = {
9304393e4c5SLorenzo Bianconi 				.addr = 0x3a,
9314393e4c5SLorenzo Bianconi 				.mask = GENMASK(9, 0),
9324393e4c5SLorenzo Bianconi 			},
9331b7da2faSLorenzo Bianconi 			.max_size = 512,
9344393e4c5SLorenzo Bianconi 			.th_wl = 1,
9354393e4c5SLorenzo Bianconi 		},
9364393e4c5SLorenzo Bianconi 		.ts_settings = {
9374393e4c5SLorenzo Bianconi 			.timer_en = {
9384393e4c5SLorenzo Bianconi 				.addr = 0x19,
9394393e4c5SLorenzo Bianconi 				.mask = BIT(5),
9404393e4c5SLorenzo Bianconi 			},
9414393e4c5SLorenzo Bianconi 			.decimator = {
9424393e4c5SLorenzo Bianconi 				.addr = 0x0a,
9434393e4c5SLorenzo Bianconi 				.mask = GENMASK(7, 6),
9444393e4c5SLorenzo Bianconi 			},
9454393e4c5SLorenzo Bianconi 			.freq_fine = 0x63,
9464393e4c5SLorenzo Bianconi 		},
9474393e4c5SLorenzo Bianconi 		.shub_settings = {
9484393e4c5SLorenzo Bianconi 			.page_mux = {
9494393e4c5SLorenzo Bianconi 				.addr = 0x01,
9504393e4c5SLorenzo Bianconi 				.mask = BIT(6),
9514393e4c5SLorenzo Bianconi 			},
9524393e4c5SLorenzo Bianconi 			.master_en = {
9534393e4c5SLorenzo Bianconi 				.sec_page = true,
9544393e4c5SLorenzo Bianconi 				.addr = 0x14,
9554393e4c5SLorenzo Bianconi 				.mask = BIT(2),
9564393e4c5SLorenzo Bianconi 			},
9574393e4c5SLorenzo Bianconi 			.pullup_en = {
9584393e4c5SLorenzo Bianconi 				.sec_page = true,
9594393e4c5SLorenzo Bianconi 				.addr = 0x14,
9604393e4c5SLorenzo Bianconi 				.mask = BIT(3),
9614393e4c5SLorenzo Bianconi 			},
9624393e4c5SLorenzo Bianconi 			.aux_sens = {
9634393e4c5SLorenzo Bianconi 				.addr = 0x14,
9644393e4c5SLorenzo Bianconi 				.mask = GENMASK(1, 0),
9654393e4c5SLorenzo Bianconi 			},
9664393e4c5SLorenzo Bianconi 			.wr_once = {
9674393e4c5SLorenzo Bianconi 				.addr = 0x14,
9684393e4c5SLorenzo Bianconi 				.mask = BIT(6),
9694393e4c5SLorenzo Bianconi 			},
9704393e4c5SLorenzo Bianconi 			.num_ext_dev = 3,
9714393e4c5SLorenzo Bianconi 			.shub_out = {
9724393e4c5SLorenzo Bianconi 				.sec_page = true,
9734393e4c5SLorenzo Bianconi 				.addr = 0x02,
9744393e4c5SLorenzo Bianconi 			},
9754393e4c5SLorenzo Bianconi 			.slv0_addr = 0x15,
9764393e4c5SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
9774393e4c5SLorenzo Bianconi 			.batch_en = BIT(3),
9784393e4c5SLorenzo Bianconi 		},
9794393e4c5SLorenzo Bianconi 		.event_settings = {
9804393e4c5SLorenzo Bianconi 			.enable_reg = {
9814393e4c5SLorenzo Bianconi 				.addr = 0x58,
9824393e4c5SLorenzo Bianconi 				.mask = BIT(7),
9834393e4c5SLorenzo Bianconi 			},
9844393e4c5SLorenzo Bianconi 			.wakeup_reg = {
9854393e4c5SLorenzo Bianconi 				.addr = 0x5b,
9864393e4c5SLorenzo Bianconi 				.mask = GENMASK(5, 0),
9874393e4c5SLorenzo Bianconi 			},
9884393e4c5SLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
9894393e4c5SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
9904393e4c5SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
9914393e4c5SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
9924393e4c5SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
9934393e4c5SLorenzo Bianconi 		},
9944393e4c5SLorenzo Bianconi 	},
99598c3544aSLorenzo Bianconi 	{
99698c3544aSLorenzo Bianconi 		.reset = {
99798c3544aSLorenzo Bianconi 			.addr = 0x12,
99898c3544aSLorenzo Bianconi 			.mask = BIT(0),
99998c3544aSLorenzo Bianconi 		},
100098c3544aSLorenzo Bianconi 		.boot = {
100198c3544aSLorenzo Bianconi 			.addr = 0x12,
100298c3544aSLorenzo Bianconi 			.mask = BIT(7),
100398c3544aSLorenzo Bianconi 		},
100498c3544aSLorenzo Bianconi 		.bdu = {
100598c3544aSLorenzo Bianconi 			.addr = 0x12,
100698c3544aSLorenzo Bianconi 			.mask = BIT(6),
100798c3544aSLorenzo Bianconi 		},
100898c3544aSLorenzo Bianconi 		.id = {
100998c3544aSLorenzo Bianconi 			{
101098c3544aSLorenzo Bianconi 				.hw_id = ST_ASM330LHH_ID,
101198c3544aSLorenzo Bianconi 				.name = ST_ASM330LHH_DEV_NAME,
101298c3544aSLorenzo Bianconi 				.wai = 0x6b,
10132c57d265SLorenzo Bianconi 			}, {
10142c57d265SLorenzo Bianconi 				.hw_id = ST_LSM6DSOP_ID,
10152c57d265SLorenzo Bianconi 				.name = ST_LSM6DSOP_DEV_NAME,
10162c57d265SLorenzo Bianconi 				.wai = 0x6c,
101798c3544aSLorenzo Bianconi 			},
101898c3544aSLorenzo Bianconi 		},
101998c3544aSLorenzo Bianconi 		.channels = {
102098c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
102198c3544aSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
102298c3544aSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
102398c3544aSLorenzo Bianconi 			},
102498c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
102598c3544aSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
102698c3544aSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
102798c3544aSLorenzo Bianconi 			},
102898c3544aSLorenzo Bianconi 		},
102998c3544aSLorenzo Bianconi 		.drdy_mask = {
103098c3544aSLorenzo Bianconi 			.addr = 0x13,
103198c3544aSLorenzo Bianconi 			.mask = BIT(3),
103298c3544aSLorenzo Bianconi 		},
103398c3544aSLorenzo Bianconi 		.odr_table = {
103498c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
103598c3544aSLorenzo Bianconi 				.reg = {
103698c3544aSLorenzo Bianconi 					.addr = 0x10,
103798c3544aSLorenzo Bianconi 					.mask = GENMASK(7, 4),
103898c3544aSLorenzo Bianconi 				},
103998c3544aSLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
104098c3544aSLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
104198c3544aSLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
104298c3544aSLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
104398c3544aSLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
104498c3544aSLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
104598c3544aSLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
104698c3544aSLorenzo Bianconi 				.odr_len = 7,
104798c3544aSLorenzo Bianconi 			},
104898c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
104998c3544aSLorenzo Bianconi 				.reg = {
105098c3544aSLorenzo Bianconi 					.addr = 0x11,
105198c3544aSLorenzo Bianconi 					.mask = GENMASK(7, 4),
105298c3544aSLorenzo Bianconi 				},
105398c3544aSLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
105498c3544aSLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
105598c3544aSLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
105698c3544aSLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
105798c3544aSLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
105898c3544aSLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
105998c3544aSLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
106098c3544aSLorenzo Bianconi 				.odr_len = 7,
106198c3544aSLorenzo Bianconi 			},
106298c3544aSLorenzo Bianconi 		},
106398c3544aSLorenzo Bianconi 		.fs_table = {
106498c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
106598c3544aSLorenzo Bianconi 				.reg = {
106698c3544aSLorenzo Bianconi 					.addr = 0x10,
106798c3544aSLorenzo Bianconi 					.mask = GENMASK(3, 2),
106898c3544aSLorenzo Bianconi 				},
106998c3544aSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
107098c3544aSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
107198c3544aSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
107298c3544aSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
107398c3544aSLorenzo Bianconi 				.fs_len = 4,
107498c3544aSLorenzo Bianconi 			},
107598c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
107698c3544aSLorenzo Bianconi 				.reg = {
107798c3544aSLorenzo Bianconi 					.addr = 0x11,
107898c3544aSLorenzo Bianconi 					.mask = GENMASK(3, 2),
107998c3544aSLorenzo Bianconi 				},
108098c3544aSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
108198c3544aSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
108298c3544aSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
108398c3544aSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
108498c3544aSLorenzo Bianconi 				.fs_len = 4,
108598c3544aSLorenzo Bianconi 			},
108698c3544aSLorenzo Bianconi 		},
108798c3544aSLorenzo Bianconi 		.irq_config = {
108898c3544aSLorenzo Bianconi 			.irq1 = {
108998c3544aSLorenzo Bianconi 				.addr = 0x0d,
109098c3544aSLorenzo Bianconi 				.mask = BIT(3),
109198c3544aSLorenzo Bianconi 			},
109298c3544aSLorenzo Bianconi 			.irq2 = {
109398c3544aSLorenzo Bianconi 				.addr = 0x0e,
109498c3544aSLorenzo Bianconi 				.mask = BIT(3),
109598c3544aSLorenzo Bianconi 			},
109698c3544aSLorenzo Bianconi 			.lir = {
109798c3544aSLorenzo Bianconi 				.addr = 0x56,
109898c3544aSLorenzo Bianconi 				.mask = BIT(0),
109998c3544aSLorenzo Bianconi 			},
110098c3544aSLorenzo Bianconi 			.clear_on_read = {
110198c3544aSLorenzo Bianconi 				.addr = 0x56,
110298c3544aSLorenzo Bianconi 				.mask = BIT(6),
110398c3544aSLorenzo Bianconi 			},
110498c3544aSLorenzo Bianconi 			.irq1_func = {
110598c3544aSLorenzo Bianconi 				.addr = 0x5e,
110698c3544aSLorenzo Bianconi 				.mask = BIT(5),
110798c3544aSLorenzo Bianconi 			},
110898c3544aSLorenzo Bianconi 			.irq2_func = {
110998c3544aSLorenzo Bianconi 				.addr = 0x5f,
111098c3544aSLorenzo Bianconi 				.mask = BIT(5),
111198c3544aSLorenzo Bianconi 			},
111298c3544aSLorenzo Bianconi 			.hla = {
111398c3544aSLorenzo Bianconi 				.addr = 0x12,
111498c3544aSLorenzo Bianconi 				.mask = BIT(5),
111598c3544aSLorenzo Bianconi 			},
111698c3544aSLorenzo Bianconi 			.od = {
111798c3544aSLorenzo Bianconi 				.addr = 0x12,
111898c3544aSLorenzo Bianconi 				.mask = BIT(4),
111998c3544aSLorenzo Bianconi 			},
112098c3544aSLorenzo Bianconi 		},
112198c3544aSLorenzo Bianconi 		.batch = {
112298c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
112398c3544aSLorenzo Bianconi 				.addr = 0x09,
112498c3544aSLorenzo Bianconi 				.mask = GENMASK(3, 0),
112598c3544aSLorenzo Bianconi 			},
112698c3544aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
112798c3544aSLorenzo Bianconi 				.addr = 0x09,
112898c3544aSLorenzo Bianconi 				.mask = GENMASK(7, 4),
112998c3544aSLorenzo Bianconi 			},
113098c3544aSLorenzo Bianconi 		},
113198c3544aSLorenzo Bianconi 		.fifo_ops = {
113298c3544aSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
113398c3544aSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
113498c3544aSLorenzo Bianconi 			.fifo_th = {
113598c3544aSLorenzo Bianconi 				.addr = 0x07,
113698c3544aSLorenzo Bianconi 				.mask = GENMASK(8, 0),
113798c3544aSLorenzo Bianconi 			},
113898c3544aSLorenzo Bianconi 			.fifo_diff = {
113998c3544aSLorenzo Bianconi 				.addr = 0x3a,
114098c3544aSLorenzo Bianconi 				.mask = GENMASK(9, 0),
114198c3544aSLorenzo Bianconi 			},
11421b7da2faSLorenzo Bianconi 			.max_size = 512,
114398c3544aSLorenzo Bianconi 			.th_wl = 1,
114498c3544aSLorenzo Bianconi 		},
114598c3544aSLorenzo Bianconi 		.ts_settings = {
114698c3544aSLorenzo Bianconi 			.timer_en = {
114798c3544aSLorenzo Bianconi 				.addr = 0x19,
114898c3544aSLorenzo Bianconi 				.mask = BIT(5),
114998c3544aSLorenzo Bianconi 			},
115098c3544aSLorenzo Bianconi 			.decimator = {
115198c3544aSLorenzo Bianconi 				.addr = 0x0a,
115298c3544aSLorenzo Bianconi 				.mask = GENMASK(7, 6),
115398c3544aSLorenzo Bianconi 			},
115498c3544aSLorenzo Bianconi 			.freq_fine = 0x63,
115598c3544aSLorenzo Bianconi 		},
115698c3544aSLorenzo Bianconi 		.event_settings = {
115798c3544aSLorenzo Bianconi 			.enable_reg = {
115898c3544aSLorenzo Bianconi 				.addr = 0x58,
115998c3544aSLorenzo Bianconi 				.mask = BIT(7),
116098c3544aSLorenzo Bianconi 			},
116198c3544aSLorenzo Bianconi 			.wakeup_reg = {
116298c3544aSLorenzo Bianconi 				.addr = 0x5B,
116398c3544aSLorenzo Bianconi 				.mask = GENMASK(5, 0),
116498c3544aSLorenzo Bianconi 			},
116598c3544aSLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
116698c3544aSLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
116798c3544aSLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
116898c3544aSLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
116998c3544aSLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
117098c3544aSLorenzo Bianconi 		},
117198c3544aSLorenzo Bianconi 	},
1172a1c6d631SLorenzo Bianconi 	{
1173a1c6d631SLorenzo Bianconi 		.reset = {
1174a1c6d631SLorenzo Bianconi 			.addr = 0x12,
1175a1c6d631SLorenzo Bianconi 			.mask = BIT(0),
1176a1c6d631SLorenzo Bianconi 		},
1177a1c6d631SLorenzo Bianconi 		.boot = {
1178a1c6d631SLorenzo Bianconi 			.addr = 0x12,
1179a1c6d631SLorenzo Bianconi 			.mask = BIT(7),
1180a1c6d631SLorenzo Bianconi 		},
1181a1c6d631SLorenzo Bianconi 		.bdu = {
1182a1c6d631SLorenzo Bianconi 			.addr = 0x12,
1183a1c6d631SLorenzo Bianconi 			.mask = BIT(6),
1184a1c6d631SLorenzo Bianconi 		},
1185a1c6d631SLorenzo Bianconi 		.id = {
1186a1c6d631SLorenzo Bianconi 			{
1187a1c6d631SLorenzo Bianconi 				.hw_id = ST_LSM6DSV_ID,
1188a1c6d631SLorenzo Bianconi 				.name = ST_LSM6DSV_DEV_NAME,
1189a1c6d631SLorenzo Bianconi 				.wai = 0x70,
119046975081SLorenzo Bianconi 			}, {
119146975081SLorenzo Bianconi 				.hw_id = ST_LSM6DSV16X_ID,
119246975081SLorenzo Bianconi 				.name = ST_LSM6DSV16X_DEV_NAME,
119346975081SLorenzo Bianconi 				.wai = 0x70,
1194a1c6d631SLorenzo Bianconi 			},
1195a1c6d631SLorenzo Bianconi 		},
1196a1c6d631SLorenzo Bianconi 		.channels = {
1197a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1198a1c6d631SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1199a1c6d631SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1200a1c6d631SLorenzo Bianconi 			},
1201a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1202a1c6d631SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1203a1c6d631SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1204a1c6d631SLorenzo Bianconi 			},
1205a1c6d631SLorenzo Bianconi 		},
1206a1c6d631SLorenzo Bianconi 		.drdy_mask = {
1207a1c6d631SLorenzo Bianconi 			.addr = 0x13,
1208a1c6d631SLorenzo Bianconi 			.mask = BIT(3),
1209a1c6d631SLorenzo Bianconi 		},
1210a1c6d631SLorenzo Bianconi 		.odr_table = {
1211a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1212a1c6d631SLorenzo Bianconi 				.reg = {
1213a1c6d631SLorenzo Bianconi 					.addr = 0x10,
1214a1c6d631SLorenzo Bianconi 					.mask = GENMASK(3, 0),
1215a1c6d631SLorenzo Bianconi 				},
1216a1c6d631SLorenzo Bianconi 				.odr_avl[0] = {   7500, 0x02 },
1217a1c6d631SLorenzo Bianconi 				.odr_avl[1] = {  15000, 0x03 },
1218a1c6d631SLorenzo Bianconi 				.odr_avl[2] = {  30000, 0x04 },
1219a1c6d631SLorenzo Bianconi 				.odr_avl[3] = {  60000, 0x05 },
1220a1c6d631SLorenzo Bianconi 				.odr_avl[4] = { 120000, 0x06 },
1221a1c6d631SLorenzo Bianconi 				.odr_avl[5] = { 240000, 0x07 },
1222a1c6d631SLorenzo Bianconi 				.odr_avl[6] = { 480000, 0x08 },
1223a1c6d631SLorenzo Bianconi 				.odr_avl[7] = { 960000, 0x09 },
1224a1c6d631SLorenzo Bianconi 				.odr_len = 8,
1225a1c6d631SLorenzo Bianconi 			},
1226a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1227a1c6d631SLorenzo Bianconi 				.reg = {
1228a1c6d631SLorenzo Bianconi 					.addr = 0x11,
1229a1c6d631SLorenzo Bianconi 					.mask = GENMASK(3, 0),
1230a1c6d631SLorenzo Bianconi 				},
1231a1c6d631SLorenzo Bianconi 				.odr_avl[0] = {   7500, 0x02 },
1232a1c6d631SLorenzo Bianconi 				.odr_avl[1] = {  15000, 0x03 },
1233a1c6d631SLorenzo Bianconi 				.odr_avl[2] = {  30000, 0x04 },
1234a1c6d631SLorenzo Bianconi 				.odr_avl[3] = {  60000, 0x05 },
1235a1c6d631SLorenzo Bianconi 				.odr_avl[4] = { 120000, 0x06 },
1236a1c6d631SLorenzo Bianconi 				.odr_avl[5] = { 240000, 0x07 },
1237a1c6d631SLorenzo Bianconi 				.odr_avl[6] = { 480000, 0x08 },
1238a1c6d631SLorenzo Bianconi 				.odr_avl[7] = { 960000, 0x09 },
1239a1c6d631SLorenzo Bianconi 				.odr_len = 8,
1240a1c6d631SLorenzo Bianconi 			},
1241a1c6d631SLorenzo Bianconi 		},
1242a1c6d631SLorenzo Bianconi 		.fs_table = {
1243a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1244a1c6d631SLorenzo Bianconi 				.reg = {
1245a1c6d631SLorenzo Bianconi 					.addr = 0x17,
1246a1c6d631SLorenzo Bianconi 					.mask = GENMASK(1, 0),
1247a1c6d631SLorenzo Bianconi 				},
1248a1c6d631SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
1249a1c6d631SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x1 },
1250a1c6d631SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x2 },
1251a1c6d631SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x3 },
1252a1c6d631SLorenzo Bianconi 				.fs_len = 4,
1253a1c6d631SLorenzo Bianconi 			},
1254a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1255a1c6d631SLorenzo Bianconi 				.reg = {
1256a1c6d631SLorenzo Bianconi 					.addr = 0x15,
1257a1c6d631SLorenzo Bianconi 					.mask = GENMASK(3, 0),
1258a1c6d631SLorenzo Bianconi 				},
1259a1c6d631SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x1 },
1260a1c6d631SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x2 },
1261a1c6d631SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x3 },
1262a1c6d631SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x4 },
1263a1c6d631SLorenzo Bianconi 				.fs_len = 4,
1264a1c6d631SLorenzo Bianconi 			},
1265a1c6d631SLorenzo Bianconi 		},
1266a1c6d631SLorenzo Bianconi 		.irq_config = {
1267a1c6d631SLorenzo Bianconi 			.irq1 = {
1268a1c6d631SLorenzo Bianconi 				.addr = 0x0d,
1269a1c6d631SLorenzo Bianconi 				.mask = BIT(3),
1270a1c6d631SLorenzo Bianconi 			},
1271a1c6d631SLorenzo Bianconi 			.irq2 = {
1272a1c6d631SLorenzo Bianconi 				.addr = 0x0e,
1273a1c6d631SLorenzo Bianconi 				.mask = BIT(3),
1274a1c6d631SLorenzo Bianconi 			},
1275a1c6d631SLorenzo Bianconi 			.lir = {
1276a1c6d631SLorenzo Bianconi 				.addr = 0x56,
1277a1c6d631SLorenzo Bianconi 				.mask = BIT(0),
1278a1c6d631SLorenzo Bianconi 			},
1279a1c6d631SLorenzo Bianconi 			.irq1_func = {
1280a1c6d631SLorenzo Bianconi 				.addr = 0x5e,
1281a1c6d631SLorenzo Bianconi 				.mask = BIT(5),
1282a1c6d631SLorenzo Bianconi 			},
1283a1c6d631SLorenzo Bianconi 			.irq2_func = {
1284a1c6d631SLorenzo Bianconi 				.addr = 0x5f,
1285a1c6d631SLorenzo Bianconi 				.mask = BIT(5),
1286a1c6d631SLorenzo Bianconi 			},
1287a1c6d631SLorenzo Bianconi 			.hla = {
1288a1c6d631SLorenzo Bianconi 				.addr = 0x03,
1289a1c6d631SLorenzo Bianconi 				.mask = BIT(4),
1290a1c6d631SLorenzo Bianconi 			},
1291a1c6d631SLorenzo Bianconi 			.od = {
1292a1c6d631SLorenzo Bianconi 				.addr = 0x03,
1293a1c6d631SLorenzo Bianconi 				.mask = BIT(3),
1294a1c6d631SLorenzo Bianconi 			},
1295a1c6d631SLorenzo Bianconi 		},
1296a1c6d631SLorenzo Bianconi 		.batch = {
1297a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1298a1c6d631SLorenzo Bianconi 				.addr = 0x09,
1299a1c6d631SLorenzo Bianconi 				.mask = GENMASK(3, 0),
1300a1c6d631SLorenzo Bianconi 			},
1301a1c6d631SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1302a1c6d631SLorenzo Bianconi 				.addr = 0x09,
1303a1c6d631SLorenzo Bianconi 				.mask = GENMASK(7, 4),
1304a1c6d631SLorenzo Bianconi 			},
1305a1c6d631SLorenzo Bianconi 		},
1306a1c6d631SLorenzo Bianconi 		.fifo_ops = {
1307a1c6d631SLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
1308a1c6d631SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
1309a1c6d631SLorenzo Bianconi 			.fifo_th = {
1310a1c6d631SLorenzo Bianconi 				.addr = 0x07,
1311a1c6d631SLorenzo Bianconi 				.mask = GENMASK(7, 0),
1312a1c6d631SLorenzo Bianconi 			},
1313a1c6d631SLorenzo Bianconi 			.fifo_diff = {
1314a1c6d631SLorenzo Bianconi 				.addr = 0x1b,
1315a1c6d631SLorenzo Bianconi 				.mask = GENMASK(8, 0),
1316a1c6d631SLorenzo Bianconi 			},
1317a1c6d631SLorenzo Bianconi 			.max_size = 512,
1318a1c6d631SLorenzo Bianconi 			.th_wl = 1,
1319a1c6d631SLorenzo Bianconi 		},
1320a1c6d631SLorenzo Bianconi 		.ts_settings = {
1321a1c6d631SLorenzo Bianconi 			.timer_en = {
1322a1c6d631SLorenzo Bianconi 				.addr = 0x50,
1323a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1324a1c6d631SLorenzo Bianconi 			},
1325a1c6d631SLorenzo Bianconi 			.decimator = {
1326a1c6d631SLorenzo Bianconi 				.addr = 0x0a,
1327a1c6d631SLorenzo Bianconi 				.mask = GENMASK(7, 6),
1328a1c6d631SLorenzo Bianconi 			},
1329a1c6d631SLorenzo Bianconi 			.freq_fine = 0x4f,
1330a1c6d631SLorenzo Bianconi 		},
1331a1c6d631SLorenzo Bianconi 		.shub_settings = {
1332a1c6d631SLorenzo Bianconi 			.page_mux = {
1333a1c6d631SLorenzo Bianconi 				.addr = 0x01,
1334a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1335a1c6d631SLorenzo Bianconi 			},
1336a1c6d631SLorenzo Bianconi 			.master_en = {
1337a1c6d631SLorenzo Bianconi 				.sec_page = true,
1338a1c6d631SLorenzo Bianconi 				.addr = 0x14,
1339a1c6d631SLorenzo Bianconi 				.mask = BIT(2),
1340a1c6d631SLorenzo Bianconi 			},
1341a1c6d631SLorenzo Bianconi 			.pullup_en = {
1342a1c6d631SLorenzo Bianconi 				.addr = 0x03,
1343a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1344a1c6d631SLorenzo Bianconi 			},
1345a1c6d631SLorenzo Bianconi 			.aux_sens = {
1346a1c6d631SLorenzo Bianconi 				.addr = 0x14,
1347a1c6d631SLorenzo Bianconi 				.mask = GENMASK(1, 0),
1348a1c6d631SLorenzo Bianconi 			},
1349a1c6d631SLorenzo Bianconi 			.wr_once = {
1350a1c6d631SLorenzo Bianconi 				.addr = 0x14,
1351a1c6d631SLorenzo Bianconi 				.mask = BIT(6),
1352a1c6d631SLorenzo Bianconi 			},
1353a1c6d631SLorenzo Bianconi 			.num_ext_dev = 3,
1354a1c6d631SLorenzo Bianconi 			.shub_out = {
1355a1c6d631SLorenzo Bianconi 				.sec_page = true,
1356a1c6d631SLorenzo Bianconi 				.addr = 0x02,
1357a1c6d631SLorenzo Bianconi 			},
1358a1c6d631SLorenzo Bianconi 			.slv0_addr = 0x15,
1359a1c6d631SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
1360a1c6d631SLorenzo Bianconi 			.batch_en = BIT(3),
1361a1c6d631SLorenzo Bianconi 		},
1362a1c6d631SLorenzo Bianconi 		.event_settings = {
1363a1c6d631SLorenzo Bianconi 			.enable_reg = {
1364a1c6d631SLorenzo Bianconi 				.addr = 0x50,
1365a1c6d631SLorenzo Bianconi 				.mask = BIT(7),
1366a1c6d631SLorenzo Bianconi 			},
1367a1c6d631SLorenzo Bianconi 			.wakeup_reg = {
1368a1c6d631SLorenzo Bianconi 				.addr = 0x5b,
1369a1c6d631SLorenzo Bianconi 				.mask = GENMASK(5, 0),
1370a1c6d631SLorenzo Bianconi 			},
1371a1c6d631SLorenzo Bianconi 			.wakeup_src_reg = 0x45,
1372a1c6d631SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
1373a1c6d631SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
1374a1c6d631SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
1375a1c6d631SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
1376a1c6d631SLorenzo Bianconi 		},
1377a1c6d631SLorenzo Bianconi 	},
1378*f35e1ee9SLorenzo Bianconi 	{
1379*f35e1ee9SLorenzo Bianconi 		.reset = {
1380*f35e1ee9SLorenzo Bianconi 			.addr = 0x12,
1381*f35e1ee9SLorenzo Bianconi 			.mask = BIT(0),
1382*f35e1ee9SLorenzo Bianconi 		},
1383*f35e1ee9SLorenzo Bianconi 		.boot = {
1384*f35e1ee9SLorenzo Bianconi 			.addr = 0x12,
1385*f35e1ee9SLorenzo Bianconi 			.mask = BIT(7),
1386*f35e1ee9SLorenzo Bianconi 		},
1387*f35e1ee9SLorenzo Bianconi 		.bdu = {
1388*f35e1ee9SLorenzo Bianconi 			.addr = 0x12,
1389*f35e1ee9SLorenzo Bianconi 			.mask = BIT(6),
1390*f35e1ee9SLorenzo Bianconi 		},
1391*f35e1ee9SLorenzo Bianconi 		.id = {
1392*f35e1ee9SLorenzo Bianconi 			{
1393*f35e1ee9SLorenzo Bianconi 				.hw_id = ST_LSM6DSO16IS_ID,
1394*f35e1ee9SLorenzo Bianconi 				.name = ST_LSM6DSO16IS_DEV_NAME,
1395*f35e1ee9SLorenzo Bianconi 				.wai = 0x22,
1396*f35e1ee9SLorenzo Bianconi 			},
1397*f35e1ee9SLorenzo Bianconi 		},
1398*f35e1ee9SLorenzo Bianconi 		.channels = {
1399*f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1400*f35e1ee9SLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1401*f35e1ee9SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1402*f35e1ee9SLorenzo Bianconi 			},
1403*f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1404*f35e1ee9SLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1405*f35e1ee9SLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1406*f35e1ee9SLorenzo Bianconi 			},
1407*f35e1ee9SLorenzo Bianconi 		},
1408*f35e1ee9SLorenzo Bianconi 		.odr_table = {
1409*f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1410*f35e1ee9SLorenzo Bianconi 				.reg = {
1411*f35e1ee9SLorenzo Bianconi 					.addr = 0x10,
1412*f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(7, 4),
1413*f35e1ee9SLorenzo Bianconi 				},
1414*f35e1ee9SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1415*f35e1ee9SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1416*f35e1ee9SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1417*f35e1ee9SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1418*f35e1ee9SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1419*f35e1ee9SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
1420*f35e1ee9SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
1421*f35e1ee9SLorenzo Bianconi 				.odr_len = 7,
1422*f35e1ee9SLorenzo Bianconi 			},
1423*f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1424*f35e1ee9SLorenzo Bianconi 				.reg = {
1425*f35e1ee9SLorenzo Bianconi 					.addr = 0x11,
1426*f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(7, 4),
1427*f35e1ee9SLorenzo Bianconi 				},
1428*f35e1ee9SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1429*f35e1ee9SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1430*f35e1ee9SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1431*f35e1ee9SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1432*f35e1ee9SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1433*f35e1ee9SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
1434*f35e1ee9SLorenzo Bianconi 				.odr_avl[6] = { 833000, 0x07 },
1435*f35e1ee9SLorenzo Bianconi 				.odr_len = 7,
1436*f35e1ee9SLorenzo Bianconi 			},
1437*f35e1ee9SLorenzo Bianconi 		},
1438*f35e1ee9SLorenzo Bianconi 		.fs_table = {
1439*f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1440*f35e1ee9SLorenzo Bianconi 				.reg = {
1441*f35e1ee9SLorenzo Bianconi 					.addr = 0x10,
1442*f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(3, 2),
1443*f35e1ee9SLorenzo Bianconi 				},
1444*f35e1ee9SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61000), 0x0 },
1445*f35e1ee9SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
1446*f35e1ee9SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
1447*f35e1ee9SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
1448*f35e1ee9SLorenzo Bianconi 				.fs_len = 4,
1449*f35e1ee9SLorenzo Bianconi 			},
1450*f35e1ee9SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1451*f35e1ee9SLorenzo Bianconi 				.reg = {
1452*f35e1ee9SLorenzo Bianconi 					.addr = 0x11,
1453*f35e1ee9SLorenzo Bianconi 					.mask = GENMASK(3, 2),
1454*f35e1ee9SLorenzo Bianconi 				},
1455*f35e1ee9SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750000), 0x0 },
1456*f35e1ee9SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
1457*f35e1ee9SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
1458*f35e1ee9SLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
1459*f35e1ee9SLorenzo Bianconi 				.fs_len = 4,
1460*f35e1ee9SLorenzo Bianconi 			},
1461*f35e1ee9SLorenzo Bianconi 		},
1462*f35e1ee9SLorenzo Bianconi 		.irq_config = {
1463*f35e1ee9SLorenzo Bianconi 			.hla = {
1464*f35e1ee9SLorenzo Bianconi 				.addr = 0x12,
1465*f35e1ee9SLorenzo Bianconi 				.mask = BIT(5),
1466*f35e1ee9SLorenzo Bianconi 			},
1467*f35e1ee9SLorenzo Bianconi 			.od = {
1468*f35e1ee9SLorenzo Bianconi 				.addr = 0x12,
1469*f35e1ee9SLorenzo Bianconi 				.mask = BIT(4),
1470*f35e1ee9SLorenzo Bianconi 			},
1471*f35e1ee9SLorenzo Bianconi 		},
1472*f35e1ee9SLorenzo Bianconi 		.shub_settings = {
1473*f35e1ee9SLorenzo Bianconi 			.page_mux = {
1474*f35e1ee9SLorenzo Bianconi 				.addr = 0x01,
1475*f35e1ee9SLorenzo Bianconi 				.mask = BIT(6),
1476*f35e1ee9SLorenzo Bianconi 			},
1477*f35e1ee9SLorenzo Bianconi 			.master_en = {
1478*f35e1ee9SLorenzo Bianconi 				.sec_page = true,
1479*f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1480*f35e1ee9SLorenzo Bianconi 				.mask = BIT(2),
1481*f35e1ee9SLorenzo Bianconi 			},
1482*f35e1ee9SLorenzo Bianconi 			.pullup_en = {
1483*f35e1ee9SLorenzo Bianconi 				.sec_page = true,
1484*f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1485*f35e1ee9SLorenzo Bianconi 				.mask = BIT(3),
1486*f35e1ee9SLorenzo Bianconi 			},
1487*f35e1ee9SLorenzo Bianconi 			.aux_sens = {
1488*f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1489*f35e1ee9SLorenzo Bianconi 				.mask = GENMASK(1, 0),
1490*f35e1ee9SLorenzo Bianconi 			},
1491*f35e1ee9SLorenzo Bianconi 			.wr_once = {
1492*f35e1ee9SLorenzo Bianconi 				.addr = 0x14,
1493*f35e1ee9SLorenzo Bianconi 				.mask = BIT(6),
1494*f35e1ee9SLorenzo Bianconi 			},
1495*f35e1ee9SLorenzo Bianconi 			.num_ext_dev = 3,
1496*f35e1ee9SLorenzo Bianconi 			.shub_out = {
1497*f35e1ee9SLorenzo Bianconi 				.sec_page = true,
1498*f35e1ee9SLorenzo Bianconi 				.addr = 0x02,
1499*f35e1ee9SLorenzo Bianconi 			},
1500*f35e1ee9SLorenzo Bianconi 			.slv0_addr = 0x15,
1501*f35e1ee9SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
1502*f35e1ee9SLorenzo Bianconi 		},
1503*f35e1ee9SLorenzo Bianconi 	},
1504290a6ce1SLorenzo Bianconi };
1505290a6ce1SLorenzo Bianconi 
1506c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1507c91c1c84SLorenzo Bianconi {
1508c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1509c91c1c84SLorenzo Bianconi 	unsigned int data;
1510c91c1c84SLorenzo Bianconi 	int err;
1511c91c1c84SLorenzo Bianconi 
1512c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1513c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1514c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1515c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1516c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1517c91c1c84SLorenzo Bianconi 
1518c91c1c84SLorenzo Bianconi 	return err;
1519c91c1c84SLorenzo Bianconi }
1520c91c1c84SLorenzo Bianconi 
152181956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
152281956a93SLorenzo Bianconi 				   const char **name)
1523290a6ce1SLorenzo Bianconi {
152451a8b707SLorenzo Bianconi 	int err, i, j, data;
1525290a6ce1SLorenzo Bianconi 
1526290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1527d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
1528fb4fbc89SStephan Gerhold 			if (st_lsm6dsx_sensor_settings[i].id[j].name &&
1529fb4fbc89SStephan Gerhold 			    id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1530d068e4a0SLorenzo Bianconi 				break;
1531d068e4a0SLorenzo Bianconi 		}
1532d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1533290a6ce1SLorenzo Bianconi 			break;
1534290a6ce1SLorenzo Bianconi 	}
1535290a6ce1SLorenzo Bianconi 
1536290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1537290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1538290a6ce1SLorenzo Bianconi 		return -ENODEV;
1539290a6ce1SLorenzo Bianconi 	}
1540290a6ce1SLorenzo Bianconi 
154151a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1542290a6ce1SLorenzo Bianconi 	if (err < 0) {
1543290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1544290a6ce1SLorenzo Bianconi 		return err;
1545290a6ce1SLorenzo Bianconi 	}
1546290a6ce1SLorenzo Bianconi 
154798c3544aSLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].id[j].wai) {
1548290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1549290a6ce1SLorenzo Bianconi 		return -ENODEV;
1550290a6ce1SLorenzo Bianconi 	}
1551290a6ce1SLorenzo Bianconi 
155281956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1553290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1554290a6ce1SLorenzo Bianconi 
1555290a6ce1SLorenzo Bianconi 	return 0;
1556290a6ce1SLorenzo Bianconi }
1557290a6ce1SLorenzo Bianconi 
1558290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1559290a6ce1SLorenzo Bianconi 				     u32 gain)
1560290a6ce1SLorenzo Bianconi {
1561640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1562739aff87SLorenzo Bianconi 	unsigned int data;
1563290a6ce1SLorenzo Bianconi 	int i, err;
1564290a6ce1SLorenzo Bianconi 
1565640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
156685ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1567640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1568290a6ce1SLorenzo Bianconi 			break;
156985ae3aeeSLorenzo Bianconi 	}
1570290a6ce1SLorenzo Bianconi 
157185ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1572290a6ce1SLorenzo Bianconi 		return -EINVAL;
1573290a6ce1SLorenzo Bianconi 
1574640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1575640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1576640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1577640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1578290a6ce1SLorenzo Bianconi 	if (err < 0)
1579290a6ce1SLorenzo Bianconi 		return err;
1580290a6ce1SLorenzo Bianconi 
1581290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1582290a6ce1SLorenzo Bianconi 
1583290a6ce1SLorenzo Bianconi 	return 0;
1584290a6ce1SLorenzo Bianconi }
1585290a6ce1SLorenzo Bianconi 
1586f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val)
1587290a6ce1SLorenzo Bianconi {
158840dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
15892ccc1503SLorenzo Bianconi 	int i;
1590290a6ce1SLorenzo Bianconi 
159140dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
159259af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++) {
15936ffb55e5SLorenzo Bianconi 		/*
15946ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
15956ffb55e5SLorenzo Bianconi 		 * accel sensor
15966ffb55e5SLorenzo Bianconi 		 */
1597f8710f03SLorenzo Bianconi 		if (odr_table->odr_avl[i].milli_hz >= odr)
1598290a6ce1SLorenzo Bianconi 			break;
159959af4e20SLorenzo Bianconi 	}
1600290a6ce1SLorenzo Bianconi 
160159af4e20SLorenzo Bianconi 	if (i == odr_table->odr_len)
1602290a6ce1SLorenzo Bianconi 		return -EINVAL;
1603290a6ce1SLorenzo Bianconi 
160440dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1605f8710f03SLorenzo Bianconi 	return odr_table->odr_avl[i].milli_hz;
1606290a6ce1SLorenzo Bianconi }
1607290a6ce1SLorenzo Bianconi 
1608f8710f03SLorenzo Bianconi static int
1609f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr,
16106ffb55e5SLorenzo Bianconi 				enum st_lsm6dsx_sensor_id id)
16112ccc1503SLorenzo Bianconi {
16126ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
16136ffb55e5SLorenzo Bianconi 
16146ffb55e5SLorenzo Bianconi 	if (odr > 0) {
16156ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
1616f8710f03SLorenzo Bianconi 			return max_t(u32, ref->odr, odr);
16176ffb55e5SLorenzo Bianconi 		else
16186ffb55e5SLorenzo Bianconi 			return odr;
16196ffb55e5SLorenzo Bianconi 	} else {
16206ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
16216ffb55e5SLorenzo Bianconi 	}
16226ffb55e5SLorenzo Bianconi }
16236ffb55e5SLorenzo Bianconi 
1624f8710f03SLorenzo Bianconi static int
1625f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
16266ffb55e5SLorenzo Bianconi {
16276ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
162851a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
162951a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1630739aff87SLorenzo Bianconi 	unsigned int data;
16316ffb55e5SLorenzo Bianconi 	u8 val = 0;
16322ccc1503SLorenzo Bianconi 	int err;
16332ccc1503SLorenzo Bianconi 
16346ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
163594be878cSTeng Qi 	case ST_LSM6DSX_ID_GYRO:
163694be878cSTeng Qi 		break;
16376ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
16386ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
16396ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
16406ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
1641f8710f03SLorenzo Bianconi 		u32 odr;
16426ffb55e5SLorenzo Bianconi 		int i;
16436ffb55e5SLorenzo Bianconi 
16446ffb55e5SLorenzo Bianconi 		/*
16456ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
16466ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
16476ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
16486ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
16496ffb55e5SLorenzo Bianconi 		 */
16506ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
16516ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
16526ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
16536ffb55e5SLorenzo Bianconi 				continue;
16546ffb55e5SLorenzo Bianconi 
16556ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
16566ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
16576ffb55e5SLorenzo Bianconi 				/* device already configured */
16586ffb55e5SLorenzo Bianconi 				return 0;
16596ffb55e5SLorenzo Bianconi 		}
16606ffb55e5SLorenzo Bianconi 		break;
16616ffb55e5SLorenzo Bianconi 	}
166294be878cSTeng Qi 	default: /* should never occur */
166394be878cSTeng Qi 		return -EINVAL;
16646ffb55e5SLorenzo Bianconi 	}
16656ffb55e5SLorenzo Bianconi 
16666ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
16676ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
16682ccc1503SLorenzo Bianconi 		if (err < 0)
16692ccc1503SLorenzo Bianconi 			return err;
16706ffb55e5SLorenzo Bianconi 	}
16712ccc1503SLorenzo Bianconi 
167240dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1673739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1674739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
16752ccc1503SLorenzo Bianconi }
16762ccc1503SLorenzo Bianconi 
1677bd41c445SLorenzo Bianconi static int
1678bd41c445SLorenzo Bianconi __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
167917750443SLorenzo Bianconi 			       bool enable)
1680290a6ce1SLorenzo Bianconi {
168151a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1682f8710f03SLorenzo Bianconi 	u32 odr = enable ? sensor->odr : 0;
1683290a6ce1SLorenzo Bianconi 	int err;
1684290a6ce1SLorenzo Bianconi 
168517750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1686290a6ce1SLorenzo Bianconi 	if (err < 0)
1687290a6ce1SLorenzo Bianconi 		return err;
1688290a6ce1SLorenzo Bianconi 
168917750443SLorenzo Bianconi 	if (enable)
169017750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
169117750443SLorenzo Bianconi 	else
169217750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1693290a6ce1SLorenzo Bianconi 
1694290a6ce1SLorenzo Bianconi 	return 0;
1695290a6ce1SLorenzo Bianconi }
1696290a6ce1SLorenzo Bianconi 
1697bd41c445SLorenzo Bianconi static int
1698bd41c445SLorenzo Bianconi st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable)
1699bd41c445SLorenzo Bianconi {
1700bd41c445SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1701bd41c445SLorenzo Bianconi 
1702bd41c445SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_GYRO || enable)
1703bd41c445SLorenzo Bianconi 		return 0;
1704bd41c445SLorenzo Bianconi 
1705bd41c445SLorenzo Bianconi 	return hw->enable_event;
1706bd41c445SLorenzo Bianconi }
1707bd41c445SLorenzo Bianconi 
1708bd41c445SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1709bd41c445SLorenzo Bianconi 				 bool enable)
1710bd41c445SLorenzo Bianconi {
1711bd41c445SLorenzo Bianconi 	if (st_lsm6dsx_check_events(sensor, enable))
1712bd41c445SLorenzo Bianconi 		return 0;
1713bd41c445SLorenzo Bianconi 
1714bd41c445SLorenzo Bianconi 	return __st_lsm6dsx_sensor_set_enable(sensor, enable);
1715bd41c445SLorenzo Bianconi }
1716bd41c445SLorenzo Bianconi 
1717290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1718290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1719290a6ce1SLorenzo Bianconi {
172051a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1721290a6ce1SLorenzo Bianconi 	int err, delay;
1722290a6ce1SLorenzo Bianconi 	__le16 data;
1723290a6ce1SLorenzo Bianconi 
172417750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1725290a6ce1SLorenzo Bianconi 	if (err < 0)
1726290a6ce1SLorenzo Bianconi 		return err;
1727290a6ce1SLorenzo Bianconi 
1728ea85bf90SLorenzo Bianconi 	/*
1729ea85bf90SLorenzo Bianconi 	 * we need to wait for sensor settling time before
1730ea85bf90SLorenzo Bianconi 	 * reading data in order to avoid corrupted samples
1731ea85bf90SLorenzo Bianconi 	 */
1732f8710f03SLorenzo Bianconi 	delay = 1000000000 / sensor->odr;
1733ea85bf90SLorenzo Bianconi 	usleep_range(3 * delay, 4 * delay);
1734290a6ce1SLorenzo Bianconi 
1735739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1736290a6ce1SLorenzo Bianconi 	if (err < 0)
1737290a6ce1SLorenzo Bianconi 		return err;
1738290a6ce1SLorenzo Bianconi 
1739a2dd9bd9SLorenzo Bianconi 	if (!hw->enable_event) {
1740a2dd9bd9SLorenzo Bianconi 		err = st_lsm6dsx_sensor_set_enable(sensor, false);
1741a2dd9bd9SLorenzo Bianconi 		if (err < 0)
1742a2dd9bd9SLorenzo Bianconi 			return err;
1743a2dd9bd9SLorenzo Bianconi 	}
1744290a6ce1SLorenzo Bianconi 
17457b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1746290a6ce1SLorenzo Bianconi 
1747290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1748290a6ce1SLorenzo Bianconi }
1749290a6ce1SLorenzo Bianconi 
1750290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1751290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1752290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1753290a6ce1SLorenzo Bianconi {
1754290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1755290a6ce1SLorenzo Bianconi 	int ret;
1756290a6ce1SLorenzo Bianconi 
1757290a6ce1SLorenzo Bianconi 	switch (mask) {
1758290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1759290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1760290a6ce1SLorenzo Bianconi 		if (ret)
1761290a6ce1SLorenzo Bianconi 			break;
1762290a6ce1SLorenzo Bianconi 
1763290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1764290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1765290a6ce1SLorenzo Bianconi 		break;
1766290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1767f8710f03SLorenzo Bianconi 		*val = sensor->odr / 1000;
1768f8710f03SLorenzo Bianconi 		*val2 = (sensor->odr % 1000) * 1000;
1769f8710f03SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1770290a6ce1SLorenzo Bianconi 		break;
1771290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1772290a6ce1SLorenzo Bianconi 		*val = 0;
1773290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
177444a76de8SMario Tesi 		ret = IIO_VAL_INT_PLUS_NANO;
1775290a6ce1SLorenzo Bianconi 		break;
1776290a6ce1SLorenzo Bianconi 	default:
1777290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1778290a6ce1SLorenzo Bianconi 		break;
1779290a6ce1SLorenzo Bianconi 	}
1780290a6ce1SLorenzo Bianconi 
1781290a6ce1SLorenzo Bianconi 	return ret;
1782290a6ce1SLorenzo Bianconi }
1783290a6ce1SLorenzo Bianconi 
1784290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1785290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1786290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1787290a6ce1SLorenzo Bianconi {
1788290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1789290a6ce1SLorenzo Bianconi 	int err;
1790290a6ce1SLorenzo Bianconi 
1791290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1792290a6ce1SLorenzo Bianconi 	if (err)
1793290a6ce1SLorenzo Bianconi 		return err;
1794290a6ce1SLorenzo Bianconi 
1795290a6ce1SLorenzo Bianconi 	switch (mask) {
1796290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1797290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1798290a6ce1SLorenzo Bianconi 		break;
17992ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
18002ccc1503SLorenzo Bianconi 		u8 data;
18012ccc1503SLorenzo Bianconi 
1802f8710f03SLorenzo Bianconi 		val = val * 1000 + val2 / 1000;
1803fc3f6ad7SLorenzo Bianconi 		val = st_lsm6dsx_check_odr(sensor, val, &data);
1804fc3f6ad7SLorenzo Bianconi 		if (val < 0)
1805fc3f6ad7SLorenzo Bianconi 			err = val;
1806fc3f6ad7SLorenzo Bianconi 		else
18075e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1808290a6ce1SLorenzo Bianconi 		break;
18092ccc1503SLorenzo Bianconi 	}
1810290a6ce1SLorenzo Bianconi 	default:
1811290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1812290a6ce1SLorenzo Bianconi 		break;
1813290a6ce1SLorenzo Bianconi 	}
1814290a6ce1SLorenzo Bianconi 
1815290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1816290a6ce1SLorenzo Bianconi 
1817290a6ce1SLorenzo Bianconi 	return err;
1818290a6ce1SLorenzo Bianconi }
1819290a6ce1SLorenzo Bianconi 
1820b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1821b5969abfSSean Nyekjaer {
182284b2e7c3SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
182304ca37d5SLorenzo Bianconi 	unsigned int data;
1824b5969abfSSean Nyekjaer 	int err;
1825b5969abfSSean Nyekjaer 
18267e906103SLorenzo Bianconi 	if (!hw->settings->irq_config.irq1_func.addr)
1827b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1828b5969abfSSean Nyekjaer 
182984b2e7c3SLorenzo Bianconi 	reg = &hw->settings->event_settings.enable_reg;
183084b2e7c3SLorenzo Bianconi 	if (reg->addr) {
183104ca37d5SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
183204ca37d5SLorenzo Bianconi 		err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
183304ca37d5SLorenzo Bianconi 						    reg->mask, data);
1834b5969abfSSean Nyekjaer 		if (err < 0)
1835b5969abfSSean Nyekjaer 			return err;
183684b2e7c3SLorenzo Bianconi 	}
1837b5969abfSSean Nyekjaer 
1838b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
183904ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
184004ca37d5SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
184104ca37d5SLorenzo Bianconi 					     hw->irq_routing->mask, data);
1842b5969abfSSean Nyekjaer }
1843b5969abfSSean Nyekjaer 
1844b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1845b5969abfSSean Nyekjaer 				 const struct iio_chan_spec *chan,
1846b5969abfSSean Nyekjaer 				 enum iio_event_type type,
1847b5969abfSSean Nyekjaer 				 enum iio_event_direction dir,
1848b5969abfSSean Nyekjaer 				 enum iio_event_info info,
1849b5969abfSSean Nyekjaer 				 int *val, int *val2)
1850b5969abfSSean Nyekjaer {
1851b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1852b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1853b5969abfSSean Nyekjaer 
1854b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1855b5969abfSSean Nyekjaer 		return -EINVAL;
1856b5969abfSSean Nyekjaer 
1857b5969abfSSean Nyekjaer 	*val2 = 0;
1858b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1859b5969abfSSean Nyekjaer 
1860b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1861b5969abfSSean Nyekjaer }
1862b5969abfSSean Nyekjaer 
1863b307f495SLorenzo Bianconi static int
1864b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1865b5969abfSSean Nyekjaer 		       const struct iio_chan_spec *chan,
1866b5969abfSSean Nyekjaer 		       enum iio_event_type type,
1867b5969abfSSean Nyekjaer 		       enum iio_event_direction dir,
1868b5969abfSSean Nyekjaer 		       enum iio_event_info info,
1869b5969abfSSean Nyekjaer 		       int val, int val2)
1870b5969abfSSean Nyekjaer {
1871b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1872b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
187304ca37d5SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
187404ca37d5SLorenzo Bianconi 	unsigned int data;
1875b5969abfSSean Nyekjaer 	int err;
1876b5969abfSSean Nyekjaer 
1877b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1878b5969abfSSean Nyekjaer 		return -EINVAL;
1879b5969abfSSean Nyekjaer 
1880b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1881b5969abfSSean Nyekjaer 		return -EINVAL;
1882b5969abfSSean Nyekjaer 
188304ca37d5SLorenzo Bianconi 	reg = &hw->settings->event_settings.wakeup_reg;
188404ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
188504ca37d5SLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
188604ca37d5SLorenzo Bianconi 					    reg->mask, data);
188704ca37d5SLorenzo Bianconi 	if (err < 0)
1888b5969abfSSean Nyekjaer 		return -EINVAL;
1889b5969abfSSean Nyekjaer 
1890b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1891b5969abfSSean Nyekjaer 
1892b5969abfSSean Nyekjaer 	return 0;
1893b5969abfSSean Nyekjaer }
1894b5969abfSSean Nyekjaer 
1895b307f495SLorenzo Bianconi static int
1896b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1897b5969abfSSean Nyekjaer 			     const struct iio_chan_spec *chan,
1898b5969abfSSean Nyekjaer 			     enum iio_event_type type,
1899b5969abfSSean Nyekjaer 			     enum iio_event_direction dir)
1900b5969abfSSean Nyekjaer {
1901b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1902b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1903b5969abfSSean Nyekjaer 
1904b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1905b5969abfSSean Nyekjaer 		return -EINVAL;
1906b5969abfSSean Nyekjaer 
19071aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1908b5969abfSSean Nyekjaer }
1909b5969abfSSean Nyekjaer 
1910b307f495SLorenzo Bianconi static int
1911b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1912b5969abfSSean Nyekjaer 			      const struct iio_chan_spec *chan,
1913b5969abfSSean Nyekjaer 			      enum iio_event_type type,
1914b307f495SLorenzo Bianconi 			      enum iio_event_direction dir, int state)
1915b5969abfSSean Nyekjaer {
1916b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1917b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
19181aabad1fSSean Nyekjaer 	u8 enable_event;
1919bd41c445SLorenzo Bianconi 	int err;
1920b5969abfSSean Nyekjaer 
1921b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1922b5969abfSSean Nyekjaer 		return -EINVAL;
1923b5969abfSSean Nyekjaer 
19241aabad1fSSean Nyekjaer 	if (state) {
19251aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
19261aabad1fSSean Nyekjaer 
1927b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
19281aabad1fSSean Nyekjaer 		if (hw->enable_event)
19291aabad1fSSean Nyekjaer 			goto out;
19301aabad1fSSean Nyekjaer 	} else {
19311aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
19321aabad1fSSean Nyekjaer 
19331aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
19341aabad1fSSean Nyekjaer 		if (enable_event)
19351aabad1fSSean Nyekjaer 			goto out;
19361aabad1fSSean Nyekjaer 	}
19371aabad1fSSean Nyekjaer 
19381aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
19391aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1940b5969abfSSean Nyekjaer 		return 0;
1941b5969abfSSean Nyekjaer 
1942b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1943b5969abfSSean Nyekjaer 	if (err < 0)
1944b5969abfSSean Nyekjaer 		return err;
1945b5969abfSSean Nyekjaer 
1946d278d447SLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1947bd41c445SLorenzo Bianconi 	if (enable_event || !(hw->fifo_mask & BIT(sensor->id)))
1948bd41c445SLorenzo Bianconi 		err = __st_lsm6dsx_sensor_set_enable(sensor, state);
1949d278d447SLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1950b5969abfSSean Nyekjaer 	if (err < 0)
1951b5969abfSSean Nyekjaer 		return err;
1952b5969abfSSean Nyekjaer 
19531aabad1fSSean Nyekjaer out:
19541aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1955b5969abfSSean Nyekjaer 
1956b5969abfSSean Nyekjaer 	return 0;
1957b5969abfSSean Nyekjaer }
1958b5969abfSSean Nyekjaer 
1959d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1960290a6ce1SLorenzo Bianconi {
1961290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1962290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
19638f2a88a2SLorenzo Bianconi 	int err;
1964290a6ce1SLorenzo Bianconi 
19659e5b4cd2SPaul Cercueil 	val = clamp_val(val, 1, hw->settings->fifo_ops.max_size);
1966290a6ce1SLorenzo Bianconi 
1967335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1968335eaedcSLorenzo Bianconi 
1969290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
1970335eaedcSLorenzo Bianconi 
1971335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1972335eaedcSLorenzo Bianconi 
1973290a6ce1SLorenzo Bianconi 	if (err < 0)
1974290a6ce1SLorenzo Bianconi 		return err;
1975290a6ce1SLorenzo Bianconi 
1976290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
1977290a6ce1SLorenzo Bianconi 
1978290a6ce1SLorenzo Bianconi 	return 0;
1979290a6ce1SLorenzo Bianconi }
1980290a6ce1SLorenzo Bianconi 
1981290a6ce1SLorenzo Bianconi static ssize_t
1982290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1983290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
1984290a6ce1SLorenzo Bianconi 					  char *buf)
1985290a6ce1SLorenzo Bianconi {
19866270bf1fSHaibo Chen 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev));
198759af4e20SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
1988290a6ce1SLorenzo Bianconi 	int i, len = 0;
1989290a6ce1SLorenzo Bianconi 
199059af4e20SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
199159af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++)
1992f8710f03SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ",
1993f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz / 1000,
1994f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz % 1000);
1995290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1996290a6ce1SLorenzo Bianconi 
1997290a6ce1SLorenzo Bianconi 	return len;
1998290a6ce1SLorenzo Bianconi }
1999290a6ce1SLorenzo Bianconi 
2000290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
2001290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
2002290a6ce1SLorenzo Bianconi 					    char *buf)
2003290a6ce1SLorenzo Bianconi {
20046270bf1fSHaibo Chen 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev));
20050f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
2006640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
2007290a6ce1SLorenzo Bianconi 	int i, len = 0;
2008290a6ce1SLorenzo Bianconi 
200985ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
201085ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
201144a76de8SMario Tesi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ",
20120f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
2013290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
2014290a6ce1SLorenzo Bianconi 
2015290a6ce1SLorenzo Bianconi 	return len;
2016290a6ce1SLorenzo Bianconi }
2017290a6ce1SLorenzo Bianconi 
201844a76de8SMario Tesi static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev,
201944a76de8SMario Tesi 					struct iio_chan_spec const *chan,
202044a76de8SMario Tesi 					long mask)
202144a76de8SMario Tesi {
202244a76de8SMario Tesi 	switch (mask) {
202344a76de8SMario Tesi 	case IIO_CHAN_INFO_SCALE:
202444a76de8SMario Tesi 		switch (chan->type) {
202544a76de8SMario Tesi 		case IIO_ANGL_VEL:
202644a76de8SMario Tesi 		case IIO_ACCEL:
202744a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_NANO;
202844a76de8SMario Tesi 		default:
202944a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_MICRO;
203044a76de8SMario Tesi 		}
203144a76de8SMario Tesi 	default:
203244a76de8SMario Tesi 		return IIO_VAL_INT_PLUS_MICRO;
203344a76de8SMario Tesi 	}
203444a76de8SMario Tesi }
203544a76de8SMario Tesi 
2036290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
2037290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
2038290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
2039290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
2040290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
2041290a6ce1SLorenzo Bianconi 
2042290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
2043290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
2044290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
2045290a6ce1SLorenzo Bianconi 	NULL,
2046290a6ce1SLorenzo Bianconi };
2047290a6ce1SLorenzo Bianconi 
2048290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
2049290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
2050290a6ce1SLorenzo Bianconi };
2051290a6ce1SLorenzo Bianconi 
2052290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
2053290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
2054290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
2055290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
2056b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
2057b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
2058b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
2059b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
2060290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
206144a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
2062290a6ce1SLorenzo Bianconi };
2063290a6ce1SLorenzo Bianconi 
2064290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
2065290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
2066290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
2067290a6ce1SLorenzo Bianconi 	NULL,
2068290a6ce1SLorenzo Bianconi };
2069290a6ce1SLorenzo Bianconi 
2070290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
2071290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
2072290a6ce1SLorenzo Bianconi };
2073290a6ce1SLorenzo Bianconi 
2074290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
2075290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
2076290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
2077290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
2078290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
207944a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
2080290a6ce1SLorenzo Bianconi };
2081290a6ce1SLorenzo Bianconi 
208203d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
2083dba32904SLorenzo Bianconi {
208403d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2085dba32904SLorenzo Bianconi 
208603d4c566SAndy Shevchenko 	if (!dev_fwnode(dev))
2087dba32904SLorenzo Bianconi 		return -EINVAL;
2088dba32904SLorenzo Bianconi 
208903d4c566SAndy Shevchenko 	return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
2090dba32904SLorenzo Bianconi }
2091dba32904SLorenzo Bianconi 
20927e906103SLorenzo Bianconi static int
20937e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
20947e906103SLorenzo Bianconi 			const struct st_lsm6dsx_reg **drdy_reg)
2095dba32904SLorenzo Bianconi {
2096dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
2097dba32904SLorenzo Bianconi 
209803d4c566SAndy Shevchenko 	if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
2099dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
2100dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
2101dba32904SLorenzo Bianconi 
2102dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
2103dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
2104dba32904SLorenzo Bianconi 	}
2105dba32904SLorenzo Bianconi 
2106dba32904SLorenzo Bianconi 	switch (drdy_pin) {
2107dba32904SLorenzo Bianconi 	case 1:
21087e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq1_func;
21097e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq1;
2110dba32904SLorenzo Bianconi 		break;
2111dba32904SLorenzo Bianconi 	case 2:
21127e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq2_func;
21137e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq2;
2114dba32904SLorenzo Bianconi 		break;
2115dba32904SLorenzo Bianconi 	default:
2116dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
2117dba32904SLorenzo Bianconi 		err = -EINVAL;
2118dba32904SLorenzo Bianconi 		break;
2119dba32904SLorenzo Bianconi 	}
2120dba32904SLorenzo Bianconi 
2121dba32904SLorenzo Bianconi 	return err;
2122dba32904SLorenzo Bianconi }
2123dba32904SLorenzo Bianconi 
2124c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
2125c91c1c84SLorenzo Bianconi {
2126c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2127c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
212803d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2129c91c1c84SLorenzo Bianconi 	unsigned int data;
2130c91c1c84SLorenzo Bianconi 	int err = 0;
2131c91c1c84SLorenzo Bianconi 
2132c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2133c91c1c84SLorenzo Bianconi 
213403d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
213503d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
2136c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
21373a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page) {
2138c91c1c84SLorenzo Bianconi 			err = st_lsm6dsx_set_page(hw, true);
2139c91c1c84SLorenzo Bianconi 			if (err < 0)
2140c91c1c84SLorenzo Bianconi 				return err;
21413a431957SLorenzo Bianconi 		}
2142c91c1c84SLorenzo Bianconi 
2143c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
2144c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2145c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
2146c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
2147c91c1c84SLorenzo Bianconi 
21483a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page)
2149c91c1c84SLorenzo Bianconi 			st_lsm6dsx_set_page(hw, false);
2150c91c1c84SLorenzo Bianconi 
2151c91c1c84SLorenzo Bianconi 		if (err < 0)
2152c91c1c84SLorenzo Bianconi 			return err;
2153c91c1c84SLorenzo Bianconi 	}
2154c91c1c84SLorenzo Bianconi 
2155c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
2156c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
2157c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
2158c91c1c84SLorenzo Bianconi 		if (err < 0)
2159c91c1c84SLorenzo Bianconi 			return err;
2160c91c1c84SLorenzo Bianconi 
2161c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
2162c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2163c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
2164c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
2165c91c1c84SLorenzo Bianconi 
2166c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
2167e485e2a2SLorenzo Bianconi 
2168e485e2a2SLorenzo Bianconi 		if (err < 0)
2169e485e2a2SLorenzo Bianconi 			return err;
2170e485e2a2SLorenzo Bianconi 	}
2171e485e2a2SLorenzo Bianconi 
2172e485e2a2SLorenzo Bianconi 	if (hub_settings->emb_func.addr) {
2173e485e2a2SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask);
2174e485e2a2SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2175e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.addr,
2176e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.mask, data);
2177c91c1c84SLorenzo Bianconi 	}
2178c91c1c84SLorenzo Bianconi 
2179c91c1c84SLorenzo Bianconi 	return err;
2180c91c1c84SLorenzo Bianconi }
2181c91c1c84SLorenzo Bianconi 
218221345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
218321345107SLorenzo Bianconi {
218421345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
218521345107SLorenzo Bianconi 	int err, val;
218621345107SLorenzo Bianconi 
218721345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
218821345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
218921345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
219021345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
219121345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
219221345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
219321345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
219421345107SLorenzo Bianconi 		if (err < 0)
219521345107SLorenzo Bianconi 			return err;
219621345107SLorenzo Bianconi 	}
219721345107SLorenzo Bianconi 
219821345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
219921345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
220021345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
220121345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
220221345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
220321345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
220421345107SLorenzo Bianconi 		if (err < 0)
220521345107SLorenzo Bianconi 			return err;
220621345107SLorenzo Bianconi 	}
220721345107SLorenzo Bianconi 
220821345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
220921345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
221021345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
221121345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
221221345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
221321345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
221421345107SLorenzo Bianconi 		if (err < 0)
221521345107SLorenzo Bianconi 			return err;
221621345107SLorenzo Bianconi 	}
2217cb3b6b8eSMario Tesi 
2218cb3b6b8eSMario Tesi 	/* calibrate timestamp sensitivity */
2219cb3b6b8eSMario Tesi 	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
2220cb3b6b8eSMario Tesi 	if (ts_settings->freq_fine) {
2221cb3b6b8eSMario Tesi 		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
2222cb3b6b8eSMario Tesi 		if (err < 0)
2223cb3b6b8eSMario Tesi 			return err;
2224cb3b6b8eSMario Tesi 
2225cb3b6b8eSMario Tesi 		/*
2226cb3b6b8eSMario Tesi 		 * linearize the AN5192 formula:
2227cb3b6b8eSMario Tesi 		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
2228cb3b6b8eSMario Tesi 		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
2229cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - 37.5 * val
2230cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
2231cb3b6b8eSMario Tesi 		 */
2232cb3b6b8eSMario Tesi 		hw->ts_gain -= ((s8)val * 37500) / 1000;
2233cb3b6b8eSMario Tesi 	}
2234cb3b6b8eSMario Tesi 
223521345107SLorenzo Bianconi 	return 0;
223621345107SLorenzo Bianconi }
223721345107SLorenzo Bianconi 
22383a63da26SLorenzo Bianconi static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
2239290a6ce1SLorenzo Bianconi {
22407e906103SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
2241290a6ce1SLorenzo Bianconi 	int err;
2242290a6ce1SLorenzo Bianconi 
22433a63da26SLorenzo Bianconi 	/*
22443a63da26SLorenzo Bianconi 	 * flush hw FIFO before device reset in order to avoid
22453a63da26SLorenzo Bianconi 	 * possible races on interrupt line 1. If the first interrupt
22463a63da26SLorenzo Bianconi 	 * line is asserted during hw reset the device will work in
22473a63da26SLorenzo Bianconi 	 * I3C-only mode (if it is supported)
22483a63da26SLorenzo Bianconi 	 */
22493a63da26SLorenzo Bianconi 	err = st_lsm6dsx_flush_fifo(hw);
22503a63da26SLorenzo Bianconi 	if (err < 0 && err != -ENOTSUPP)
22513a63da26SLorenzo Bianconi 		return err;
22523a63da26SLorenzo Bianconi 
225319435425SLorenzo Bianconi 	/* device sw reset */
225466b662a1SLorenzo Bianconi 	reg = &hw->settings->reset;
225566b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
225666b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2257290a6ce1SLorenzo Bianconi 	if (err < 0)
2258290a6ce1SLorenzo Bianconi 		return err;
2259290a6ce1SLorenzo Bianconi 
226019435425SLorenzo Bianconi 	msleep(50);
226119435425SLorenzo Bianconi 
226219435425SLorenzo Bianconi 	/* reload trimming parameter */
226366b662a1SLorenzo Bianconi 	reg = &hw->settings->boot;
226466b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
226566b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
226619435425SLorenzo Bianconi 	if (err < 0)
226719435425SLorenzo Bianconi 		return err;
226819435425SLorenzo Bianconi 
226919435425SLorenzo Bianconi 	msleep(50);
2270290a6ce1SLorenzo Bianconi 
22713a63da26SLorenzo Bianconi 	return 0;
22723a63da26SLorenzo Bianconi }
22733a63da26SLorenzo Bianconi 
22743a63da26SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
22753a63da26SLorenzo Bianconi {
22763a63da26SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
22773a63da26SLorenzo Bianconi 	int err;
22783a63da26SLorenzo Bianconi 
22793a63da26SLorenzo Bianconi 	err = st_lsm6dsx_reset_device(hw);
22803a63da26SLorenzo Bianconi 	if (err < 0)
22813a63da26SLorenzo Bianconi 		return err;
22823a63da26SLorenzo Bianconi 
2283290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
228466b662a1SLorenzo Bianconi 	reg = &hw->settings->bdu;
228566b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
228666b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2287290a6ce1SLorenzo Bianconi 	if (err < 0)
2288290a6ce1SLorenzo Bianconi 		return err;
2289290a6ce1SLorenzo Bianconi 
2290290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
22917e906103SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &reg);
2292290a6ce1SLorenzo Bianconi 	if (err < 0)
2293290a6ce1SLorenzo Bianconi 		return err;
2294290a6ce1SLorenzo Bianconi 
22957e906103SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
22967e906103SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
229721345107SLorenzo Bianconi 	if (err < 0)
229821345107SLorenzo Bianconi 		return err;
229921345107SLorenzo Bianconi 
23009db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
23017e906103SLorenzo Bianconi 	if (hw->settings->irq_config.lir.addr) {
23027e906103SLorenzo Bianconi 		reg = &hw->settings->irq_config.lir;
23037e906103SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
23047e906103SLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
23059db02d32SLorenzo Bianconi 		if (err < 0)
23069db02d32SLorenzo Bianconi 			return err;
230722ea5651SLorenzo Bianconi 
230822ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
23097e906103SLorenzo Bianconi 		if (hw->settings->irq_config.clear_on_read.addr) {
23107e906103SLorenzo Bianconi 			reg = &hw->settings->irq_config.clear_on_read;
231122ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
23127e906103SLorenzo Bianconi 					reg->addr, reg->mask,
23137e906103SLorenzo Bianconi 					ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
231422ea5651SLorenzo Bianconi 			if (err < 0)
231522ea5651SLorenzo Bianconi 				return err;
231622ea5651SLorenzo Bianconi 		}
23179db02d32SLorenzo Bianconi 	}
23189db02d32SLorenzo Bianconi 
2319960506edSLorenzo Bianconi 	/* enable drdy-mas if available */
2320960506edSLorenzo Bianconi 	if (hw->settings->drdy_mask.addr) {
2321960506edSLorenzo Bianconi 		reg = &hw->settings->drdy_mask;
2322960506edSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2323960506edSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2324960506edSLorenzo Bianconi 		if (err < 0)
2325960506edSLorenzo Bianconi 			return err;
2326960506edSLorenzo Bianconi 	}
2327960506edSLorenzo Bianconi 
2328c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
2329c91c1c84SLorenzo Bianconi 	if (err < 0)
2330c91c1c84SLorenzo Bianconi 		return err;
2331c91c1c84SLorenzo Bianconi 
233221345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
2333290a6ce1SLorenzo Bianconi }
2334290a6ce1SLorenzo Bianconi 
2335290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
2336510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
2337510c0106SLorenzo Bianconi 					       const char *name)
2338290a6ce1SLorenzo Bianconi {
2339290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2340290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
2341290a6ce1SLorenzo Bianconi 
2342290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
2343290a6ce1SLorenzo Bianconi 	if (!iio_dev)
2344290a6ce1SLorenzo Bianconi 		return NULL;
2345290a6ce1SLorenzo Bianconi 
2346290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
2347290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2348f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
2349f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
2350290a6ce1SLorenzo Bianconi 
2351290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
2352290a6ce1SLorenzo Bianconi 	sensor->id = id;
2353290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
2354f8710f03SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz;
2355640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
2356290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
2357290a6ce1SLorenzo Bianconi 
2358290a6ce1SLorenzo Bianconi 	switch (id) {
2359290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
2360290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
2361510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
2362510c0106SLorenzo Bianconi 			  name);
2363290a6ce1SLorenzo Bianconi 		break;
2364290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
2365290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
2366510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
2367510c0106SLorenzo Bianconi 			  name);
2368290a6ce1SLorenzo Bianconi 		break;
2369290a6ce1SLorenzo Bianconi 	default:
2370290a6ce1SLorenzo Bianconi 		return NULL;
2371290a6ce1SLorenzo Bianconi 	}
2372510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
2373290a6ce1SLorenzo Bianconi 
2374290a6ce1SLorenzo Bianconi 	return iio_dev;
2375290a6ce1SLorenzo Bianconi }
2376290a6ce1SLorenzo Bianconi 
2377615bd378SLorenzo Bianconi static bool
2378615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
23791aabad1fSSean Nyekjaer {
2380615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
2381615bd378SLorenzo Bianconi 	int err, data;
2382615bd378SLorenzo Bianconi 	s64 timestamp;
23831aabad1fSSean Nyekjaer 
2384615bd378SLorenzo Bianconi 	if (!hw->enable_event)
2385615bd378SLorenzo Bianconi 		return false;
2386615bd378SLorenzo Bianconi 
2387615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
2388615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2389615bd378SLorenzo Bianconi 				     &data, sizeof(data));
2390615bd378SLorenzo Bianconi 	if (err < 0)
2391615bd378SLorenzo Bianconi 		return false;
2392615bd378SLorenzo Bianconi 
2393615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
23941aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
23951aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
23961aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
23971aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
23981aabad1fSSean Nyekjaer 						  0,
23991aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
24001aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24011aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24021aabad1fSSean Nyekjaer 						  timestamp);
24031aabad1fSSean Nyekjaer 
24041aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
24051aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
24061aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24071aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24081aabad1fSSean Nyekjaer 						  0,
24091aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
24101aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24111aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24121aabad1fSSean Nyekjaer 						  timestamp);
24131aabad1fSSean Nyekjaer 
24141aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
24151aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
24161aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
24171aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
24181aabad1fSSean Nyekjaer 						  0,
24191aabad1fSSean Nyekjaer 						  IIO_MOD_X,
24201aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
24211aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
24221aabad1fSSean Nyekjaer 						  timestamp);
2423615bd378SLorenzo Bianconi 
2424615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
24251aabad1fSSean Nyekjaer }
24261aabad1fSSean Nyekjaer 
24276ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
24286ee6a368SSean Nyekjaer {
24296ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
24303f9bce7aSLorenzo Bianconi 	int fifo_len = 0, len;
2431615bd378SLorenzo Bianconi 	bool event;
24321aabad1fSSean Nyekjaer 
2433615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
24346ee6a368SSean Nyekjaer 
2435a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
2436a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
2437a912ee4cSLorenzo Bianconi 
24383f9bce7aSLorenzo Bianconi 	/*
24393f9bce7aSLorenzo Bianconi 	 * If we are using edge IRQs, new samples can arrive while
24403f9bce7aSLorenzo Bianconi 	 * processing current interrupt since there are no hw
24413f9bce7aSLorenzo Bianconi 	 * guarantees the irq line stays "low" long enough to properly
24423f9bce7aSLorenzo Bianconi 	 * detect the new interrupt. In this case the new sample will
24433f9bce7aSLorenzo Bianconi 	 * be missed.
24443f9bce7aSLorenzo Bianconi 	 * Polling FIFO status register allow us to read new
24453f9bce7aSLorenzo Bianconi 	 * samples even if the interrupt arrives while processing
24463f9bce7aSLorenzo Bianconi 	 * previous data and the timeslot where the line is "low" is
24473f9bce7aSLorenzo Bianconi 	 * too short to be properly detected.
24483f9bce7aSLorenzo Bianconi 	 */
24493f9bce7aSLorenzo Bianconi 	do {
24506ee6a368SSean Nyekjaer 		mutex_lock(&hw->fifo_lock);
24513f9bce7aSLorenzo Bianconi 		len = hw->settings->fifo_ops.read_fifo(hw);
24526ee6a368SSean Nyekjaer 		mutex_unlock(&hw->fifo_lock);
24536ee6a368SSean Nyekjaer 
24543f9bce7aSLorenzo Bianconi 		if (len > 0)
24553f9bce7aSLorenzo Bianconi 			fifo_len += len;
24563f9bce7aSLorenzo Bianconi 	} while (len > 0);
24573f9bce7aSLorenzo Bianconi 
24583f9bce7aSLorenzo Bianconi 	return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
24596ee6a368SSean Nyekjaer }
24606ee6a368SSean Nyekjaer 
24612cfb2180SLorenzo Bianconi static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq,
24622cfb2180SLorenzo Bianconi 							void *private)
24632cfb2180SLorenzo Bianconi {
24642cfb2180SLorenzo Bianconi 	struct iio_poll_func *pf = private;
24652cfb2180SLorenzo Bianconi 	struct iio_dev *iio_dev = pf->indio_dev;
24662cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
24672cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
24682cfb2180SLorenzo Bianconi 
24692cfb2180SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
24702cfb2180SLorenzo Bianconi 	    sensor->id == ST_LSM6DSX_ID_EXT1 ||
24712cfb2180SLorenzo Bianconi 	    sensor->id == ST_LSM6DSX_ID_EXT2)
24722cfb2180SLorenzo Bianconi 		st_lsm6dsx_shub_read_output(hw,
24732cfb2180SLorenzo Bianconi 					    (u8 *)hw->scan[sensor->id].channels,
24742cfb2180SLorenzo Bianconi 					    sizeof(hw->scan[sensor->id].channels));
24752cfb2180SLorenzo Bianconi 	else
24762cfb2180SLorenzo Bianconi 		st_lsm6dsx_read_locked(hw, iio_dev->channels[0].address,
24772cfb2180SLorenzo Bianconi 				       hw->scan[sensor->id].channels,
24782cfb2180SLorenzo Bianconi 				       sizeof(hw->scan[sensor->id].channels));
24792cfb2180SLorenzo Bianconi 
24802cfb2180SLorenzo Bianconi 	iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan[sensor->id],
24812cfb2180SLorenzo Bianconi 					   iio_get_time_ns(iio_dev));
24822cfb2180SLorenzo Bianconi 	iio_trigger_notify_done(iio_dev->trig);
24832cfb2180SLorenzo Bianconi 
24842cfb2180SLorenzo Bianconi 	return IRQ_HANDLED;
24852cfb2180SLorenzo Bianconi }
24862cfb2180SLorenzo Bianconi 
24876ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
24886ee6a368SSean Nyekjaer {
248931fe8d4eSLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
249031fe8d4eSLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
249103d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
24926ee6a368SSean Nyekjaer 	unsigned long irq_type;
24936ee6a368SSean Nyekjaer 	bool irq_active_low;
24946ee6a368SSean Nyekjaer 	int err;
24956ee6a368SSean Nyekjaer 
24966ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
24976ee6a368SSean Nyekjaer 
24986ee6a368SSean Nyekjaer 	switch (irq_type) {
24996ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
25006ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
25016ee6a368SSean Nyekjaer 		irq_active_low = false;
25026ee6a368SSean Nyekjaer 		break;
25036ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
25046ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
25056ee6a368SSean Nyekjaer 		irq_active_low = true;
25066ee6a368SSean Nyekjaer 		break;
25076ee6a368SSean Nyekjaer 	default:
25086ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
25096ee6a368SSean Nyekjaer 		return -EINVAL;
25106ee6a368SSean Nyekjaer 	}
25116ee6a368SSean Nyekjaer 
251231fe8d4eSLorenzo Bianconi 	reg = &hw->settings->irq_config.hla;
251331fe8d4eSLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
251431fe8d4eSLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(irq_active_low,
251531fe8d4eSLorenzo Bianconi 						      reg->mask));
25166ee6a368SSean Nyekjaer 	if (err < 0)
25176ee6a368SSean Nyekjaer 		return err;
25186ee6a368SSean Nyekjaer 
251903d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
252003d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
25216ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
252231fe8d4eSLorenzo Bianconi 		reg = &hw->settings->irq_config.od;
252331fe8d4eSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
252431fe8d4eSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
25256ee6a368SSean Nyekjaer 		if (err < 0)
25266ee6a368SSean Nyekjaer 			return err;
25276ee6a368SSean Nyekjaer 
25286ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
25296ee6a368SSean Nyekjaer 	}
25306ee6a368SSean Nyekjaer 
25316ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
2532a3aa17d4SSean Nyekjaer 					NULL,
25336ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
25346ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
25356ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
25366ee6a368SSean Nyekjaer 	if (err) {
25376ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
25386ee6a368SSean Nyekjaer 			hw->irq);
25396ee6a368SSean Nyekjaer 		return err;
25406ee6a368SSean Nyekjaer 	}
25416ee6a368SSean Nyekjaer 
25426ee6a368SSean Nyekjaer 	return 0;
25436ee6a368SSean Nyekjaer }
25446ee6a368SSean Nyekjaer 
25452cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev)
25462cfb2180SLorenzo Bianconi {
25472cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
25482cfb2180SLorenzo Bianconi 
25492cfb2180SLorenzo Bianconi 	return st_lsm6dsx_device_set_enable(sensor, true);
25502cfb2180SLorenzo Bianconi }
25512cfb2180SLorenzo Bianconi 
25522cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev)
25532cfb2180SLorenzo Bianconi {
25542cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
25552cfb2180SLorenzo Bianconi 
25562cfb2180SLorenzo Bianconi 	return st_lsm6dsx_device_set_enable(sensor, false);
25572cfb2180SLorenzo Bianconi }
25582cfb2180SLorenzo Bianconi 
25592cfb2180SLorenzo Bianconi static const struct iio_buffer_setup_ops st_lsm6dsx_sw_buffer_ops = {
25602cfb2180SLorenzo Bianconi 	.preenable = st_lsm6dsx_sw_buffer_preenable,
25612cfb2180SLorenzo Bianconi 	.postdisable = st_lsm6dsx_sw_buffer_postdisable,
25622cfb2180SLorenzo Bianconi };
25632cfb2180SLorenzo Bianconi 
25642cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw *hw)
25652cfb2180SLorenzo Bianconi {
25662cfb2180SLorenzo Bianconi 	int i;
25672cfb2180SLorenzo Bianconi 
25682cfb2180SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
25692cfb2180SLorenzo Bianconi 		int err;
25702cfb2180SLorenzo Bianconi 
25712cfb2180SLorenzo Bianconi 		if (!hw->iio_devs[i])
25722cfb2180SLorenzo Bianconi 			continue;
25732cfb2180SLorenzo Bianconi 
25742cfb2180SLorenzo Bianconi 		err = devm_iio_triggered_buffer_setup(hw->dev,
25752cfb2180SLorenzo Bianconi 					hw->iio_devs[i], NULL,
25762cfb2180SLorenzo Bianconi 					st_lsm6dsx_sw_trigger_handler_thread,
25772cfb2180SLorenzo Bianconi 					&st_lsm6dsx_sw_buffer_ops);
25782cfb2180SLorenzo Bianconi 		if (err)
25792cfb2180SLorenzo Bianconi 			return err;
25802cfb2180SLorenzo Bianconi 	}
25812cfb2180SLorenzo Bianconi 
25822cfb2180SLorenzo Bianconi 	return 0;
25832cfb2180SLorenzo Bianconi }
25842cfb2180SLorenzo Bianconi 
2585f346b16fSLorenzo Bianconi static int st_lsm6dsx_init_regulators(struct device *dev)
2586f346b16fSLorenzo Bianconi {
25876900cdbfSMatti Vaittinen 	/* vdd-vddio power regulators */
25886900cdbfSMatti Vaittinen 	static const char * const regulators[] = { "vdd", "vddio" };
2589f346b16fSLorenzo Bianconi 	int err;
2590f346b16fSLorenzo Bianconi 
25916900cdbfSMatti Vaittinen 	err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),
25926900cdbfSMatti Vaittinen 					     regulators);
2593f346b16fSLorenzo Bianconi 	if (err)
25946900cdbfSMatti Vaittinen 		return dev_err_probe(dev, err, "failed to enable regulators\n");
2595f346b16fSLorenzo Bianconi 
2596f346b16fSLorenzo Bianconi 	msleep(50);
2597f346b16fSLorenzo Bianconi 
2598f346b16fSLorenzo Bianconi 	return 0;
2599f346b16fSLorenzo Bianconi }
2600f346b16fSLorenzo Bianconi 
260181956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
260251a8b707SLorenzo Bianconi 		     struct regmap *regmap)
2603290a6ce1SLorenzo Bianconi {
2604b7a73b33SLorenzo Bianconi 	struct st_sensors_platform_data *pdata = dev->platform_data;
2605c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2606290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
260781956a93SLorenzo Bianconi 	const char *name = NULL;
2608290a6ce1SLorenzo Bianconi 	int i, err;
2609290a6ce1SLorenzo Bianconi 
2610290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
2611290a6ce1SLorenzo Bianconi 	if (!hw)
2612290a6ce1SLorenzo Bianconi 		return -ENOMEM;
2613290a6ce1SLorenzo Bianconi 
2614290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
2615290a6ce1SLorenzo Bianconi 
2616290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
2617335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
2618739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
2619290a6ce1SLorenzo Bianconi 
2620f346b16fSLorenzo Bianconi 	err = st_lsm6dsx_init_regulators(dev);
2621f346b16fSLorenzo Bianconi 	if (err)
2622f346b16fSLorenzo Bianconi 		return err;
2623f346b16fSLorenzo Bianconi 
262491a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
262591a6b841SLorenzo Bianconi 	if (!hw->buff)
262691a6b841SLorenzo Bianconi 		return -ENOMEM;
262791a6b841SLorenzo Bianconi 
2628290a6ce1SLorenzo Bianconi 	hw->dev = dev;
2629290a6ce1SLorenzo Bianconi 	hw->irq = irq;
263051a8b707SLorenzo Bianconi 	hw->regmap = regmap;
2631290a6ce1SLorenzo Bianconi 
263281956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
2633290a6ce1SLorenzo Bianconi 	if (err < 0)
2634290a6ce1SLorenzo Bianconi 		return err;
2635290a6ce1SLorenzo Bianconi 
26366ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
2637510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
2638290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
2639290a6ce1SLorenzo Bianconi 			return -ENOMEM;
2640290a6ce1SLorenzo Bianconi 	}
2641290a6ce1SLorenzo Bianconi 
2642290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
2643290a6ce1SLorenzo Bianconi 	if (err < 0)
2644290a6ce1SLorenzo Bianconi 		return err;
2645290a6ce1SLorenzo Bianconi 
2646c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
264735619155SLorenzo Bianconi 	if (hub_settings->master_en.addr &&
264835619155SLorenzo Bianconi 	    (!dev_fwnode(dev) ||
264935619155SLorenzo Bianconi 	     !device_property_read_bool(dev, "st,disable-sensor-hub"))) {
2650c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
2651c91c1c84SLorenzo Bianconi 		if (err < 0)
2652c91c1c84SLorenzo Bianconi 			return err;
2653c91c1c84SLorenzo Bianconi 	}
2654c91c1c84SLorenzo Bianconi 
2655290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
26566ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
26576ee6a368SSean Nyekjaer 		if (err < 0)
26586ee6a368SSean Nyekjaer 			return err;
26596ee6a368SSean Nyekjaer 
2660290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
2661290a6ce1SLorenzo Bianconi 		if (err < 0)
2662290a6ce1SLorenzo Bianconi 			return err;
2663290a6ce1SLorenzo Bianconi 	}
2664290a6ce1SLorenzo Bianconi 
26652cfb2180SLorenzo Bianconi 	if (!hw->irq || !hw->settings->fifo_ops.read_fifo) {
26662cfb2180SLorenzo Bianconi 		/*
26672cfb2180SLorenzo Bianconi 		 * Rely on sw triggers (e.g. hr-timers) if irq pin is not
26682cfb2180SLorenzo Bianconi 		 * connected of if the device does not support HW FIFO
26692cfb2180SLorenzo Bianconi 		 */
26702cfb2180SLorenzo Bianconi 		err = st_lsm6dsx_sw_buffers_setup(hw);
26712cfb2180SLorenzo Bianconi 		if (err)
26722cfb2180SLorenzo Bianconi 			return err;
26732cfb2180SLorenzo Bianconi 	}
26742cfb2180SLorenzo Bianconi 
2675b892770aSAndy Shevchenko 	err = iio_read_mount_matrix(hw->dev, &hw->orientation);
267604e6fedbSMartin Kepplinger 	if (err)
267704e6fedbSMartin Kepplinger 		return err;
267804e6fedbSMartin Kepplinger 
2679290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
26806ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
26816ffb55e5SLorenzo Bianconi 			continue;
26826ffb55e5SLorenzo Bianconi 
2683290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
2684290a6ce1SLorenzo Bianconi 		if (err)
2685290a6ce1SLorenzo Bianconi 			return err;
2686290a6ce1SLorenzo Bianconi 	}
2687290a6ce1SLorenzo Bianconi 
268803d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
2689b7a73b33SLorenzo Bianconi 	    (pdata && pdata->wakeup_source))
26904c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
26914c997dfaSSean Nyekjaer 
2692290a6ce1SLorenzo Bianconi 	return 0;
2693290a6ce1SLorenzo Bianconi }
26942b059449SJonathan Cameron EXPORT_SYMBOL_NS(st_lsm6dsx_probe, IIO_LSM6DSX);
2695290a6ce1SLorenzo Bianconi 
2696acc416ffSJonathan Cameron static int st_lsm6dsx_suspend(struct device *dev)
2697d3f77058SLorenzo Bianconi {
2698d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2699d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2700d3f77058SLorenzo Bianconi 	int i, err = 0;
2701d3f77058SLorenzo Bianconi 
2702d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
27036ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
27046ffb55e5SLorenzo Bianconi 			continue;
27056ffb55e5SLorenzo Bianconi 
2706d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
2707d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
2708d3f77058SLorenzo Bianconi 			continue;
2709d3f77058SLorenzo Bianconi 
27104c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
27114c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
27124c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
27134c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
27144c997dfaSSean Nyekjaer 			continue;
27154c997dfaSSean Nyekjaer 		}
27164c997dfaSSean Nyekjaer 
2717cd83c5c1SLorenzo Bianconi 		err = st_lsm6dsx_device_set_enable(sensor, false);
2718d3f77058SLorenzo Bianconi 		if (err < 0)
2719d3f77058SLorenzo Bianconi 			return err;
2720bce0d57dSLorenzo Bianconi 
2721bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2722d3f77058SLorenzo Bianconi 	}
2723d3f77058SLorenzo Bianconi 
2724c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2725d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2726d3f77058SLorenzo Bianconi 
2727d3f77058SLorenzo Bianconi 	return err;
2728d3f77058SLorenzo Bianconi }
2729d3f77058SLorenzo Bianconi 
2730acc416ffSJonathan Cameron static int st_lsm6dsx_resume(struct device *dev)
2731d3f77058SLorenzo Bianconi {
2732d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2733d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2734d3f77058SLorenzo Bianconi 	int i, err = 0;
2735d3f77058SLorenzo Bianconi 
2736d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
27376ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
27386ffb55e5SLorenzo Bianconi 			continue;
27396ffb55e5SLorenzo Bianconi 
2740d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
27414c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
27424c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
27434c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
27444c997dfaSSean Nyekjaer 
2745bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2746d3f77058SLorenzo Bianconi 			continue;
2747d3f77058SLorenzo Bianconi 
2748cd83c5c1SLorenzo Bianconi 		err = st_lsm6dsx_device_set_enable(sensor, true);
2749d3f77058SLorenzo Bianconi 		if (err < 0)
2750d3f77058SLorenzo Bianconi 			return err;
2751bce0d57dSLorenzo Bianconi 
2752bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2753d3f77058SLorenzo Bianconi 	}
2754d3f77058SLorenzo Bianconi 
2755c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2756a1bab939SLorenzo Bianconi 		err = st_lsm6dsx_resume_fifo(hw);
2757d3f77058SLorenzo Bianconi 
2758d3f77058SLorenzo Bianconi 	return err;
2759d3f77058SLorenzo Bianconi }
2760d3f77058SLorenzo Bianconi 
27612b059449SJonathan Cameron EXPORT_NS_SIMPLE_DEV_PM_OPS(st_lsm6dsx_pm_ops, st_lsm6dsx_suspend,
27622b059449SJonathan Cameron 			    st_lsm6dsx_resume, IIO_LSM6DSX);
2763d3f77058SLorenzo Bianconi 
2764290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2765290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2766290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2767290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2768