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*d94fbd92SLorenzo Bianconi  *   LSM6DSTX:
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  *
37*d94fbd92SLorenzo Bianconi  * - LSM6DSV/LSM6DSV16X:
38*d94fbd92SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 7.5, 15, 30, 60, 120, 240,
39*d94fbd92SLorenzo Bianconi  *     480, 960
40*d94fbd92SLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
41*d94fbd92SLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-250/+-500/+-1000/+-2000
42*d94fbd92SLorenzo Bianconi  *   - FIFO size: 3KB
43*d94fbd92SLorenzo 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 	},
1378290a6ce1SLorenzo Bianconi };
1379290a6ce1SLorenzo Bianconi 
1380c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1381c91c1c84SLorenzo Bianconi {
1382c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1383c91c1c84SLorenzo Bianconi 	unsigned int data;
1384c91c1c84SLorenzo Bianconi 	int err;
1385c91c1c84SLorenzo Bianconi 
1386c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1387c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1388c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1389c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1390c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1391c91c1c84SLorenzo Bianconi 
1392c91c1c84SLorenzo Bianconi 	return err;
1393c91c1c84SLorenzo Bianconi }
1394c91c1c84SLorenzo Bianconi 
139581956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
139681956a93SLorenzo Bianconi 				   const char **name)
1397290a6ce1SLorenzo Bianconi {
139851a8b707SLorenzo Bianconi 	int err, i, j, data;
1399290a6ce1SLorenzo Bianconi 
1400290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1401d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
1402fb4fbc89SStephan Gerhold 			if (st_lsm6dsx_sensor_settings[i].id[j].name &&
1403fb4fbc89SStephan Gerhold 			    id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1404d068e4a0SLorenzo Bianconi 				break;
1405d068e4a0SLorenzo Bianconi 		}
1406d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1407290a6ce1SLorenzo Bianconi 			break;
1408290a6ce1SLorenzo Bianconi 	}
1409290a6ce1SLorenzo Bianconi 
1410290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1411290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1412290a6ce1SLorenzo Bianconi 		return -ENODEV;
1413290a6ce1SLorenzo Bianconi 	}
1414290a6ce1SLorenzo Bianconi 
141551a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1416290a6ce1SLorenzo Bianconi 	if (err < 0) {
1417290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1418290a6ce1SLorenzo Bianconi 		return err;
1419290a6ce1SLorenzo Bianconi 	}
1420290a6ce1SLorenzo Bianconi 
142198c3544aSLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].id[j].wai) {
1422290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1423290a6ce1SLorenzo Bianconi 		return -ENODEV;
1424290a6ce1SLorenzo Bianconi 	}
1425290a6ce1SLorenzo Bianconi 
142681956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1427290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1428290a6ce1SLorenzo Bianconi 
1429290a6ce1SLorenzo Bianconi 	return 0;
1430290a6ce1SLorenzo Bianconi }
1431290a6ce1SLorenzo Bianconi 
1432290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1433290a6ce1SLorenzo Bianconi 				     u32 gain)
1434290a6ce1SLorenzo Bianconi {
1435640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1436739aff87SLorenzo Bianconi 	unsigned int data;
1437290a6ce1SLorenzo Bianconi 	int i, err;
1438290a6ce1SLorenzo Bianconi 
1439640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
144085ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1441640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1442290a6ce1SLorenzo Bianconi 			break;
144385ae3aeeSLorenzo Bianconi 	}
1444290a6ce1SLorenzo Bianconi 
144585ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1446290a6ce1SLorenzo Bianconi 		return -EINVAL;
1447290a6ce1SLorenzo Bianconi 
1448640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1449640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1450640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1451640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1452290a6ce1SLorenzo Bianconi 	if (err < 0)
1453290a6ce1SLorenzo Bianconi 		return err;
1454290a6ce1SLorenzo Bianconi 
1455290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1456290a6ce1SLorenzo Bianconi 
1457290a6ce1SLorenzo Bianconi 	return 0;
1458290a6ce1SLorenzo Bianconi }
1459290a6ce1SLorenzo Bianconi 
1460f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val)
1461290a6ce1SLorenzo Bianconi {
146240dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
14632ccc1503SLorenzo Bianconi 	int i;
1464290a6ce1SLorenzo Bianconi 
146540dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
146659af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++) {
14676ffb55e5SLorenzo Bianconi 		/*
14686ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
14696ffb55e5SLorenzo Bianconi 		 * accel sensor
14706ffb55e5SLorenzo Bianconi 		 */
1471f8710f03SLorenzo Bianconi 		if (odr_table->odr_avl[i].milli_hz >= odr)
1472290a6ce1SLorenzo Bianconi 			break;
147359af4e20SLorenzo Bianconi 	}
1474290a6ce1SLorenzo Bianconi 
147559af4e20SLorenzo Bianconi 	if (i == odr_table->odr_len)
1476290a6ce1SLorenzo Bianconi 		return -EINVAL;
1477290a6ce1SLorenzo Bianconi 
147840dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1479f8710f03SLorenzo Bianconi 	return odr_table->odr_avl[i].milli_hz;
1480290a6ce1SLorenzo Bianconi }
1481290a6ce1SLorenzo Bianconi 
1482f8710f03SLorenzo Bianconi static int
1483f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr,
14846ffb55e5SLorenzo Bianconi 				enum st_lsm6dsx_sensor_id id)
14852ccc1503SLorenzo Bianconi {
14866ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
14876ffb55e5SLorenzo Bianconi 
14886ffb55e5SLorenzo Bianconi 	if (odr > 0) {
14896ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
1490f8710f03SLorenzo Bianconi 			return max_t(u32, ref->odr, odr);
14916ffb55e5SLorenzo Bianconi 		else
14926ffb55e5SLorenzo Bianconi 			return odr;
14936ffb55e5SLorenzo Bianconi 	} else {
14946ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
14956ffb55e5SLorenzo Bianconi 	}
14966ffb55e5SLorenzo Bianconi }
14976ffb55e5SLorenzo Bianconi 
1498f8710f03SLorenzo Bianconi static int
1499f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
15006ffb55e5SLorenzo Bianconi {
15016ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
150251a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
150351a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1504739aff87SLorenzo Bianconi 	unsigned int data;
15056ffb55e5SLorenzo Bianconi 	u8 val = 0;
15062ccc1503SLorenzo Bianconi 	int err;
15072ccc1503SLorenzo Bianconi 
15086ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
150994be878cSTeng Qi 	case ST_LSM6DSX_ID_GYRO:
151094be878cSTeng Qi 		break;
15116ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
15126ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
15136ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
15146ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
1515f8710f03SLorenzo Bianconi 		u32 odr;
15166ffb55e5SLorenzo Bianconi 		int i;
15176ffb55e5SLorenzo Bianconi 
15186ffb55e5SLorenzo Bianconi 		/*
15196ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
15206ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
15216ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
15226ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
15236ffb55e5SLorenzo Bianconi 		 */
15246ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
15256ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
15266ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
15276ffb55e5SLorenzo Bianconi 				continue;
15286ffb55e5SLorenzo Bianconi 
15296ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
15306ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
15316ffb55e5SLorenzo Bianconi 				/* device already configured */
15326ffb55e5SLorenzo Bianconi 				return 0;
15336ffb55e5SLorenzo Bianconi 		}
15346ffb55e5SLorenzo Bianconi 		break;
15356ffb55e5SLorenzo Bianconi 	}
153694be878cSTeng Qi 	default: /* should never occur */
153794be878cSTeng Qi 		return -EINVAL;
15386ffb55e5SLorenzo Bianconi 	}
15396ffb55e5SLorenzo Bianconi 
15406ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
15416ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
15422ccc1503SLorenzo Bianconi 		if (err < 0)
15432ccc1503SLorenzo Bianconi 			return err;
15446ffb55e5SLorenzo Bianconi 	}
15452ccc1503SLorenzo Bianconi 
154640dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1547739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1548739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
15492ccc1503SLorenzo Bianconi }
15502ccc1503SLorenzo Bianconi 
1551bd41c445SLorenzo Bianconi static int
1552bd41c445SLorenzo Bianconi __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
155317750443SLorenzo Bianconi 			       bool enable)
1554290a6ce1SLorenzo Bianconi {
155551a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1556f8710f03SLorenzo Bianconi 	u32 odr = enable ? sensor->odr : 0;
1557290a6ce1SLorenzo Bianconi 	int err;
1558290a6ce1SLorenzo Bianconi 
155917750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1560290a6ce1SLorenzo Bianconi 	if (err < 0)
1561290a6ce1SLorenzo Bianconi 		return err;
1562290a6ce1SLorenzo Bianconi 
156317750443SLorenzo Bianconi 	if (enable)
156417750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
156517750443SLorenzo Bianconi 	else
156617750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1567290a6ce1SLorenzo Bianconi 
1568290a6ce1SLorenzo Bianconi 	return 0;
1569290a6ce1SLorenzo Bianconi }
1570290a6ce1SLorenzo Bianconi 
1571bd41c445SLorenzo Bianconi static int
1572bd41c445SLorenzo Bianconi st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable)
1573bd41c445SLorenzo Bianconi {
1574bd41c445SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1575bd41c445SLorenzo Bianconi 
1576bd41c445SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_GYRO || enable)
1577bd41c445SLorenzo Bianconi 		return 0;
1578bd41c445SLorenzo Bianconi 
1579bd41c445SLorenzo Bianconi 	return hw->enable_event;
1580bd41c445SLorenzo Bianconi }
1581bd41c445SLorenzo Bianconi 
1582bd41c445SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1583bd41c445SLorenzo Bianconi 				 bool enable)
1584bd41c445SLorenzo Bianconi {
1585bd41c445SLorenzo Bianconi 	if (st_lsm6dsx_check_events(sensor, enable))
1586bd41c445SLorenzo Bianconi 		return 0;
1587bd41c445SLorenzo Bianconi 
1588bd41c445SLorenzo Bianconi 	return __st_lsm6dsx_sensor_set_enable(sensor, enable);
1589bd41c445SLorenzo Bianconi }
1590bd41c445SLorenzo Bianconi 
1591290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1592290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1593290a6ce1SLorenzo Bianconi {
159451a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1595290a6ce1SLorenzo Bianconi 	int err, delay;
1596290a6ce1SLorenzo Bianconi 	__le16 data;
1597290a6ce1SLorenzo Bianconi 
159817750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1599290a6ce1SLorenzo Bianconi 	if (err < 0)
1600290a6ce1SLorenzo Bianconi 		return err;
1601290a6ce1SLorenzo Bianconi 
1602ea85bf90SLorenzo Bianconi 	/*
1603ea85bf90SLorenzo Bianconi 	 * we need to wait for sensor settling time before
1604ea85bf90SLorenzo Bianconi 	 * reading data in order to avoid corrupted samples
1605ea85bf90SLorenzo Bianconi 	 */
1606f8710f03SLorenzo Bianconi 	delay = 1000000000 / sensor->odr;
1607ea85bf90SLorenzo Bianconi 	usleep_range(3 * delay, 4 * delay);
1608290a6ce1SLorenzo Bianconi 
1609739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1610290a6ce1SLorenzo Bianconi 	if (err < 0)
1611290a6ce1SLorenzo Bianconi 		return err;
1612290a6ce1SLorenzo Bianconi 
1613a2dd9bd9SLorenzo Bianconi 	if (!hw->enable_event) {
1614a2dd9bd9SLorenzo Bianconi 		err = st_lsm6dsx_sensor_set_enable(sensor, false);
1615a2dd9bd9SLorenzo Bianconi 		if (err < 0)
1616a2dd9bd9SLorenzo Bianconi 			return err;
1617a2dd9bd9SLorenzo Bianconi 	}
1618290a6ce1SLorenzo Bianconi 
16197b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1620290a6ce1SLorenzo Bianconi 
1621290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1622290a6ce1SLorenzo Bianconi }
1623290a6ce1SLorenzo Bianconi 
1624290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1625290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1626290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1627290a6ce1SLorenzo Bianconi {
1628290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1629290a6ce1SLorenzo Bianconi 	int ret;
1630290a6ce1SLorenzo Bianconi 
1631290a6ce1SLorenzo Bianconi 	switch (mask) {
1632290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1633290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1634290a6ce1SLorenzo Bianconi 		if (ret)
1635290a6ce1SLorenzo Bianconi 			break;
1636290a6ce1SLorenzo Bianconi 
1637290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1638290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1639290a6ce1SLorenzo Bianconi 		break;
1640290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1641f8710f03SLorenzo Bianconi 		*val = sensor->odr / 1000;
1642f8710f03SLorenzo Bianconi 		*val2 = (sensor->odr % 1000) * 1000;
1643f8710f03SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1644290a6ce1SLorenzo Bianconi 		break;
1645290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1646290a6ce1SLorenzo Bianconi 		*val = 0;
1647290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
164844a76de8SMario Tesi 		ret = IIO_VAL_INT_PLUS_NANO;
1649290a6ce1SLorenzo Bianconi 		break;
1650290a6ce1SLorenzo Bianconi 	default:
1651290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1652290a6ce1SLorenzo Bianconi 		break;
1653290a6ce1SLorenzo Bianconi 	}
1654290a6ce1SLorenzo Bianconi 
1655290a6ce1SLorenzo Bianconi 	return ret;
1656290a6ce1SLorenzo Bianconi }
1657290a6ce1SLorenzo Bianconi 
1658290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1659290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1660290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1661290a6ce1SLorenzo Bianconi {
1662290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1663290a6ce1SLorenzo Bianconi 	int err;
1664290a6ce1SLorenzo Bianconi 
1665290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1666290a6ce1SLorenzo Bianconi 	if (err)
1667290a6ce1SLorenzo Bianconi 		return err;
1668290a6ce1SLorenzo Bianconi 
1669290a6ce1SLorenzo Bianconi 	switch (mask) {
1670290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1671290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1672290a6ce1SLorenzo Bianconi 		break;
16732ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
16742ccc1503SLorenzo Bianconi 		u8 data;
16752ccc1503SLorenzo Bianconi 
1676f8710f03SLorenzo Bianconi 		val = val * 1000 + val2 / 1000;
1677fc3f6ad7SLorenzo Bianconi 		val = st_lsm6dsx_check_odr(sensor, val, &data);
1678fc3f6ad7SLorenzo Bianconi 		if (val < 0)
1679fc3f6ad7SLorenzo Bianconi 			err = val;
1680fc3f6ad7SLorenzo Bianconi 		else
16815e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1682290a6ce1SLorenzo Bianconi 		break;
16832ccc1503SLorenzo Bianconi 	}
1684290a6ce1SLorenzo Bianconi 	default:
1685290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1686290a6ce1SLorenzo Bianconi 		break;
1687290a6ce1SLorenzo Bianconi 	}
1688290a6ce1SLorenzo Bianconi 
1689290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1690290a6ce1SLorenzo Bianconi 
1691290a6ce1SLorenzo Bianconi 	return err;
1692290a6ce1SLorenzo Bianconi }
1693290a6ce1SLorenzo Bianconi 
1694b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1695b5969abfSSean Nyekjaer {
169684b2e7c3SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
169704ca37d5SLorenzo Bianconi 	unsigned int data;
1698b5969abfSSean Nyekjaer 	int err;
1699b5969abfSSean Nyekjaer 
17007e906103SLorenzo Bianconi 	if (!hw->settings->irq_config.irq1_func.addr)
1701b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1702b5969abfSSean Nyekjaer 
170384b2e7c3SLorenzo Bianconi 	reg = &hw->settings->event_settings.enable_reg;
170484b2e7c3SLorenzo Bianconi 	if (reg->addr) {
170504ca37d5SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
170604ca37d5SLorenzo Bianconi 		err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
170704ca37d5SLorenzo Bianconi 						    reg->mask, data);
1708b5969abfSSean Nyekjaer 		if (err < 0)
1709b5969abfSSean Nyekjaer 			return err;
171084b2e7c3SLorenzo Bianconi 	}
1711b5969abfSSean Nyekjaer 
1712b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
171304ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
171404ca37d5SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
171504ca37d5SLorenzo Bianconi 					     hw->irq_routing->mask, data);
1716b5969abfSSean Nyekjaer }
1717b5969abfSSean Nyekjaer 
1718b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1719b5969abfSSean Nyekjaer 				 const struct iio_chan_spec *chan,
1720b5969abfSSean Nyekjaer 				 enum iio_event_type type,
1721b5969abfSSean Nyekjaer 				 enum iio_event_direction dir,
1722b5969abfSSean Nyekjaer 				 enum iio_event_info info,
1723b5969abfSSean Nyekjaer 				 int *val, int *val2)
1724b5969abfSSean Nyekjaer {
1725b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1726b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1727b5969abfSSean Nyekjaer 
1728b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1729b5969abfSSean Nyekjaer 		return -EINVAL;
1730b5969abfSSean Nyekjaer 
1731b5969abfSSean Nyekjaer 	*val2 = 0;
1732b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1733b5969abfSSean Nyekjaer 
1734b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1735b5969abfSSean Nyekjaer }
1736b5969abfSSean Nyekjaer 
1737b307f495SLorenzo Bianconi static int
1738b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1739b5969abfSSean Nyekjaer 		       const struct iio_chan_spec *chan,
1740b5969abfSSean Nyekjaer 		       enum iio_event_type type,
1741b5969abfSSean Nyekjaer 		       enum iio_event_direction dir,
1742b5969abfSSean Nyekjaer 		       enum iio_event_info info,
1743b5969abfSSean Nyekjaer 		       int val, int val2)
1744b5969abfSSean Nyekjaer {
1745b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1746b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
174704ca37d5SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
174804ca37d5SLorenzo Bianconi 	unsigned int data;
1749b5969abfSSean Nyekjaer 	int err;
1750b5969abfSSean Nyekjaer 
1751b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1752b5969abfSSean Nyekjaer 		return -EINVAL;
1753b5969abfSSean Nyekjaer 
1754b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1755b5969abfSSean Nyekjaer 		return -EINVAL;
1756b5969abfSSean Nyekjaer 
175704ca37d5SLorenzo Bianconi 	reg = &hw->settings->event_settings.wakeup_reg;
175804ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
175904ca37d5SLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
176004ca37d5SLorenzo Bianconi 					    reg->mask, data);
176104ca37d5SLorenzo Bianconi 	if (err < 0)
1762b5969abfSSean Nyekjaer 		return -EINVAL;
1763b5969abfSSean Nyekjaer 
1764b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1765b5969abfSSean Nyekjaer 
1766b5969abfSSean Nyekjaer 	return 0;
1767b5969abfSSean Nyekjaer }
1768b5969abfSSean Nyekjaer 
1769b307f495SLorenzo Bianconi static int
1770b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1771b5969abfSSean Nyekjaer 			     const struct iio_chan_spec *chan,
1772b5969abfSSean Nyekjaer 			     enum iio_event_type type,
1773b5969abfSSean Nyekjaer 			     enum iio_event_direction dir)
1774b5969abfSSean Nyekjaer {
1775b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1776b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1777b5969abfSSean Nyekjaer 
1778b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1779b5969abfSSean Nyekjaer 		return -EINVAL;
1780b5969abfSSean Nyekjaer 
17811aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1782b5969abfSSean Nyekjaer }
1783b5969abfSSean Nyekjaer 
1784b307f495SLorenzo Bianconi static int
1785b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1786b5969abfSSean Nyekjaer 			      const struct iio_chan_spec *chan,
1787b5969abfSSean Nyekjaer 			      enum iio_event_type type,
1788b307f495SLorenzo Bianconi 			      enum iio_event_direction dir, int state)
1789b5969abfSSean Nyekjaer {
1790b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1791b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
17921aabad1fSSean Nyekjaer 	u8 enable_event;
1793bd41c445SLorenzo Bianconi 	int err;
1794b5969abfSSean Nyekjaer 
1795b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1796b5969abfSSean Nyekjaer 		return -EINVAL;
1797b5969abfSSean Nyekjaer 
17981aabad1fSSean Nyekjaer 	if (state) {
17991aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
18001aabad1fSSean Nyekjaer 
1801b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
18021aabad1fSSean Nyekjaer 		if (hw->enable_event)
18031aabad1fSSean Nyekjaer 			goto out;
18041aabad1fSSean Nyekjaer 	} else {
18051aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
18061aabad1fSSean Nyekjaer 
18071aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
18081aabad1fSSean Nyekjaer 		if (enable_event)
18091aabad1fSSean Nyekjaer 			goto out;
18101aabad1fSSean Nyekjaer 	}
18111aabad1fSSean Nyekjaer 
18121aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
18131aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1814b5969abfSSean Nyekjaer 		return 0;
1815b5969abfSSean Nyekjaer 
1816b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1817b5969abfSSean Nyekjaer 	if (err < 0)
1818b5969abfSSean Nyekjaer 		return err;
1819b5969abfSSean Nyekjaer 
1820d278d447SLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1821bd41c445SLorenzo Bianconi 	if (enable_event || !(hw->fifo_mask & BIT(sensor->id)))
1822bd41c445SLorenzo Bianconi 		err = __st_lsm6dsx_sensor_set_enable(sensor, state);
1823d278d447SLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1824b5969abfSSean Nyekjaer 	if (err < 0)
1825b5969abfSSean Nyekjaer 		return err;
1826b5969abfSSean Nyekjaer 
18271aabad1fSSean Nyekjaer out:
18281aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1829b5969abfSSean Nyekjaer 
1830b5969abfSSean Nyekjaer 	return 0;
1831b5969abfSSean Nyekjaer }
1832b5969abfSSean Nyekjaer 
1833d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1834290a6ce1SLorenzo Bianconi {
1835290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1836290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
18378f2a88a2SLorenzo Bianconi 	int err;
1838290a6ce1SLorenzo Bianconi 
18399e5b4cd2SPaul Cercueil 	val = clamp_val(val, 1, hw->settings->fifo_ops.max_size);
1840290a6ce1SLorenzo Bianconi 
1841335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1842335eaedcSLorenzo Bianconi 
1843290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
1844335eaedcSLorenzo Bianconi 
1845335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1846335eaedcSLorenzo Bianconi 
1847290a6ce1SLorenzo Bianconi 	if (err < 0)
1848290a6ce1SLorenzo Bianconi 		return err;
1849290a6ce1SLorenzo Bianconi 
1850290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
1851290a6ce1SLorenzo Bianconi 
1852290a6ce1SLorenzo Bianconi 	return 0;
1853290a6ce1SLorenzo Bianconi }
1854290a6ce1SLorenzo Bianconi 
1855290a6ce1SLorenzo Bianconi static ssize_t
1856290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1857290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
1858290a6ce1SLorenzo Bianconi 					  char *buf)
1859290a6ce1SLorenzo Bianconi {
18606270bf1fSHaibo Chen 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev));
186159af4e20SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
1862290a6ce1SLorenzo Bianconi 	int i, len = 0;
1863290a6ce1SLorenzo Bianconi 
186459af4e20SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
186559af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++)
1866f8710f03SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ",
1867f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz / 1000,
1868f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz % 1000);
1869290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1870290a6ce1SLorenzo Bianconi 
1871290a6ce1SLorenzo Bianconi 	return len;
1872290a6ce1SLorenzo Bianconi }
1873290a6ce1SLorenzo Bianconi 
1874290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
1875290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
1876290a6ce1SLorenzo Bianconi 					    char *buf)
1877290a6ce1SLorenzo Bianconi {
18786270bf1fSHaibo Chen 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev));
18790f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1880640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1881290a6ce1SLorenzo Bianconi 	int i, len = 0;
1882290a6ce1SLorenzo Bianconi 
188385ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
188485ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
188544a76de8SMario Tesi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ",
18860f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
1887290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1888290a6ce1SLorenzo Bianconi 
1889290a6ce1SLorenzo Bianconi 	return len;
1890290a6ce1SLorenzo Bianconi }
1891290a6ce1SLorenzo Bianconi 
189244a76de8SMario Tesi static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev,
189344a76de8SMario Tesi 					struct iio_chan_spec const *chan,
189444a76de8SMario Tesi 					long mask)
189544a76de8SMario Tesi {
189644a76de8SMario Tesi 	switch (mask) {
189744a76de8SMario Tesi 	case IIO_CHAN_INFO_SCALE:
189844a76de8SMario Tesi 		switch (chan->type) {
189944a76de8SMario Tesi 		case IIO_ANGL_VEL:
190044a76de8SMario Tesi 		case IIO_ACCEL:
190144a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_NANO;
190244a76de8SMario Tesi 		default:
190344a76de8SMario Tesi 			return IIO_VAL_INT_PLUS_MICRO;
190444a76de8SMario Tesi 		}
190544a76de8SMario Tesi 	default:
190644a76de8SMario Tesi 		return IIO_VAL_INT_PLUS_MICRO;
190744a76de8SMario Tesi 	}
190844a76de8SMario Tesi }
190944a76de8SMario Tesi 
1910290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
1911290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
1912290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1913290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
1914290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1915290a6ce1SLorenzo Bianconi 
1916290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
1917290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1918290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1919290a6ce1SLorenzo Bianconi 	NULL,
1920290a6ce1SLorenzo Bianconi };
1921290a6ce1SLorenzo Bianconi 
1922290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
1923290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
1924290a6ce1SLorenzo Bianconi };
1925290a6ce1SLorenzo Bianconi 
1926290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
1927290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
1928290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1929290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1930b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
1931b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
1932b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
1933b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
1934290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
193544a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
1936290a6ce1SLorenzo Bianconi };
1937290a6ce1SLorenzo Bianconi 
1938290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
1939290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1940290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
1941290a6ce1SLorenzo Bianconi 	NULL,
1942290a6ce1SLorenzo Bianconi };
1943290a6ce1SLorenzo Bianconi 
1944290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
1945290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
1946290a6ce1SLorenzo Bianconi };
1947290a6ce1SLorenzo Bianconi 
1948290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
1949290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
1950290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1951290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1952290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
195344a76de8SMario Tesi 	.write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
1954290a6ce1SLorenzo Bianconi };
1955290a6ce1SLorenzo Bianconi 
195603d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1957dba32904SLorenzo Bianconi {
195803d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
1959dba32904SLorenzo Bianconi 
196003d4c566SAndy Shevchenko 	if (!dev_fwnode(dev))
1961dba32904SLorenzo Bianconi 		return -EINVAL;
1962dba32904SLorenzo Bianconi 
196303d4c566SAndy Shevchenko 	return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
1964dba32904SLorenzo Bianconi }
1965dba32904SLorenzo Bianconi 
19667e906103SLorenzo Bianconi static int
19677e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
19687e906103SLorenzo Bianconi 			const struct st_lsm6dsx_reg **drdy_reg)
1969dba32904SLorenzo Bianconi {
1970dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
1971dba32904SLorenzo Bianconi 
197203d4c566SAndy Shevchenko 	if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
1973dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
1974dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
1975dba32904SLorenzo Bianconi 
1976dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
1977dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
1978dba32904SLorenzo Bianconi 	}
1979dba32904SLorenzo Bianconi 
1980dba32904SLorenzo Bianconi 	switch (drdy_pin) {
1981dba32904SLorenzo Bianconi 	case 1:
19827e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq1_func;
19837e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq1;
1984dba32904SLorenzo Bianconi 		break;
1985dba32904SLorenzo Bianconi 	case 2:
19867e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq2_func;
19877e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq2;
1988dba32904SLorenzo Bianconi 		break;
1989dba32904SLorenzo Bianconi 	default:
1990dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
1991dba32904SLorenzo Bianconi 		err = -EINVAL;
1992dba32904SLorenzo Bianconi 		break;
1993dba32904SLorenzo Bianconi 	}
1994dba32904SLorenzo Bianconi 
1995dba32904SLorenzo Bianconi 	return err;
1996dba32904SLorenzo Bianconi }
1997dba32904SLorenzo Bianconi 
1998c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1999c91c1c84SLorenzo Bianconi {
2000c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2001c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
200203d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
2003c91c1c84SLorenzo Bianconi 	unsigned int data;
2004c91c1c84SLorenzo Bianconi 	int err = 0;
2005c91c1c84SLorenzo Bianconi 
2006c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2007c91c1c84SLorenzo Bianconi 
200803d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
200903d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
2010c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
20113a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page) {
2012c91c1c84SLorenzo Bianconi 			err = st_lsm6dsx_set_page(hw, true);
2013c91c1c84SLorenzo Bianconi 			if (err < 0)
2014c91c1c84SLorenzo Bianconi 				return err;
20153a431957SLorenzo Bianconi 		}
2016c91c1c84SLorenzo Bianconi 
2017c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
2018c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2019c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
2020c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
2021c91c1c84SLorenzo Bianconi 
20223a431957SLorenzo Bianconi 		if (hub_settings->pullup_en.sec_page)
2023c91c1c84SLorenzo Bianconi 			st_lsm6dsx_set_page(hw, false);
2024c91c1c84SLorenzo Bianconi 
2025c91c1c84SLorenzo Bianconi 		if (err < 0)
2026c91c1c84SLorenzo Bianconi 			return err;
2027c91c1c84SLorenzo Bianconi 	}
2028c91c1c84SLorenzo Bianconi 
2029c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
2030c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
2031c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
2032c91c1c84SLorenzo Bianconi 		if (err < 0)
2033c91c1c84SLorenzo Bianconi 			return err;
2034c91c1c84SLorenzo Bianconi 
2035c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
2036c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2037c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
2038c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
2039c91c1c84SLorenzo Bianconi 
2040c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
2041e485e2a2SLorenzo Bianconi 
2042e485e2a2SLorenzo Bianconi 		if (err < 0)
2043e485e2a2SLorenzo Bianconi 			return err;
2044e485e2a2SLorenzo Bianconi 	}
2045e485e2a2SLorenzo Bianconi 
2046e485e2a2SLorenzo Bianconi 	if (hub_settings->emb_func.addr) {
2047e485e2a2SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask);
2048e485e2a2SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
2049e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.addr,
2050e485e2a2SLorenzo Bianconi 					 hub_settings->emb_func.mask, data);
2051c91c1c84SLorenzo Bianconi 	}
2052c91c1c84SLorenzo Bianconi 
2053c91c1c84SLorenzo Bianconi 	return err;
2054c91c1c84SLorenzo Bianconi }
2055c91c1c84SLorenzo Bianconi 
205621345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
205721345107SLorenzo Bianconi {
205821345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
205921345107SLorenzo Bianconi 	int err, val;
206021345107SLorenzo Bianconi 
206121345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
206221345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
206321345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
206421345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
206521345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
206621345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
206721345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
206821345107SLorenzo Bianconi 		if (err < 0)
206921345107SLorenzo Bianconi 			return err;
207021345107SLorenzo Bianconi 	}
207121345107SLorenzo Bianconi 
207221345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
207321345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
207421345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
207521345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
207621345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
207721345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
207821345107SLorenzo Bianconi 		if (err < 0)
207921345107SLorenzo Bianconi 			return err;
208021345107SLorenzo Bianconi 	}
208121345107SLorenzo Bianconi 
208221345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
208321345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
208421345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
208521345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
208621345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
208721345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
208821345107SLorenzo Bianconi 		if (err < 0)
208921345107SLorenzo Bianconi 			return err;
209021345107SLorenzo Bianconi 	}
2091cb3b6b8eSMario Tesi 
2092cb3b6b8eSMario Tesi 	/* calibrate timestamp sensitivity */
2093cb3b6b8eSMario Tesi 	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
2094cb3b6b8eSMario Tesi 	if (ts_settings->freq_fine) {
2095cb3b6b8eSMario Tesi 		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
2096cb3b6b8eSMario Tesi 		if (err < 0)
2097cb3b6b8eSMario Tesi 			return err;
2098cb3b6b8eSMario Tesi 
2099cb3b6b8eSMario Tesi 		/*
2100cb3b6b8eSMario Tesi 		 * linearize the AN5192 formula:
2101cb3b6b8eSMario Tesi 		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
2102cb3b6b8eSMario Tesi 		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
2103cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - 37.5 * val
2104cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
2105cb3b6b8eSMario Tesi 		 */
2106cb3b6b8eSMario Tesi 		hw->ts_gain -= ((s8)val * 37500) / 1000;
2107cb3b6b8eSMario Tesi 	}
2108cb3b6b8eSMario Tesi 
210921345107SLorenzo Bianconi 	return 0;
211021345107SLorenzo Bianconi }
211121345107SLorenzo Bianconi 
21123a63da26SLorenzo Bianconi static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
2113290a6ce1SLorenzo Bianconi {
21147e906103SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
2115290a6ce1SLorenzo Bianconi 	int err;
2116290a6ce1SLorenzo Bianconi 
21173a63da26SLorenzo Bianconi 	/*
21183a63da26SLorenzo Bianconi 	 * flush hw FIFO before device reset in order to avoid
21193a63da26SLorenzo Bianconi 	 * possible races on interrupt line 1. If the first interrupt
21203a63da26SLorenzo Bianconi 	 * line is asserted during hw reset the device will work in
21213a63da26SLorenzo Bianconi 	 * I3C-only mode (if it is supported)
21223a63da26SLorenzo Bianconi 	 */
21233a63da26SLorenzo Bianconi 	err = st_lsm6dsx_flush_fifo(hw);
21243a63da26SLorenzo Bianconi 	if (err < 0 && err != -ENOTSUPP)
21253a63da26SLorenzo Bianconi 		return err;
21263a63da26SLorenzo Bianconi 
212719435425SLorenzo Bianconi 	/* device sw reset */
212866b662a1SLorenzo Bianconi 	reg = &hw->settings->reset;
212966b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
213066b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2131290a6ce1SLorenzo Bianconi 	if (err < 0)
2132290a6ce1SLorenzo Bianconi 		return err;
2133290a6ce1SLorenzo Bianconi 
213419435425SLorenzo Bianconi 	msleep(50);
213519435425SLorenzo Bianconi 
213619435425SLorenzo Bianconi 	/* reload trimming parameter */
213766b662a1SLorenzo Bianconi 	reg = &hw->settings->boot;
213866b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
213966b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
214019435425SLorenzo Bianconi 	if (err < 0)
214119435425SLorenzo Bianconi 		return err;
214219435425SLorenzo Bianconi 
214319435425SLorenzo Bianconi 	msleep(50);
2144290a6ce1SLorenzo Bianconi 
21453a63da26SLorenzo Bianconi 	return 0;
21463a63da26SLorenzo Bianconi }
21473a63da26SLorenzo Bianconi 
21483a63da26SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
21493a63da26SLorenzo Bianconi {
21503a63da26SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
21513a63da26SLorenzo Bianconi 	int err;
21523a63da26SLorenzo Bianconi 
21533a63da26SLorenzo Bianconi 	err = st_lsm6dsx_reset_device(hw);
21543a63da26SLorenzo Bianconi 	if (err < 0)
21553a63da26SLorenzo Bianconi 		return err;
21563a63da26SLorenzo Bianconi 
2157290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
215866b662a1SLorenzo Bianconi 	reg = &hw->settings->bdu;
215966b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
216066b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2161290a6ce1SLorenzo Bianconi 	if (err < 0)
2162290a6ce1SLorenzo Bianconi 		return err;
2163290a6ce1SLorenzo Bianconi 
2164290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
21657e906103SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &reg);
2166290a6ce1SLorenzo Bianconi 	if (err < 0)
2167290a6ce1SLorenzo Bianconi 		return err;
2168290a6ce1SLorenzo Bianconi 
21697e906103SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
21707e906103SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
217121345107SLorenzo Bianconi 	if (err < 0)
217221345107SLorenzo Bianconi 		return err;
217321345107SLorenzo Bianconi 
21749db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
21757e906103SLorenzo Bianconi 	if (hw->settings->irq_config.lir.addr) {
21767e906103SLorenzo Bianconi 		reg = &hw->settings->irq_config.lir;
21777e906103SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
21787e906103SLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
21799db02d32SLorenzo Bianconi 		if (err < 0)
21809db02d32SLorenzo Bianconi 			return err;
218122ea5651SLorenzo Bianconi 
218222ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
21837e906103SLorenzo Bianconi 		if (hw->settings->irq_config.clear_on_read.addr) {
21847e906103SLorenzo Bianconi 			reg = &hw->settings->irq_config.clear_on_read;
218522ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
21867e906103SLorenzo Bianconi 					reg->addr, reg->mask,
21877e906103SLorenzo Bianconi 					ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
218822ea5651SLorenzo Bianconi 			if (err < 0)
218922ea5651SLorenzo Bianconi 				return err;
219022ea5651SLorenzo Bianconi 		}
21919db02d32SLorenzo Bianconi 	}
21929db02d32SLorenzo Bianconi 
2193960506edSLorenzo Bianconi 	/* enable drdy-mas if available */
2194960506edSLorenzo Bianconi 	if (hw->settings->drdy_mask.addr) {
2195960506edSLorenzo Bianconi 		reg = &hw->settings->drdy_mask;
2196960506edSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2197960506edSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2198960506edSLorenzo Bianconi 		if (err < 0)
2199960506edSLorenzo Bianconi 			return err;
2200960506edSLorenzo Bianconi 	}
2201960506edSLorenzo Bianconi 
2202c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
2203c91c1c84SLorenzo Bianconi 	if (err < 0)
2204c91c1c84SLorenzo Bianconi 		return err;
2205c91c1c84SLorenzo Bianconi 
220621345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
2207290a6ce1SLorenzo Bianconi }
2208290a6ce1SLorenzo Bianconi 
2209290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
2210510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
2211510c0106SLorenzo Bianconi 					       const char *name)
2212290a6ce1SLorenzo Bianconi {
2213290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2214290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
2215290a6ce1SLorenzo Bianconi 
2216290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
2217290a6ce1SLorenzo Bianconi 	if (!iio_dev)
2218290a6ce1SLorenzo Bianconi 		return NULL;
2219290a6ce1SLorenzo Bianconi 
2220290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
2221290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2222f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
2223f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
2224290a6ce1SLorenzo Bianconi 
2225290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
2226290a6ce1SLorenzo Bianconi 	sensor->id = id;
2227290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
2228f8710f03SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz;
2229640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
2230290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
2231290a6ce1SLorenzo Bianconi 
2232290a6ce1SLorenzo Bianconi 	switch (id) {
2233290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
2234290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
2235510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
2236510c0106SLorenzo Bianconi 			  name);
2237290a6ce1SLorenzo Bianconi 		break;
2238290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
2239290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
2240510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
2241510c0106SLorenzo Bianconi 			  name);
2242290a6ce1SLorenzo Bianconi 		break;
2243290a6ce1SLorenzo Bianconi 	default:
2244290a6ce1SLorenzo Bianconi 		return NULL;
2245290a6ce1SLorenzo Bianconi 	}
2246510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
2247290a6ce1SLorenzo Bianconi 
2248290a6ce1SLorenzo Bianconi 	return iio_dev;
2249290a6ce1SLorenzo Bianconi }
2250290a6ce1SLorenzo Bianconi 
2251615bd378SLorenzo Bianconi static bool
2252615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
22531aabad1fSSean Nyekjaer {
2254615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
2255615bd378SLorenzo Bianconi 	int err, data;
2256615bd378SLorenzo Bianconi 	s64 timestamp;
22571aabad1fSSean Nyekjaer 
2258615bd378SLorenzo Bianconi 	if (!hw->enable_event)
2259615bd378SLorenzo Bianconi 		return false;
2260615bd378SLorenzo Bianconi 
2261615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
2262615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2263615bd378SLorenzo Bianconi 				     &data, sizeof(data));
2264615bd378SLorenzo Bianconi 	if (err < 0)
2265615bd378SLorenzo Bianconi 		return false;
2266615bd378SLorenzo Bianconi 
2267615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
22681aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
22691aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
22701aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
22711aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
22721aabad1fSSean Nyekjaer 						  0,
22731aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
22741aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
22751aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
22761aabad1fSSean Nyekjaer 						  timestamp);
22771aabad1fSSean Nyekjaer 
22781aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
22791aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
22801aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
22811aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
22821aabad1fSSean Nyekjaer 						  0,
22831aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
22841aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
22851aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
22861aabad1fSSean Nyekjaer 						  timestamp);
22871aabad1fSSean Nyekjaer 
22881aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
22891aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
22901aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
22911aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
22921aabad1fSSean Nyekjaer 						  0,
22931aabad1fSSean Nyekjaer 						  IIO_MOD_X,
22941aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
22951aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
22961aabad1fSSean Nyekjaer 						  timestamp);
2297615bd378SLorenzo Bianconi 
2298615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
22991aabad1fSSean Nyekjaer }
23001aabad1fSSean Nyekjaer 
23016ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
23026ee6a368SSean Nyekjaer {
23036ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
23043f9bce7aSLorenzo Bianconi 	int fifo_len = 0, len;
2305615bd378SLorenzo Bianconi 	bool event;
23061aabad1fSSean Nyekjaer 
2307615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
23086ee6a368SSean Nyekjaer 
2309a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
2310a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
2311a912ee4cSLorenzo Bianconi 
23123f9bce7aSLorenzo Bianconi 	/*
23133f9bce7aSLorenzo Bianconi 	 * If we are using edge IRQs, new samples can arrive while
23143f9bce7aSLorenzo Bianconi 	 * processing current interrupt since there are no hw
23153f9bce7aSLorenzo Bianconi 	 * guarantees the irq line stays "low" long enough to properly
23163f9bce7aSLorenzo Bianconi 	 * detect the new interrupt. In this case the new sample will
23173f9bce7aSLorenzo Bianconi 	 * be missed.
23183f9bce7aSLorenzo Bianconi 	 * Polling FIFO status register allow us to read new
23193f9bce7aSLorenzo Bianconi 	 * samples even if the interrupt arrives while processing
23203f9bce7aSLorenzo Bianconi 	 * previous data and the timeslot where the line is "low" is
23213f9bce7aSLorenzo Bianconi 	 * too short to be properly detected.
23223f9bce7aSLorenzo Bianconi 	 */
23233f9bce7aSLorenzo Bianconi 	do {
23246ee6a368SSean Nyekjaer 		mutex_lock(&hw->fifo_lock);
23253f9bce7aSLorenzo Bianconi 		len = hw->settings->fifo_ops.read_fifo(hw);
23266ee6a368SSean Nyekjaer 		mutex_unlock(&hw->fifo_lock);
23276ee6a368SSean Nyekjaer 
23283f9bce7aSLorenzo Bianconi 		if (len > 0)
23293f9bce7aSLorenzo Bianconi 			fifo_len += len;
23303f9bce7aSLorenzo Bianconi 	} while (len > 0);
23313f9bce7aSLorenzo Bianconi 
23323f9bce7aSLorenzo Bianconi 	return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
23336ee6a368SSean Nyekjaer }
23346ee6a368SSean Nyekjaer 
23352cfb2180SLorenzo Bianconi static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq,
23362cfb2180SLorenzo Bianconi 							void *private)
23372cfb2180SLorenzo Bianconi {
23382cfb2180SLorenzo Bianconi 	struct iio_poll_func *pf = private;
23392cfb2180SLorenzo Bianconi 	struct iio_dev *iio_dev = pf->indio_dev;
23402cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
23412cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
23422cfb2180SLorenzo Bianconi 
23432cfb2180SLorenzo Bianconi 	if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
23442cfb2180SLorenzo Bianconi 	    sensor->id == ST_LSM6DSX_ID_EXT1 ||
23452cfb2180SLorenzo Bianconi 	    sensor->id == ST_LSM6DSX_ID_EXT2)
23462cfb2180SLorenzo Bianconi 		st_lsm6dsx_shub_read_output(hw,
23472cfb2180SLorenzo Bianconi 					    (u8 *)hw->scan[sensor->id].channels,
23482cfb2180SLorenzo Bianconi 					    sizeof(hw->scan[sensor->id].channels));
23492cfb2180SLorenzo Bianconi 	else
23502cfb2180SLorenzo Bianconi 		st_lsm6dsx_read_locked(hw, iio_dev->channels[0].address,
23512cfb2180SLorenzo Bianconi 				       hw->scan[sensor->id].channels,
23522cfb2180SLorenzo Bianconi 				       sizeof(hw->scan[sensor->id].channels));
23532cfb2180SLorenzo Bianconi 
23542cfb2180SLorenzo Bianconi 	iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan[sensor->id],
23552cfb2180SLorenzo Bianconi 					   iio_get_time_ns(iio_dev));
23562cfb2180SLorenzo Bianconi 	iio_trigger_notify_done(iio_dev->trig);
23572cfb2180SLorenzo Bianconi 
23582cfb2180SLorenzo Bianconi 	return IRQ_HANDLED;
23592cfb2180SLorenzo Bianconi }
23602cfb2180SLorenzo Bianconi 
23616ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
23626ee6a368SSean Nyekjaer {
236331fe8d4eSLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
236431fe8d4eSLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
236503d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
23666ee6a368SSean Nyekjaer 	unsigned long irq_type;
23676ee6a368SSean Nyekjaer 	bool irq_active_low;
23686ee6a368SSean Nyekjaer 	int err;
23696ee6a368SSean Nyekjaer 
23706ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
23716ee6a368SSean Nyekjaer 
23726ee6a368SSean Nyekjaer 	switch (irq_type) {
23736ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
23746ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
23756ee6a368SSean Nyekjaer 		irq_active_low = false;
23766ee6a368SSean Nyekjaer 		break;
23776ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
23786ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
23796ee6a368SSean Nyekjaer 		irq_active_low = true;
23806ee6a368SSean Nyekjaer 		break;
23816ee6a368SSean Nyekjaer 	default:
23826ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
23836ee6a368SSean Nyekjaer 		return -EINVAL;
23846ee6a368SSean Nyekjaer 	}
23856ee6a368SSean Nyekjaer 
238631fe8d4eSLorenzo Bianconi 	reg = &hw->settings->irq_config.hla;
238731fe8d4eSLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
238831fe8d4eSLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(irq_active_low,
238931fe8d4eSLorenzo Bianconi 						      reg->mask));
23906ee6a368SSean Nyekjaer 	if (err < 0)
23916ee6a368SSean Nyekjaer 		return err;
23926ee6a368SSean Nyekjaer 
239303d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
239403d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
23956ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
239631fe8d4eSLorenzo Bianconi 		reg = &hw->settings->irq_config.od;
239731fe8d4eSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
239831fe8d4eSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
23996ee6a368SSean Nyekjaer 		if (err < 0)
24006ee6a368SSean Nyekjaer 			return err;
24016ee6a368SSean Nyekjaer 
24026ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
24036ee6a368SSean Nyekjaer 	}
24046ee6a368SSean Nyekjaer 
24056ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
2406a3aa17d4SSean Nyekjaer 					NULL,
24076ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
24086ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
24096ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
24106ee6a368SSean Nyekjaer 	if (err) {
24116ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
24126ee6a368SSean Nyekjaer 			hw->irq);
24136ee6a368SSean Nyekjaer 		return err;
24146ee6a368SSean Nyekjaer 	}
24156ee6a368SSean Nyekjaer 
24166ee6a368SSean Nyekjaer 	return 0;
24176ee6a368SSean Nyekjaer }
24186ee6a368SSean Nyekjaer 
24192cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev)
24202cfb2180SLorenzo Bianconi {
24212cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
24222cfb2180SLorenzo Bianconi 
24232cfb2180SLorenzo Bianconi 	return st_lsm6dsx_device_set_enable(sensor, true);
24242cfb2180SLorenzo Bianconi }
24252cfb2180SLorenzo Bianconi 
24262cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev)
24272cfb2180SLorenzo Bianconi {
24282cfb2180SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
24292cfb2180SLorenzo Bianconi 
24302cfb2180SLorenzo Bianconi 	return st_lsm6dsx_device_set_enable(sensor, false);
24312cfb2180SLorenzo Bianconi }
24322cfb2180SLorenzo Bianconi 
24332cfb2180SLorenzo Bianconi static const struct iio_buffer_setup_ops st_lsm6dsx_sw_buffer_ops = {
24342cfb2180SLorenzo Bianconi 	.preenable = st_lsm6dsx_sw_buffer_preenable,
24352cfb2180SLorenzo Bianconi 	.postdisable = st_lsm6dsx_sw_buffer_postdisable,
24362cfb2180SLorenzo Bianconi };
24372cfb2180SLorenzo Bianconi 
24382cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw *hw)
24392cfb2180SLorenzo Bianconi {
24402cfb2180SLorenzo Bianconi 	int i;
24412cfb2180SLorenzo Bianconi 
24422cfb2180SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
24432cfb2180SLorenzo Bianconi 		int err;
24442cfb2180SLorenzo Bianconi 
24452cfb2180SLorenzo Bianconi 		if (!hw->iio_devs[i])
24462cfb2180SLorenzo Bianconi 			continue;
24472cfb2180SLorenzo Bianconi 
24482cfb2180SLorenzo Bianconi 		err = devm_iio_triggered_buffer_setup(hw->dev,
24492cfb2180SLorenzo Bianconi 					hw->iio_devs[i], NULL,
24502cfb2180SLorenzo Bianconi 					st_lsm6dsx_sw_trigger_handler_thread,
24512cfb2180SLorenzo Bianconi 					&st_lsm6dsx_sw_buffer_ops);
24522cfb2180SLorenzo Bianconi 		if (err)
24532cfb2180SLorenzo Bianconi 			return err;
24542cfb2180SLorenzo Bianconi 	}
24552cfb2180SLorenzo Bianconi 
24562cfb2180SLorenzo Bianconi 	return 0;
24572cfb2180SLorenzo Bianconi }
24582cfb2180SLorenzo Bianconi 
2459f346b16fSLorenzo Bianconi static int st_lsm6dsx_init_regulators(struct device *dev)
2460f346b16fSLorenzo Bianconi {
24616900cdbfSMatti Vaittinen 	/* vdd-vddio power regulators */
24626900cdbfSMatti Vaittinen 	static const char * const regulators[] = { "vdd", "vddio" };
2463f346b16fSLorenzo Bianconi 	int err;
2464f346b16fSLorenzo Bianconi 
24656900cdbfSMatti Vaittinen 	err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),
24666900cdbfSMatti Vaittinen 					     regulators);
2467f346b16fSLorenzo Bianconi 	if (err)
24686900cdbfSMatti Vaittinen 		return dev_err_probe(dev, err, "failed to enable regulators\n");
2469f346b16fSLorenzo Bianconi 
2470f346b16fSLorenzo Bianconi 	msleep(50);
2471f346b16fSLorenzo Bianconi 
2472f346b16fSLorenzo Bianconi 	return 0;
2473f346b16fSLorenzo Bianconi }
2474f346b16fSLorenzo Bianconi 
247581956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
247651a8b707SLorenzo Bianconi 		     struct regmap *regmap)
2477290a6ce1SLorenzo Bianconi {
2478b7a73b33SLorenzo Bianconi 	struct st_sensors_platform_data *pdata = dev->platform_data;
2479c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2480290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
248181956a93SLorenzo Bianconi 	const char *name = NULL;
2482290a6ce1SLorenzo Bianconi 	int i, err;
2483290a6ce1SLorenzo Bianconi 
2484290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
2485290a6ce1SLorenzo Bianconi 	if (!hw)
2486290a6ce1SLorenzo Bianconi 		return -ENOMEM;
2487290a6ce1SLorenzo Bianconi 
2488290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
2489290a6ce1SLorenzo Bianconi 
2490290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
2491335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
2492739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
2493290a6ce1SLorenzo Bianconi 
2494f346b16fSLorenzo Bianconi 	err = st_lsm6dsx_init_regulators(dev);
2495f346b16fSLorenzo Bianconi 	if (err)
2496f346b16fSLorenzo Bianconi 		return err;
2497f346b16fSLorenzo Bianconi 
249891a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
249991a6b841SLorenzo Bianconi 	if (!hw->buff)
250091a6b841SLorenzo Bianconi 		return -ENOMEM;
250191a6b841SLorenzo Bianconi 
2502290a6ce1SLorenzo Bianconi 	hw->dev = dev;
2503290a6ce1SLorenzo Bianconi 	hw->irq = irq;
250451a8b707SLorenzo Bianconi 	hw->regmap = regmap;
2505290a6ce1SLorenzo Bianconi 
250681956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
2507290a6ce1SLorenzo Bianconi 	if (err < 0)
2508290a6ce1SLorenzo Bianconi 		return err;
2509290a6ce1SLorenzo Bianconi 
25106ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
2511510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
2512290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
2513290a6ce1SLorenzo Bianconi 			return -ENOMEM;
2514290a6ce1SLorenzo Bianconi 	}
2515290a6ce1SLorenzo Bianconi 
2516290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
2517290a6ce1SLorenzo Bianconi 	if (err < 0)
2518290a6ce1SLorenzo Bianconi 		return err;
2519290a6ce1SLorenzo Bianconi 
2520c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
252135619155SLorenzo Bianconi 	if (hub_settings->master_en.addr &&
252235619155SLorenzo Bianconi 	    (!dev_fwnode(dev) ||
252335619155SLorenzo Bianconi 	     !device_property_read_bool(dev, "st,disable-sensor-hub"))) {
2524c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
2525c91c1c84SLorenzo Bianconi 		if (err < 0)
2526c91c1c84SLorenzo Bianconi 			return err;
2527c91c1c84SLorenzo Bianconi 	}
2528c91c1c84SLorenzo Bianconi 
2529290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
25306ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
25316ee6a368SSean Nyekjaer 		if (err < 0)
25326ee6a368SSean Nyekjaer 			return err;
25336ee6a368SSean Nyekjaer 
2534290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
2535290a6ce1SLorenzo Bianconi 		if (err < 0)
2536290a6ce1SLorenzo Bianconi 			return err;
2537290a6ce1SLorenzo Bianconi 	}
2538290a6ce1SLorenzo Bianconi 
25392cfb2180SLorenzo Bianconi 	if (!hw->irq || !hw->settings->fifo_ops.read_fifo) {
25402cfb2180SLorenzo Bianconi 		/*
25412cfb2180SLorenzo Bianconi 		 * Rely on sw triggers (e.g. hr-timers) if irq pin is not
25422cfb2180SLorenzo Bianconi 		 * connected of if the device does not support HW FIFO
25432cfb2180SLorenzo Bianconi 		 */
25442cfb2180SLorenzo Bianconi 		err = st_lsm6dsx_sw_buffers_setup(hw);
25452cfb2180SLorenzo Bianconi 		if (err)
25462cfb2180SLorenzo Bianconi 			return err;
25472cfb2180SLorenzo Bianconi 	}
25482cfb2180SLorenzo Bianconi 
2549b892770aSAndy Shevchenko 	err = iio_read_mount_matrix(hw->dev, &hw->orientation);
255004e6fedbSMartin Kepplinger 	if (err)
255104e6fedbSMartin Kepplinger 		return err;
255204e6fedbSMartin Kepplinger 
2553290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
25546ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
25556ffb55e5SLorenzo Bianconi 			continue;
25566ffb55e5SLorenzo Bianconi 
2557290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
2558290a6ce1SLorenzo Bianconi 		if (err)
2559290a6ce1SLorenzo Bianconi 			return err;
2560290a6ce1SLorenzo Bianconi 	}
2561290a6ce1SLorenzo Bianconi 
256203d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
2563b7a73b33SLorenzo Bianconi 	    (pdata && pdata->wakeup_source))
25644c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
25654c997dfaSSean Nyekjaer 
2566290a6ce1SLorenzo Bianconi 	return 0;
2567290a6ce1SLorenzo Bianconi }
25682b059449SJonathan Cameron EXPORT_SYMBOL_NS(st_lsm6dsx_probe, IIO_LSM6DSX);
2569290a6ce1SLorenzo Bianconi 
2570acc416ffSJonathan Cameron static int st_lsm6dsx_suspend(struct device *dev)
2571d3f77058SLorenzo Bianconi {
2572d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2573d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2574d3f77058SLorenzo Bianconi 	int i, err = 0;
2575d3f77058SLorenzo Bianconi 
2576d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
25776ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
25786ffb55e5SLorenzo Bianconi 			continue;
25796ffb55e5SLorenzo Bianconi 
2580d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
2581d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
2582d3f77058SLorenzo Bianconi 			continue;
2583d3f77058SLorenzo Bianconi 
25844c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
25854c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
25864c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
25874c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
25884c997dfaSSean Nyekjaer 			continue;
25894c997dfaSSean Nyekjaer 		}
25904c997dfaSSean Nyekjaer 
2591cd83c5c1SLorenzo Bianconi 		err = st_lsm6dsx_device_set_enable(sensor, false);
2592d3f77058SLorenzo Bianconi 		if (err < 0)
2593d3f77058SLorenzo Bianconi 			return err;
2594bce0d57dSLorenzo Bianconi 
2595bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2596d3f77058SLorenzo Bianconi 	}
2597d3f77058SLorenzo Bianconi 
2598c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2599d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2600d3f77058SLorenzo Bianconi 
2601d3f77058SLorenzo Bianconi 	return err;
2602d3f77058SLorenzo Bianconi }
2603d3f77058SLorenzo Bianconi 
2604acc416ffSJonathan Cameron static int st_lsm6dsx_resume(struct device *dev)
2605d3f77058SLorenzo Bianconi {
2606d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2607d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2608d3f77058SLorenzo Bianconi 	int i, err = 0;
2609d3f77058SLorenzo Bianconi 
2610d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
26116ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
26126ffb55e5SLorenzo Bianconi 			continue;
26136ffb55e5SLorenzo Bianconi 
2614d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
26154c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
26164c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
26174c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
26184c997dfaSSean Nyekjaer 
2619bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2620d3f77058SLorenzo Bianconi 			continue;
2621d3f77058SLorenzo Bianconi 
2622cd83c5c1SLorenzo Bianconi 		err = st_lsm6dsx_device_set_enable(sensor, true);
2623d3f77058SLorenzo Bianconi 		if (err < 0)
2624d3f77058SLorenzo Bianconi 			return err;
2625bce0d57dSLorenzo Bianconi 
2626bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2627d3f77058SLorenzo Bianconi 	}
2628d3f77058SLorenzo Bianconi 
2629c2686eb2SLorenzo Bianconi 	if (hw->fifo_mask)
2630a1bab939SLorenzo Bianconi 		err = st_lsm6dsx_resume_fifo(hw);
2631d3f77058SLorenzo Bianconi 
2632d3f77058SLorenzo Bianconi 	return err;
2633d3f77058SLorenzo Bianconi }
2634d3f77058SLorenzo Bianconi 
26352b059449SJonathan Cameron EXPORT_NS_SIMPLE_DEV_PM_OPS(st_lsm6dsx_pm_ops, st_lsm6dsx_suspend,
26362b059449SJonathan Cameron 			    st_lsm6dsx_resume, IIO_LSM6DSX);
2637d3f77058SLorenzo Bianconi 
2638290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2639290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2640290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2641290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2642