1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2290a6ce1SLorenzo Bianconi /*
3290a6ce1SLorenzo Bianconi  * STMicroelectronics st_lsm6dsx sensor driver
4290a6ce1SLorenzo Bianconi  *
5290a6ce1SLorenzo Bianconi  * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer
6290a6ce1SLorenzo Bianconi  * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial
7290a6ce1SLorenzo Bianconi  * interface standard output.
8290a6ce1SLorenzo Bianconi  * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale
9290a6ce1SLorenzo Bianconi  * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of
10290a6ce1SLorenzo Bianconi  * +-125/+-245/+-500/+-1000/+-2000 dps
11290a6ce1SLorenzo Bianconi  * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
12290a6ce1SLorenzo Bianconi  * allowing dynamic batching of sensor data.
1352f4b1f1SMartin Kepplinger  * LSM9DSx series is similar but includes an additional magnetometer, handled
1452f4b1f1SMartin Kepplinger  * by a different driver.
15290a6ce1SLorenzo Bianconi  *
16290a6ce1SLorenzo Bianconi  * Supported sensors:
17290a6ce1SLorenzo Bianconi  * - LSM6DS3:
18290a6ce1SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
19290a6ce1SLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
20290a6ce1SLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
21290a6ce1SLorenzo Bianconi  *   - FIFO size: 8KB
22290a6ce1SLorenzo Bianconi  *
23dbcd2088SLorenzo Bianconi  * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
24290a6ce1SLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
25290a6ce1SLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
26290a6ce1SLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
27290a6ce1SLorenzo Bianconi  *   - FIFO size: 4KB
28290a6ce1SLorenzo Bianconi  *
29db947a79SLorenzo Bianconi  * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX:
30801a6e0aSLorenzo Bianconi  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
31801a6e0aSLorenzo Bianconi  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
32801a6e0aSLorenzo Bianconi  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
33801a6e0aSLorenzo Bianconi  *   - FIFO size: 3KB
34801a6e0aSLorenzo Bianconi  *
3552f4b1f1SMartin Kepplinger  * - LSM9DS1:
3652f4b1f1SMartin Kepplinger  *   - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
3752f4b1f1SMartin Kepplinger  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
3852f4b1f1SMartin Kepplinger  *   - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
3952f4b1f1SMartin Kepplinger  *   - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
4052f4b1f1SMartin Kepplinger  *   - FIFO size: 32
4152f4b1f1SMartin Kepplinger  *
42290a6ce1SLorenzo Bianconi  * Copyright 2016 STMicroelectronics Inc.
43290a6ce1SLorenzo Bianconi  *
44290a6ce1SLorenzo Bianconi  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
45290a6ce1SLorenzo Bianconi  * Denis Ciocca <denis.ciocca@st.com>
46290a6ce1SLorenzo Bianconi  */
47290a6ce1SLorenzo Bianconi 
48290a6ce1SLorenzo Bianconi #include <linux/kernel.h>
49290a6ce1SLorenzo Bianconi #include <linux/module.h>
50290a6ce1SLorenzo Bianconi #include <linux/delay.h>
511aabad1fSSean Nyekjaer #include <linux/iio/events.h>
52290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h>
53290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h>
546ee6a368SSean Nyekjaer #include <linux/interrupt.h>
556ee6a368SSean Nyekjaer #include <linux/irq.h>
56d3f77058SLorenzo Bianconi #include <linux/pm.h>
5751a8b707SLorenzo Bianconi #include <linux/regmap.h>
5851a8b707SLorenzo Bianconi #include <linux/bitfield.h>
59290a6ce1SLorenzo Bianconi 
60dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h>
61dba32904SLorenzo Bianconi 
62290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h"
63290a6ce1SLorenzo Bianconi 
64290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
65290a6ce1SLorenzo Bianconi 
66cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
67cb3b6b8eSMario Tesi 
68f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
69b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
70b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
71b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
72f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
73f48bc49bSLorenzo Bianconi };
74f48bc49bSLorenzo Bianconi 
75f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
76f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
77f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
78f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
79f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
80f48bc49bSLorenzo Bianconi };
81f48bc49bSLorenzo Bianconi 
8252f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
8352f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
8452f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
8552f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
8652f4b1f1SMartin Kepplinger 	IIO_CHAN_SOFT_TIMESTAMP(3),
8752f4b1f1SMartin Kepplinger };
8852f4b1f1SMartin Kepplinger 
89290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
90290a6ce1SLorenzo Bianconi 	{
9152f4b1f1SMartin Kepplinger 		.wai = 0x68,
9266b662a1SLorenzo Bianconi 		.reset = {
9366b662a1SLorenzo Bianconi 			.addr = 0x22,
9466b662a1SLorenzo Bianconi 			.mask = BIT(0),
9566b662a1SLorenzo Bianconi 		},
9666b662a1SLorenzo Bianconi 		.boot = {
9766b662a1SLorenzo Bianconi 			.addr = 0x22,
9866b662a1SLorenzo Bianconi 			.mask = BIT(7),
9966b662a1SLorenzo Bianconi 		},
10066b662a1SLorenzo Bianconi 		.bdu = {
10166b662a1SLorenzo Bianconi 			.addr = 0x22,
10266b662a1SLorenzo Bianconi 			.mask = BIT(6),
10366b662a1SLorenzo Bianconi 		},
10452f4b1f1SMartin Kepplinger 		.max_fifo_size = 32,
10552f4b1f1SMartin Kepplinger 		.id = {
10652f4b1f1SMartin Kepplinger 			{
10752f4b1f1SMartin Kepplinger 				.hw_id = ST_LSM9DS1_ID,
10852f4b1f1SMartin Kepplinger 				.name = ST_LSM9DS1_DEV_NAME,
10952f4b1f1SMartin Kepplinger 			},
11052f4b1f1SMartin Kepplinger 		},
11152f4b1f1SMartin Kepplinger 		.channels = {
11252f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
11352f4b1f1SMartin Kepplinger 				.chan = st_lsm6dsx_acc_channels,
11452f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
11552f4b1f1SMartin Kepplinger 			},
11652f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
11752f4b1f1SMartin Kepplinger 				.chan = st_lsm6ds0_gyro_channels,
11852f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
11952f4b1f1SMartin Kepplinger 			},
12052f4b1f1SMartin Kepplinger 		},
12152f4b1f1SMartin Kepplinger 		.odr_table = {
12252f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
12352f4b1f1SMartin Kepplinger 				.reg = {
12452f4b1f1SMartin Kepplinger 					.addr = 0x20,
12552f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
12652f4b1f1SMartin Kepplinger 				},
12752f4b1f1SMartin Kepplinger 				.odr_avl[0] = {  10, 0x01 },
12852f4b1f1SMartin Kepplinger 				.odr_avl[1] = {  50, 0x02 },
12952f4b1f1SMartin Kepplinger 				.odr_avl[2] = { 119, 0x03 },
13052f4b1f1SMartin Kepplinger 				.odr_avl[3] = { 238, 0x04 },
13152f4b1f1SMartin Kepplinger 				.odr_avl[4] = { 476, 0x05 },
13252f4b1f1SMartin Kepplinger 				.odr_avl[5] = { 952, 0x06 },
13352f4b1f1SMartin Kepplinger 			},
13452f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
13552f4b1f1SMartin Kepplinger 				.reg = {
13652f4b1f1SMartin Kepplinger 					.addr = 0x10,
13752f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
13852f4b1f1SMartin Kepplinger 				},
13952f4b1f1SMartin Kepplinger 				.odr_avl[0] = {  15, 0x01 },
14052f4b1f1SMartin Kepplinger 				.odr_avl[1] = {  60, 0x02 },
14152f4b1f1SMartin Kepplinger 				.odr_avl[2] = { 119, 0x03 },
14252f4b1f1SMartin Kepplinger 				.odr_avl[3] = { 238, 0x04 },
14352f4b1f1SMartin Kepplinger 				.odr_avl[4] = { 476, 0x05 },
14452f4b1f1SMartin Kepplinger 				.odr_avl[5] = { 952, 0x06 },
14552f4b1f1SMartin Kepplinger 			},
14652f4b1f1SMartin Kepplinger 		},
14752f4b1f1SMartin Kepplinger 		.fs_table = {
14852f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
14952f4b1f1SMartin Kepplinger 				.reg = {
15052f4b1f1SMartin Kepplinger 					.addr = 0x20,
15152f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
15252f4b1f1SMartin Kepplinger 				},
1536fa02948SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
1546fa02948SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
1556fa02948SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
1566fa02948SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
15785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
15852f4b1f1SMartin Kepplinger 			},
15952f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
16052f4b1f1SMartin Kepplinger 				.reg = {
16152f4b1f1SMartin Kepplinger 					.addr = 0x10,
16252f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
16352f4b1f1SMartin Kepplinger 				},
1641b375101SLorenzo Bianconi 
1651b375101SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
1661b375101SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
1671b375101SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
16885ae3aeeSLorenzo Bianconi 				.fs_len = 3,
16952f4b1f1SMartin Kepplinger 			},
17052f4b1f1SMartin Kepplinger 		},
1717e906103SLorenzo Bianconi 		.irq_config = {
1727e906103SLorenzo Bianconi 			.irq1 = {
1737e906103SLorenzo Bianconi 				.addr = 0x0c,
1747e906103SLorenzo Bianconi 				.mask = BIT(3),
1757e906103SLorenzo Bianconi 			},
1767e906103SLorenzo Bianconi 			.irq2 = {
1777e906103SLorenzo Bianconi 				.addr = 0x0d,
1787e906103SLorenzo Bianconi 				.mask = BIT(3),
1797e906103SLorenzo Bianconi 			},
18031fe8d4eSLorenzo Bianconi 			.hla = {
18131fe8d4eSLorenzo Bianconi 				.addr = 0x22,
18231fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
18331fe8d4eSLorenzo Bianconi 			},
18431fe8d4eSLorenzo Bianconi 			.od = {
18531fe8d4eSLorenzo Bianconi 				.addr = 0x22,
18631fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
18731fe8d4eSLorenzo Bianconi 			},
1887e906103SLorenzo Bianconi 		},
18952f4b1f1SMartin Kepplinger 	},
19052f4b1f1SMartin Kepplinger 	{
191d068e4a0SLorenzo Bianconi 		.wai = 0x69,
19266b662a1SLorenzo Bianconi 		.reset = {
19366b662a1SLorenzo Bianconi 			.addr = 0x12,
19466b662a1SLorenzo Bianconi 			.mask = BIT(0),
19566b662a1SLorenzo Bianconi 		},
19666b662a1SLorenzo Bianconi 		.boot = {
19766b662a1SLorenzo Bianconi 			.addr = 0x12,
19866b662a1SLorenzo Bianconi 			.mask = BIT(7),
19966b662a1SLorenzo Bianconi 		},
20066b662a1SLorenzo Bianconi 		.bdu = {
20166b662a1SLorenzo Bianconi 			.addr = 0x12,
20266b662a1SLorenzo Bianconi 			.mask = BIT(6),
20366b662a1SLorenzo Bianconi 		},
2048f2a88a2SLorenzo Bianconi 		.max_fifo_size = 1365,
205d068e4a0SLorenzo Bianconi 		.id = {
20681956a93SLorenzo Bianconi 			{
20781956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3_ID,
20881956a93SLorenzo Bianconi 				.name = ST_LSM6DS3_DEV_NAME,
20981956a93SLorenzo Bianconi 			},
210d068e4a0SLorenzo Bianconi 		},
211f48bc49bSLorenzo Bianconi 		.channels = {
212f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
213f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
214f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
215f48bc49bSLorenzo Bianconi 			},
216f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
217f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
218f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
219f48bc49bSLorenzo Bianconi 			},
220f48bc49bSLorenzo Bianconi 		},
22140dd7343SLorenzo Bianconi 		.odr_table = {
22240dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
22340dd7343SLorenzo Bianconi 				.reg = {
22440dd7343SLorenzo Bianconi 					.addr = 0x10,
22540dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
22640dd7343SLorenzo Bianconi 				},
22740dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
22840dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
22940dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
23040dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
23140dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
23240dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
23340dd7343SLorenzo Bianconi 			},
23440dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
23540dd7343SLorenzo Bianconi 				.reg = {
23640dd7343SLorenzo Bianconi 					.addr = 0x11,
23740dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
23840dd7343SLorenzo Bianconi 				},
23940dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
24040dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
24140dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
24240dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
24340dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
24440dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
24540dd7343SLorenzo Bianconi 			},
24640dd7343SLorenzo Bianconi 		},
247640aca3fSLorenzo Bianconi 		.fs_table = {
248640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
249640aca3fSLorenzo Bianconi 				.reg = {
250640aca3fSLorenzo Bianconi 					.addr = 0x10,
251640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
252640aca3fSLorenzo Bianconi 				},
253640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
254640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
255640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
256640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
25785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
258640aca3fSLorenzo Bianconi 			},
259640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
260640aca3fSLorenzo Bianconi 				.reg = {
261640aca3fSLorenzo Bianconi 					.addr = 0x11,
262640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
263640aca3fSLorenzo Bianconi 				},
264640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
265640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
266640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
267640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
26885ae3aeeSLorenzo Bianconi 				.fs_len = 4,
269640aca3fSLorenzo Bianconi 			},
270640aca3fSLorenzo Bianconi 		},
2717e906103SLorenzo Bianconi 		.irq_config = {
2727e906103SLorenzo Bianconi 			.irq1 = {
2737e906103SLorenzo Bianconi 				.addr = 0x0d,
2747e906103SLorenzo Bianconi 				.mask = BIT(3),
2757e906103SLorenzo Bianconi 			},
2767e906103SLorenzo Bianconi 			.irq2 = {
2777e906103SLorenzo Bianconi 				.addr = 0x0e,
2787e906103SLorenzo Bianconi 				.mask = BIT(3),
2797e906103SLorenzo Bianconi 			},
2807e906103SLorenzo Bianconi 			.lir = {
2817e906103SLorenzo Bianconi 				.addr = 0x58,
2827e906103SLorenzo Bianconi 				.mask = BIT(0),
2837e906103SLorenzo Bianconi 			},
2847e906103SLorenzo Bianconi 			.irq1_func = {
2857e906103SLorenzo Bianconi 				.addr = 0x5e,
2867e906103SLorenzo Bianconi 				.mask = BIT(5),
2877e906103SLorenzo Bianconi 			},
2887e906103SLorenzo Bianconi 			.irq2_func = {
2897e906103SLorenzo Bianconi 				.addr = 0x5f,
2907e906103SLorenzo Bianconi 				.mask = BIT(5),
2917e906103SLorenzo Bianconi 			},
29231fe8d4eSLorenzo Bianconi 			.hla = {
29331fe8d4eSLorenzo Bianconi 				.addr = 0x12,
29431fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
29531fe8d4eSLorenzo Bianconi 			},
29631fe8d4eSLorenzo Bianconi 			.od = {
29731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
29831fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
29931fe8d4eSLorenzo Bianconi 			},
3007e906103SLorenzo Bianconi 		},
3017ca3ac9eSLorenzo Bianconi 		.decimator = {
3027ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
3037ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3047ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
3057ca3ac9eSLorenzo Bianconi 			},
3067ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
3077ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3087ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
3097ca3ac9eSLorenzo Bianconi 			},
3107ca3ac9eSLorenzo Bianconi 		},
31192617c15SLorenzo Bianconi 		.fifo_ops = {
3123b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
31350ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
31492617c15SLorenzo Bianconi 			.fifo_th = {
31592617c15SLorenzo Bianconi 				.addr = 0x06,
31692617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
31792617c15SLorenzo Bianconi 			},
31892617c15SLorenzo Bianconi 			.fifo_diff = {
31992617c15SLorenzo Bianconi 				.addr = 0x3a,
32092617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
32192617c15SLorenzo Bianconi 			},
32292617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
32392617c15SLorenzo Bianconi 		},
32421345107SLorenzo Bianconi 		.ts_settings = {
32521345107SLorenzo Bianconi 			.timer_en = {
32621345107SLorenzo Bianconi 				.addr = 0x58,
32721345107SLorenzo Bianconi 				.mask = BIT(7),
32821345107SLorenzo Bianconi 			},
32921345107SLorenzo Bianconi 			.hr_timer = {
33021345107SLorenzo Bianconi 				.addr = 0x5c,
33121345107SLorenzo Bianconi 				.mask = BIT(4),
33221345107SLorenzo Bianconi 			},
33321345107SLorenzo Bianconi 			.fifo_en = {
33421345107SLorenzo Bianconi 				.addr = 0x07,
33521345107SLorenzo Bianconi 				.mask = BIT(7),
33621345107SLorenzo Bianconi 			},
33721345107SLorenzo Bianconi 			.decimator = {
33821345107SLorenzo Bianconi 				.addr = 0x09,
33921345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
34021345107SLorenzo Bianconi 			},
34121345107SLorenzo Bianconi 		},
342b5969abfSSean Nyekjaer 		.event_settings = {
343b5969abfSSean Nyekjaer 			.wakeup_reg = {
344b5969abfSSean Nyekjaer 				.addr = 0x5B,
345b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
346b5969abfSSean Nyekjaer 			},
3471aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
3481aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
3491aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
3501aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
3511aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
352b5969abfSSean Nyekjaer 		},
353290a6ce1SLorenzo Bianconi 	},
354290a6ce1SLorenzo Bianconi 	{
355df47710aSLorenzo Bianconi 		.wai = 0x69,
35666b662a1SLorenzo Bianconi 		.reset = {
35766b662a1SLorenzo Bianconi 			.addr = 0x12,
35866b662a1SLorenzo Bianconi 			.mask = BIT(0),
35966b662a1SLorenzo Bianconi 		},
36066b662a1SLorenzo Bianconi 		.boot = {
36166b662a1SLorenzo Bianconi 			.addr = 0x12,
36266b662a1SLorenzo Bianconi 			.mask = BIT(7),
36366b662a1SLorenzo Bianconi 		},
36466b662a1SLorenzo Bianconi 		.bdu = {
36566b662a1SLorenzo Bianconi 			.addr = 0x12,
36666b662a1SLorenzo Bianconi 			.mask = BIT(6),
36766b662a1SLorenzo Bianconi 		},
3688f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
369df47710aSLorenzo Bianconi 		.id = {
37081956a93SLorenzo Bianconi 			{
37181956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3H_ID,
37281956a93SLorenzo Bianconi 				.name = ST_LSM6DS3H_DEV_NAME,
37381956a93SLorenzo Bianconi 			},
374df47710aSLorenzo Bianconi 		},
375f48bc49bSLorenzo Bianconi 		.channels = {
376f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
377f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
378f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
379f48bc49bSLorenzo Bianconi 			},
380f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
381f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
382f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
383f48bc49bSLorenzo Bianconi 			},
384f48bc49bSLorenzo Bianconi 		},
38540dd7343SLorenzo Bianconi 		.odr_table = {
38640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
38740dd7343SLorenzo Bianconi 				.reg = {
38840dd7343SLorenzo Bianconi 					.addr = 0x10,
38940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
39040dd7343SLorenzo Bianconi 				},
39140dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
39240dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
39340dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
39440dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
39540dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
39640dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
39740dd7343SLorenzo Bianconi 			},
39840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
39940dd7343SLorenzo Bianconi 				.reg = {
40040dd7343SLorenzo Bianconi 					.addr = 0x11,
40140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
40240dd7343SLorenzo Bianconi 				},
40340dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
40440dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
40540dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
40640dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
40740dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
40840dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
40940dd7343SLorenzo Bianconi 			},
41040dd7343SLorenzo Bianconi 		},
411640aca3fSLorenzo Bianconi 		.fs_table = {
412640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
413640aca3fSLorenzo Bianconi 				.reg = {
414640aca3fSLorenzo Bianconi 					.addr = 0x10,
415640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
416640aca3fSLorenzo Bianconi 				},
417640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
418640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
419640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
420640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
42185ae3aeeSLorenzo Bianconi 				.fs_len = 4,
422640aca3fSLorenzo Bianconi 			},
423640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
424640aca3fSLorenzo Bianconi 				.reg = {
425640aca3fSLorenzo Bianconi 					.addr = 0x11,
426640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
427640aca3fSLorenzo Bianconi 				},
428640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
429640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
430640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
431640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
43285ae3aeeSLorenzo Bianconi 				.fs_len = 4,
433640aca3fSLorenzo Bianconi 			},
434640aca3fSLorenzo Bianconi 		},
4357e906103SLorenzo Bianconi 		.irq_config = {
4367e906103SLorenzo Bianconi 			.irq1 = {
4377e906103SLorenzo Bianconi 				.addr = 0x0d,
4387e906103SLorenzo Bianconi 				.mask = BIT(3),
4397e906103SLorenzo Bianconi 			},
4407e906103SLorenzo Bianconi 			.irq2 = {
4417e906103SLorenzo Bianconi 				.addr = 0x0e,
4427e906103SLorenzo Bianconi 				.mask = BIT(3),
4437e906103SLorenzo Bianconi 			},
4447e906103SLorenzo Bianconi 			.lir = {
4457e906103SLorenzo Bianconi 				.addr = 0x58,
4467e906103SLorenzo Bianconi 				.mask = BIT(0),
4477e906103SLorenzo Bianconi 			},
4487e906103SLorenzo Bianconi 			.irq1_func = {
4497e906103SLorenzo Bianconi 				.addr = 0x5e,
4507e906103SLorenzo Bianconi 				.mask = BIT(5),
4517e906103SLorenzo Bianconi 			},
4527e906103SLorenzo Bianconi 			.irq2_func = {
4537e906103SLorenzo Bianconi 				.addr = 0x5f,
4547e906103SLorenzo Bianconi 				.mask = BIT(5),
4557e906103SLorenzo Bianconi 			},
45631fe8d4eSLorenzo Bianconi 			.hla = {
45731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
45831fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
45931fe8d4eSLorenzo Bianconi 			},
46031fe8d4eSLorenzo Bianconi 			.od = {
46131fe8d4eSLorenzo Bianconi 				.addr = 0x12,
46231fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
46331fe8d4eSLorenzo Bianconi 			},
4647e906103SLorenzo Bianconi 		},
4657ca3ac9eSLorenzo Bianconi 		.decimator = {
4667ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
4677ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4687ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
4697ca3ac9eSLorenzo Bianconi 			},
4707ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
4717ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4727ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
4737ca3ac9eSLorenzo Bianconi 			},
4747ca3ac9eSLorenzo Bianconi 		},
47592617c15SLorenzo Bianconi 		.fifo_ops = {
4763b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
47750ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
47892617c15SLorenzo Bianconi 			.fifo_th = {
47992617c15SLorenzo Bianconi 				.addr = 0x06,
48092617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
48192617c15SLorenzo Bianconi 			},
48292617c15SLorenzo Bianconi 			.fifo_diff = {
48392617c15SLorenzo Bianconi 				.addr = 0x3a,
48492617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
48592617c15SLorenzo Bianconi 			},
48692617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
48792617c15SLorenzo Bianconi 		},
48821345107SLorenzo Bianconi 		.ts_settings = {
48921345107SLorenzo Bianconi 			.timer_en = {
49021345107SLorenzo Bianconi 				.addr = 0x58,
49121345107SLorenzo Bianconi 				.mask = BIT(7),
49221345107SLorenzo Bianconi 			},
49321345107SLorenzo Bianconi 			.hr_timer = {
49421345107SLorenzo Bianconi 				.addr = 0x5c,
49521345107SLorenzo Bianconi 				.mask = BIT(4),
49621345107SLorenzo Bianconi 			},
49721345107SLorenzo Bianconi 			.fifo_en = {
49821345107SLorenzo Bianconi 				.addr = 0x07,
49921345107SLorenzo Bianconi 				.mask = BIT(7),
50021345107SLorenzo Bianconi 			},
50121345107SLorenzo Bianconi 			.decimator = {
50221345107SLorenzo Bianconi 				.addr = 0x09,
50321345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
50421345107SLorenzo Bianconi 			},
50521345107SLorenzo Bianconi 		},
506b5969abfSSean Nyekjaer 		.event_settings = {
507b5969abfSSean Nyekjaer 			.wakeup_reg = {
508b5969abfSSean Nyekjaer 				.addr = 0x5B,
509b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
510b5969abfSSean Nyekjaer 			},
5111aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
5121aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
5131aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
5141aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
5151aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
516b5969abfSSean Nyekjaer 		},
517df47710aSLorenzo Bianconi 	},
518df47710aSLorenzo Bianconi 	{
519d068e4a0SLorenzo Bianconi 		.wai = 0x6a,
52066b662a1SLorenzo Bianconi 		.reset = {
52166b662a1SLorenzo Bianconi 			.addr = 0x12,
52266b662a1SLorenzo Bianconi 			.mask = BIT(0),
52366b662a1SLorenzo Bianconi 		},
52466b662a1SLorenzo Bianconi 		.boot = {
52566b662a1SLorenzo Bianconi 			.addr = 0x12,
52666b662a1SLorenzo Bianconi 			.mask = BIT(7),
52766b662a1SLorenzo Bianconi 		},
52866b662a1SLorenzo Bianconi 		.bdu = {
52966b662a1SLorenzo Bianconi 			.addr = 0x12,
53066b662a1SLorenzo Bianconi 			.mask = BIT(6),
53166b662a1SLorenzo Bianconi 		},
5328f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
533d068e4a0SLorenzo Bianconi 		.id = {
53481956a93SLorenzo Bianconi 			{
53581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSL_ID,
53681956a93SLorenzo Bianconi 				.name = ST_LSM6DSL_DEV_NAME,
53781956a93SLorenzo Bianconi 			}, {
53881956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSM_ID,
53981956a93SLorenzo Bianconi 				.name = ST_LSM6DSM_DEV_NAME,
54081956a93SLorenzo Bianconi 			}, {
54181956a93SLorenzo Bianconi 				.hw_id = ST_ISM330DLC_ID,
54281956a93SLorenzo Bianconi 				.name = ST_ISM330DLC_DEV_NAME,
543dbcd2088SLorenzo Bianconi 			}, {
544dbcd2088SLorenzo Bianconi 				.hw_id = ST_LSM6DS3TRC_ID,
545dbcd2088SLorenzo Bianconi 				.name = ST_LSM6DS3TRC_DEV_NAME,
54681956a93SLorenzo Bianconi 			},
547d068e4a0SLorenzo Bianconi 		},
548f48bc49bSLorenzo Bianconi 		.channels = {
549f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
550f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
551f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
552f48bc49bSLorenzo Bianconi 			},
553f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
554f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
555f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
556f48bc49bSLorenzo Bianconi 			},
557f48bc49bSLorenzo Bianconi 		},
55840dd7343SLorenzo Bianconi 		.odr_table = {
55940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
56040dd7343SLorenzo Bianconi 				.reg = {
56140dd7343SLorenzo Bianconi 					.addr = 0x10,
56240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
56340dd7343SLorenzo Bianconi 				},
56440dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
56540dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
56640dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
56740dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
56840dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
56940dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
57040dd7343SLorenzo Bianconi 			},
57140dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
57240dd7343SLorenzo Bianconi 				.reg = {
57340dd7343SLorenzo Bianconi 					.addr = 0x11,
57440dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
57540dd7343SLorenzo Bianconi 				},
57640dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
57740dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
57840dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
57940dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
58040dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
58140dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
58240dd7343SLorenzo Bianconi 			},
58340dd7343SLorenzo Bianconi 		},
584640aca3fSLorenzo Bianconi 		.fs_table = {
585640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
586640aca3fSLorenzo Bianconi 				.reg = {
587640aca3fSLorenzo Bianconi 					.addr = 0x10,
588640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
589640aca3fSLorenzo Bianconi 				},
590640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
591640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
592640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
593640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
59485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
595640aca3fSLorenzo Bianconi 			},
596640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
597640aca3fSLorenzo Bianconi 				.reg = {
598640aca3fSLorenzo Bianconi 					.addr = 0x11,
599640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
600640aca3fSLorenzo Bianconi 				},
601640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
602640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
603640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
604640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
60585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
606640aca3fSLorenzo Bianconi 			},
607640aca3fSLorenzo Bianconi 		},
6087e906103SLorenzo Bianconi 		.irq_config = {
6097e906103SLorenzo Bianconi 			.irq1 = {
6107e906103SLorenzo Bianconi 				.addr = 0x0d,
6117e906103SLorenzo Bianconi 				.mask = BIT(3),
6127e906103SLorenzo Bianconi 			},
6137e906103SLorenzo Bianconi 			.irq2 = {
6147e906103SLorenzo Bianconi 				.addr = 0x0e,
6157e906103SLorenzo Bianconi 				.mask = BIT(3),
6167e906103SLorenzo Bianconi 			},
6177e906103SLorenzo Bianconi 			.lir = {
6187e906103SLorenzo Bianconi 				.addr = 0x58,
6197e906103SLorenzo Bianconi 				.mask = BIT(0),
6207e906103SLorenzo Bianconi 			},
6217e906103SLorenzo Bianconi 			.irq1_func = {
6227e906103SLorenzo Bianconi 				.addr = 0x5e,
6237e906103SLorenzo Bianconi 				.mask = BIT(5),
6247e906103SLorenzo Bianconi 			},
6257e906103SLorenzo Bianconi 			.irq2_func = {
6267e906103SLorenzo Bianconi 				.addr = 0x5f,
6277e906103SLorenzo Bianconi 				.mask = BIT(5),
6287e906103SLorenzo Bianconi 			},
62931fe8d4eSLorenzo Bianconi 			.hla = {
63031fe8d4eSLorenzo Bianconi 				.addr = 0x12,
63131fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
63231fe8d4eSLorenzo Bianconi 			},
63331fe8d4eSLorenzo Bianconi 			.od = {
63431fe8d4eSLorenzo Bianconi 				.addr = 0x12,
63531fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
63631fe8d4eSLorenzo Bianconi 			},
6377e906103SLorenzo Bianconi 		},
6387ca3ac9eSLorenzo Bianconi 		.decimator = {
6397ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
6407ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6417ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
6427ca3ac9eSLorenzo Bianconi 			},
6437ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
6447ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6457ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
6467ca3ac9eSLorenzo Bianconi 			},
6477ca3ac9eSLorenzo Bianconi 		},
64892617c15SLorenzo Bianconi 		.fifo_ops = {
6493b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
65050ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
65192617c15SLorenzo Bianconi 			.fifo_th = {
65292617c15SLorenzo Bianconi 				.addr = 0x06,
653be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
65492617c15SLorenzo Bianconi 			},
65592617c15SLorenzo Bianconi 			.fifo_diff = {
65692617c15SLorenzo Bianconi 				.addr = 0x3a,
657be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
65892617c15SLorenzo Bianconi 			},
65992617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
66092617c15SLorenzo Bianconi 		},
66121345107SLorenzo Bianconi 		.ts_settings = {
66221345107SLorenzo Bianconi 			.timer_en = {
66321345107SLorenzo Bianconi 				.addr = 0x19,
66421345107SLorenzo Bianconi 				.mask = BIT(5),
66521345107SLorenzo Bianconi 			},
66621345107SLorenzo Bianconi 			.hr_timer = {
66721345107SLorenzo Bianconi 				.addr = 0x5c,
66821345107SLorenzo Bianconi 				.mask = BIT(4),
66921345107SLorenzo Bianconi 			},
67021345107SLorenzo Bianconi 			.fifo_en = {
67121345107SLorenzo Bianconi 				.addr = 0x07,
67221345107SLorenzo Bianconi 				.mask = BIT(7),
67321345107SLorenzo Bianconi 			},
67421345107SLorenzo Bianconi 			.decimator = {
67521345107SLorenzo Bianconi 				.addr = 0x09,
67621345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
67721345107SLorenzo Bianconi 			},
67821345107SLorenzo Bianconi 		},
679b5969abfSSean Nyekjaer 		.event_settings = {
680b5969abfSSean Nyekjaer 			.enable_reg = {
681b5969abfSSean Nyekjaer 				.addr = 0x58,
682b5969abfSSean Nyekjaer 				.mask = BIT(7),
683b5969abfSSean Nyekjaer 			},
684b5969abfSSean Nyekjaer 			.wakeup_reg = {
685b5969abfSSean Nyekjaer 				.addr = 0x5B,
686b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
687b5969abfSSean Nyekjaer 			},
6881aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
6891aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
6901aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
6911aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
6921aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
693b5969abfSSean Nyekjaer 		},
694290a6ce1SLorenzo Bianconi 	},
695801a6e0aSLorenzo Bianconi 	{
696801a6e0aSLorenzo Bianconi 		.wai = 0x6c,
69766b662a1SLorenzo Bianconi 		.reset = {
69866b662a1SLorenzo Bianconi 			.addr = 0x12,
69966b662a1SLorenzo Bianconi 			.mask = BIT(0),
70066b662a1SLorenzo Bianconi 		},
70166b662a1SLorenzo Bianconi 		.boot = {
70266b662a1SLorenzo Bianconi 			.addr = 0x12,
70366b662a1SLorenzo Bianconi 			.mask = BIT(7),
70466b662a1SLorenzo Bianconi 		},
70566b662a1SLorenzo Bianconi 		.bdu = {
70666b662a1SLorenzo Bianconi 			.addr = 0x12,
70766b662a1SLorenzo Bianconi 			.mask = BIT(6),
70866b662a1SLorenzo Bianconi 		},
709801a6e0aSLorenzo Bianconi 		.max_fifo_size = 512,
710801a6e0aSLorenzo Bianconi 		.id = {
71181956a93SLorenzo Bianconi 			{
71281956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSO_ID,
71381956a93SLorenzo Bianconi 				.name = ST_LSM6DSO_DEV_NAME,
71481956a93SLorenzo Bianconi 			}, {
71581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSOX_ID,
71681956a93SLorenzo Bianconi 				.name = ST_LSM6DSOX_DEV_NAME,
71781956a93SLorenzo Bianconi 			},
718801a6e0aSLorenzo Bianconi 		},
719f48bc49bSLorenzo Bianconi 		.channels = {
720f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
721f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
722f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
723f48bc49bSLorenzo Bianconi 			},
724f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
725f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
726f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
727f48bc49bSLorenzo Bianconi 			},
728f48bc49bSLorenzo Bianconi 		},
729960506edSLorenzo Bianconi 		.drdy_mask = {
730960506edSLorenzo Bianconi 			.addr = 0x13,
731960506edSLorenzo Bianconi 			.mask = BIT(3),
732960506edSLorenzo Bianconi 		},
73340dd7343SLorenzo Bianconi 		.odr_table = {
73440dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
73540dd7343SLorenzo Bianconi 				.reg = {
73640dd7343SLorenzo Bianconi 					.addr = 0x10,
73740dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
73840dd7343SLorenzo Bianconi 				},
73940dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
74040dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
74140dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
74240dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
74340dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
74440dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
74540dd7343SLorenzo Bianconi 			},
74640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
74740dd7343SLorenzo Bianconi 				.reg = {
74840dd7343SLorenzo Bianconi 					.addr = 0x11,
74940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
75040dd7343SLorenzo Bianconi 				},
75140dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
75240dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
75340dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
75440dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
75540dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
75640dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
75740dd7343SLorenzo Bianconi 			},
75840dd7343SLorenzo Bianconi 		},
759640aca3fSLorenzo Bianconi 		.fs_table = {
760640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
761640aca3fSLorenzo Bianconi 				.reg = {
762640aca3fSLorenzo Bianconi 					.addr = 0x10,
763640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
764640aca3fSLorenzo Bianconi 				},
765640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
766640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
767640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
768640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
76985ae3aeeSLorenzo Bianconi 				.fs_len = 4,
770640aca3fSLorenzo Bianconi 			},
771640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
772640aca3fSLorenzo Bianconi 				.reg = {
773640aca3fSLorenzo Bianconi 					.addr = 0x11,
774640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
775640aca3fSLorenzo Bianconi 				},
776640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
777640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
778640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
779640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
78085ae3aeeSLorenzo Bianconi 				.fs_len = 4,
781640aca3fSLorenzo Bianconi 			},
782640aca3fSLorenzo Bianconi 		},
7837e906103SLorenzo Bianconi 		.irq_config = {
7847e906103SLorenzo Bianconi 			.irq1 = {
7857e906103SLorenzo Bianconi 				.addr = 0x0d,
7867e906103SLorenzo Bianconi 				.mask = BIT(3),
7877e906103SLorenzo Bianconi 			},
7887e906103SLorenzo Bianconi 			.irq2 = {
7897e906103SLorenzo Bianconi 				.addr = 0x0e,
7907e906103SLorenzo Bianconi 				.mask = BIT(3),
7917e906103SLorenzo Bianconi 			},
7927e906103SLorenzo Bianconi 			.lir = {
7937e906103SLorenzo Bianconi 				.addr = 0x56,
7947e906103SLorenzo Bianconi 				.mask = BIT(0),
7957e906103SLorenzo Bianconi 			},
7967e906103SLorenzo Bianconi 			.clear_on_read = {
7977e906103SLorenzo Bianconi 				.addr = 0x56,
7987e906103SLorenzo Bianconi 				.mask = BIT(6),
7997e906103SLorenzo Bianconi 			},
8003ea39d61SLorenzo Bianconi 			.irq1_func = {
8013ea39d61SLorenzo Bianconi 				.addr = 0x5e,
8023ea39d61SLorenzo Bianconi 				.mask = BIT(5),
8033ea39d61SLorenzo Bianconi 			},
8043ea39d61SLorenzo Bianconi 			.irq2_func = {
8053ea39d61SLorenzo Bianconi 				.addr = 0x5f,
8063ea39d61SLorenzo Bianconi 				.mask = BIT(5),
8073ea39d61SLorenzo Bianconi 			},
80831fe8d4eSLorenzo Bianconi 			.hla = {
80931fe8d4eSLorenzo Bianconi 				.addr = 0x12,
81031fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
81131fe8d4eSLorenzo Bianconi 			},
81231fe8d4eSLorenzo Bianconi 			.od = {
81331fe8d4eSLorenzo Bianconi 				.addr = 0x12,
81431fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
81531fe8d4eSLorenzo Bianconi 			},
8167e906103SLorenzo Bianconi 		},
817801a6e0aSLorenzo Bianconi 		.batch = {
818801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
819801a6e0aSLorenzo Bianconi 				.addr = 0x09,
820801a6e0aSLorenzo Bianconi 				.mask = GENMASK(3, 0),
821801a6e0aSLorenzo Bianconi 			},
822801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
823801a6e0aSLorenzo Bianconi 				.addr = 0x09,
824801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 4),
825801a6e0aSLorenzo Bianconi 			},
826801a6e0aSLorenzo Bianconi 		},
827801a6e0aSLorenzo Bianconi 		.fifo_ops = {
8283b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
829801a6e0aSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
830801a6e0aSLorenzo Bianconi 			.fifo_th = {
831801a6e0aSLorenzo Bianconi 				.addr = 0x07,
832801a6e0aSLorenzo Bianconi 				.mask = GENMASK(8, 0),
833801a6e0aSLorenzo Bianconi 			},
834801a6e0aSLorenzo Bianconi 			.fifo_diff = {
835801a6e0aSLorenzo Bianconi 				.addr = 0x3a,
83670575abeSmario tesi 				.mask = GENMASK(9, 0),
837801a6e0aSLorenzo Bianconi 			},
838801a6e0aSLorenzo Bianconi 			.th_wl = 1,
839801a6e0aSLorenzo Bianconi 		},
840801a6e0aSLorenzo Bianconi 		.ts_settings = {
841801a6e0aSLorenzo Bianconi 			.timer_en = {
842801a6e0aSLorenzo Bianconi 				.addr = 0x19,
843801a6e0aSLorenzo Bianconi 				.mask = BIT(5),
844801a6e0aSLorenzo Bianconi 			},
845801a6e0aSLorenzo Bianconi 			.decimator = {
846801a6e0aSLorenzo Bianconi 				.addr = 0x0a,
847801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 6),
848801a6e0aSLorenzo Bianconi 			},
849cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
850801a6e0aSLorenzo Bianconi 		},
851c91c1c84SLorenzo Bianconi 		.shub_settings = {
852c91c1c84SLorenzo Bianconi 			.page_mux = {
853c91c1c84SLorenzo Bianconi 				.addr = 0x01,
854c91c1c84SLorenzo Bianconi 				.mask = BIT(6),
855c91c1c84SLorenzo Bianconi 			},
856c91c1c84SLorenzo Bianconi 			.master_en = {
857c91c1c84SLorenzo Bianconi 				.addr = 0x14,
858c91c1c84SLorenzo Bianconi 				.mask = BIT(2),
859c91c1c84SLorenzo Bianconi 			},
860c91c1c84SLorenzo Bianconi 			.pullup_en = {
861c91c1c84SLorenzo Bianconi 				.addr = 0x14,
862c91c1c84SLorenzo Bianconi 				.mask = BIT(3),
863c91c1c84SLorenzo Bianconi 			},
864c91c1c84SLorenzo Bianconi 			.aux_sens = {
865c91c1c84SLorenzo Bianconi 				.addr = 0x14,
866c91c1c84SLorenzo Bianconi 				.mask = GENMASK(1, 0),
867c91c1c84SLorenzo Bianconi 			},
8686d0205fdSLorenzo Bianconi 			.wr_once = {
8696d0205fdSLorenzo Bianconi 				.addr = 0x14,
8706d0205fdSLorenzo Bianconi 				.mask = BIT(6),
8716d0205fdSLorenzo Bianconi 			},
872c91c1c84SLorenzo Bianconi 			.shub_out = 0x02,
873c91c1c84SLorenzo Bianconi 			.slv0_addr = 0x15,
874c91c1c84SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
8756d0205fdSLorenzo Bianconi 			.batch_en = BIT(3),
8763ea39d61SLorenzo Bianconi 		},
8773ea39d61SLorenzo Bianconi 		.event_settings = {
8783ea39d61SLorenzo Bianconi 			.enable_reg = {
8793ea39d61SLorenzo Bianconi 				.addr = 0x58,
8803ea39d61SLorenzo Bianconi 				.mask = BIT(7),
8813ea39d61SLorenzo Bianconi 			},
8823ea39d61SLorenzo Bianconi 			.wakeup_reg = {
8833ea39d61SLorenzo Bianconi 				.addr = 0x5b,
8843ea39d61SLorenzo Bianconi 				.mask = GENMASK(5, 0),
8853ea39d61SLorenzo Bianconi 			},
8863ea39d61SLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
8873ea39d61SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
8883ea39d61SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
8893ea39d61SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
8903ea39d61SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
8913ea39d61SLorenzo Bianconi 		},
892801a6e0aSLorenzo Bianconi 	},
8933054c4ffSLorenzo Bianconi 	{
8943054c4ffSLorenzo Bianconi 		.wai = 0x6b,
89566b662a1SLorenzo Bianconi 		.reset = {
89666b662a1SLorenzo Bianconi 			.addr = 0x12,
89766b662a1SLorenzo Bianconi 			.mask = BIT(0),
89866b662a1SLorenzo Bianconi 		},
89966b662a1SLorenzo Bianconi 		.boot = {
90066b662a1SLorenzo Bianconi 			.addr = 0x12,
90166b662a1SLorenzo Bianconi 			.mask = BIT(7),
90266b662a1SLorenzo Bianconi 		},
90366b662a1SLorenzo Bianconi 		.bdu = {
90466b662a1SLorenzo Bianconi 			.addr = 0x12,
90566b662a1SLorenzo Bianconi 			.mask = BIT(6),
90666b662a1SLorenzo Bianconi 		},
9073054c4ffSLorenzo Bianconi 		.max_fifo_size = 512,
9083054c4ffSLorenzo Bianconi 		.id = {
90981956a93SLorenzo Bianconi 			{
91081956a93SLorenzo Bianconi 				.hw_id = ST_ASM330LHH_ID,
91181956a93SLorenzo Bianconi 				.name = ST_ASM330LHH_DEV_NAME,
91281956a93SLorenzo Bianconi 			},
9133054c4ffSLorenzo Bianconi 		},
914f48bc49bSLorenzo Bianconi 		.channels = {
915f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
916f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
917f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
918f48bc49bSLorenzo Bianconi 			},
919f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
920f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
921f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
922f48bc49bSLorenzo Bianconi 			},
923f48bc49bSLorenzo Bianconi 		},
924960506edSLorenzo Bianconi 		.drdy_mask = {
925960506edSLorenzo Bianconi 			.addr = 0x13,
926960506edSLorenzo Bianconi 			.mask = BIT(3),
927960506edSLorenzo Bianconi 		},
92840dd7343SLorenzo Bianconi 		.odr_table = {
92940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
93040dd7343SLorenzo Bianconi 				.reg = {
93140dd7343SLorenzo Bianconi 					.addr = 0x10,
93240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
93340dd7343SLorenzo Bianconi 				},
93440dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
93540dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
93640dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
93740dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
93840dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
93940dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
94040dd7343SLorenzo Bianconi 			},
94140dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
94240dd7343SLorenzo Bianconi 				.reg = {
94340dd7343SLorenzo Bianconi 					.addr = 0x11,
94440dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
94540dd7343SLorenzo Bianconi 				},
94640dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
94740dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
94840dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
94940dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
95040dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
95140dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
95240dd7343SLorenzo Bianconi 			},
95340dd7343SLorenzo Bianconi 		},
954640aca3fSLorenzo Bianconi 		.fs_table = {
955640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
956640aca3fSLorenzo Bianconi 				.reg = {
957640aca3fSLorenzo Bianconi 					.addr = 0x10,
958640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
959640aca3fSLorenzo Bianconi 				},
960640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
961640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
962640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
963640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
96485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
965640aca3fSLorenzo Bianconi 			},
966640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
967640aca3fSLorenzo Bianconi 				.reg = {
968640aca3fSLorenzo Bianconi 					.addr = 0x11,
969640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
970640aca3fSLorenzo Bianconi 				},
971640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
972640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
973640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
974640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
97585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
976640aca3fSLorenzo Bianconi 			},
977640aca3fSLorenzo Bianconi 		},
9787e906103SLorenzo Bianconi 		.irq_config = {
9797e906103SLorenzo Bianconi 			.irq1 = {
9807e906103SLorenzo Bianconi 				.addr = 0x0d,
9817e906103SLorenzo Bianconi 				.mask = BIT(3),
9827e906103SLorenzo Bianconi 			},
9837e906103SLorenzo Bianconi 			.irq2 = {
9847e906103SLorenzo Bianconi 				.addr = 0x0e,
9857e906103SLorenzo Bianconi 				.mask = BIT(3),
9867e906103SLorenzo Bianconi 			},
9877e906103SLorenzo Bianconi 			.lir = {
9887e906103SLorenzo Bianconi 				.addr = 0x56,
9897e906103SLorenzo Bianconi 				.mask = BIT(0),
9907e906103SLorenzo Bianconi 			},
9917e906103SLorenzo Bianconi 			.clear_on_read = {
9927e906103SLorenzo Bianconi 				.addr = 0x56,
9937e906103SLorenzo Bianconi 				.mask = BIT(6),
9947e906103SLorenzo Bianconi 			},
9957e906103SLorenzo Bianconi 			.irq1_func = {
9967e906103SLorenzo Bianconi 				.addr = 0x5e,
9977e906103SLorenzo Bianconi 				.mask = BIT(5),
9987e906103SLorenzo Bianconi 			},
9997e906103SLorenzo Bianconi 			.irq2_func = {
10007e906103SLorenzo Bianconi 				.addr = 0x5f,
10017e906103SLorenzo Bianconi 				.mask = BIT(5),
10027e906103SLorenzo Bianconi 			},
100331fe8d4eSLorenzo Bianconi 			.hla = {
100431fe8d4eSLorenzo Bianconi 				.addr = 0x12,
100531fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
100631fe8d4eSLorenzo Bianconi 			},
100731fe8d4eSLorenzo Bianconi 			.od = {
100831fe8d4eSLorenzo Bianconi 				.addr = 0x12,
100931fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
101031fe8d4eSLorenzo Bianconi 			},
10117e906103SLorenzo Bianconi 		},
10123054c4ffSLorenzo Bianconi 		.batch = {
10133054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
10143054c4ffSLorenzo Bianconi 				.addr = 0x09,
10153054c4ffSLorenzo Bianconi 				.mask = GENMASK(3, 0),
10163054c4ffSLorenzo Bianconi 			},
10173054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
10183054c4ffSLorenzo Bianconi 				.addr = 0x09,
10193054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 4),
10203054c4ffSLorenzo Bianconi 			},
10213054c4ffSLorenzo Bianconi 		},
10223054c4ffSLorenzo Bianconi 		.fifo_ops = {
10233b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
10243054c4ffSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
10253054c4ffSLorenzo Bianconi 			.fifo_th = {
10263054c4ffSLorenzo Bianconi 				.addr = 0x07,
10273054c4ffSLorenzo Bianconi 				.mask = GENMASK(8, 0),
10283054c4ffSLorenzo Bianconi 			},
10293054c4ffSLorenzo Bianconi 			.fifo_diff = {
10303054c4ffSLorenzo Bianconi 				.addr = 0x3a,
103170575abeSmario tesi 				.mask = GENMASK(9, 0),
10323054c4ffSLorenzo Bianconi 			},
10333054c4ffSLorenzo Bianconi 			.th_wl = 1,
10343054c4ffSLorenzo Bianconi 		},
10353054c4ffSLorenzo Bianconi 		.ts_settings = {
10363054c4ffSLorenzo Bianconi 			.timer_en = {
10373054c4ffSLorenzo Bianconi 				.addr = 0x19,
10383054c4ffSLorenzo Bianconi 				.mask = BIT(5),
10393054c4ffSLorenzo Bianconi 			},
10403054c4ffSLorenzo Bianconi 			.decimator = {
10413054c4ffSLorenzo Bianconi 				.addr = 0x0a,
10423054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 6),
10433054c4ffSLorenzo Bianconi 			},
1044cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
10453054c4ffSLorenzo Bianconi 		},
1046b5969abfSSean Nyekjaer 		.event_settings = {
1047b5969abfSSean Nyekjaer 			.enable_reg = {
1048b5969abfSSean Nyekjaer 				.addr = 0x58,
1049b5969abfSSean Nyekjaer 				.mask = BIT(7),
1050b5969abfSSean Nyekjaer 			},
1051b5969abfSSean Nyekjaer 			.wakeup_reg = {
1052b5969abfSSean Nyekjaer 				.addr = 0x5B,
1053b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1054b5969abfSSean Nyekjaer 			},
10551aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
10561aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
10571aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
10581aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
10591aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
1060b5969abfSSean Nyekjaer 		},
10613054c4ffSLorenzo Bianconi 	},
106243901008SLorenzo Bianconi 	{
106343901008SLorenzo Bianconi 		.wai = 0x6b,
106466b662a1SLorenzo Bianconi 		.reset = {
106566b662a1SLorenzo Bianconi 			.addr = 0x12,
106666b662a1SLorenzo Bianconi 			.mask = BIT(0),
106766b662a1SLorenzo Bianconi 		},
106866b662a1SLorenzo Bianconi 		.boot = {
106966b662a1SLorenzo Bianconi 			.addr = 0x12,
107066b662a1SLorenzo Bianconi 			.mask = BIT(7),
107166b662a1SLorenzo Bianconi 		},
107266b662a1SLorenzo Bianconi 		.bdu = {
107366b662a1SLorenzo Bianconi 			.addr = 0x12,
107466b662a1SLorenzo Bianconi 			.mask = BIT(6),
107566b662a1SLorenzo Bianconi 		},
107643901008SLorenzo Bianconi 		.max_fifo_size = 512,
107743901008SLorenzo Bianconi 		.id = {
107881956a93SLorenzo Bianconi 			{
107981956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSR_ID,
108081956a93SLorenzo Bianconi 				.name = ST_LSM6DSR_DEV_NAME,
1081db947a79SLorenzo Bianconi 			}, {
1082db947a79SLorenzo Bianconi 				.hw_id = ST_ISM330DHCX_ID,
1083db947a79SLorenzo Bianconi 				.name = ST_ISM330DHCX_DEV_NAME,
108481956a93SLorenzo Bianconi 			},
108543901008SLorenzo Bianconi 		},
1086f48bc49bSLorenzo Bianconi 		.channels = {
1087f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1088f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1089f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1090f48bc49bSLorenzo Bianconi 			},
1091f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1092f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1093f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1094f48bc49bSLorenzo Bianconi 			},
1095f48bc49bSLorenzo Bianconi 		},
1096960506edSLorenzo Bianconi 		.drdy_mask = {
1097960506edSLorenzo Bianconi 			.addr = 0x13,
1098960506edSLorenzo Bianconi 			.mask = BIT(3),
1099960506edSLorenzo Bianconi 		},
110040dd7343SLorenzo Bianconi 		.odr_table = {
110140dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
110240dd7343SLorenzo Bianconi 				.reg = {
110340dd7343SLorenzo Bianconi 					.addr = 0x10,
110440dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
110540dd7343SLorenzo Bianconi 				},
110640dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
110740dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
110840dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
110940dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
111040dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
111140dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
111240dd7343SLorenzo Bianconi 			},
111340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
111440dd7343SLorenzo Bianconi 				.reg = {
111540dd7343SLorenzo Bianconi 					.addr = 0x11,
111640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
111740dd7343SLorenzo Bianconi 				},
111840dd7343SLorenzo Bianconi 				.odr_avl[0] = {  13, 0x01 },
111940dd7343SLorenzo Bianconi 				.odr_avl[1] = {  26, 0x02 },
112040dd7343SLorenzo Bianconi 				.odr_avl[2] = {  52, 0x03 },
112140dd7343SLorenzo Bianconi 				.odr_avl[3] = { 104, 0x04 },
112240dd7343SLorenzo Bianconi 				.odr_avl[4] = { 208, 0x05 },
112340dd7343SLorenzo Bianconi 				.odr_avl[5] = { 416, 0x06 },
112440dd7343SLorenzo Bianconi 			},
112540dd7343SLorenzo Bianconi 		},
1126640aca3fSLorenzo Bianconi 		.fs_table = {
1127640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1128640aca3fSLorenzo Bianconi 				.reg = {
1129640aca3fSLorenzo Bianconi 					.addr = 0x10,
1130640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1131640aca3fSLorenzo Bianconi 				},
1132640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
1133640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
1134640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
1135640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
113685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1137640aca3fSLorenzo Bianconi 			},
1138640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1139640aca3fSLorenzo Bianconi 				.reg = {
1140640aca3fSLorenzo Bianconi 					.addr = 0x11,
1141640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1142640aca3fSLorenzo Bianconi 				},
1143640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
1144640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
1145640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
1146640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
114785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1148640aca3fSLorenzo Bianconi 			},
1149640aca3fSLorenzo Bianconi 		},
11507e906103SLorenzo Bianconi 		.irq_config = {
11517e906103SLorenzo Bianconi 			.irq1 = {
11527e906103SLorenzo Bianconi 				.addr = 0x0d,
11537e906103SLorenzo Bianconi 				.mask = BIT(3),
11547e906103SLorenzo Bianconi 			},
11557e906103SLorenzo Bianconi 			.irq2 = {
11567e906103SLorenzo Bianconi 				.addr = 0x0e,
11577e906103SLorenzo Bianconi 				.mask = BIT(3),
11587e906103SLorenzo Bianconi 			},
11597e906103SLorenzo Bianconi 			.lir = {
11607e906103SLorenzo Bianconi 				.addr = 0x56,
11617e906103SLorenzo Bianconi 				.mask = BIT(0),
11627e906103SLorenzo Bianconi 			},
11637e906103SLorenzo Bianconi 			.clear_on_read = {
11647e906103SLorenzo Bianconi 				.addr = 0x56,
11657e906103SLorenzo Bianconi 				.mask = BIT(6),
11667e906103SLorenzo Bianconi 			},
11677e906103SLorenzo Bianconi 			.irq1_func = {
11687e906103SLorenzo Bianconi 				.addr = 0x5e,
11697e906103SLorenzo Bianconi 				.mask = BIT(5),
11707e906103SLorenzo Bianconi 			},
11717e906103SLorenzo Bianconi 			.irq2_func = {
11727e906103SLorenzo Bianconi 				.addr = 0x5f,
11737e906103SLorenzo Bianconi 				.mask = BIT(5),
11747e906103SLorenzo Bianconi 			},
117531fe8d4eSLorenzo Bianconi 			.hla = {
117631fe8d4eSLorenzo Bianconi 				.addr = 0x12,
117731fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
117831fe8d4eSLorenzo Bianconi 			},
117931fe8d4eSLorenzo Bianconi 			.od = {
118031fe8d4eSLorenzo Bianconi 				.addr = 0x12,
118131fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
118231fe8d4eSLorenzo Bianconi 			},
11837e906103SLorenzo Bianconi 		},
118443901008SLorenzo Bianconi 		.batch = {
118543901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
118643901008SLorenzo Bianconi 				.addr = 0x09,
118743901008SLorenzo Bianconi 				.mask = GENMASK(3, 0),
118843901008SLorenzo Bianconi 			},
118943901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
119043901008SLorenzo Bianconi 				.addr = 0x09,
119143901008SLorenzo Bianconi 				.mask = GENMASK(7, 4),
119243901008SLorenzo Bianconi 			},
119343901008SLorenzo Bianconi 		},
119443901008SLorenzo Bianconi 		.fifo_ops = {
11953b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
119643901008SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
119743901008SLorenzo Bianconi 			.fifo_th = {
119843901008SLorenzo Bianconi 				.addr = 0x07,
119943901008SLorenzo Bianconi 				.mask = GENMASK(8, 0),
120043901008SLorenzo Bianconi 			},
120143901008SLorenzo Bianconi 			.fifo_diff = {
120243901008SLorenzo Bianconi 				.addr = 0x3a,
120370575abeSmario tesi 				.mask = GENMASK(9, 0),
120443901008SLorenzo Bianconi 			},
120543901008SLorenzo Bianconi 			.th_wl = 1,
120643901008SLorenzo Bianconi 		},
120743901008SLorenzo Bianconi 		.ts_settings = {
120843901008SLorenzo Bianconi 			.timer_en = {
120943901008SLorenzo Bianconi 				.addr = 0x19,
121043901008SLorenzo Bianconi 				.mask = BIT(5),
121143901008SLorenzo Bianconi 			},
121243901008SLorenzo Bianconi 			.decimator = {
121343901008SLorenzo Bianconi 				.addr = 0x0a,
121443901008SLorenzo Bianconi 				.mask = GENMASK(7, 6),
121543901008SLorenzo Bianconi 			},
1216cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
121743901008SLorenzo Bianconi 		},
121843901008SLorenzo Bianconi 		.shub_settings = {
121943901008SLorenzo Bianconi 			.page_mux = {
122043901008SLorenzo Bianconi 				.addr = 0x01,
122143901008SLorenzo Bianconi 				.mask = BIT(6),
122243901008SLorenzo Bianconi 			},
122343901008SLorenzo Bianconi 			.master_en = {
122443901008SLorenzo Bianconi 				.addr = 0x14,
122543901008SLorenzo Bianconi 				.mask = BIT(2),
122643901008SLorenzo Bianconi 			},
122743901008SLorenzo Bianconi 			.pullup_en = {
122843901008SLorenzo Bianconi 				.addr = 0x14,
122943901008SLorenzo Bianconi 				.mask = BIT(3),
123043901008SLorenzo Bianconi 			},
123143901008SLorenzo Bianconi 			.aux_sens = {
123243901008SLorenzo Bianconi 				.addr = 0x14,
123343901008SLorenzo Bianconi 				.mask = GENMASK(1, 0),
123443901008SLorenzo Bianconi 			},
123543901008SLorenzo Bianconi 			.wr_once = {
123643901008SLorenzo Bianconi 				.addr = 0x14,
123743901008SLorenzo Bianconi 				.mask = BIT(6),
123843901008SLorenzo Bianconi 			},
123943901008SLorenzo Bianconi 			.shub_out = 0x02,
124043901008SLorenzo Bianconi 			.slv0_addr = 0x15,
124143901008SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
124243901008SLorenzo Bianconi 			.batch_en = BIT(3),
1243b5969abfSSean Nyekjaer 		},
1244b5969abfSSean Nyekjaer 		.event_settings = {
1245b5969abfSSean Nyekjaer 			.enable_reg = {
1246b5969abfSSean Nyekjaer 				.addr = 0x58,
1247b5969abfSSean Nyekjaer 				.mask = BIT(7),
1248b5969abfSSean Nyekjaer 			},
1249b5969abfSSean Nyekjaer 			.wakeup_reg = {
1250b5969abfSSean Nyekjaer 				.addr = 0x5B,
1251b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1252b5969abfSSean Nyekjaer 			},
12531aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
12541aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
12551aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
12561aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
12571aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
125843901008SLorenzo Bianconi 		}
125943901008SLorenzo Bianconi 	},
1260290a6ce1SLorenzo Bianconi };
1261290a6ce1SLorenzo Bianconi 
1262c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1263c91c1c84SLorenzo Bianconi {
1264c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1265c91c1c84SLorenzo Bianconi 	unsigned int data;
1266c91c1c84SLorenzo Bianconi 	int err;
1267c91c1c84SLorenzo Bianconi 
1268c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1269c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1270c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1271c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1272c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1273c91c1c84SLorenzo Bianconi 
1274c91c1c84SLorenzo Bianconi 	return err;
1275c91c1c84SLorenzo Bianconi }
1276c91c1c84SLorenzo Bianconi 
127781956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
127881956a93SLorenzo Bianconi 				   const char **name)
1279290a6ce1SLorenzo Bianconi {
128051a8b707SLorenzo Bianconi 	int err, i, j, data;
1281290a6ce1SLorenzo Bianconi 
1282290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1283d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
128481956a93SLorenzo Bianconi 			if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1285d068e4a0SLorenzo Bianconi 				break;
1286d068e4a0SLorenzo Bianconi 		}
1287d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1288290a6ce1SLorenzo Bianconi 			break;
1289290a6ce1SLorenzo Bianconi 	}
1290290a6ce1SLorenzo Bianconi 
1291290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1292290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1293290a6ce1SLorenzo Bianconi 		return -ENODEV;
1294290a6ce1SLorenzo Bianconi 	}
1295290a6ce1SLorenzo Bianconi 
129651a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1297290a6ce1SLorenzo Bianconi 	if (err < 0) {
1298290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1299290a6ce1SLorenzo Bianconi 		return err;
1300290a6ce1SLorenzo Bianconi 	}
1301290a6ce1SLorenzo Bianconi 
1302290a6ce1SLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].wai) {
1303290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1304290a6ce1SLorenzo Bianconi 		return -ENODEV;
1305290a6ce1SLorenzo Bianconi 	}
1306290a6ce1SLorenzo Bianconi 
130781956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1308290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1309290a6ce1SLorenzo Bianconi 
1310290a6ce1SLorenzo Bianconi 	return 0;
1311290a6ce1SLorenzo Bianconi }
1312290a6ce1SLorenzo Bianconi 
1313290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1314290a6ce1SLorenzo Bianconi 				     u32 gain)
1315290a6ce1SLorenzo Bianconi {
1316640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1317739aff87SLorenzo Bianconi 	unsigned int data;
1318290a6ce1SLorenzo Bianconi 	int i, err;
1319290a6ce1SLorenzo Bianconi 
1320640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
132185ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1322640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1323290a6ce1SLorenzo Bianconi 			break;
132485ae3aeeSLorenzo Bianconi 	}
1325290a6ce1SLorenzo Bianconi 
132685ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1327290a6ce1SLorenzo Bianconi 		return -EINVAL;
1328290a6ce1SLorenzo Bianconi 
1329640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1330640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1331640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1332640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1333290a6ce1SLorenzo Bianconi 	if (err < 0)
1334290a6ce1SLorenzo Bianconi 		return err;
1335290a6ce1SLorenzo Bianconi 
1336290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1337290a6ce1SLorenzo Bianconi 
1338290a6ce1SLorenzo Bianconi 	return 0;
1339290a6ce1SLorenzo Bianconi }
1340290a6ce1SLorenzo Bianconi 
134154a6d0c6SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
1342290a6ce1SLorenzo Bianconi {
134340dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
13442ccc1503SLorenzo Bianconi 	int i;
1345290a6ce1SLorenzo Bianconi 
134640dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
1347290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
13486ffb55e5SLorenzo Bianconi 		/*
13496ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
13506ffb55e5SLorenzo Bianconi 		 * accel sensor
13516ffb55e5SLorenzo Bianconi 		 */
135240dd7343SLorenzo Bianconi 		if (odr_table->odr_avl[i].hz >= odr)
1353290a6ce1SLorenzo Bianconi 			break;
1354290a6ce1SLorenzo Bianconi 
1355290a6ce1SLorenzo Bianconi 	if (i == ST_LSM6DSX_ODR_LIST_SIZE)
1356290a6ce1SLorenzo Bianconi 		return -EINVAL;
1357290a6ce1SLorenzo Bianconi 
135840dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1359290a6ce1SLorenzo Bianconi 
1360290a6ce1SLorenzo Bianconi 	return 0;
1361290a6ce1SLorenzo Bianconi }
1362290a6ce1SLorenzo Bianconi 
13636ffb55e5SLorenzo Bianconi static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr,
13646ffb55e5SLorenzo Bianconi 					   enum st_lsm6dsx_sensor_id id)
13652ccc1503SLorenzo Bianconi {
13666ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
13676ffb55e5SLorenzo Bianconi 
13686ffb55e5SLorenzo Bianconi 	if (odr > 0) {
13696ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
13706ffb55e5SLorenzo Bianconi 			return max_t(u16, ref->odr, odr);
13716ffb55e5SLorenzo Bianconi 		else
13726ffb55e5SLorenzo Bianconi 			return odr;
13736ffb55e5SLorenzo Bianconi 	} else {
13746ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
13756ffb55e5SLorenzo Bianconi 	}
13766ffb55e5SLorenzo Bianconi }
13776ffb55e5SLorenzo Bianconi 
13786ffb55e5SLorenzo Bianconi static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)
13796ffb55e5SLorenzo Bianconi {
13806ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
138151a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
138251a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1383739aff87SLorenzo Bianconi 	unsigned int data;
13846ffb55e5SLorenzo Bianconi 	u8 val = 0;
13852ccc1503SLorenzo Bianconi 	int err;
13862ccc1503SLorenzo Bianconi 
13876ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
13886ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
13896ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
13906ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
13916ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
13926ffb55e5SLorenzo Bianconi 		u16 odr;
13936ffb55e5SLorenzo Bianconi 		int i;
13946ffb55e5SLorenzo Bianconi 
13956ffb55e5SLorenzo Bianconi 		/*
13966ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
13976ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
13986ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
13996ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
14006ffb55e5SLorenzo Bianconi 		 */
14016ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
14026ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
14036ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
14046ffb55e5SLorenzo Bianconi 				continue;
14056ffb55e5SLorenzo Bianconi 
14066ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
14076ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
14086ffb55e5SLorenzo Bianconi 				/* device already configured */
14096ffb55e5SLorenzo Bianconi 				return 0;
14106ffb55e5SLorenzo Bianconi 		}
14116ffb55e5SLorenzo Bianconi 		break;
14126ffb55e5SLorenzo Bianconi 	}
14136ffb55e5SLorenzo Bianconi 	default:
14146ffb55e5SLorenzo Bianconi 		break;
14156ffb55e5SLorenzo Bianconi 	}
14166ffb55e5SLorenzo Bianconi 
14176ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
14186ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
14192ccc1503SLorenzo Bianconi 		if (err < 0)
14202ccc1503SLorenzo Bianconi 			return err;
14216ffb55e5SLorenzo Bianconi 	}
14222ccc1503SLorenzo Bianconi 
142340dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1424739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1425739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
14262ccc1503SLorenzo Bianconi }
14272ccc1503SLorenzo Bianconi 
142817750443SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
142917750443SLorenzo Bianconi 				 bool enable)
1430290a6ce1SLorenzo Bianconi {
143151a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
143217750443SLorenzo Bianconi 	u16 odr = enable ? sensor->odr : 0;
1433290a6ce1SLorenzo Bianconi 	int err;
1434290a6ce1SLorenzo Bianconi 
143517750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1436290a6ce1SLorenzo Bianconi 	if (err < 0)
1437290a6ce1SLorenzo Bianconi 		return err;
1438290a6ce1SLorenzo Bianconi 
143917750443SLorenzo Bianconi 	if (enable)
144017750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
144117750443SLorenzo Bianconi 	else
144217750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1443290a6ce1SLorenzo Bianconi 
1444290a6ce1SLorenzo Bianconi 	return 0;
1445290a6ce1SLorenzo Bianconi }
1446290a6ce1SLorenzo Bianconi 
1447290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1448290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1449290a6ce1SLorenzo Bianconi {
145051a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1451290a6ce1SLorenzo Bianconi 	int err, delay;
1452290a6ce1SLorenzo Bianconi 	__le16 data;
1453290a6ce1SLorenzo Bianconi 
145417750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1455290a6ce1SLorenzo Bianconi 	if (err < 0)
1456290a6ce1SLorenzo Bianconi 		return err;
1457290a6ce1SLorenzo Bianconi 
1458290a6ce1SLorenzo Bianconi 	delay = 1000000 / sensor->odr;
1459290a6ce1SLorenzo Bianconi 	usleep_range(delay, 2 * delay);
1460290a6ce1SLorenzo Bianconi 
1461739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1462290a6ce1SLorenzo Bianconi 	if (err < 0)
1463290a6ce1SLorenzo Bianconi 		return err;
1464290a6ce1SLorenzo Bianconi 
1465b5969abfSSean Nyekjaer 	if (!hw->enable_event)
146617750443SLorenzo Bianconi 		st_lsm6dsx_sensor_set_enable(sensor, false);
1467290a6ce1SLorenzo Bianconi 
14687b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1469290a6ce1SLorenzo Bianconi 
1470290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1471290a6ce1SLorenzo Bianconi }
1472290a6ce1SLorenzo Bianconi 
1473290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1474290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1475290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1476290a6ce1SLorenzo Bianconi {
1477290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1478290a6ce1SLorenzo Bianconi 	int ret;
1479290a6ce1SLorenzo Bianconi 
1480290a6ce1SLorenzo Bianconi 	switch (mask) {
1481290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1482290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1483290a6ce1SLorenzo Bianconi 		if (ret)
1484290a6ce1SLorenzo Bianconi 			break;
1485290a6ce1SLorenzo Bianconi 
1486290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1487290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1488290a6ce1SLorenzo Bianconi 		break;
1489290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1490290a6ce1SLorenzo Bianconi 		*val = sensor->odr;
1491290a6ce1SLorenzo Bianconi 		ret = IIO_VAL_INT;
1492290a6ce1SLorenzo Bianconi 		break;
1493290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1494290a6ce1SLorenzo Bianconi 		*val = 0;
1495290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
1496290a6ce1SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1497290a6ce1SLorenzo Bianconi 		break;
1498290a6ce1SLorenzo Bianconi 	default:
1499290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1500290a6ce1SLorenzo Bianconi 		break;
1501290a6ce1SLorenzo Bianconi 	}
1502290a6ce1SLorenzo Bianconi 
1503290a6ce1SLorenzo Bianconi 	return ret;
1504290a6ce1SLorenzo Bianconi }
1505290a6ce1SLorenzo Bianconi 
1506290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1507290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1508290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1509290a6ce1SLorenzo Bianconi {
1510290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1511290a6ce1SLorenzo Bianconi 	int err;
1512290a6ce1SLorenzo Bianconi 
1513290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1514290a6ce1SLorenzo Bianconi 	if (err)
1515290a6ce1SLorenzo Bianconi 		return err;
1516290a6ce1SLorenzo Bianconi 
1517290a6ce1SLorenzo Bianconi 	switch (mask) {
1518290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1519290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1520290a6ce1SLorenzo Bianconi 		break;
15212ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
15222ccc1503SLorenzo Bianconi 		u8 data;
15232ccc1503SLorenzo Bianconi 
15242ccc1503SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(sensor, val, &data);
15255e3c3e33SLorenzo Bianconi 		if (!err)
15265e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1527290a6ce1SLorenzo Bianconi 		break;
15282ccc1503SLorenzo Bianconi 	}
1529290a6ce1SLorenzo Bianconi 	default:
1530290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1531290a6ce1SLorenzo Bianconi 		break;
1532290a6ce1SLorenzo Bianconi 	}
1533290a6ce1SLorenzo Bianconi 
1534290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1535290a6ce1SLorenzo Bianconi 
1536290a6ce1SLorenzo Bianconi 	return err;
1537290a6ce1SLorenzo Bianconi }
1538290a6ce1SLorenzo Bianconi 
1539b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1540b5969abfSSean Nyekjaer {
154184b2e7c3SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
154204ca37d5SLorenzo Bianconi 	unsigned int data;
1543b5969abfSSean Nyekjaer 	int err;
1544b5969abfSSean Nyekjaer 
15457e906103SLorenzo Bianconi 	if (!hw->settings->irq_config.irq1_func.addr)
1546b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1547b5969abfSSean Nyekjaer 
154884b2e7c3SLorenzo Bianconi 	reg = &hw->settings->event_settings.enable_reg;
154984b2e7c3SLorenzo Bianconi 	if (reg->addr) {
155004ca37d5SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
155104ca37d5SLorenzo Bianconi 		err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
155204ca37d5SLorenzo Bianconi 						    reg->mask, data);
1553b5969abfSSean Nyekjaer 		if (err < 0)
1554b5969abfSSean Nyekjaer 			return err;
155584b2e7c3SLorenzo Bianconi 	}
1556b5969abfSSean Nyekjaer 
1557b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
155804ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
155904ca37d5SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
156004ca37d5SLorenzo Bianconi 					     hw->irq_routing->mask, data);
1561b5969abfSSean Nyekjaer }
1562b5969abfSSean Nyekjaer 
1563b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1564b5969abfSSean Nyekjaer 				   const struct iio_chan_spec *chan,
1565b5969abfSSean Nyekjaer 				   enum iio_event_type type,
1566b5969abfSSean Nyekjaer 				   enum iio_event_direction dir,
1567b5969abfSSean Nyekjaer 				   enum iio_event_info info,
1568b5969abfSSean Nyekjaer 				   int *val, int *val2)
1569b5969abfSSean Nyekjaer {
1570b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1571b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1572b5969abfSSean Nyekjaer 
1573b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1574b5969abfSSean Nyekjaer 		return -EINVAL;
1575b5969abfSSean Nyekjaer 
1576b5969abfSSean Nyekjaer 	*val2 = 0;
1577b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1578b5969abfSSean Nyekjaer 
1579b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1580b5969abfSSean Nyekjaer }
1581b5969abfSSean Nyekjaer 
1582b307f495SLorenzo Bianconi static int
1583b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1584b5969abfSSean Nyekjaer 		       const struct iio_chan_spec *chan,
1585b5969abfSSean Nyekjaer 		       enum iio_event_type type,
1586b5969abfSSean Nyekjaer 		       enum iio_event_direction dir,
1587b5969abfSSean Nyekjaer 		       enum iio_event_info info,
1588b5969abfSSean Nyekjaer 		       int val, int val2)
1589b5969abfSSean Nyekjaer {
1590b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1591b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
159204ca37d5SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
159304ca37d5SLorenzo Bianconi 	unsigned int data;
1594b5969abfSSean Nyekjaer 	int err;
1595b5969abfSSean Nyekjaer 
1596b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1597b5969abfSSean Nyekjaer 		return -EINVAL;
1598b5969abfSSean Nyekjaer 
1599b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1600b5969abfSSean Nyekjaer 		return -EINVAL;
1601b5969abfSSean Nyekjaer 
160204ca37d5SLorenzo Bianconi 	reg = &hw->settings->event_settings.wakeup_reg;
160304ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
160404ca37d5SLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
160504ca37d5SLorenzo Bianconi 					    reg->mask, data);
160604ca37d5SLorenzo Bianconi 	if (err < 0)
1607b5969abfSSean Nyekjaer 		return -EINVAL;
1608b5969abfSSean Nyekjaer 
1609b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1610b5969abfSSean Nyekjaer 
1611b5969abfSSean Nyekjaer 	return 0;
1612b5969abfSSean Nyekjaer }
1613b5969abfSSean Nyekjaer 
1614b307f495SLorenzo Bianconi static int
1615b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1616b5969abfSSean Nyekjaer 			     const struct iio_chan_spec *chan,
1617b5969abfSSean Nyekjaer 			     enum iio_event_type type,
1618b5969abfSSean Nyekjaer 			     enum iio_event_direction dir)
1619b5969abfSSean Nyekjaer {
1620b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1621b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1622b5969abfSSean Nyekjaer 
1623b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1624b5969abfSSean Nyekjaer 		return -EINVAL;
1625b5969abfSSean Nyekjaer 
16261aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1627b5969abfSSean Nyekjaer }
1628b5969abfSSean Nyekjaer 
1629b307f495SLorenzo Bianconi static int
1630b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1631b5969abfSSean Nyekjaer 			      const struct iio_chan_spec *chan,
1632b5969abfSSean Nyekjaer 			      enum iio_event_type type,
1633b307f495SLorenzo Bianconi 			      enum iio_event_direction dir, int state)
1634b5969abfSSean Nyekjaer {
1635b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1636b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
16371aabad1fSSean Nyekjaer 	u8 enable_event;
1638b5969abfSSean Nyekjaer 	int err = 0;
1639b5969abfSSean Nyekjaer 
1640b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1641b5969abfSSean Nyekjaer 		return -EINVAL;
1642b5969abfSSean Nyekjaer 
16431aabad1fSSean Nyekjaer 	if (state) {
16441aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
16451aabad1fSSean Nyekjaer 
1646b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
16471aabad1fSSean Nyekjaer 		if (hw->enable_event)
16481aabad1fSSean Nyekjaer 			goto out;
16491aabad1fSSean Nyekjaer 	} else {
16501aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
16511aabad1fSSean Nyekjaer 
16521aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
16531aabad1fSSean Nyekjaer 		if (enable_event)
16541aabad1fSSean Nyekjaer 			goto out;
16551aabad1fSSean Nyekjaer 	}
16561aabad1fSSean Nyekjaer 
16571aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
16581aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1659b5969abfSSean Nyekjaer 		return 0;
1660b5969abfSSean Nyekjaer 
1661b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1662b5969abfSSean Nyekjaer 	if (err < 0)
1663b5969abfSSean Nyekjaer 		return err;
1664b5969abfSSean Nyekjaer 
1665d278d447SLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1666b5969abfSSean Nyekjaer 	err = st_lsm6dsx_sensor_set_enable(sensor, state);
1667d278d447SLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1668b5969abfSSean Nyekjaer 	if (err < 0)
1669b5969abfSSean Nyekjaer 		return err;
1670b5969abfSSean Nyekjaer 
16711aabad1fSSean Nyekjaer out:
16721aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1673b5969abfSSean Nyekjaer 
1674b5969abfSSean Nyekjaer 	return 0;
1675b5969abfSSean Nyekjaer }
1676b5969abfSSean Nyekjaer 
1677d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1678290a6ce1SLorenzo Bianconi {
1679290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1680290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
16818f2a88a2SLorenzo Bianconi 	int err;
1682290a6ce1SLorenzo Bianconi 
16838f2a88a2SLorenzo Bianconi 	if (val < 1 || val > hw->settings->max_fifo_size)
1684290a6ce1SLorenzo Bianconi 		return -EINVAL;
1685290a6ce1SLorenzo Bianconi 
1686335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1687335eaedcSLorenzo Bianconi 
1688290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
1689335eaedcSLorenzo Bianconi 
1690335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1691335eaedcSLorenzo Bianconi 
1692290a6ce1SLorenzo Bianconi 	if (err < 0)
1693290a6ce1SLorenzo Bianconi 		return err;
1694290a6ce1SLorenzo Bianconi 
1695290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
1696290a6ce1SLorenzo Bianconi 
1697290a6ce1SLorenzo Bianconi 	return 0;
1698290a6ce1SLorenzo Bianconi }
1699290a6ce1SLorenzo Bianconi 
1700290a6ce1SLorenzo Bianconi static ssize_t
1701290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1702290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
1703290a6ce1SLorenzo Bianconi 					  char *buf)
1704290a6ce1SLorenzo Bianconi {
1705290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
1706290a6ce1SLorenzo Bianconi 	enum st_lsm6dsx_sensor_id id = sensor->id;
170740dd7343SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1708290a6ce1SLorenzo Bianconi 	int i, len = 0;
1709290a6ce1SLorenzo Bianconi 
1710290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
1711290a6ce1SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
171240dd7343SLorenzo Bianconi 				 hw->settings->odr_table[id].odr_avl[i].hz);
1713290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1714290a6ce1SLorenzo Bianconi 
1715290a6ce1SLorenzo Bianconi 	return len;
1716290a6ce1SLorenzo Bianconi }
1717290a6ce1SLorenzo Bianconi 
1718290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
1719290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
1720290a6ce1SLorenzo Bianconi 					    char *buf)
1721290a6ce1SLorenzo Bianconi {
1722290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
17230f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1724640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1725290a6ce1SLorenzo Bianconi 	int i, len = 0;
1726290a6ce1SLorenzo Bianconi 
172785ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
172885ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
1729290a6ce1SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
17300f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
1731290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1732290a6ce1SLorenzo Bianconi 
1733290a6ce1SLorenzo Bianconi 	return len;
1734290a6ce1SLorenzo Bianconi }
1735290a6ce1SLorenzo Bianconi 
1736290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
1737290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
1738290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1739290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
1740290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1741290a6ce1SLorenzo Bianconi 
1742290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
1743290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1744290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1745290a6ce1SLorenzo Bianconi 	NULL,
1746290a6ce1SLorenzo Bianconi };
1747290a6ce1SLorenzo Bianconi 
1748290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
1749290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
1750290a6ce1SLorenzo Bianconi };
1751290a6ce1SLorenzo Bianconi 
1752290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
1753290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
1754290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1755290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1756b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
1757b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
1758b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
1759b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
1760290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1761290a6ce1SLorenzo Bianconi };
1762290a6ce1SLorenzo Bianconi 
1763290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
1764290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1765290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
1766290a6ce1SLorenzo Bianconi 	NULL,
1767290a6ce1SLorenzo Bianconi };
1768290a6ce1SLorenzo Bianconi 
1769290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
1770290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
1771290a6ce1SLorenzo Bianconi };
1772290a6ce1SLorenzo Bianconi 
1773290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
1774290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
1775290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1776290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1777290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1778290a6ce1SLorenzo Bianconi };
1779290a6ce1SLorenzo Bianconi 
1780dba32904SLorenzo Bianconi static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1781dba32904SLorenzo Bianconi {
1782dba32904SLorenzo Bianconi 	struct device_node *np = hw->dev->of_node;
1783dba32904SLorenzo Bianconi 
1784dba32904SLorenzo Bianconi 	if (!np)
1785dba32904SLorenzo Bianconi 		return -EINVAL;
1786dba32904SLorenzo Bianconi 
1787bf235277SLorenzo Bianconi 	return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
1788dba32904SLorenzo Bianconi }
1789dba32904SLorenzo Bianconi 
17907e906103SLorenzo Bianconi static int
17917e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
17927e906103SLorenzo Bianconi 			const struct st_lsm6dsx_reg **drdy_reg)
1793dba32904SLorenzo Bianconi {
1794dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
1795dba32904SLorenzo Bianconi 
1796dba32904SLorenzo Bianconi 	if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
1797dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
1798dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
1799dba32904SLorenzo Bianconi 
1800dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
1801dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
1802dba32904SLorenzo Bianconi 	}
1803dba32904SLorenzo Bianconi 
1804dba32904SLorenzo Bianconi 	switch (drdy_pin) {
1805dba32904SLorenzo Bianconi 	case 1:
18067e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq1_func;
18077e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq1;
1808dba32904SLorenzo Bianconi 		break;
1809dba32904SLorenzo Bianconi 	case 2:
18107e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq2_func;
18117e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq2;
1812dba32904SLorenzo Bianconi 		break;
1813dba32904SLorenzo Bianconi 	default:
1814dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
1815dba32904SLorenzo Bianconi 		err = -EINVAL;
1816dba32904SLorenzo Bianconi 		break;
1817dba32904SLorenzo Bianconi 	}
1818dba32904SLorenzo Bianconi 
1819dba32904SLorenzo Bianconi 	return err;
1820dba32904SLorenzo Bianconi }
1821dba32904SLorenzo Bianconi 
1822c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1823c91c1c84SLorenzo Bianconi {
1824c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1825c91c1c84SLorenzo Bianconi 	struct device_node *np = hw->dev->of_node;
1826c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
1827c91c1c84SLorenzo Bianconi 	unsigned int data;
1828c91c1c84SLorenzo Bianconi 	int err = 0;
1829c91c1c84SLorenzo Bianconi 
1830c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1831c91c1c84SLorenzo Bianconi 
1832c91c1c84SLorenzo Bianconi 	pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
1833c91c1c84SLorenzo Bianconi 	if ((np && of_property_read_bool(np, "st,pullups")) ||
1834c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
1835c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
1836c91c1c84SLorenzo Bianconi 		if (err < 0)
1837c91c1c84SLorenzo Bianconi 			return err;
1838c91c1c84SLorenzo Bianconi 
1839c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
1840c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
1841c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
1842c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
1843c91c1c84SLorenzo Bianconi 
1844c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
1845c91c1c84SLorenzo Bianconi 
1846c91c1c84SLorenzo Bianconi 		if (err < 0)
1847c91c1c84SLorenzo Bianconi 			return err;
1848c91c1c84SLorenzo Bianconi 	}
1849c91c1c84SLorenzo Bianconi 
1850c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
1851c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
1852c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
1853c91c1c84SLorenzo Bianconi 		if (err < 0)
1854c91c1c84SLorenzo Bianconi 			return err;
1855c91c1c84SLorenzo Bianconi 
1856c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
1857c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
1858c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
1859c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
1860c91c1c84SLorenzo Bianconi 
1861c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
1862c91c1c84SLorenzo Bianconi 	}
1863c91c1c84SLorenzo Bianconi 
1864c91c1c84SLorenzo Bianconi 	return err;
1865c91c1c84SLorenzo Bianconi }
1866c91c1c84SLorenzo Bianconi 
186721345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
186821345107SLorenzo Bianconi {
186921345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
187021345107SLorenzo Bianconi 	int err, val;
187121345107SLorenzo Bianconi 
187221345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
187321345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
187421345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
187521345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
187621345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
187721345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
187821345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
187921345107SLorenzo Bianconi 		if (err < 0)
188021345107SLorenzo Bianconi 			return err;
188121345107SLorenzo Bianconi 	}
188221345107SLorenzo Bianconi 
188321345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
188421345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
188521345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
188621345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
188721345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
188821345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
188921345107SLorenzo Bianconi 		if (err < 0)
189021345107SLorenzo Bianconi 			return err;
189121345107SLorenzo Bianconi 	}
189221345107SLorenzo Bianconi 
189321345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
189421345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
189521345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
189621345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
189721345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
189821345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
189921345107SLorenzo Bianconi 		if (err < 0)
190021345107SLorenzo Bianconi 			return err;
190121345107SLorenzo Bianconi 	}
1902cb3b6b8eSMario Tesi 
1903cb3b6b8eSMario Tesi 	/* calibrate timestamp sensitivity */
1904cb3b6b8eSMario Tesi 	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
1905cb3b6b8eSMario Tesi 	if (ts_settings->freq_fine) {
1906cb3b6b8eSMario Tesi 		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
1907cb3b6b8eSMario Tesi 		if (err < 0)
1908cb3b6b8eSMario Tesi 			return err;
1909cb3b6b8eSMario Tesi 
1910cb3b6b8eSMario Tesi 		/*
1911cb3b6b8eSMario Tesi 		 * linearize the AN5192 formula:
1912cb3b6b8eSMario Tesi 		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
1913cb3b6b8eSMario Tesi 		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
1914cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - 37.5 * val
1915cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
1916cb3b6b8eSMario Tesi 		 */
1917cb3b6b8eSMario Tesi 		hw->ts_gain -= ((s8)val * 37500) / 1000;
1918cb3b6b8eSMario Tesi 	}
1919cb3b6b8eSMario Tesi 
192021345107SLorenzo Bianconi 	return 0;
192121345107SLorenzo Bianconi }
192221345107SLorenzo Bianconi 
1923290a6ce1SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
1924290a6ce1SLorenzo Bianconi {
19257e906103SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1926290a6ce1SLorenzo Bianconi 	int err;
1927290a6ce1SLorenzo Bianconi 
192819435425SLorenzo Bianconi 	/* device sw reset */
192966b662a1SLorenzo Bianconi 	reg = &hw->settings->reset;
193066b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
193166b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
1932290a6ce1SLorenzo Bianconi 	if (err < 0)
1933290a6ce1SLorenzo Bianconi 		return err;
1934290a6ce1SLorenzo Bianconi 
193519435425SLorenzo Bianconi 	msleep(50);
193619435425SLorenzo Bianconi 
193719435425SLorenzo Bianconi 	/* reload trimming parameter */
193866b662a1SLorenzo Bianconi 	reg = &hw->settings->boot;
193966b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
194066b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
194119435425SLorenzo Bianconi 	if (err < 0)
194219435425SLorenzo Bianconi 		return err;
194319435425SLorenzo Bianconi 
194419435425SLorenzo Bianconi 	msleep(50);
1945290a6ce1SLorenzo Bianconi 
1946290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
194766b662a1SLorenzo Bianconi 	reg = &hw->settings->bdu;
194866b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
194966b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
1950290a6ce1SLorenzo Bianconi 	if (err < 0)
1951290a6ce1SLorenzo Bianconi 		return err;
1952290a6ce1SLorenzo Bianconi 
1953290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
19547e906103SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &reg);
1955290a6ce1SLorenzo Bianconi 	if (err < 0)
1956290a6ce1SLorenzo Bianconi 		return err;
1957290a6ce1SLorenzo Bianconi 
19587e906103SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
19597e906103SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
196021345107SLorenzo Bianconi 	if (err < 0)
196121345107SLorenzo Bianconi 		return err;
196221345107SLorenzo Bianconi 
19639db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
19647e906103SLorenzo Bianconi 	if (hw->settings->irq_config.lir.addr) {
19657e906103SLorenzo Bianconi 		reg = &hw->settings->irq_config.lir;
19667e906103SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
19677e906103SLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
19689db02d32SLorenzo Bianconi 		if (err < 0)
19699db02d32SLorenzo Bianconi 			return err;
197022ea5651SLorenzo Bianconi 
197122ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
19727e906103SLorenzo Bianconi 		if (hw->settings->irq_config.clear_on_read.addr) {
19737e906103SLorenzo Bianconi 			reg = &hw->settings->irq_config.clear_on_read;
197422ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
19757e906103SLorenzo Bianconi 					reg->addr, reg->mask,
19767e906103SLorenzo Bianconi 					ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
197722ea5651SLorenzo Bianconi 			if (err < 0)
197822ea5651SLorenzo Bianconi 				return err;
197922ea5651SLorenzo Bianconi 		}
19809db02d32SLorenzo Bianconi 	}
19819db02d32SLorenzo Bianconi 
1982960506edSLorenzo Bianconi 	/* enable drdy-mas if available */
1983960506edSLorenzo Bianconi 	if (hw->settings->drdy_mask.addr) {
1984960506edSLorenzo Bianconi 		reg = &hw->settings->drdy_mask;
1985960506edSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
1986960506edSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
1987960506edSLorenzo Bianconi 		if (err < 0)
1988960506edSLorenzo Bianconi 			return err;
1989960506edSLorenzo Bianconi 	}
1990960506edSLorenzo Bianconi 
1991c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
1992c91c1c84SLorenzo Bianconi 	if (err < 0)
1993c91c1c84SLorenzo Bianconi 		return err;
1994c91c1c84SLorenzo Bianconi 
199521345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
1996290a6ce1SLorenzo Bianconi }
1997290a6ce1SLorenzo Bianconi 
1998290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
1999510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
2000510c0106SLorenzo Bianconi 					       const char *name)
2001290a6ce1SLorenzo Bianconi {
2002290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2003290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
2004290a6ce1SLorenzo Bianconi 
2005290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
2006290a6ce1SLorenzo Bianconi 	if (!iio_dev)
2007290a6ce1SLorenzo Bianconi 		return NULL;
2008290a6ce1SLorenzo Bianconi 
2009290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
2010290a6ce1SLorenzo Bianconi 	iio_dev->dev.parent = hw->dev;
2011290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2012f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
2013f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
2014290a6ce1SLorenzo Bianconi 
2015290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
2016290a6ce1SLorenzo Bianconi 	sensor->id = id;
2017290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
201840dd7343SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
2019640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
2020290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
2021290a6ce1SLorenzo Bianconi 
2022290a6ce1SLorenzo Bianconi 	switch (id) {
2023290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
2024290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
2025510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
2026510c0106SLorenzo Bianconi 			  name);
2027290a6ce1SLorenzo Bianconi 		break;
2028290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
2029290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
2030510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
2031510c0106SLorenzo Bianconi 			  name);
2032290a6ce1SLorenzo Bianconi 		break;
2033290a6ce1SLorenzo Bianconi 	default:
2034290a6ce1SLorenzo Bianconi 		return NULL;
2035290a6ce1SLorenzo Bianconi 	}
2036510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
2037290a6ce1SLorenzo Bianconi 
2038290a6ce1SLorenzo Bianconi 	return iio_dev;
2039290a6ce1SLorenzo Bianconi }
2040290a6ce1SLorenzo Bianconi 
2041615bd378SLorenzo Bianconi static bool
2042615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
20431aabad1fSSean Nyekjaer {
2044615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
2045615bd378SLorenzo Bianconi 	int err, data;
2046615bd378SLorenzo Bianconi 	s64 timestamp;
20471aabad1fSSean Nyekjaer 
2048615bd378SLorenzo Bianconi 	if (!hw->enable_event)
2049615bd378SLorenzo Bianconi 		return false;
2050615bd378SLorenzo Bianconi 
2051615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
2052615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2053615bd378SLorenzo Bianconi 				     &data, sizeof(data));
2054615bd378SLorenzo Bianconi 	if (err < 0)
2055615bd378SLorenzo Bianconi 		return false;
2056615bd378SLorenzo Bianconi 
2057615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
20581aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
20591aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
20601aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
20611aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
20621aabad1fSSean Nyekjaer 						  0,
20631aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
20641aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
20651aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
20661aabad1fSSean Nyekjaer 						  timestamp);
20671aabad1fSSean Nyekjaer 
20681aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
20691aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
20701aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
20711aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
20721aabad1fSSean Nyekjaer 						  0,
20731aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
20741aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
20751aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
20761aabad1fSSean Nyekjaer 						  timestamp);
20771aabad1fSSean Nyekjaer 
20781aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
20791aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
20801aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
20811aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
20821aabad1fSSean Nyekjaer 						  0,
20831aabad1fSSean Nyekjaer 						  IIO_MOD_X,
20841aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
20851aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
20861aabad1fSSean Nyekjaer 						  timestamp);
2087615bd378SLorenzo Bianconi 
2088615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
20891aabad1fSSean Nyekjaer }
20901aabad1fSSean Nyekjaer 
20916ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
20926ee6a368SSean Nyekjaer {
20936ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
2094615bd378SLorenzo Bianconi 	bool event;
20956ee6a368SSean Nyekjaer 	int count;
20961aabad1fSSean Nyekjaer 
2097615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
20986ee6a368SSean Nyekjaer 
2099a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
2100a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
2101a912ee4cSLorenzo Bianconi 
21026ee6a368SSean Nyekjaer 	mutex_lock(&hw->fifo_lock);
21036ee6a368SSean Nyekjaer 	count = hw->settings->fifo_ops.read_fifo(hw);
21046ee6a368SSean Nyekjaer 	mutex_unlock(&hw->fifo_lock);
21056ee6a368SSean Nyekjaer 
2106615bd378SLorenzo Bianconi 	return count || event ? IRQ_HANDLED : IRQ_NONE;
21076ee6a368SSean Nyekjaer }
21086ee6a368SSean Nyekjaer 
21096ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
21106ee6a368SSean Nyekjaer {
21116ee6a368SSean Nyekjaer 	struct device_node *np = hw->dev->of_node;
211231fe8d4eSLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
211331fe8d4eSLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
21146ee6a368SSean Nyekjaer 	unsigned long irq_type;
21156ee6a368SSean Nyekjaer 	bool irq_active_low;
21166ee6a368SSean Nyekjaer 	int err;
21176ee6a368SSean Nyekjaer 
21186ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
21196ee6a368SSean Nyekjaer 
21206ee6a368SSean Nyekjaer 	switch (irq_type) {
21216ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
21226ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
21236ee6a368SSean Nyekjaer 		irq_active_low = false;
21246ee6a368SSean Nyekjaer 		break;
21256ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
21266ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
21276ee6a368SSean Nyekjaer 		irq_active_low = true;
21286ee6a368SSean Nyekjaer 		break;
21296ee6a368SSean Nyekjaer 	default:
21306ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
21316ee6a368SSean Nyekjaer 		return -EINVAL;
21326ee6a368SSean Nyekjaer 	}
21336ee6a368SSean Nyekjaer 
213431fe8d4eSLorenzo Bianconi 	reg = &hw->settings->irq_config.hla;
213531fe8d4eSLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
213631fe8d4eSLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(irq_active_low,
213731fe8d4eSLorenzo Bianconi 						      reg->mask));
21386ee6a368SSean Nyekjaer 	if (err < 0)
21396ee6a368SSean Nyekjaer 		return err;
21406ee6a368SSean Nyekjaer 
21416ee6a368SSean Nyekjaer 	pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
21426ee6a368SSean Nyekjaer 	if ((np && of_property_read_bool(np, "drive-open-drain")) ||
21436ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
214431fe8d4eSLorenzo Bianconi 		reg = &hw->settings->irq_config.od;
214531fe8d4eSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
214631fe8d4eSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
21476ee6a368SSean Nyekjaer 		if (err < 0)
21486ee6a368SSean Nyekjaer 			return err;
21496ee6a368SSean Nyekjaer 
21506ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
21516ee6a368SSean Nyekjaer 	}
21526ee6a368SSean Nyekjaer 
21536ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
2154a3aa17d4SSean Nyekjaer 					NULL,
21556ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
21566ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
21576ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
21586ee6a368SSean Nyekjaer 	if (err) {
21596ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
21606ee6a368SSean Nyekjaer 			hw->irq);
21616ee6a368SSean Nyekjaer 		return err;
21626ee6a368SSean Nyekjaer 	}
21636ee6a368SSean Nyekjaer 
21646ee6a368SSean Nyekjaer 	return 0;
21656ee6a368SSean Nyekjaer }
21666ee6a368SSean Nyekjaer 
216781956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
216851a8b707SLorenzo Bianconi 		     struct regmap *regmap)
2169290a6ce1SLorenzo Bianconi {
2170b7a73b33SLorenzo Bianconi 	struct st_sensors_platform_data *pdata = dev->platform_data;
2171c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2172b7a73b33SLorenzo Bianconi 	struct device_node *np = dev->of_node;
2173290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
217481956a93SLorenzo Bianconi 	const char *name = NULL;
2175290a6ce1SLorenzo Bianconi 	int i, err;
2176290a6ce1SLorenzo Bianconi 
2177290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
2178290a6ce1SLorenzo Bianconi 	if (!hw)
2179290a6ce1SLorenzo Bianconi 		return -ENOMEM;
2180290a6ce1SLorenzo Bianconi 
2181290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
2182290a6ce1SLorenzo Bianconi 
2183290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
2184335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
2185739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
2186290a6ce1SLorenzo Bianconi 
218791a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
218891a6b841SLorenzo Bianconi 	if (!hw->buff)
218991a6b841SLorenzo Bianconi 		return -ENOMEM;
219091a6b841SLorenzo Bianconi 
2191290a6ce1SLorenzo Bianconi 	hw->dev = dev;
2192290a6ce1SLorenzo Bianconi 	hw->irq = irq;
219351a8b707SLorenzo Bianconi 	hw->regmap = regmap;
2194290a6ce1SLorenzo Bianconi 
219581956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
2196290a6ce1SLorenzo Bianconi 	if (err < 0)
2197290a6ce1SLorenzo Bianconi 		return err;
2198290a6ce1SLorenzo Bianconi 
21996ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
2200510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
2201290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
2202290a6ce1SLorenzo Bianconi 			return -ENOMEM;
2203290a6ce1SLorenzo Bianconi 	}
2204290a6ce1SLorenzo Bianconi 
2205290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
2206290a6ce1SLorenzo Bianconi 	if (err < 0)
2207290a6ce1SLorenzo Bianconi 		return err;
2208290a6ce1SLorenzo Bianconi 
2209c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2210c91c1c84SLorenzo Bianconi 	if (hub_settings->master_en.addr) {
2211c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
2212c91c1c84SLorenzo Bianconi 		if (err < 0)
2213c91c1c84SLorenzo Bianconi 			return err;
2214c91c1c84SLorenzo Bianconi 	}
2215c91c1c84SLorenzo Bianconi 
2216290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
22176ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
22186ee6a368SSean Nyekjaer 		if (err < 0)
22196ee6a368SSean Nyekjaer 			return err;
22206ee6a368SSean Nyekjaer 
2221290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
2222290a6ce1SLorenzo Bianconi 		if (err < 0)
2223290a6ce1SLorenzo Bianconi 			return err;
2224290a6ce1SLorenzo Bianconi 	}
2225290a6ce1SLorenzo Bianconi 
2226290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
22276ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
22286ffb55e5SLorenzo Bianconi 			continue;
22296ffb55e5SLorenzo Bianconi 
2230290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
2231290a6ce1SLorenzo Bianconi 		if (err)
2232290a6ce1SLorenzo Bianconi 			return err;
2233290a6ce1SLorenzo Bianconi 	}
2234290a6ce1SLorenzo Bianconi 
2235b7a73b33SLorenzo Bianconi 	if ((np && of_property_read_bool(np, "wakeup-source")) ||
2236b7a73b33SLorenzo Bianconi 	    (pdata && pdata->wakeup_source))
22374c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
22384c997dfaSSean Nyekjaer 
2239290a6ce1SLorenzo Bianconi 	return 0;
2240290a6ce1SLorenzo Bianconi }
2241290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe);
2242290a6ce1SLorenzo Bianconi 
22433cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
2244d3f77058SLorenzo Bianconi {
2245d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2246d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2247d3f77058SLorenzo Bianconi 	int i, err = 0;
2248d3f77058SLorenzo Bianconi 
2249d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
22506ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
22516ffb55e5SLorenzo Bianconi 			continue;
22526ffb55e5SLorenzo Bianconi 
2253d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
2254d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
2255d3f77058SLorenzo Bianconi 			continue;
2256d3f77058SLorenzo Bianconi 
22574c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
22584c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
22594c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
22604c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
22614c997dfaSSean Nyekjaer 			continue;
22624c997dfaSSean Nyekjaer 		}
22634c997dfaSSean Nyekjaer 
2264bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2265bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2266bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2267bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, false);
2268bce0d57dSLorenzo Bianconi 		else
2269bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, false);
2270d3f77058SLorenzo Bianconi 		if (err < 0)
2271d3f77058SLorenzo Bianconi 			return err;
2272bce0d57dSLorenzo Bianconi 
2273bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2274d3f77058SLorenzo Bianconi 	}
2275d3f77058SLorenzo Bianconi 
2276d3f77058SLorenzo Bianconi 	if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
2277d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2278d3f77058SLorenzo Bianconi 
2279d3f77058SLorenzo Bianconi 	return err;
2280d3f77058SLorenzo Bianconi }
2281d3f77058SLorenzo Bianconi 
22823cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
2283d3f77058SLorenzo Bianconi {
2284d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2285d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2286d3f77058SLorenzo Bianconi 	int i, err = 0;
2287d3f77058SLorenzo Bianconi 
2288d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
22896ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
22906ffb55e5SLorenzo Bianconi 			continue;
22916ffb55e5SLorenzo Bianconi 
2292d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
22934c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
22944c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
22954c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
22964c997dfaSSean Nyekjaer 
2297bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2298d3f77058SLorenzo Bianconi 			continue;
2299d3f77058SLorenzo Bianconi 
2300bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2301bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2302bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2303bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, true);
2304bce0d57dSLorenzo Bianconi 		else
2305bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, true);
2306d3f77058SLorenzo Bianconi 		if (err < 0)
2307d3f77058SLorenzo Bianconi 			return err;
2308bce0d57dSLorenzo Bianconi 
2309bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2310d3f77058SLorenzo Bianconi 	}
2311d3f77058SLorenzo Bianconi 
2312d3f77058SLorenzo Bianconi 	if (hw->enable_mask)
2313d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
2314d3f77058SLorenzo Bianconi 
2315d3f77058SLorenzo Bianconi 	return err;
2316d3f77058SLorenzo Bianconi }
2317d3f77058SLorenzo Bianconi 
2318d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = {
2319d3f77058SLorenzo Bianconi 	SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
2320d3f77058SLorenzo Bianconi };
2321d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
2322d3f77058SLorenzo Bianconi 
2323290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2324290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2325290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2326290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2327