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  *
35fa060a3dSLorenzo Bianconi  * - LSM9DS1/LSM6DS0:
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>
5703d4c566SAndy Shevchenko #include <linux/property.h>
5851a8b707SLorenzo Bianconi #include <linux/regmap.h>
5951a8b707SLorenzo Bianconi #include <linux/bitfield.h>
60290a6ce1SLorenzo Bianconi 
61dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h>
62dba32904SLorenzo Bianconi 
63290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h"
64290a6ce1SLorenzo Bianconi 
65290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR		0x0f
66290a6ce1SLorenzo Bianconi 
67cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY		25000UL /* 25us */
68cb3b6b8eSMario Tesi 
69f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
70b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
71b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
72b5969abfSSean Nyekjaer 	ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
73f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
74f48bc49bSLorenzo Bianconi };
75f48bc49bSLorenzo Bianconi 
76f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
77f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
78f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
79f48bc49bSLorenzo Bianconi 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
80f48bc49bSLorenzo Bianconi 	IIO_CHAN_SOFT_TIMESTAMP(3),
81f48bc49bSLorenzo Bianconi };
82f48bc49bSLorenzo Bianconi 
8352f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
8452f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
8552f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
8652f4b1f1SMartin Kepplinger 	ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
8752f4b1f1SMartin Kepplinger 	IIO_CHAN_SOFT_TIMESTAMP(3),
8852f4b1f1SMartin Kepplinger };
8952f4b1f1SMartin Kepplinger 
90290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
91290a6ce1SLorenzo Bianconi 	{
9252f4b1f1SMartin Kepplinger 		.wai = 0x68,
9366b662a1SLorenzo Bianconi 		.reset = {
9466b662a1SLorenzo Bianconi 			.addr = 0x22,
9566b662a1SLorenzo Bianconi 			.mask = BIT(0),
9666b662a1SLorenzo Bianconi 		},
9766b662a1SLorenzo Bianconi 		.boot = {
9866b662a1SLorenzo Bianconi 			.addr = 0x22,
9966b662a1SLorenzo Bianconi 			.mask = BIT(7),
10066b662a1SLorenzo Bianconi 		},
10166b662a1SLorenzo Bianconi 		.bdu = {
10266b662a1SLorenzo Bianconi 			.addr = 0x22,
10366b662a1SLorenzo Bianconi 			.mask = BIT(6),
10466b662a1SLorenzo Bianconi 		},
10552f4b1f1SMartin Kepplinger 		.max_fifo_size = 32,
10652f4b1f1SMartin Kepplinger 		.id = {
10752f4b1f1SMartin Kepplinger 			{
10852f4b1f1SMartin Kepplinger 				.hw_id = ST_LSM9DS1_ID,
10952f4b1f1SMartin Kepplinger 				.name = ST_LSM9DS1_DEV_NAME,
110fa060a3dSLorenzo Bianconi 			}, {
111fa060a3dSLorenzo Bianconi 				.hw_id = ST_LSM6DS0_ID,
112fa060a3dSLorenzo Bianconi 				.name = ST_LSM6DS0_DEV_NAME,
11352f4b1f1SMartin Kepplinger 			},
11452f4b1f1SMartin Kepplinger 		},
11552f4b1f1SMartin Kepplinger 		.channels = {
11652f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
11752f4b1f1SMartin Kepplinger 				.chan = st_lsm6dsx_acc_channels,
11852f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
11952f4b1f1SMartin Kepplinger 			},
12052f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
12152f4b1f1SMartin Kepplinger 				.chan = st_lsm6ds0_gyro_channels,
12252f4b1f1SMartin Kepplinger 				.len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
12352f4b1f1SMartin Kepplinger 			},
12452f4b1f1SMartin Kepplinger 		},
12552f4b1f1SMartin Kepplinger 		.odr_table = {
12652f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
12752f4b1f1SMartin Kepplinger 				.reg = {
12852f4b1f1SMartin Kepplinger 					.addr = 0x20,
12952f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
13052f4b1f1SMartin Kepplinger 				},
131f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  10000, 0x01 },
132f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  50000, 0x02 },
133f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
134f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
135f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
136f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
13759af4e20SLorenzo Bianconi 				.odr_len = 6,
13852f4b1f1SMartin Kepplinger 			},
13952f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
14052f4b1f1SMartin Kepplinger 				.reg = {
14152f4b1f1SMartin Kepplinger 					.addr = 0x10,
14252f4b1f1SMartin Kepplinger 					.mask = GENMASK(7, 5),
14352f4b1f1SMartin Kepplinger 				},
144f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  14900, 0x01 },
145f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  59500, 0x02 },
146f8710f03SLorenzo Bianconi 				.odr_avl[2] = { 119000, 0x03 },
147f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 238000, 0x04 },
148f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 476000, 0x05 },
149f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 952000, 0x06 },
15059af4e20SLorenzo Bianconi 				.odr_len = 6,
15152f4b1f1SMartin Kepplinger 			},
15252f4b1f1SMartin Kepplinger 		},
15352f4b1f1SMartin Kepplinger 		.fs_table = {
15452f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_ACC] = {
15552f4b1f1SMartin Kepplinger 				.reg = {
15652f4b1f1SMartin Kepplinger 					.addr = 0x20,
15752f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
15852f4b1f1SMartin Kepplinger 				},
1596fa02948SLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
1606fa02948SLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
1616fa02948SLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
1626fa02948SLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
16385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
16452f4b1f1SMartin Kepplinger 			},
16552f4b1f1SMartin Kepplinger 			[ST_LSM6DSX_ID_GYRO] = {
16652f4b1f1SMartin Kepplinger 				.reg = {
16752f4b1f1SMartin Kepplinger 					.addr = 0x10,
16852f4b1f1SMartin Kepplinger 					.mask = GENMASK(4, 3),
16952f4b1f1SMartin Kepplinger 				},
1701b375101SLorenzo Bianconi 
1711b375101SLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
1721b375101SLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
1731b375101SLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
17485ae3aeeSLorenzo Bianconi 				.fs_len = 3,
17552f4b1f1SMartin Kepplinger 			},
17652f4b1f1SMartin Kepplinger 		},
1777e906103SLorenzo Bianconi 		.irq_config = {
1787e906103SLorenzo Bianconi 			.irq1 = {
1797e906103SLorenzo Bianconi 				.addr = 0x0c,
1807e906103SLorenzo Bianconi 				.mask = BIT(3),
1817e906103SLorenzo Bianconi 			},
1827e906103SLorenzo Bianconi 			.irq2 = {
1837e906103SLorenzo Bianconi 				.addr = 0x0d,
1847e906103SLorenzo Bianconi 				.mask = BIT(3),
1857e906103SLorenzo Bianconi 			},
18631fe8d4eSLorenzo Bianconi 			.hla = {
18731fe8d4eSLorenzo Bianconi 				.addr = 0x22,
18831fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
18931fe8d4eSLorenzo Bianconi 			},
19031fe8d4eSLorenzo Bianconi 			.od = {
19131fe8d4eSLorenzo Bianconi 				.addr = 0x22,
19231fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
19331fe8d4eSLorenzo Bianconi 			},
1947e906103SLorenzo Bianconi 		},
19552f4b1f1SMartin Kepplinger 	},
19652f4b1f1SMartin Kepplinger 	{
197d068e4a0SLorenzo Bianconi 		.wai = 0x69,
19866b662a1SLorenzo Bianconi 		.reset = {
19966b662a1SLorenzo Bianconi 			.addr = 0x12,
20066b662a1SLorenzo Bianconi 			.mask = BIT(0),
20166b662a1SLorenzo Bianconi 		},
20266b662a1SLorenzo Bianconi 		.boot = {
20366b662a1SLorenzo Bianconi 			.addr = 0x12,
20466b662a1SLorenzo Bianconi 			.mask = BIT(7),
20566b662a1SLorenzo Bianconi 		},
20666b662a1SLorenzo Bianconi 		.bdu = {
20766b662a1SLorenzo Bianconi 			.addr = 0x12,
20866b662a1SLorenzo Bianconi 			.mask = BIT(6),
20966b662a1SLorenzo Bianconi 		},
2108f2a88a2SLorenzo Bianconi 		.max_fifo_size = 1365,
211d068e4a0SLorenzo Bianconi 		.id = {
21281956a93SLorenzo Bianconi 			{
21381956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3_ID,
21481956a93SLorenzo Bianconi 				.name = ST_LSM6DS3_DEV_NAME,
21581956a93SLorenzo Bianconi 			},
216d068e4a0SLorenzo Bianconi 		},
217f48bc49bSLorenzo Bianconi 		.channels = {
218f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
219f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
220f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
221f48bc49bSLorenzo Bianconi 			},
222f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
223f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
224f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
225f48bc49bSLorenzo Bianconi 			},
226f48bc49bSLorenzo Bianconi 		},
22740dd7343SLorenzo Bianconi 		.odr_table = {
22840dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
22940dd7343SLorenzo Bianconi 				.reg = {
23040dd7343SLorenzo Bianconi 					.addr = 0x10,
23140dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
23240dd7343SLorenzo Bianconi 				},
233f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
234f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
235f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
236f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
237f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
238f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
23959af4e20SLorenzo Bianconi 				.odr_len = 6,
24040dd7343SLorenzo Bianconi 			},
24140dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
24240dd7343SLorenzo Bianconi 				.reg = {
24340dd7343SLorenzo Bianconi 					.addr = 0x11,
24440dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
24540dd7343SLorenzo Bianconi 				},
246f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
247f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
248f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
249f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
250f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
251f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
25259af4e20SLorenzo Bianconi 				.odr_len = 6,
25340dd7343SLorenzo Bianconi 			},
25440dd7343SLorenzo Bianconi 		},
255640aca3fSLorenzo Bianconi 		.fs_table = {
256640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
257640aca3fSLorenzo Bianconi 				.reg = {
258640aca3fSLorenzo Bianconi 					.addr = 0x10,
259640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
260640aca3fSLorenzo Bianconi 				},
261640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
262640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
263640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
264640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
26585ae3aeeSLorenzo Bianconi 				.fs_len = 4,
266640aca3fSLorenzo Bianconi 			},
267640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
268640aca3fSLorenzo Bianconi 				.reg = {
269640aca3fSLorenzo Bianconi 					.addr = 0x11,
270640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
271640aca3fSLorenzo Bianconi 				},
272640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
273640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
274640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
275640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
27685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
277640aca3fSLorenzo Bianconi 			},
278640aca3fSLorenzo Bianconi 		},
2797e906103SLorenzo Bianconi 		.irq_config = {
2807e906103SLorenzo Bianconi 			.irq1 = {
2817e906103SLorenzo Bianconi 				.addr = 0x0d,
2827e906103SLorenzo Bianconi 				.mask = BIT(3),
2837e906103SLorenzo Bianconi 			},
2847e906103SLorenzo Bianconi 			.irq2 = {
2857e906103SLorenzo Bianconi 				.addr = 0x0e,
2867e906103SLorenzo Bianconi 				.mask = BIT(3),
2877e906103SLorenzo Bianconi 			},
2887e906103SLorenzo Bianconi 			.lir = {
2897e906103SLorenzo Bianconi 				.addr = 0x58,
2907e906103SLorenzo Bianconi 				.mask = BIT(0),
2917e906103SLorenzo Bianconi 			},
2927e906103SLorenzo Bianconi 			.irq1_func = {
2937e906103SLorenzo Bianconi 				.addr = 0x5e,
2947e906103SLorenzo Bianconi 				.mask = BIT(5),
2957e906103SLorenzo Bianconi 			},
2967e906103SLorenzo Bianconi 			.irq2_func = {
2977e906103SLorenzo Bianconi 				.addr = 0x5f,
2987e906103SLorenzo Bianconi 				.mask = BIT(5),
2997e906103SLorenzo Bianconi 			},
30031fe8d4eSLorenzo Bianconi 			.hla = {
30131fe8d4eSLorenzo Bianconi 				.addr = 0x12,
30231fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
30331fe8d4eSLorenzo Bianconi 			},
30431fe8d4eSLorenzo Bianconi 			.od = {
30531fe8d4eSLorenzo Bianconi 				.addr = 0x12,
30631fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
30731fe8d4eSLorenzo Bianconi 			},
3087e906103SLorenzo Bianconi 		},
3097ca3ac9eSLorenzo Bianconi 		.decimator = {
3107ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
3117ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3127ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
3137ca3ac9eSLorenzo Bianconi 			},
3147ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
3157ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
3167ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
3177ca3ac9eSLorenzo Bianconi 			},
3187ca3ac9eSLorenzo Bianconi 		},
31992617c15SLorenzo Bianconi 		.fifo_ops = {
3203b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
32150ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
32292617c15SLorenzo Bianconi 			.fifo_th = {
32392617c15SLorenzo Bianconi 				.addr = 0x06,
32492617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
32592617c15SLorenzo Bianconi 			},
32692617c15SLorenzo Bianconi 			.fifo_diff = {
32792617c15SLorenzo Bianconi 				.addr = 0x3a,
32892617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
32992617c15SLorenzo Bianconi 			},
33092617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
33192617c15SLorenzo Bianconi 		},
33221345107SLorenzo Bianconi 		.ts_settings = {
33321345107SLorenzo Bianconi 			.timer_en = {
33421345107SLorenzo Bianconi 				.addr = 0x58,
33521345107SLorenzo Bianconi 				.mask = BIT(7),
33621345107SLorenzo Bianconi 			},
33721345107SLorenzo Bianconi 			.hr_timer = {
33821345107SLorenzo Bianconi 				.addr = 0x5c,
33921345107SLorenzo Bianconi 				.mask = BIT(4),
34021345107SLorenzo Bianconi 			},
34121345107SLorenzo Bianconi 			.fifo_en = {
34221345107SLorenzo Bianconi 				.addr = 0x07,
34321345107SLorenzo Bianconi 				.mask = BIT(7),
34421345107SLorenzo Bianconi 			},
34521345107SLorenzo Bianconi 			.decimator = {
34621345107SLorenzo Bianconi 				.addr = 0x09,
34721345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
34821345107SLorenzo Bianconi 			},
34921345107SLorenzo Bianconi 		},
350b5969abfSSean Nyekjaer 		.event_settings = {
351b5969abfSSean Nyekjaer 			.wakeup_reg = {
352b5969abfSSean Nyekjaer 				.addr = 0x5B,
353b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
354b5969abfSSean Nyekjaer 			},
3551aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
3561aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
3571aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
3581aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
3591aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
360b5969abfSSean Nyekjaer 		},
361290a6ce1SLorenzo Bianconi 	},
362290a6ce1SLorenzo Bianconi 	{
363df47710aSLorenzo Bianconi 		.wai = 0x69,
36466b662a1SLorenzo Bianconi 		.reset = {
36566b662a1SLorenzo Bianconi 			.addr = 0x12,
36666b662a1SLorenzo Bianconi 			.mask = BIT(0),
36766b662a1SLorenzo Bianconi 		},
36866b662a1SLorenzo Bianconi 		.boot = {
36966b662a1SLorenzo Bianconi 			.addr = 0x12,
37066b662a1SLorenzo Bianconi 			.mask = BIT(7),
37166b662a1SLorenzo Bianconi 		},
37266b662a1SLorenzo Bianconi 		.bdu = {
37366b662a1SLorenzo Bianconi 			.addr = 0x12,
37466b662a1SLorenzo Bianconi 			.mask = BIT(6),
37566b662a1SLorenzo Bianconi 		},
3768f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
377df47710aSLorenzo Bianconi 		.id = {
37881956a93SLorenzo Bianconi 			{
37981956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DS3H_ID,
38081956a93SLorenzo Bianconi 				.name = ST_LSM6DS3H_DEV_NAME,
38181956a93SLorenzo Bianconi 			},
382df47710aSLorenzo Bianconi 		},
383f48bc49bSLorenzo Bianconi 		.channels = {
384f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
385f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
386f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
387f48bc49bSLorenzo Bianconi 			},
388f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
389f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
390f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
391f48bc49bSLorenzo Bianconi 			},
392f48bc49bSLorenzo Bianconi 		},
39340dd7343SLorenzo Bianconi 		.odr_table = {
39440dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
39540dd7343SLorenzo Bianconi 				.reg = {
39640dd7343SLorenzo Bianconi 					.addr = 0x10,
39740dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
39840dd7343SLorenzo Bianconi 				},
399f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
400f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
401f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
402f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
403f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
404f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
40559af4e20SLorenzo Bianconi 				.odr_len = 6,
40640dd7343SLorenzo Bianconi 			},
40740dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
40840dd7343SLorenzo Bianconi 				.reg = {
40940dd7343SLorenzo Bianconi 					.addr = 0x11,
41040dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
41140dd7343SLorenzo Bianconi 				},
412f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
413f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
414f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
415f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
416f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
417f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
41859af4e20SLorenzo Bianconi 				.odr_len = 6,
41940dd7343SLorenzo Bianconi 			},
42040dd7343SLorenzo Bianconi 		},
421640aca3fSLorenzo Bianconi 		.fs_table = {
422640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
423640aca3fSLorenzo Bianconi 				.reg = {
424640aca3fSLorenzo Bianconi 					.addr = 0x10,
425640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
426640aca3fSLorenzo Bianconi 				},
427640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
428640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
429640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
430640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
43185ae3aeeSLorenzo Bianconi 				.fs_len = 4,
432640aca3fSLorenzo Bianconi 			},
433640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
434640aca3fSLorenzo Bianconi 				.reg = {
435640aca3fSLorenzo Bianconi 					.addr = 0x11,
436640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
437640aca3fSLorenzo Bianconi 				},
438640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
439640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
440640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
441640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
44285ae3aeeSLorenzo Bianconi 				.fs_len = 4,
443640aca3fSLorenzo Bianconi 			},
444640aca3fSLorenzo Bianconi 		},
4457e906103SLorenzo Bianconi 		.irq_config = {
4467e906103SLorenzo Bianconi 			.irq1 = {
4477e906103SLorenzo Bianconi 				.addr = 0x0d,
4487e906103SLorenzo Bianconi 				.mask = BIT(3),
4497e906103SLorenzo Bianconi 			},
4507e906103SLorenzo Bianconi 			.irq2 = {
4517e906103SLorenzo Bianconi 				.addr = 0x0e,
4527e906103SLorenzo Bianconi 				.mask = BIT(3),
4537e906103SLorenzo Bianconi 			},
4547e906103SLorenzo Bianconi 			.lir = {
4557e906103SLorenzo Bianconi 				.addr = 0x58,
4567e906103SLorenzo Bianconi 				.mask = BIT(0),
4577e906103SLorenzo Bianconi 			},
4587e906103SLorenzo Bianconi 			.irq1_func = {
4597e906103SLorenzo Bianconi 				.addr = 0x5e,
4607e906103SLorenzo Bianconi 				.mask = BIT(5),
4617e906103SLorenzo Bianconi 			},
4627e906103SLorenzo Bianconi 			.irq2_func = {
4637e906103SLorenzo Bianconi 				.addr = 0x5f,
4647e906103SLorenzo Bianconi 				.mask = BIT(5),
4657e906103SLorenzo Bianconi 			},
46631fe8d4eSLorenzo Bianconi 			.hla = {
46731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
46831fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
46931fe8d4eSLorenzo Bianconi 			},
47031fe8d4eSLorenzo Bianconi 			.od = {
47131fe8d4eSLorenzo Bianconi 				.addr = 0x12,
47231fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
47331fe8d4eSLorenzo Bianconi 			},
4747e906103SLorenzo Bianconi 		},
4757ca3ac9eSLorenzo Bianconi 		.decimator = {
4767ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
4777ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4787ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
4797ca3ac9eSLorenzo Bianconi 			},
4807ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
4817ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
4827ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
4837ca3ac9eSLorenzo Bianconi 			},
4847ca3ac9eSLorenzo Bianconi 		},
48592617c15SLorenzo Bianconi 		.fifo_ops = {
4863b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
48750ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
48892617c15SLorenzo Bianconi 			.fifo_th = {
48992617c15SLorenzo Bianconi 				.addr = 0x06,
49092617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
49192617c15SLorenzo Bianconi 			},
49292617c15SLorenzo Bianconi 			.fifo_diff = {
49392617c15SLorenzo Bianconi 				.addr = 0x3a,
49492617c15SLorenzo Bianconi 				.mask = GENMASK(11, 0),
49592617c15SLorenzo Bianconi 			},
49692617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
49792617c15SLorenzo Bianconi 		},
49821345107SLorenzo Bianconi 		.ts_settings = {
49921345107SLorenzo Bianconi 			.timer_en = {
50021345107SLorenzo Bianconi 				.addr = 0x58,
50121345107SLorenzo Bianconi 				.mask = BIT(7),
50221345107SLorenzo Bianconi 			},
50321345107SLorenzo Bianconi 			.hr_timer = {
50421345107SLorenzo Bianconi 				.addr = 0x5c,
50521345107SLorenzo Bianconi 				.mask = BIT(4),
50621345107SLorenzo Bianconi 			},
50721345107SLorenzo Bianconi 			.fifo_en = {
50821345107SLorenzo Bianconi 				.addr = 0x07,
50921345107SLorenzo Bianconi 				.mask = BIT(7),
51021345107SLorenzo Bianconi 			},
51121345107SLorenzo Bianconi 			.decimator = {
51221345107SLorenzo Bianconi 				.addr = 0x09,
51321345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
51421345107SLorenzo Bianconi 			},
51521345107SLorenzo Bianconi 		},
516b5969abfSSean Nyekjaer 		.event_settings = {
517b5969abfSSean Nyekjaer 			.wakeup_reg = {
518b5969abfSSean Nyekjaer 				.addr = 0x5B,
519b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
520b5969abfSSean Nyekjaer 			},
5211aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
5221aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
5231aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
5241aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
5251aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
526b5969abfSSean Nyekjaer 		},
527df47710aSLorenzo Bianconi 	},
528df47710aSLorenzo Bianconi 	{
529d068e4a0SLorenzo Bianconi 		.wai = 0x6a,
53066b662a1SLorenzo Bianconi 		.reset = {
53166b662a1SLorenzo Bianconi 			.addr = 0x12,
53266b662a1SLorenzo Bianconi 			.mask = BIT(0),
53366b662a1SLorenzo Bianconi 		},
53466b662a1SLorenzo Bianconi 		.boot = {
53566b662a1SLorenzo Bianconi 			.addr = 0x12,
53666b662a1SLorenzo Bianconi 			.mask = BIT(7),
53766b662a1SLorenzo Bianconi 		},
53866b662a1SLorenzo Bianconi 		.bdu = {
53966b662a1SLorenzo Bianconi 			.addr = 0x12,
54066b662a1SLorenzo Bianconi 			.mask = BIT(6),
54166b662a1SLorenzo Bianconi 		},
5428f2a88a2SLorenzo Bianconi 		.max_fifo_size = 682,
543d068e4a0SLorenzo Bianconi 		.id = {
54481956a93SLorenzo Bianconi 			{
54581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSL_ID,
54681956a93SLorenzo Bianconi 				.name = ST_LSM6DSL_DEV_NAME,
54781956a93SLorenzo Bianconi 			}, {
54881956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSM_ID,
54981956a93SLorenzo Bianconi 				.name = ST_LSM6DSM_DEV_NAME,
55081956a93SLorenzo Bianconi 			}, {
55181956a93SLorenzo Bianconi 				.hw_id = ST_ISM330DLC_ID,
55281956a93SLorenzo Bianconi 				.name = ST_ISM330DLC_DEV_NAME,
553dbcd2088SLorenzo Bianconi 			}, {
554dbcd2088SLorenzo Bianconi 				.hw_id = ST_LSM6DS3TRC_ID,
555dbcd2088SLorenzo Bianconi 				.name = ST_LSM6DS3TRC_DEV_NAME,
55681956a93SLorenzo Bianconi 			},
557d068e4a0SLorenzo Bianconi 		},
558f48bc49bSLorenzo Bianconi 		.channels = {
559f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
560f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
561f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
562f48bc49bSLorenzo Bianconi 			},
563f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
564f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
565f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
566f48bc49bSLorenzo Bianconi 			},
567f48bc49bSLorenzo Bianconi 		},
56840dd7343SLorenzo Bianconi 		.odr_table = {
56940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
57040dd7343SLorenzo Bianconi 				.reg = {
57140dd7343SLorenzo Bianconi 					.addr = 0x10,
57240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
57340dd7343SLorenzo Bianconi 				},
574f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
575f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
576f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
577f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
578f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
579f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
58059af4e20SLorenzo Bianconi 				.odr_len = 6,
58140dd7343SLorenzo Bianconi 			},
58240dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
58340dd7343SLorenzo Bianconi 				.reg = {
58440dd7343SLorenzo Bianconi 					.addr = 0x11,
58540dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
58640dd7343SLorenzo Bianconi 				},
587f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
588f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
589f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
590f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
591f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
592f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
59359af4e20SLorenzo Bianconi 				.odr_len = 6,
59440dd7343SLorenzo Bianconi 			},
59540dd7343SLorenzo Bianconi 		},
596640aca3fSLorenzo Bianconi 		.fs_table = {
597640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
598640aca3fSLorenzo Bianconi 				.reg = {
599640aca3fSLorenzo Bianconi 					.addr = 0x10,
600640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
601640aca3fSLorenzo Bianconi 				},
602640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
603640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
604640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
605640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
60685ae3aeeSLorenzo Bianconi 				.fs_len = 4,
607640aca3fSLorenzo Bianconi 			},
608640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
609640aca3fSLorenzo Bianconi 				.reg = {
610640aca3fSLorenzo Bianconi 					.addr = 0x11,
611640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
612640aca3fSLorenzo Bianconi 				},
613640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
614640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
615640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
616640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
61785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
618640aca3fSLorenzo Bianconi 			},
619640aca3fSLorenzo Bianconi 		},
6207e906103SLorenzo Bianconi 		.irq_config = {
6217e906103SLorenzo Bianconi 			.irq1 = {
6227e906103SLorenzo Bianconi 				.addr = 0x0d,
6237e906103SLorenzo Bianconi 				.mask = BIT(3),
6247e906103SLorenzo Bianconi 			},
6257e906103SLorenzo Bianconi 			.irq2 = {
6267e906103SLorenzo Bianconi 				.addr = 0x0e,
6277e906103SLorenzo Bianconi 				.mask = BIT(3),
6287e906103SLorenzo Bianconi 			},
6297e906103SLorenzo Bianconi 			.lir = {
6307e906103SLorenzo Bianconi 				.addr = 0x58,
6317e906103SLorenzo Bianconi 				.mask = BIT(0),
6327e906103SLorenzo Bianconi 			},
6337e906103SLorenzo Bianconi 			.irq1_func = {
6347e906103SLorenzo Bianconi 				.addr = 0x5e,
6357e906103SLorenzo Bianconi 				.mask = BIT(5),
6367e906103SLorenzo Bianconi 			},
6377e906103SLorenzo Bianconi 			.irq2_func = {
6387e906103SLorenzo Bianconi 				.addr = 0x5f,
6397e906103SLorenzo Bianconi 				.mask = BIT(5),
6407e906103SLorenzo Bianconi 			},
64131fe8d4eSLorenzo Bianconi 			.hla = {
64231fe8d4eSLorenzo Bianconi 				.addr = 0x12,
64331fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
64431fe8d4eSLorenzo Bianconi 			},
64531fe8d4eSLorenzo Bianconi 			.od = {
64631fe8d4eSLorenzo Bianconi 				.addr = 0x12,
64731fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
64831fe8d4eSLorenzo Bianconi 			},
6497e906103SLorenzo Bianconi 		},
6507ca3ac9eSLorenzo Bianconi 		.decimator = {
6517ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
6527ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6537ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(2, 0),
6547ca3ac9eSLorenzo Bianconi 			},
6557ca3ac9eSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
6567ca3ac9eSLorenzo Bianconi 				.addr = 0x08,
6577ca3ac9eSLorenzo Bianconi 				.mask = GENMASK(5, 3),
6587ca3ac9eSLorenzo Bianconi 			},
6597ca3ac9eSLorenzo Bianconi 		},
66092617c15SLorenzo Bianconi 		.fifo_ops = {
6613b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
66250ff457dSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_fifo,
66392617c15SLorenzo Bianconi 			.fifo_th = {
66492617c15SLorenzo Bianconi 				.addr = 0x06,
665be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
66692617c15SLorenzo Bianconi 			},
66792617c15SLorenzo Bianconi 			.fifo_diff = {
66892617c15SLorenzo Bianconi 				.addr = 0x3a,
669be75eb86SLorenzo Bianconi 				.mask = GENMASK(10, 0),
67092617c15SLorenzo Bianconi 			},
67192617c15SLorenzo Bianconi 			.th_wl = 3, /* 1LSB = 2B */
67292617c15SLorenzo Bianconi 		},
67321345107SLorenzo Bianconi 		.ts_settings = {
67421345107SLorenzo Bianconi 			.timer_en = {
67521345107SLorenzo Bianconi 				.addr = 0x19,
67621345107SLorenzo Bianconi 				.mask = BIT(5),
67721345107SLorenzo Bianconi 			},
67821345107SLorenzo Bianconi 			.hr_timer = {
67921345107SLorenzo Bianconi 				.addr = 0x5c,
68021345107SLorenzo Bianconi 				.mask = BIT(4),
68121345107SLorenzo Bianconi 			},
68221345107SLorenzo Bianconi 			.fifo_en = {
68321345107SLorenzo Bianconi 				.addr = 0x07,
68421345107SLorenzo Bianconi 				.mask = BIT(7),
68521345107SLorenzo Bianconi 			},
68621345107SLorenzo Bianconi 			.decimator = {
68721345107SLorenzo Bianconi 				.addr = 0x09,
68821345107SLorenzo Bianconi 				.mask = GENMASK(5, 3),
68921345107SLorenzo Bianconi 			},
69021345107SLorenzo Bianconi 		},
691b5969abfSSean Nyekjaer 		.event_settings = {
692b5969abfSSean Nyekjaer 			.enable_reg = {
693b5969abfSSean Nyekjaer 				.addr = 0x58,
694b5969abfSSean Nyekjaer 				.mask = BIT(7),
695b5969abfSSean Nyekjaer 			},
696b5969abfSSean Nyekjaer 			.wakeup_reg = {
697b5969abfSSean Nyekjaer 				.addr = 0x5B,
698b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
699b5969abfSSean Nyekjaer 			},
7001aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
7011aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
7021aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
7031aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
7041aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
705b5969abfSSean Nyekjaer 		},
706290a6ce1SLorenzo Bianconi 	},
707801a6e0aSLorenzo Bianconi 	{
708801a6e0aSLorenzo Bianconi 		.wai = 0x6c,
70966b662a1SLorenzo Bianconi 		.reset = {
71066b662a1SLorenzo Bianconi 			.addr = 0x12,
71166b662a1SLorenzo Bianconi 			.mask = BIT(0),
71266b662a1SLorenzo Bianconi 		},
71366b662a1SLorenzo Bianconi 		.boot = {
71466b662a1SLorenzo Bianconi 			.addr = 0x12,
71566b662a1SLorenzo Bianconi 			.mask = BIT(7),
71666b662a1SLorenzo Bianconi 		},
71766b662a1SLorenzo Bianconi 		.bdu = {
71866b662a1SLorenzo Bianconi 			.addr = 0x12,
71966b662a1SLorenzo Bianconi 			.mask = BIT(6),
72066b662a1SLorenzo Bianconi 		},
721801a6e0aSLorenzo Bianconi 		.max_fifo_size = 512,
722801a6e0aSLorenzo Bianconi 		.id = {
72381956a93SLorenzo Bianconi 			{
72481956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSO_ID,
72581956a93SLorenzo Bianconi 				.name = ST_LSM6DSO_DEV_NAME,
72681956a93SLorenzo Bianconi 			}, {
72781956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSOX_ID,
72881956a93SLorenzo Bianconi 				.name = ST_LSM6DSOX_DEV_NAME,
72981956a93SLorenzo Bianconi 			},
730801a6e0aSLorenzo Bianconi 		},
731f48bc49bSLorenzo Bianconi 		.channels = {
732f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
733f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
734f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
735f48bc49bSLorenzo Bianconi 			},
736f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
737f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
738f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
739f48bc49bSLorenzo Bianconi 			},
740f48bc49bSLorenzo Bianconi 		},
741960506edSLorenzo Bianconi 		.drdy_mask = {
742960506edSLorenzo Bianconi 			.addr = 0x13,
743960506edSLorenzo Bianconi 			.mask = BIT(3),
744960506edSLorenzo Bianconi 		},
74540dd7343SLorenzo Bianconi 		.odr_table = {
74640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
74740dd7343SLorenzo Bianconi 				.reg = {
74840dd7343SLorenzo Bianconi 					.addr = 0x10,
74940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
75040dd7343SLorenzo Bianconi 				},
751f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
752f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
753f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
754f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
755f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
756f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
75759af4e20SLorenzo Bianconi 				.odr_len = 6,
75840dd7343SLorenzo Bianconi 			},
75940dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
76040dd7343SLorenzo Bianconi 				.reg = {
76140dd7343SLorenzo Bianconi 					.addr = 0x11,
76240dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
76340dd7343SLorenzo Bianconi 				},
764f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
765f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
766f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
767f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
768f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
769f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
77059af4e20SLorenzo Bianconi 				.odr_len = 6,
77140dd7343SLorenzo Bianconi 			},
77240dd7343SLorenzo Bianconi 		},
773640aca3fSLorenzo Bianconi 		.fs_table = {
774640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
775640aca3fSLorenzo Bianconi 				.reg = {
776640aca3fSLorenzo Bianconi 					.addr = 0x10,
777640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
778640aca3fSLorenzo Bianconi 				},
779640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
780640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
781640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
782640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
78385ae3aeeSLorenzo Bianconi 				.fs_len = 4,
784640aca3fSLorenzo Bianconi 			},
785640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
786640aca3fSLorenzo Bianconi 				.reg = {
787640aca3fSLorenzo Bianconi 					.addr = 0x11,
788640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
789640aca3fSLorenzo Bianconi 				},
790640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
791640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
792640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
793640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
79485ae3aeeSLorenzo Bianconi 				.fs_len = 4,
795640aca3fSLorenzo Bianconi 			},
796640aca3fSLorenzo Bianconi 		},
7977e906103SLorenzo Bianconi 		.irq_config = {
7987e906103SLorenzo Bianconi 			.irq1 = {
7997e906103SLorenzo Bianconi 				.addr = 0x0d,
8007e906103SLorenzo Bianconi 				.mask = BIT(3),
8017e906103SLorenzo Bianconi 			},
8027e906103SLorenzo Bianconi 			.irq2 = {
8037e906103SLorenzo Bianconi 				.addr = 0x0e,
8047e906103SLorenzo Bianconi 				.mask = BIT(3),
8057e906103SLorenzo Bianconi 			},
8067e906103SLorenzo Bianconi 			.lir = {
8077e906103SLorenzo Bianconi 				.addr = 0x56,
8087e906103SLorenzo Bianconi 				.mask = BIT(0),
8097e906103SLorenzo Bianconi 			},
8107e906103SLorenzo Bianconi 			.clear_on_read = {
8117e906103SLorenzo Bianconi 				.addr = 0x56,
8127e906103SLorenzo Bianconi 				.mask = BIT(6),
8137e906103SLorenzo Bianconi 			},
8143ea39d61SLorenzo Bianconi 			.irq1_func = {
8153ea39d61SLorenzo Bianconi 				.addr = 0x5e,
8163ea39d61SLorenzo Bianconi 				.mask = BIT(5),
8173ea39d61SLorenzo Bianconi 			},
8183ea39d61SLorenzo Bianconi 			.irq2_func = {
8193ea39d61SLorenzo Bianconi 				.addr = 0x5f,
8203ea39d61SLorenzo Bianconi 				.mask = BIT(5),
8213ea39d61SLorenzo Bianconi 			},
82231fe8d4eSLorenzo Bianconi 			.hla = {
82331fe8d4eSLorenzo Bianconi 				.addr = 0x12,
82431fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
82531fe8d4eSLorenzo Bianconi 			},
82631fe8d4eSLorenzo Bianconi 			.od = {
82731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
82831fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
82931fe8d4eSLorenzo Bianconi 			},
8307e906103SLorenzo Bianconi 		},
831801a6e0aSLorenzo Bianconi 		.batch = {
832801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
833801a6e0aSLorenzo Bianconi 				.addr = 0x09,
834801a6e0aSLorenzo Bianconi 				.mask = GENMASK(3, 0),
835801a6e0aSLorenzo Bianconi 			},
836801a6e0aSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
837801a6e0aSLorenzo Bianconi 				.addr = 0x09,
838801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 4),
839801a6e0aSLorenzo Bianconi 			},
840801a6e0aSLorenzo Bianconi 		},
841801a6e0aSLorenzo Bianconi 		.fifo_ops = {
8423b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
843801a6e0aSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
844801a6e0aSLorenzo Bianconi 			.fifo_th = {
845801a6e0aSLorenzo Bianconi 				.addr = 0x07,
846801a6e0aSLorenzo Bianconi 				.mask = GENMASK(8, 0),
847801a6e0aSLorenzo Bianconi 			},
848801a6e0aSLorenzo Bianconi 			.fifo_diff = {
849801a6e0aSLorenzo Bianconi 				.addr = 0x3a,
85070575abeSmario tesi 				.mask = GENMASK(9, 0),
851801a6e0aSLorenzo Bianconi 			},
852801a6e0aSLorenzo Bianconi 			.th_wl = 1,
853801a6e0aSLorenzo Bianconi 		},
854801a6e0aSLorenzo Bianconi 		.ts_settings = {
855801a6e0aSLorenzo Bianconi 			.timer_en = {
856801a6e0aSLorenzo Bianconi 				.addr = 0x19,
857801a6e0aSLorenzo Bianconi 				.mask = BIT(5),
858801a6e0aSLorenzo Bianconi 			},
859801a6e0aSLorenzo Bianconi 			.decimator = {
860801a6e0aSLorenzo Bianconi 				.addr = 0x0a,
861801a6e0aSLorenzo Bianconi 				.mask = GENMASK(7, 6),
862801a6e0aSLorenzo Bianconi 			},
863cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
864801a6e0aSLorenzo Bianconi 		},
865c91c1c84SLorenzo Bianconi 		.shub_settings = {
866c91c1c84SLorenzo Bianconi 			.page_mux = {
867c91c1c84SLorenzo Bianconi 				.addr = 0x01,
868c91c1c84SLorenzo Bianconi 				.mask = BIT(6),
869c91c1c84SLorenzo Bianconi 			},
870c91c1c84SLorenzo Bianconi 			.master_en = {
871c91c1c84SLorenzo Bianconi 				.addr = 0x14,
872c91c1c84SLorenzo Bianconi 				.mask = BIT(2),
873c91c1c84SLorenzo Bianconi 			},
874c91c1c84SLorenzo Bianconi 			.pullup_en = {
875c91c1c84SLorenzo Bianconi 				.addr = 0x14,
876c91c1c84SLorenzo Bianconi 				.mask = BIT(3),
877c91c1c84SLorenzo Bianconi 			},
878c91c1c84SLorenzo Bianconi 			.aux_sens = {
879c91c1c84SLorenzo Bianconi 				.addr = 0x14,
880c91c1c84SLorenzo Bianconi 				.mask = GENMASK(1, 0),
881c91c1c84SLorenzo Bianconi 			},
8826d0205fdSLorenzo Bianconi 			.wr_once = {
8836d0205fdSLorenzo Bianconi 				.addr = 0x14,
8846d0205fdSLorenzo Bianconi 				.mask = BIT(6),
8856d0205fdSLorenzo Bianconi 			},
886c91c1c84SLorenzo Bianconi 			.shub_out = 0x02,
887c91c1c84SLorenzo Bianconi 			.slv0_addr = 0x15,
888c91c1c84SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
8896d0205fdSLorenzo Bianconi 			.batch_en = BIT(3),
8903ea39d61SLorenzo Bianconi 		},
8913ea39d61SLorenzo Bianconi 		.event_settings = {
8923ea39d61SLorenzo Bianconi 			.enable_reg = {
8933ea39d61SLorenzo Bianconi 				.addr = 0x58,
8943ea39d61SLorenzo Bianconi 				.mask = BIT(7),
8953ea39d61SLorenzo Bianconi 			},
8963ea39d61SLorenzo Bianconi 			.wakeup_reg = {
8973ea39d61SLorenzo Bianconi 				.addr = 0x5b,
8983ea39d61SLorenzo Bianconi 				.mask = GENMASK(5, 0),
8993ea39d61SLorenzo Bianconi 			},
9003ea39d61SLorenzo Bianconi 			.wakeup_src_reg = 0x1b,
9013ea39d61SLorenzo Bianconi 			.wakeup_src_status_mask = BIT(3),
9023ea39d61SLorenzo Bianconi 			.wakeup_src_z_mask = BIT(0),
9033ea39d61SLorenzo Bianconi 			.wakeup_src_y_mask = BIT(1),
9043ea39d61SLorenzo Bianconi 			.wakeup_src_x_mask = BIT(2),
9053ea39d61SLorenzo Bianconi 		},
906801a6e0aSLorenzo Bianconi 	},
9073054c4ffSLorenzo Bianconi 	{
9083054c4ffSLorenzo Bianconi 		.wai = 0x6b,
90966b662a1SLorenzo Bianconi 		.reset = {
91066b662a1SLorenzo Bianconi 			.addr = 0x12,
91166b662a1SLorenzo Bianconi 			.mask = BIT(0),
91266b662a1SLorenzo Bianconi 		},
91366b662a1SLorenzo Bianconi 		.boot = {
91466b662a1SLorenzo Bianconi 			.addr = 0x12,
91566b662a1SLorenzo Bianconi 			.mask = BIT(7),
91666b662a1SLorenzo Bianconi 		},
91766b662a1SLorenzo Bianconi 		.bdu = {
91866b662a1SLorenzo Bianconi 			.addr = 0x12,
91966b662a1SLorenzo Bianconi 			.mask = BIT(6),
92066b662a1SLorenzo Bianconi 		},
9213054c4ffSLorenzo Bianconi 		.max_fifo_size = 512,
9223054c4ffSLorenzo Bianconi 		.id = {
92381956a93SLorenzo Bianconi 			{
92481956a93SLorenzo Bianconi 				.hw_id = ST_ASM330LHH_ID,
92581956a93SLorenzo Bianconi 				.name = ST_ASM330LHH_DEV_NAME,
92681956a93SLorenzo Bianconi 			},
9273054c4ffSLorenzo Bianconi 		},
928f48bc49bSLorenzo Bianconi 		.channels = {
929f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
930f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
931f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
932f48bc49bSLorenzo Bianconi 			},
933f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
934f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
935f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
936f48bc49bSLorenzo Bianconi 			},
937f48bc49bSLorenzo Bianconi 		},
938960506edSLorenzo Bianconi 		.drdy_mask = {
939960506edSLorenzo Bianconi 			.addr = 0x13,
940960506edSLorenzo Bianconi 			.mask = BIT(3),
941960506edSLorenzo Bianconi 		},
94240dd7343SLorenzo Bianconi 		.odr_table = {
94340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
94440dd7343SLorenzo Bianconi 				.reg = {
94540dd7343SLorenzo Bianconi 					.addr = 0x10,
94640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
94740dd7343SLorenzo Bianconi 				},
948f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
949f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
950f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
951f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
952f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
953f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
95459af4e20SLorenzo Bianconi 				.odr_len = 6,
95540dd7343SLorenzo Bianconi 			},
95640dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
95740dd7343SLorenzo Bianconi 				.reg = {
95840dd7343SLorenzo Bianconi 					.addr = 0x11,
95940dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
96040dd7343SLorenzo Bianconi 				},
961f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
962f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
963f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
964f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
965f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
966f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
96759af4e20SLorenzo Bianconi 				.odr_len = 6,
96840dd7343SLorenzo Bianconi 			},
96940dd7343SLorenzo Bianconi 		},
970640aca3fSLorenzo Bianconi 		.fs_table = {
971640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
972640aca3fSLorenzo Bianconi 				.reg = {
973640aca3fSLorenzo Bianconi 					.addr = 0x10,
974640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
975640aca3fSLorenzo Bianconi 				},
976640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
977640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
978640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
979640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
98085ae3aeeSLorenzo Bianconi 				.fs_len = 4,
981640aca3fSLorenzo Bianconi 			},
982640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
983640aca3fSLorenzo Bianconi 				.reg = {
984640aca3fSLorenzo Bianconi 					.addr = 0x11,
985640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
986640aca3fSLorenzo Bianconi 				},
987640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
988640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
989640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
990640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
99185ae3aeeSLorenzo Bianconi 				.fs_len = 4,
992640aca3fSLorenzo Bianconi 			},
993640aca3fSLorenzo Bianconi 		},
9947e906103SLorenzo Bianconi 		.irq_config = {
9957e906103SLorenzo Bianconi 			.irq1 = {
9967e906103SLorenzo Bianconi 				.addr = 0x0d,
9977e906103SLorenzo Bianconi 				.mask = BIT(3),
9987e906103SLorenzo Bianconi 			},
9997e906103SLorenzo Bianconi 			.irq2 = {
10007e906103SLorenzo Bianconi 				.addr = 0x0e,
10017e906103SLorenzo Bianconi 				.mask = BIT(3),
10027e906103SLorenzo Bianconi 			},
10037e906103SLorenzo Bianconi 			.lir = {
10047e906103SLorenzo Bianconi 				.addr = 0x56,
10057e906103SLorenzo Bianconi 				.mask = BIT(0),
10067e906103SLorenzo Bianconi 			},
10077e906103SLorenzo Bianconi 			.clear_on_read = {
10087e906103SLorenzo Bianconi 				.addr = 0x56,
10097e906103SLorenzo Bianconi 				.mask = BIT(6),
10107e906103SLorenzo Bianconi 			},
10117e906103SLorenzo Bianconi 			.irq1_func = {
10127e906103SLorenzo Bianconi 				.addr = 0x5e,
10137e906103SLorenzo Bianconi 				.mask = BIT(5),
10147e906103SLorenzo Bianconi 			},
10157e906103SLorenzo Bianconi 			.irq2_func = {
10167e906103SLorenzo Bianconi 				.addr = 0x5f,
10177e906103SLorenzo Bianconi 				.mask = BIT(5),
10187e906103SLorenzo Bianconi 			},
101931fe8d4eSLorenzo Bianconi 			.hla = {
102031fe8d4eSLorenzo Bianconi 				.addr = 0x12,
102131fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
102231fe8d4eSLorenzo Bianconi 			},
102331fe8d4eSLorenzo Bianconi 			.od = {
102431fe8d4eSLorenzo Bianconi 				.addr = 0x12,
102531fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
102631fe8d4eSLorenzo Bianconi 			},
10277e906103SLorenzo Bianconi 		},
10283054c4ffSLorenzo Bianconi 		.batch = {
10293054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
10303054c4ffSLorenzo Bianconi 				.addr = 0x09,
10313054c4ffSLorenzo Bianconi 				.mask = GENMASK(3, 0),
10323054c4ffSLorenzo Bianconi 			},
10333054c4ffSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
10343054c4ffSLorenzo Bianconi 				.addr = 0x09,
10353054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 4),
10363054c4ffSLorenzo Bianconi 			},
10373054c4ffSLorenzo Bianconi 		},
10383054c4ffSLorenzo Bianconi 		.fifo_ops = {
10393b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
10403054c4ffSLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
10413054c4ffSLorenzo Bianconi 			.fifo_th = {
10423054c4ffSLorenzo Bianconi 				.addr = 0x07,
10433054c4ffSLorenzo Bianconi 				.mask = GENMASK(8, 0),
10443054c4ffSLorenzo Bianconi 			},
10453054c4ffSLorenzo Bianconi 			.fifo_diff = {
10463054c4ffSLorenzo Bianconi 				.addr = 0x3a,
104770575abeSmario tesi 				.mask = GENMASK(9, 0),
10483054c4ffSLorenzo Bianconi 			},
10493054c4ffSLorenzo Bianconi 			.th_wl = 1,
10503054c4ffSLorenzo Bianconi 		},
10513054c4ffSLorenzo Bianconi 		.ts_settings = {
10523054c4ffSLorenzo Bianconi 			.timer_en = {
10533054c4ffSLorenzo Bianconi 				.addr = 0x19,
10543054c4ffSLorenzo Bianconi 				.mask = BIT(5),
10553054c4ffSLorenzo Bianconi 			},
10563054c4ffSLorenzo Bianconi 			.decimator = {
10573054c4ffSLorenzo Bianconi 				.addr = 0x0a,
10583054c4ffSLorenzo Bianconi 				.mask = GENMASK(7, 6),
10593054c4ffSLorenzo Bianconi 			},
1060cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
10613054c4ffSLorenzo Bianconi 		},
1062b5969abfSSean Nyekjaer 		.event_settings = {
1063b5969abfSSean Nyekjaer 			.enable_reg = {
1064b5969abfSSean Nyekjaer 				.addr = 0x58,
1065b5969abfSSean Nyekjaer 				.mask = BIT(7),
1066b5969abfSSean Nyekjaer 			},
1067b5969abfSSean Nyekjaer 			.wakeup_reg = {
1068b5969abfSSean Nyekjaer 				.addr = 0x5B,
1069b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1070b5969abfSSean Nyekjaer 			},
10711aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
10721aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
10731aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
10741aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
10751aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
1076b5969abfSSean Nyekjaer 		},
10773054c4ffSLorenzo Bianconi 	},
107843901008SLorenzo Bianconi 	{
107943901008SLorenzo Bianconi 		.wai = 0x6b,
108066b662a1SLorenzo Bianconi 		.reset = {
108166b662a1SLorenzo Bianconi 			.addr = 0x12,
108266b662a1SLorenzo Bianconi 			.mask = BIT(0),
108366b662a1SLorenzo Bianconi 		},
108466b662a1SLorenzo Bianconi 		.boot = {
108566b662a1SLorenzo Bianconi 			.addr = 0x12,
108666b662a1SLorenzo Bianconi 			.mask = BIT(7),
108766b662a1SLorenzo Bianconi 		},
108866b662a1SLorenzo Bianconi 		.bdu = {
108966b662a1SLorenzo Bianconi 			.addr = 0x12,
109066b662a1SLorenzo Bianconi 			.mask = BIT(6),
109166b662a1SLorenzo Bianconi 		},
109243901008SLorenzo Bianconi 		.max_fifo_size = 512,
109343901008SLorenzo Bianconi 		.id = {
109481956a93SLorenzo Bianconi 			{
109581956a93SLorenzo Bianconi 				.hw_id = ST_LSM6DSR_ID,
109681956a93SLorenzo Bianconi 				.name = ST_LSM6DSR_DEV_NAME,
1097db947a79SLorenzo Bianconi 			}, {
1098db947a79SLorenzo Bianconi 				.hw_id = ST_ISM330DHCX_ID,
1099db947a79SLorenzo Bianconi 				.name = ST_ISM330DHCX_DEV_NAME,
1100cf9c71b3SLorenzo Bianconi 			}, {
1101cf9c71b3SLorenzo Bianconi 				.hw_id = ST_LSM6DSRX_ID,
1102cf9c71b3SLorenzo Bianconi 				.name = ST_LSM6DSRX_DEV_NAME,
110381956a93SLorenzo Bianconi 			},
110443901008SLorenzo Bianconi 		},
1105f48bc49bSLorenzo Bianconi 		.channels = {
1106f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1107f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_acc_channels,
1108f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1109f48bc49bSLorenzo Bianconi 			},
1110f48bc49bSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1111f48bc49bSLorenzo Bianconi 				.chan = st_lsm6dsx_gyro_channels,
1112f48bc49bSLorenzo Bianconi 				.len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1113f48bc49bSLorenzo Bianconi 			},
1114f48bc49bSLorenzo Bianconi 		},
1115960506edSLorenzo Bianconi 		.drdy_mask = {
1116960506edSLorenzo Bianconi 			.addr = 0x13,
1117960506edSLorenzo Bianconi 			.mask = BIT(3),
1118960506edSLorenzo Bianconi 		},
111940dd7343SLorenzo Bianconi 		.odr_table = {
112040dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
112140dd7343SLorenzo Bianconi 				.reg = {
112240dd7343SLorenzo Bianconi 					.addr = 0x10,
112340dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
112440dd7343SLorenzo Bianconi 				},
1125f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1126f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1127f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1128f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1129f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1130f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
113159af4e20SLorenzo Bianconi 				.odr_len = 6,
113240dd7343SLorenzo Bianconi 			},
113340dd7343SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
113440dd7343SLorenzo Bianconi 				.reg = {
113540dd7343SLorenzo Bianconi 					.addr = 0x11,
113640dd7343SLorenzo Bianconi 					.mask = GENMASK(7, 4),
113740dd7343SLorenzo Bianconi 				},
1138f8710f03SLorenzo Bianconi 				.odr_avl[0] = {  12500, 0x01 },
1139f8710f03SLorenzo Bianconi 				.odr_avl[1] = {  26000, 0x02 },
1140f8710f03SLorenzo Bianconi 				.odr_avl[2] = {  52000, 0x03 },
1141f8710f03SLorenzo Bianconi 				.odr_avl[3] = { 104000, 0x04 },
1142f8710f03SLorenzo Bianconi 				.odr_avl[4] = { 208000, 0x05 },
1143f8710f03SLorenzo Bianconi 				.odr_avl[5] = { 416000, 0x06 },
114459af4e20SLorenzo Bianconi 				.odr_len = 6,
114540dd7343SLorenzo Bianconi 			},
114640dd7343SLorenzo Bianconi 		},
1147640aca3fSLorenzo Bianconi 		.fs_table = {
1148640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
1149640aca3fSLorenzo Bianconi 				.reg = {
1150640aca3fSLorenzo Bianconi 					.addr = 0x10,
1151640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1152640aca3fSLorenzo Bianconi 				},
1153640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
1154640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
1155640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
1156640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
115785ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1158640aca3fSLorenzo Bianconi 			},
1159640aca3fSLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
1160640aca3fSLorenzo Bianconi 				.reg = {
1161640aca3fSLorenzo Bianconi 					.addr = 0x11,
1162640aca3fSLorenzo Bianconi 					.mask = GENMASK(3, 2),
1163640aca3fSLorenzo Bianconi 				},
1164640aca3fSLorenzo Bianconi 				.fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
1165640aca3fSLorenzo Bianconi 				.fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
1166640aca3fSLorenzo Bianconi 				.fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
1167640aca3fSLorenzo Bianconi 				.fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
116885ae3aeeSLorenzo Bianconi 				.fs_len = 4,
1169640aca3fSLorenzo Bianconi 			},
1170640aca3fSLorenzo Bianconi 		},
11717e906103SLorenzo Bianconi 		.irq_config = {
11727e906103SLorenzo Bianconi 			.irq1 = {
11737e906103SLorenzo Bianconi 				.addr = 0x0d,
11747e906103SLorenzo Bianconi 				.mask = BIT(3),
11757e906103SLorenzo Bianconi 			},
11767e906103SLorenzo Bianconi 			.irq2 = {
11777e906103SLorenzo Bianconi 				.addr = 0x0e,
11787e906103SLorenzo Bianconi 				.mask = BIT(3),
11797e906103SLorenzo Bianconi 			},
11807e906103SLorenzo Bianconi 			.lir = {
11817e906103SLorenzo Bianconi 				.addr = 0x56,
11827e906103SLorenzo Bianconi 				.mask = BIT(0),
11837e906103SLorenzo Bianconi 			},
11847e906103SLorenzo Bianconi 			.clear_on_read = {
11857e906103SLorenzo Bianconi 				.addr = 0x56,
11867e906103SLorenzo Bianconi 				.mask = BIT(6),
11877e906103SLorenzo Bianconi 			},
11887e906103SLorenzo Bianconi 			.irq1_func = {
11897e906103SLorenzo Bianconi 				.addr = 0x5e,
11907e906103SLorenzo Bianconi 				.mask = BIT(5),
11917e906103SLorenzo Bianconi 			},
11927e906103SLorenzo Bianconi 			.irq2_func = {
11937e906103SLorenzo Bianconi 				.addr = 0x5f,
11947e906103SLorenzo Bianconi 				.mask = BIT(5),
11957e906103SLorenzo Bianconi 			},
119631fe8d4eSLorenzo Bianconi 			.hla = {
119731fe8d4eSLorenzo Bianconi 				.addr = 0x12,
119831fe8d4eSLorenzo Bianconi 				.mask = BIT(5),
119931fe8d4eSLorenzo Bianconi 			},
120031fe8d4eSLorenzo Bianconi 			.od = {
120131fe8d4eSLorenzo Bianconi 				.addr = 0x12,
120231fe8d4eSLorenzo Bianconi 				.mask = BIT(4),
120331fe8d4eSLorenzo Bianconi 			},
12047e906103SLorenzo Bianconi 		},
120543901008SLorenzo Bianconi 		.batch = {
120643901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_ACC] = {
120743901008SLorenzo Bianconi 				.addr = 0x09,
120843901008SLorenzo Bianconi 				.mask = GENMASK(3, 0),
120943901008SLorenzo Bianconi 			},
121043901008SLorenzo Bianconi 			[ST_LSM6DSX_ID_GYRO] = {
121143901008SLorenzo Bianconi 				.addr = 0x09,
121243901008SLorenzo Bianconi 				.mask = GENMASK(7, 4),
121343901008SLorenzo Bianconi 			},
121443901008SLorenzo Bianconi 		},
121543901008SLorenzo Bianconi 		.fifo_ops = {
12163b72950dSLorenzo Bianconi 			.update_fifo = st_lsm6dsx_update_fifo,
121743901008SLorenzo Bianconi 			.read_fifo = st_lsm6dsx_read_tagged_fifo,
121843901008SLorenzo Bianconi 			.fifo_th = {
121943901008SLorenzo Bianconi 				.addr = 0x07,
122043901008SLorenzo Bianconi 				.mask = GENMASK(8, 0),
122143901008SLorenzo Bianconi 			},
122243901008SLorenzo Bianconi 			.fifo_diff = {
122343901008SLorenzo Bianconi 				.addr = 0x3a,
122470575abeSmario tesi 				.mask = GENMASK(9, 0),
122543901008SLorenzo Bianconi 			},
122643901008SLorenzo Bianconi 			.th_wl = 1,
122743901008SLorenzo Bianconi 		},
122843901008SLorenzo Bianconi 		.ts_settings = {
122943901008SLorenzo Bianconi 			.timer_en = {
123043901008SLorenzo Bianconi 				.addr = 0x19,
123143901008SLorenzo Bianconi 				.mask = BIT(5),
123243901008SLorenzo Bianconi 			},
123343901008SLorenzo Bianconi 			.decimator = {
123443901008SLorenzo Bianconi 				.addr = 0x0a,
123543901008SLorenzo Bianconi 				.mask = GENMASK(7, 6),
123643901008SLorenzo Bianconi 			},
1237cb3b6b8eSMario Tesi 			.freq_fine = 0x63,
123843901008SLorenzo Bianconi 		},
123943901008SLorenzo Bianconi 		.shub_settings = {
124043901008SLorenzo Bianconi 			.page_mux = {
124143901008SLorenzo Bianconi 				.addr = 0x01,
124243901008SLorenzo Bianconi 				.mask = BIT(6),
124343901008SLorenzo Bianconi 			},
124443901008SLorenzo Bianconi 			.master_en = {
124543901008SLorenzo Bianconi 				.addr = 0x14,
124643901008SLorenzo Bianconi 				.mask = BIT(2),
124743901008SLorenzo Bianconi 			},
124843901008SLorenzo Bianconi 			.pullup_en = {
124943901008SLorenzo Bianconi 				.addr = 0x14,
125043901008SLorenzo Bianconi 				.mask = BIT(3),
125143901008SLorenzo Bianconi 			},
125243901008SLorenzo Bianconi 			.aux_sens = {
125343901008SLorenzo Bianconi 				.addr = 0x14,
125443901008SLorenzo Bianconi 				.mask = GENMASK(1, 0),
125543901008SLorenzo Bianconi 			},
125643901008SLorenzo Bianconi 			.wr_once = {
125743901008SLorenzo Bianconi 				.addr = 0x14,
125843901008SLorenzo Bianconi 				.mask = BIT(6),
125943901008SLorenzo Bianconi 			},
126043901008SLorenzo Bianconi 			.shub_out = 0x02,
126143901008SLorenzo Bianconi 			.slv0_addr = 0x15,
126243901008SLorenzo Bianconi 			.dw_slv0_addr = 0x21,
126343901008SLorenzo Bianconi 			.batch_en = BIT(3),
1264b5969abfSSean Nyekjaer 		},
1265b5969abfSSean Nyekjaer 		.event_settings = {
1266b5969abfSSean Nyekjaer 			.enable_reg = {
1267b5969abfSSean Nyekjaer 				.addr = 0x58,
1268b5969abfSSean Nyekjaer 				.mask = BIT(7),
1269b5969abfSSean Nyekjaer 			},
1270b5969abfSSean Nyekjaer 			.wakeup_reg = {
1271b5969abfSSean Nyekjaer 				.addr = 0x5B,
1272b5969abfSSean Nyekjaer 				.mask = GENMASK(5, 0),
1273b5969abfSSean Nyekjaer 			},
12741aabad1fSSean Nyekjaer 			.wakeup_src_reg = 0x1b,
12751aabad1fSSean Nyekjaer 			.wakeup_src_status_mask = BIT(3),
12761aabad1fSSean Nyekjaer 			.wakeup_src_z_mask = BIT(0),
12771aabad1fSSean Nyekjaer 			.wakeup_src_y_mask = BIT(1),
12781aabad1fSSean Nyekjaer 			.wakeup_src_x_mask = BIT(2),
127943901008SLorenzo Bianconi 		}
128043901008SLorenzo Bianconi 	},
1281290a6ce1SLorenzo Bianconi };
1282290a6ce1SLorenzo Bianconi 
1283c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1284c91c1c84SLorenzo Bianconi {
1285c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1286c91c1c84SLorenzo Bianconi 	unsigned int data;
1287c91c1c84SLorenzo Bianconi 	int err;
1288c91c1c84SLorenzo Bianconi 
1289c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1290c91c1c84SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1291c91c1c84SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1292c91c1c84SLorenzo Bianconi 				 hub_settings->page_mux.mask, data);
1293c91c1c84SLorenzo Bianconi 	usleep_range(100, 150);
1294c91c1c84SLorenzo Bianconi 
1295c91c1c84SLorenzo Bianconi 	return err;
1296c91c1c84SLorenzo Bianconi }
1297c91c1c84SLorenzo Bianconi 
129881956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
129981956a93SLorenzo Bianconi 				   const char **name)
1300290a6ce1SLorenzo Bianconi {
130151a8b707SLorenzo Bianconi 	int err, i, j, data;
1302290a6ce1SLorenzo Bianconi 
1303290a6ce1SLorenzo Bianconi 	for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
1304d068e4a0SLorenzo Bianconi 		for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
130581956a93SLorenzo Bianconi 			if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
1306d068e4a0SLorenzo Bianconi 				break;
1307d068e4a0SLorenzo Bianconi 		}
1308d068e4a0SLorenzo Bianconi 		if (j < ST_LSM6DSX_MAX_ID)
1309290a6ce1SLorenzo Bianconi 			break;
1310290a6ce1SLorenzo Bianconi 	}
1311290a6ce1SLorenzo Bianconi 
1312290a6ce1SLorenzo Bianconi 	if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
1313290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
1314290a6ce1SLorenzo Bianconi 		return -ENODEV;
1315290a6ce1SLorenzo Bianconi 	}
1316290a6ce1SLorenzo Bianconi 
131751a8b707SLorenzo Bianconi 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
1318290a6ce1SLorenzo Bianconi 	if (err < 0) {
1319290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "failed to read whoami register\n");
1320290a6ce1SLorenzo Bianconi 		return err;
1321290a6ce1SLorenzo Bianconi 	}
1322290a6ce1SLorenzo Bianconi 
1323290a6ce1SLorenzo Bianconi 	if (data != st_lsm6dsx_sensor_settings[i].wai) {
1324290a6ce1SLorenzo Bianconi 		dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
1325290a6ce1SLorenzo Bianconi 		return -ENODEV;
1326290a6ce1SLorenzo Bianconi 	}
1327290a6ce1SLorenzo Bianconi 
132881956a93SLorenzo Bianconi 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
1329290a6ce1SLorenzo Bianconi 	hw->settings = &st_lsm6dsx_sensor_settings[i];
1330290a6ce1SLorenzo Bianconi 
1331290a6ce1SLorenzo Bianconi 	return 0;
1332290a6ce1SLorenzo Bianconi }
1333290a6ce1SLorenzo Bianconi 
1334290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
1335290a6ce1SLorenzo Bianconi 				     u32 gain)
1336290a6ce1SLorenzo Bianconi {
1337640aca3fSLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1338739aff87SLorenzo Bianconi 	unsigned int data;
1339290a6ce1SLorenzo Bianconi 	int i, err;
1340290a6ce1SLorenzo Bianconi 
1341640aca3fSLorenzo Bianconi 	fs_table = &sensor->hw->settings->fs_table[sensor->id];
134285ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++) {
1343640aca3fSLorenzo Bianconi 		if (fs_table->fs_avl[i].gain == gain)
1344290a6ce1SLorenzo Bianconi 			break;
134585ae3aeeSLorenzo Bianconi 	}
1346290a6ce1SLorenzo Bianconi 
134785ae3aeeSLorenzo Bianconi 	if (i == fs_table->fs_len)
1348290a6ce1SLorenzo Bianconi 		return -EINVAL;
1349290a6ce1SLorenzo Bianconi 
1350640aca3fSLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1351640aca3fSLorenzo Bianconi 				    fs_table->reg.mask);
1352640aca3fSLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1353640aca3fSLorenzo Bianconi 					    fs_table->reg.mask, data);
1354290a6ce1SLorenzo Bianconi 	if (err < 0)
1355290a6ce1SLorenzo Bianconi 		return err;
1356290a6ce1SLorenzo Bianconi 
1357290a6ce1SLorenzo Bianconi 	sensor->gain = gain;
1358290a6ce1SLorenzo Bianconi 
1359290a6ce1SLorenzo Bianconi 	return 0;
1360290a6ce1SLorenzo Bianconi }
1361290a6ce1SLorenzo Bianconi 
1362f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val)
1363290a6ce1SLorenzo Bianconi {
136440dd7343SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
13652ccc1503SLorenzo Bianconi 	int i;
1366290a6ce1SLorenzo Bianconi 
136740dd7343SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
136859af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++) {
13696ffb55e5SLorenzo Bianconi 		/*
13706ffb55e5SLorenzo Bianconi 		 * ext devices can run at different odr respect to
13716ffb55e5SLorenzo Bianconi 		 * accel sensor
13726ffb55e5SLorenzo Bianconi 		 */
1373f8710f03SLorenzo Bianconi 		if (odr_table->odr_avl[i].milli_hz >= odr)
1374290a6ce1SLorenzo Bianconi 			break;
137559af4e20SLorenzo Bianconi 	}
1376290a6ce1SLorenzo Bianconi 
137759af4e20SLorenzo Bianconi 	if (i == odr_table->odr_len)
1378290a6ce1SLorenzo Bianconi 		return -EINVAL;
1379290a6ce1SLorenzo Bianconi 
138040dd7343SLorenzo Bianconi 	*val = odr_table->odr_avl[i].val;
1381f8710f03SLorenzo Bianconi 	return odr_table->odr_avl[i].milli_hz;
1382290a6ce1SLorenzo Bianconi }
1383290a6ce1SLorenzo Bianconi 
1384f8710f03SLorenzo Bianconi static int
1385f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr,
13866ffb55e5SLorenzo Bianconi 				enum st_lsm6dsx_sensor_id id)
13872ccc1503SLorenzo Bianconi {
13886ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
13896ffb55e5SLorenzo Bianconi 
13906ffb55e5SLorenzo Bianconi 	if (odr > 0) {
13916ffb55e5SLorenzo Bianconi 		if (hw->enable_mask & BIT(id))
1392f8710f03SLorenzo Bianconi 			return max_t(u32, ref->odr, odr);
13936ffb55e5SLorenzo Bianconi 		else
13946ffb55e5SLorenzo Bianconi 			return odr;
13956ffb55e5SLorenzo Bianconi 	} else {
13966ffb55e5SLorenzo Bianconi 		return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
13976ffb55e5SLorenzo Bianconi 	}
13986ffb55e5SLorenzo Bianconi }
13996ffb55e5SLorenzo Bianconi 
1400f8710f03SLorenzo Bianconi static int
1401f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
14026ffb55e5SLorenzo Bianconi {
14036ffb55e5SLorenzo Bianconi 	struct st_lsm6dsx_sensor *ref_sensor = sensor;
140451a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
140551a8b707SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1406739aff87SLorenzo Bianconi 	unsigned int data;
14076ffb55e5SLorenzo Bianconi 	u8 val = 0;
14082ccc1503SLorenzo Bianconi 	int err;
14092ccc1503SLorenzo Bianconi 
14106ffb55e5SLorenzo Bianconi 	switch (sensor->id) {
14116ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT0:
14126ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT1:
14136ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_EXT2:
14146ffb55e5SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC: {
1415f8710f03SLorenzo Bianconi 		u32 odr;
14166ffb55e5SLorenzo Bianconi 		int i;
14176ffb55e5SLorenzo Bianconi 
14186ffb55e5SLorenzo Bianconi 		/*
14196ffb55e5SLorenzo Bianconi 		 * i2c embedded controller relies on the accelerometer sensor as
14206ffb55e5SLorenzo Bianconi 		 * bus read/write trigger so we need to enable accel device
14216ffb55e5SLorenzo Bianconi 		 * at odr = max(accel_odr, ext_odr) in order to properly
14226ffb55e5SLorenzo Bianconi 		 * communicate with i2c slave devices
14236ffb55e5SLorenzo Bianconi 		 */
14246ffb55e5SLorenzo Bianconi 		ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
14256ffb55e5SLorenzo Bianconi 		for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
14266ffb55e5SLorenzo Bianconi 			if (!hw->iio_devs[i] || i == sensor->id)
14276ffb55e5SLorenzo Bianconi 				continue;
14286ffb55e5SLorenzo Bianconi 
14296ffb55e5SLorenzo Bianconi 			odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
14306ffb55e5SLorenzo Bianconi 			if (odr != req_odr)
14316ffb55e5SLorenzo Bianconi 				/* device already configured */
14326ffb55e5SLorenzo Bianconi 				return 0;
14336ffb55e5SLorenzo Bianconi 		}
14346ffb55e5SLorenzo Bianconi 		break;
14356ffb55e5SLorenzo Bianconi 	}
14366ffb55e5SLorenzo Bianconi 	default:
14376ffb55e5SLorenzo Bianconi 		break;
14386ffb55e5SLorenzo Bianconi 	}
14396ffb55e5SLorenzo Bianconi 
14406ffb55e5SLorenzo Bianconi 	if (req_odr > 0) {
14416ffb55e5SLorenzo Bianconi 		err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
14422ccc1503SLorenzo Bianconi 		if (err < 0)
14432ccc1503SLorenzo Bianconi 			return err;
14446ffb55e5SLorenzo Bianconi 	}
14452ccc1503SLorenzo Bianconi 
144640dd7343SLorenzo Bianconi 	reg = &hw->settings->odr_table[ref_sensor->id].reg;
1447739aff87SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1448739aff87SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
14492ccc1503SLorenzo Bianconi }
14502ccc1503SLorenzo Bianconi 
145117750443SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
145217750443SLorenzo Bianconi 				 bool enable)
1453290a6ce1SLorenzo Bianconi {
145451a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1455f8710f03SLorenzo Bianconi 	u32 odr = enable ? sensor->odr : 0;
1456290a6ce1SLorenzo Bianconi 	int err;
1457290a6ce1SLorenzo Bianconi 
145817750443SLorenzo Bianconi 	err = st_lsm6dsx_set_odr(sensor, odr);
1459290a6ce1SLorenzo Bianconi 	if (err < 0)
1460290a6ce1SLorenzo Bianconi 		return err;
1461290a6ce1SLorenzo Bianconi 
146217750443SLorenzo Bianconi 	if (enable)
146317750443SLorenzo Bianconi 		hw->enable_mask |= BIT(sensor->id);
146417750443SLorenzo Bianconi 	else
146517750443SLorenzo Bianconi 		hw->enable_mask &= ~BIT(sensor->id);
1466290a6ce1SLorenzo Bianconi 
1467290a6ce1SLorenzo Bianconi 	return 0;
1468290a6ce1SLorenzo Bianconi }
1469290a6ce1SLorenzo Bianconi 
1470290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1471290a6ce1SLorenzo Bianconi 				   u8 addr, int *val)
1472290a6ce1SLorenzo Bianconi {
147351a8b707SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1474290a6ce1SLorenzo Bianconi 	int err, delay;
1475290a6ce1SLorenzo Bianconi 	__le16 data;
1476290a6ce1SLorenzo Bianconi 
147717750443SLorenzo Bianconi 	err = st_lsm6dsx_sensor_set_enable(sensor, true);
1478290a6ce1SLorenzo Bianconi 	if (err < 0)
1479290a6ce1SLorenzo Bianconi 		return err;
1480290a6ce1SLorenzo Bianconi 
1481f8710f03SLorenzo Bianconi 	delay = 1000000000 / sensor->odr;
1482290a6ce1SLorenzo Bianconi 	usleep_range(delay, 2 * delay);
1483290a6ce1SLorenzo Bianconi 
1484739aff87SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1485290a6ce1SLorenzo Bianconi 	if (err < 0)
1486290a6ce1SLorenzo Bianconi 		return err;
1487290a6ce1SLorenzo Bianconi 
1488b5969abfSSean Nyekjaer 	if (!hw->enable_event)
148917750443SLorenzo Bianconi 		st_lsm6dsx_sensor_set_enable(sensor, false);
1490290a6ce1SLorenzo Bianconi 
14917b9ebe42SLorenzo Bianconi 	*val = (s16)le16_to_cpu(data);
1492290a6ce1SLorenzo Bianconi 
1493290a6ce1SLorenzo Bianconi 	return IIO_VAL_INT;
1494290a6ce1SLorenzo Bianconi }
1495290a6ce1SLorenzo Bianconi 
1496290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1497290a6ce1SLorenzo Bianconi 			       struct iio_chan_spec const *ch,
1498290a6ce1SLorenzo Bianconi 			       int *val, int *val2, long mask)
1499290a6ce1SLorenzo Bianconi {
1500290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1501290a6ce1SLorenzo Bianconi 	int ret;
1502290a6ce1SLorenzo Bianconi 
1503290a6ce1SLorenzo Bianconi 	switch (mask) {
1504290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_RAW:
1505290a6ce1SLorenzo Bianconi 		ret = iio_device_claim_direct_mode(iio_dev);
1506290a6ce1SLorenzo Bianconi 		if (ret)
1507290a6ce1SLorenzo Bianconi 			break;
1508290a6ce1SLorenzo Bianconi 
1509290a6ce1SLorenzo Bianconi 		ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1510290a6ce1SLorenzo Bianconi 		iio_device_release_direct_mode(iio_dev);
1511290a6ce1SLorenzo Bianconi 		break;
1512290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ:
1513f8710f03SLorenzo Bianconi 		*val = sensor->odr / 1000;
1514f8710f03SLorenzo Bianconi 		*val2 = (sensor->odr % 1000) * 1000;
1515f8710f03SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1516290a6ce1SLorenzo Bianconi 		break;
1517290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1518290a6ce1SLorenzo Bianconi 		*val = 0;
1519290a6ce1SLorenzo Bianconi 		*val2 = sensor->gain;
1520290a6ce1SLorenzo Bianconi 		ret = IIO_VAL_INT_PLUS_MICRO;
1521290a6ce1SLorenzo Bianconi 		break;
1522290a6ce1SLorenzo Bianconi 	default:
1523290a6ce1SLorenzo Bianconi 		ret = -EINVAL;
1524290a6ce1SLorenzo Bianconi 		break;
1525290a6ce1SLorenzo Bianconi 	}
1526290a6ce1SLorenzo Bianconi 
1527290a6ce1SLorenzo Bianconi 	return ret;
1528290a6ce1SLorenzo Bianconi }
1529290a6ce1SLorenzo Bianconi 
1530290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1531290a6ce1SLorenzo Bianconi 				struct iio_chan_spec const *chan,
1532290a6ce1SLorenzo Bianconi 				int val, int val2, long mask)
1533290a6ce1SLorenzo Bianconi {
1534290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1535290a6ce1SLorenzo Bianconi 	int err;
1536290a6ce1SLorenzo Bianconi 
1537290a6ce1SLorenzo Bianconi 	err = iio_device_claim_direct_mode(iio_dev);
1538290a6ce1SLorenzo Bianconi 	if (err)
1539290a6ce1SLorenzo Bianconi 		return err;
1540290a6ce1SLorenzo Bianconi 
1541290a6ce1SLorenzo Bianconi 	switch (mask) {
1542290a6ce1SLorenzo Bianconi 	case IIO_CHAN_INFO_SCALE:
1543290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_set_full_scale(sensor, val2);
1544290a6ce1SLorenzo Bianconi 		break;
15452ccc1503SLorenzo Bianconi 	case IIO_CHAN_INFO_SAMP_FREQ: {
15462ccc1503SLorenzo Bianconi 		u8 data;
15472ccc1503SLorenzo Bianconi 
1548f8710f03SLorenzo Bianconi 		val = val * 1000 + val2 / 1000;
1549fc3f6ad7SLorenzo Bianconi 		val = st_lsm6dsx_check_odr(sensor, val, &data);
1550fc3f6ad7SLorenzo Bianconi 		if (val < 0)
1551fc3f6ad7SLorenzo Bianconi 			err = val;
1552fc3f6ad7SLorenzo Bianconi 		else
15535e3c3e33SLorenzo Bianconi 			sensor->odr = val;
1554290a6ce1SLorenzo Bianconi 		break;
15552ccc1503SLorenzo Bianconi 	}
1556290a6ce1SLorenzo Bianconi 	default:
1557290a6ce1SLorenzo Bianconi 		err = -EINVAL;
1558290a6ce1SLorenzo Bianconi 		break;
1559290a6ce1SLorenzo Bianconi 	}
1560290a6ce1SLorenzo Bianconi 
1561290a6ce1SLorenzo Bianconi 	iio_device_release_direct_mode(iio_dev);
1562290a6ce1SLorenzo Bianconi 
1563290a6ce1SLorenzo Bianconi 	return err;
1564290a6ce1SLorenzo Bianconi }
1565290a6ce1SLorenzo Bianconi 
1566b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1567b5969abfSSean Nyekjaer {
156884b2e7c3SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
156904ca37d5SLorenzo Bianconi 	unsigned int data;
1570b5969abfSSean Nyekjaer 	int err;
1571b5969abfSSean Nyekjaer 
15727e906103SLorenzo Bianconi 	if (!hw->settings->irq_config.irq1_func.addr)
1573b5969abfSSean Nyekjaer 		return -ENOTSUPP;
1574b5969abfSSean Nyekjaer 
157584b2e7c3SLorenzo Bianconi 	reg = &hw->settings->event_settings.enable_reg;
157684b2e7c3SLorenzo Bianconi 	if (reg->addr) {
157704ca37d5SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
157804ca37d5SLorenzo Bianconi 		err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
157904ca37d5SLorenzo Bianconi 						    reg->mask, data);
1580b5969abfSSean Nyekjaer 		if (err < 0)
1581b5969abfSSean Nyekjaer 			return err;
158284b2e7c3SLorenzo Bianconi 	}
1583b5969abfSSean Nyekjaer 
1584b5969abfSSean Nyekjaer 	/* Enable wakeup interrupt */
158504ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
158604ca37d5SLorenzo Bianconi 	return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
158704ca37d5SLorenzo Bianconi 					     hw->irq_routing->mask, data);
1588b5969abfSSean Nyekjaer }
1589b5969abfSSean Nyekjaer 
1590b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1591b5969abfSSean Nyekjaer 				 const struct iio_chan_spec *chan,
1592b5969abfSSean Nyekjaer 				 enum iio_event_type type,
1593b5969abfSSean Nyekjaer 				 enum iio_event_direction dir,
1594b5969abfSSean Nyekjaer 				 enum iio_event_info info,
1595b5969abfSSean Nyekjaer 				 int *val, int *val2)
1596b5969abfSSean Nyekjaer {
1597b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1598b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1599b5969abfSSean Nyekjaer 
1600b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1601b5969abfSSean Nyekjaer 		return -EINVAL;
1602b5969abfSSean Nyekjaer 
1603b5969abfSSean Nyekjaer 	*val2 = 0;
1604b5969abfSSean Nyekjaer 	*val = hw->event_threshold;
1605b5969abfSSean Nyekjaer 
1606b5969abfSSean Nyekjaer 	return IIO_VAL_INT;
1607b5969abfSSean Nyekjaer }
1608b5969abfSSean Nyekjaer 
1609b307f495SLorenzo Bianconi static int
1610b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1611b5969abfSSean Nyekjaer 		       const struct iio_chan_spec *chan,
1612b5969abfSSean Nyekjaer 		       enum iio_event_type type,
1613b5969abfSSean Nyekjaer 		       enum iio_event_direction dir,
1614b5969abfSSean Nyekjaer 		       enum iio_event_info info,
1615b5969abfSSean Nyekjaer 		       int val, int val2)
1616b5969abfSSean Nyekjaer {
1617b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1618b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
161904ca37d5SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
162004ca37d5SLorenzo Bianconi 	unsigned int data;
1621b5969abfSSean Nyekjaer 	int err;
1622b5969abfSSean Nyekjaer 
1623b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1624b5969abfSSean Nyekjaer 		return -EINVAL;
1625b5969abfSSean Nyekjaer 
1626b5969abfSSean Nyekjaer 	if (val < 0 || val > 31)
1627b5969abfSSean Nyekjaer 		return -EINVAL;
1628b5969abfSSean Nyekjaer 
162904ca37d5SLorenzo Bianconi 	reg = &hw->settings->event_settings.wakeup_reg;
163004ca37d5SLorenzo Bianconi 	data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
163104ca37d5SLorenzo Bianconi 	err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
163204ca37d5SLorenzo Bianconi 					    reg->mask, data);
163304ca37d5SLorenzo Bianconi 	if (err < 0)
1634b5969abfSSean Nyekjaer 		return -EINVAL;
1635b5969abfSSean Nyekjaer 
1636b5969abfSSean Nyekjaer 	hw->event_threshold = val;
1637b5969abfSSean Nyekjaer 
1638b5969abfSSean Nyekjaer 	return 0;
1639b5969abfSSean Nyekjaer }
1640b5969abfSSean Nyekjaer 
1641b307f495SLorenzo Bianconi static int
1642b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1643b5969abfSSean Nyekjaer 			     const struct iio_chan_spec *chan,
1644b5969abfSSean Nyekjaer 			     enum iio_event_type type,
1645b5969abfSSean Nyekjaer 			     enum iio_event_direction dir)
1646b5969abfSSean Nyekjaer {
1647b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1648b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
1649b5969abfSSean Nyekjaer 
1650b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1651b5969abfSSean Nyekjaer 		return -EINVAL;
1652b5969abfSSean Nyekjaer 
16531aabad1fSSean Nyekjaer 	return !!(hw->enable_event & BIT(chan->channel2));
1654b5969abfSSean Nyekjaer }
1655b5969abfSSean Nyekjaer 
1656b307f495SLorenzo Bianconi static int
1657b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1658b5969abfSSean Nyekjaer 			      const struct iio_chan_spec *chan,
1659b5969abfSSean Nyekjaer 			      enum iio_event_type type,
1660b307f495SLorenzo Bianconi 			      enum iio_event_direction dir, int state)
1661b5969abfSSean Nyekjaer {
1662b5969abfSSean Nyekjaer 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1663b5969abfSSean Nyekjaer 	struct st_lsm6dsx_hw *hw = sensor->hw;
16641aabad1fSSean Nyekjaer 	u8 enable_event;
1665b5969abfSSean Nyekjaer 	int err = 0;
1666b5969abfSSean Nyekjaer 
1667b5969abfSSean Nyekjaer 	if (type != IIO_EV_TYPE_THRESH)
1668b5969abfSSean Nyekjaer 		return -EINVAL;
1669b5969abfSSean Nyekjaer 
16701aabad1fSSean Nyekjaer 	if (state) {
16711aabad1fSSean Nyekjaer 		enable_event = hw->enable_event | BIT(chan->channel2);
16721aabad1fSSean Nyekjaer 
1673b5969abfSSean Nyekjaer 		/* do not enable events if they are already enabled */
16741aabad1fSSean Nyekjaer 		if (hw->enable_event)
16751aabad1fSSean Nyekjaer 			goto out;
16761aabad1fSSean Nyekjaer 	} else {
16771aabad1fSSean Nyekjaer 		enable_event = hw->enable_event & ~BIT(chan->channel2);
16781aabad1fSSean Nyekjaer 
16791aabad1fSSean Nyekjaer 		/* only turn off sensor if no events is enabled */
16801aabad1fSSean Nyekjaer 		if (enable_event)
16811aabad1fSSean Nyekjaer 			goto out;
16821aabad1fSSean Nyekjaer 	}
16831aabad1fSSean Nyekjaer 
16841aabad1fSSean Nyekjaer 	/* stop here if no changes have been made */
16851aabad1fSSean Nyekjaer 	if (hw->enable_event == enable_event)
1686b5969abfSSean Nyekjaer 		return 0;
1687b5969abfSSean Nyekjaer 
1688b5969abfSSean Nyekjaer 	err = st_lsm6dsx_event_setup(hw, state);
1689b5969abfSSean Nyekjaer 	if (err < 0)
1690b5969abfSSean Nyekjaer 		return err;
1691b5969abfSSean Nyekjaer 
1692d278d447SLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1693b5969abfSSean Nyekjaer 	err = st_lsm6dsx_sensor_set_enable(sensor, state);
1694d278d447SLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1695b5969abfSSean Nyekjaer 	if (err < 0)
1696b5969abfSSean Nyekjaer 		return err;
1697b5969abfSSean Nyekjaer 
16981aabad1fSSean Nyekjaer out:
16991aabad1fSSean Nyekjaer 	hw->enable_event = enable_event;
1700b5969abfSSean Nyekjaer 
1701b5969abfSSean Nyekjaer 	return 0;
1702b5969abfSSean Nyekjaer }
1703b5969abfSSean Nyekjaer 
1704d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1705290a6ce1SLorenzo Bianconi {
1706290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1707290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
17088f2a88a2SLorenzo Bianconi 	int err;
1709290a6ce1SLorenzo Bianconi 
17108f2a88a2SLorenzo Bianconi 	if (val < 1 || val > hw->settings->max_fifo_size)
1711290a6ce1SLorenzo Bianconi 		return -EINVAL;
1712290a6ce1SLorenzo Bianconi 
1713335eaedcSLorenzo Bianconi 	mutex_lock(&hw->conf_lock);
1714335eaedcSLorenzo Bianconi 
1715290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_update_watermark(sensor, val);
1716335eaedcSLorenzo Bianconi 
1717335eaedcSLorenzo Bianconi 	mutex_unlock(&hw->conf_lock);
1718335eaedcSLorenzo Bianconi 
1719290a6ce1SLorenzo Bianconi 	if (err < 0)
1720290a6ce1SLorenzo Bianconi 		return err;
1721290a6ce1SLorenzo Bianconi 
1722290a6ce1SLorenzo Bianconi 	sensor->watermark = val;
1723290a6ce1SLorenzo Bianconi 
1724290a6ce1SLorenzo Bianconi 	return 0;
1725290a6ce1SLorenzo Bianconi }
1726290a6ce1SLorenzo Bianconi 
1727290a6ce1SLorenzo Bianconi static ssize_t
1728290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1729290a6ce1SLorenzo Bianconi 					  struct device_attribute *attr,
1730290a6ce1SLorenzo Bianconi 					  char *buf)
1731290a6ce1SLorenzo Bianconi {
1732290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
173359af4e20SLorenzo Bianconi 	const struct st_lsm6dsx_odr_table_entry *odr_table;
1734290a6ce1SLorenzo Bianconi 	int i, len = 0;
1735290a6ce1SLorenzo Bianconi 
173659af4e20SLorenzo Bianconi 	odr_table = &sensor->hw->settings->odr_table[sensor->id];
173759af4e20SLorenzo Bianconi 	for (i = 0; i < odr_table->odr_len; i++)
1738f8710f03SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ",
1739f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz / 1000,
1740f8710f03SLorenzo Bianconi 				 odr_table->odr_avl[i].milli_hz % 1000);
1741290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1742290a6ce1SLorenzo Bianconi 
1743290a6ce1SLorenzo Bianconi 	return len;
1744290a6ce1SLorenzo Bianconi }
1745290a6ce1SLorenzo Bianconi 
1746290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
1747290a6ce1SLorenzo Bianconi 					    struct device_attribute *attr,
1748290a6ce1SLorenzo Bianconi 					    char *buf)
1749290a6ce1SLorenzo Bianconi {
1750290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
17510f7e1728SLorenzo Bianconi 	const struct st_lsm6dsx_fs_table_entry *fs_table;
1752640aca3fSLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = sensor->hw;
1753290a6ce1SLorenzo Bianconi 	int i, len = 0;
1754290a6ce1SLorenzo Bianconi 
175585ae3aeeSLorenzo Bianconi 	fs_table = &hw->settings->fs_table[sensor->id];
175685ae3aeeSLorenzo Bianconi 	for (i = 0; i < fs_table->fs_len; i++)
1757290a6ce1SLorenzo Bianconi 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
17580f7e1728SLorenzo Bianconi 				 fs_table->fs_avl[i].gain);
1759290a6ce1SLorenzo Bianconi 	buf[len - 1] = '\n';
1760290a6ce1SLorenzo Bianconi 
1761290a6ce1SLorenzo Bianconi 	return len;
1762290a6ce1SLorenzo Bianconi }
1763290a6ce1SLorenzo Bianconi 
1764290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
1765290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
1766290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1767290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
1768290a6ce1SLorenzo Bianconi 		       st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1769290a6ce1SLorenzo Bianconi 
1770290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = {
1771290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1772290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1773290a6ce1SLorenzo Bianconi 	NULL,
1774290a6ce1SLorenzo Bianconi };
1775290a6ce1SLorenzo Bianconi 
1776290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
1777290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_acc_attributes,
1778290a6ce1SLorenzo Bianconi };
1779290a6ce1SLorenzo Bianconi 
1780290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = {
1781290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_acc_attribute_group,
1782290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1783290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1784b5969abfSSean Nyekjaer 	.read_event_value = st_lsm6dsx_read_event,
1785b5969abfSSean Nyekjaer 	.write_event_value = st_lsm6dsx_write_event,
1786b5969abfSSean Nyekjaer 	.read_event_config = st_lsm6dsx_read_event_config,
1787b5969abfSSean Nyekjaer 	.write_event_config = st_lsm6dsx_write_event_config,
1788290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1789290a6ce1SLorenzo Bianconi };
1790290a6ce1SLorenzo Bianconi 
1791290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = {
1792290a6ce1SLorenzo Bianconi 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1793290a6ce1SLorenzo Bianconi 	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
1794290a6ce1SLorenzo Bianconi 	NULL,
1795290a6ce1SLorenzo Bianconi };
1796290a6ce1SLorenzo Bianconi 
1797290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
1798290a6ce1SLorenzo Bianconi 	.attrs = st_lsm6dsx_gyro_attributes,
1799290a6ce1SLorenzo Bianconi };
1800290a6ce1SLorenzo Bianconi 
1801290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = {
1802290a6ce1SLorenzo Bianconi 	.attrs = &st_lsm6dsx_gyro_attribute_group,
1803290a6ce1SLorenzo Bianconi 	.read_raw = st_lsm6dsx_read_raw,
1804290a6ce1SLorenzo Bianconi 	.write_raw = st_lsm6dsx_write_raw,
1805290a6ce1SLorenzo Bianconi 	.hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1806290a6ce1SLorenzo Bianconi };
1807290a6ce1SLorenzo Bianconi 
180803d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1809dba32904SLorenzo Bianconi {
181003d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
1811dba32904SLorenzo Bianconi 
181203d4c566SAndy Shevchenko 	if (!dev_fwnode(dev))
1813dba32904SLorenzo Bianconi 		return -EINVAL;
1814dba32904SLorenzo Bianconi 
181503d4c566SAndy Shevchenko 	return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
1816dba32904SLorenzo Bianconi }
1817dba32904SLorenzo Bianconi 
18187e906103SLorenzo Bianconi static int
18197e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
18207e906103SLorenzo Bianconi 			const struct st_lsm6dsx_reg **drdy_reg)
1821dba32904SLorenzo Bianconi {
1822dba32904SLorenzo Bianconi 	int err = 0, drdy_pin;
1823dba32904SLorenzo Bianconi 
182403d4c566SAndy Shevchenko 	if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
1825dba32904SLorenzo Bianconi 		struct st_sensors_platform_data *pdata;
1826dba32904SLorenzo Bianconi 		struct device *dev = hw->dev;
1827dba32904SLorenzo Bianconi 
1828dba32904SLorenzo Bianconi 		pdata = (struct st_sensors_platform_data *)dev->platform_data;
1829dba32904SLorenzo Bianconi 		drdy_pin = pdata ? pdata->drdy_int_pin : 1;
1830dba32904SLorenzo Bianconi 	}
1831dba32904SLorenzo Bianconi 
1832dba32904SLorenzo Bianconi 	switch (drdy_pin) {
1833dba32904SLorenzo Bianconi 	case 1:
18347e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq1_func;
18357e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq1;
1836dba32904SLorenzo Bianconi 		break;
1837dba32904SLorenzo Bianconi 	case 2:
18387e906103SLorenzo Bianconi 		hw->irq_routing = &hw->settings->irq_config.irq2_func;
18397e906103SLorenzo Bianconi 		*drdy_reg = &hw->settings->irq_config.irq2;
1840dba32904SLorenzo Bianconi 		break;
1841dba32904SLorenzo Bianconi 	default:
1842dba32904SLorenzo Bianconi 		dev_err(hw->dev, "unsupported data ready pin\n");
1843dba32904SLorenzo Bianconi 		err = -EINVAL;
1844dba32904SLorenzo Bianconi 		break;
1845dba32904SLorenzo Bianconi 	}
1846dba32904SLorenzo Bianconi 
1847dba32904SLorenzo Bianconi 	return err;
1848dba32904SLorenzo Bianconi }
1849dba32904SLorenzo Bianconi 
1850c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1851c91c1c84SLorenzo Bianconi {
1852c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
1853c91c1c84SLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
185403d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
1855c91c1c84SLorenzo Bianconi 	unsigned int data;
1856c91c1c84SLorenzo Bianconi 	int err = 0;
1857c91c1c84SLorenzo Bianconi 
1858c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
1859c91c1c84SLorenzo Bianconi 
186003d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
186103d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
1862c91c1c84SLorenzo Bianconi 	    (pdata && pdata->pullups)) {
1863c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
1864c91c1c84SLorenzo Bianconi 		if (err < 0)
1865c91c1c84SLorenzo Bianconi 			return err;
1866c91c1c84SLorenzo Bianconi 
1867c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
1868c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
1869c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.addr,
1870c91c1c84SLorenzo Bianconi 					 hub_settings->pullup_en.mask, data);
1871c91c1c84SLorenzo Bianconi 
1872c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
1873c91c1c84SLorenzo Bianconi 
1874c91c1c84SLorenzo Bianconi 		if (err < 0)
1875c91c1c84SLorenzo Bianconi 			return err;
1876c91c1c84SLorenzo Bianconi 	}
1877c91c1c84SLorenzo Bianconi 
1878c91c1c84SLorenzo Bianconi 	if (hub_settings->aux_sens.addr) {
1879c91c1c84SLorenzo Bianconi 		/* configure aux sensors */
1880c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_set_page(hw, true);
1881c91c1c84SLorenzo Bianconi 		if (err < 0)
1882c91c1c84SLorenzo Bianconi 			return err;
1883c91c1c84SLorenzo Bianconi 
1884c91c1c84SLorenzo Bianconi 		data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
1885c91c1c84SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
1886c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.addr,
1887c91c1c84SLorenzo Bianconi 					 hub_settings->aux_sens.mask, data);
1888c91c1c84SLorenzo Bianconi 
1889c91c1c84SLorenzo Bianconi 		st_lsm6dsx_set_page(hw, false);
1890c91c1c84SLorenzo Bianconi 	}
1891c91c1c84SLorenzo Bianconi 
1892c91c1c84SLorenzo Bianconi 	return err;
1893c91c1c84SLorenzo Bianconi }
1894c91c1c84SLorenzo Bianconi 
189521345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
189621345107SLorenzo Bianconi {
189721345107SLorenzo Bianconi 	const struct st_lsm6dsx_hw_ts_settings *ts_settings;
189821345107SLorenzo Bianconi 	int err, val;
189921345107SLorenzo Bianconi 
190021345107SLorenzo Bianconi 	ts_settings = &hw->settings->ts_settings;
190121345107SLorenzo Bianconi 	/* enable hw timestamp generation if necessary */
190221345107SLorenzo Bianconi 	if (ts_settings->timer_en.addr) {
190321345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
190421345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
190521345107SLorenzo Bianconi 					 ts_settings->timer_en.addr,
190621345107SLorenzo Bianconi 					 ts_settings->timer_en.mask, val);
190721345107SLorenzo Bianconi 		if (err < 0)
190821345107SLorenzo Bianconi 			return err;
190921345107SLorenzo Bianconi 	}
191021345107SLorenzo Bianconi 
191121345107SLorenzo Bianconi 	/* enable high resolution for hw ts timer if necessary */
191221345107SLorenzo Bianconi 	if (ts_settings->hr_timer.addr) {
191321345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
191421345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
191521345107SLorenzo Bianconi 					 ts_settings->hr_timer.addr,
191621345107SLorenzo Bianconi 					 ts_settings->hr_timer.mask, val);
191721345107SLorenzo Bianconi 		if (err < 0)
191821345107SLorenzo Bianconi 			return err;
191921345107SLorenzo Bianconi 	}
192021345107SLorenzo Bianconi 
192121345107SLorenzo Bianconi 	/* enable ts queueing in FIFO if necessary */
192221345107SLorenzo Bianconi 	if (ts_settings->fifo_en.addr) {
192321345107SLorenzo Bianconi 		val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
192421345107SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap,
192521345107SLorenzo Bianconi 					 ts_settings->fifo_en.addr,
192621345107SLorenzo Bianconi 					 ts_settings->fifo_en.mask, val);
192721345107SLorenzo Bianconi 		if (err < 0)
192821345107SLorenzo Bianconi 			return err;
192921345107SLorenzo Bianconi 	}
1930cb3b6b8eSMario Tesi 
1931cb3b6b8eSMario Tesi 	/* calibrate timestamp sensitivity */
1932cb3b6b8eSMario Tesi 	hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
1933cb3b6b8eSMario Tesi 	if (ts_settings->freq_fine) {
1934cb3b6b8eSMario Tesi 		err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
1935cb3b6b8eSMario Tesi 		if (err < 0)
1936cb3b6b8eSMario Tesi 			return err;
1937cb3b6b8eSMario Tesi 
1938cb3b6b8eSMario Tesi 		/*
1939cb3b6b8eSMario Tesi 		 * linearize the AN5192 formula:
1940cb3b6b8eSMario Tesi 		 * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
1941cb3b6b8eSMario Tesi 		 * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
1942cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - 37.5 * val
1943cb3b6b8eSMario Tesi 		 * ttrim[ns] ~= 25000 - (37500 * val) / 1000
1944cb3b6b8eSMario Tesi 		 */
1945cb3b6b8eSMario Tesi 		hw->ts_gain -= ((s8)val * 37500) / 1000;
1946cb3b6b8eSMario Tesi 	}
1947cb3b6b8eSMario Tesi 
194821345107SLorenzo Bianconi 	return 0;
194921345107SLorenzo Bianconi }
195021345107SLorenzo Bianconi 
1951290a6ce1SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
1952290a6ce1SLorenzo Bianconi {
19537e906103SLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
1954290a6ce1SLorenzo Bianconi 	int err;
1955290a6ce1SLorenzo Bianconi 
195619435425SLorenzo Bianconi 	/* device sw reset */
195766b662a1SLorenzo Bianconi 	reg = &hw->settings->reset;
195866b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
195966b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
1960290a6ce1SLorenzo Bianconi 	if (err < 0)
1961290a6ce1SLorenzo Bianconi 		return err;
1962290a6ce1SLorenzo Bianconi 
196319435425SLorenzo Bianconi 	msleep(50);
196419435425SLorenzo Bianconi 
196519435425SLorenzo Bianconi 	/* reload trimming parameter */
196666b662a1SLorenzo Bianconi 	reg = &hw->settings->boot;
196766b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
196866b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
196919435425SLorenzo Bianconi 	if (err < 0)
197019435425SLorenzo Bianconi 		return err;
197119435425SLorenzo Bianconi 
197219435425SLorenzo Bianconi 	msleep(50);
1973290a6ce1SLorenzo Bianconi 
1974290a6ce1SLorenzo Bianconi 	/* enable Block Data Update */
197566b662a1SLorenzo Bianconi 	reg = &hw->settings->bdu;
197666b662a1SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
197766b662a1SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
1978290a6ce1SLorenzo Bianconi 	if (err < 0)
1979290a6ce1SLorenzo Bianconi 		return err;
1980290a6ce1SLorenzo Bianconi 
1981290a6ce1SLorenzo Bianconi 	/* enable FIFO watermak interrupt */
19827e906103SLorenzo Bianconi 	err = st_lsm6dsx_get_drdy_reg(hw, &reg);
1983290a6ce1SLorenzo Bianconi 	if (err < 0)
1984290a6ce1SLorenzo Bianconi 		return err;
1985290a6ce1SLorenzo Bianconi 
19867e906103SLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
19877e906103SLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
198821345107SLorenzo Bianconi 	if (err < 0)
198921345107SLorenzo Bianconi 		return err;
199021345107SLorenzo Bianconi 
19919db02d32SLorenzo Bianconi 	/* enable Latched interrupts for device events */
19927e906103SLorenzo Bianconi 	if (hw->settings->irq_config.lir.addr) {
19937e906103SLorenzo Bianconi 		reg = &hw->settings->irq_config.lir;
19947e906103SLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
19957e906103SLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
19969db02d32SLorenzo Bianconi 		if (err < 0)
19979db02d32SLorenzo Bianconi 			return err;
199822ea5651SLorenzo Bianconi 
199922ea5651SLorenzo Bianconi 		/* enable clear on read for latched interrupts */
20007e906103SLorenzo Bianconi 		if (hw->settings->irq_config.clear_on_read.addr) {
20017e906103SLorenzo Bianconi 			reg = &hw->settings->irq_config.clear_on_read;
200222ea5651SLorenzo Bianconi 			err = regmap_update_bits(hw->regmap,
20037e906103SLorenzo Bianconi 					reg->addr, reg->mask,
20047e906103SLorenzo Bianconi 					ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
200522ea5651SLorenzo Bianconi 			if (err < 0)
200622ea5651SLorenzo Bianconi 				return err;
200722ea5651SLorenzo Bianconi 		}
20089db02d32SLorenzo Bianconi 	}
20099db02d32SLorenzo Bianconi 
2010960506edSLorenzo Bianconi 	/* enable drdy-mas if available */
2011960506edSLorenzo Bianconi 	if (hw->settings->drdy_mask.addr) {
2012960506edSLorenzo Bianconi 		reg = &hw->settings->drdy_mask;
2013960506edSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2014960506edSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2015960506edSLorenzo Bianconi 		if (err < 0)
2016960506edSLorenzo Bianconi 			return err;
2017960506edSLorenzo Bianconi 	}
2018960506edSLorenzo Bianconi 
2019c91c1c84SLorenzo Bianconi 	err = st_lsm6dsx_init_shub(hw);
2020c91c1c84SLorenzo Bianconi 	if (err < 0)
2021c91c1c84SLorenzo Bianconi 		return err;
2022c91c1c84SLorenzo Bianconi 
202321345107SLorenzo Bianconi 	return st_lsm6dsx_init_hw_timer(hw);
2024290a6ce1SLorenzo Bianconi }
2025290a6ce1SLorenzo Bianconi 
2026290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
2027510c0106SLorenzo Bianconi 					       enum st_lsm6dsx_sensor_id id,
2028510c0106SLorenzo Bianconi 					       const char *name)
2029290a6ce1SLorenzo Bianconi {
2030290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2031290a6ce1SLorenzo Bianconi 	struct iio_dev *iio_dev;
2032290a6ce1SLorenzo Bianconi 
2033290a6ce1SLorenzo Bianconi 	iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
2034290a6ce1SLorenzo Bianconi 	if (!iio_dev)
2035290a6ce1SLorenzo Bianconi 		return NULL;
2036290a6ce1SLorenzo Bianconi 
2037290a6ce1SLorenzo Bianconi 	iio_dev->modes = INDIO_DIRECT_MODE;
2038290a6ce1SLorenzo Bianconi 	iio_dev->dev.parent = hw->dev;
2039290a6ce1SLorenzo Bianconi 	iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2040f48bc49bSLorenzo Bianconi 	iio_dev->channels = hw->settings->channels[id].chan;
2041f48bc49bSLorenzo Bianconi 	iio_dev->num_channels = hw->settings->channels[id].len;
2042290a6ce1SLorenzo Bianconi 
2043290a6ce1SLorenzo Bianconi 	sensor = iio_priv(iio_dev);
2044290a6ce1SLorenzo Bianconi 	sensor->id = id;
2045290a6ce1SLorenzo Bianconi 	sensor->hw = hw;
2046f8710f03SLorenzo Bianconi 	sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz;
2047640aca3fSLorenzo Bianconi 	sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
2048290a6ce1SLorenzo Bianconi 	sensor->watermark = 1;
2049290a6ce1SLorenzo Bianconi 
2050290a6ce1SLorenzo Bianconi 	switch (id) {
2051290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_ACC:
2052290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_acc_info;
2053510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
2054510c0106SLorenzo Bianconi 			  name);
2055290a6ce1SLorenzo Bianconi 		break;
2056290a6ce1SLorenzo Bianconi 	case ST_LSM6DSX_ID_GYRO:
2057290a6ce1SLorenzo Bianconi 		iio_dev->info = &st_lsm6dsx_gyro_info;
2058510c0106SLorenzo Bianconi 		scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
2059510c0106SLorenzo Bianconi 			  name);
2060290a6ce1SLorenzo Bianconi 		break;
2061290a6ce1SLorenzo Bianconi 	default:
2062290a6ce1SLorenzo Bianconi 		return NULL;
2063290a6ce1SLorenzo Bianconi 	}
2064510c0106SLorenzo Bianconi 	iio_dev->name = sensor->name;
2065290a6ce1SLorenzo Bianconi 
2066290a6ce1SLorenzo Bianconi 	return iio_dev;
2067290a6ce1SLorenzo Bianconi }
2068290a6ce1SLorenzo Bianconi 
2069615bd378SLorenzo Bianconi static bool
2070615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
20711aabad1fSSean Nyekjaer {
2072615bd378SLorenzo Bianconi 	const struct st_lsm6dsx_event_settings *event_settings;
2073615bd378SLorenzo Bianconi 	int err, data;
2074615bd378SLorenzo Bianconi 	s64 timestamp;
20751aabad1fSSean Nyekjaer 
2076615bd378SLorenzo Bianconi 	if (!hw->enable_event)
2077615bd378SLorenzo Bianconi 		return false;
2078615bd378SLorenzo Bianconi 
2079615bd378SLorenzo Bianconi 	event_settings = &hw->settings->event_settings;
2080615bd378SLorenzo Bianconi 	err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2081615bd378SLorenzo Bianconi 				     &data, sizeof(data));
2082615bd378SLorenzo Bianconi 	if (err < 0)
2083615bd378SLorenzo Bianconi 		return false;
2084615bd378SLorenzo Bianconi 
2085615bd378SLorenzo Bianconi 	timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
20861aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
20871aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Z)))
20881aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
20891aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
20901aabad1fSSean Nyekjaer 						  0,
20911aabad1fSSean Nyekjaer 						  IIO_MOD_Z,
20921aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
20931aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
20941aabad1fSSean Nyekjaer 						  timestamp);
20951aabad1fSSean Nyekjaer 
20961aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
20971aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_Y)))
20981aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
20991aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
21001aabad1fSSean Nyekjaer 						  0,
21011aabad1fSSean Nyekjaer 						  IIO_MOD_Y,
21021aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
21031aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
21041aabad1fSSean Nyekjaer 						  timestamp);
21051aabad1fSSean Nyekjaer 
21061aabad1fSSean Nyekjaer 	if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
21071aabad1fSSean Nyekjaer 	    (hw->enable_event & BIT(IIO_MOD_X)))
21081aabad1fSSean Nyekjaer 		iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
21091aabad1fSSean Nyekjaer 			       IIO_MOD_EVENT_CODE(IIO_ACCEL,
21101aabad1fSSean Nyekjaer 						  0,
21111aabad1fSSean Nyekjaer 						  IIO_MOD_X,
21121aabad1fSSean Nyekjaer 						  IIO_EV_TYPE_THRESH,
21131aabad1fSSean Nyekjaer 						  IIO_EV_DIR_EITHER),
21141aabad1fSSean Nyekjaer 						  timestamp);
2115615bd378SLorenzo Bianconi 
2116615bd378SLorenzo Bianconi 	return data & event_settings->wakeup_src_status_mask;
21171aabad1fSSean Nyekjaer }
21181aabad1fSSean Nyekjaer 
21196ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
21206ee6a368SSean Nyekjaer {
21216ee6a368SSean Nyekjaer 	struct st_lsm6dsx_hw *hw = private;
2122615bd378SLorenzo Bianconi 	bool event;
21236ee6a368SSean Nyekjaer 	int count;
21241aabad1fSSean Nyekjaer 
2125615bd378SLorenzo Bianconi 	event = st_lsm6dsx_report_motion_event(hw);
21266ee6a368SSean Nyekjaer 
2127a912ee4cSLorenzo Bianconi 	if (!hw->settings->fifo_ops.read_fifo)
2128a912ee4cSLorenzo Bianconi 		return event ? IRQ_HANDLED : IRQ_NONE;
2129a912ee4cSLorenzo Bianconi 
21306ee6a368SSean Nyekjaer 	mutex_lock(&hw->fifo_lock);
21316ee6a368SSean Nyekjaer 	count = hw->settings->fifo_ops.read_fifo(hw);
21326ee6a368SSean Nyekjaer 	mutex_unlock(&hw->fifo_lock);
21336ee6a368SSean Nyekjaer 
2134615bd378SLorenzo Bianconi 	return count || event ? IRQ_HANDLED : IRQ_NONE;
21356ee6a368SSean Nyekjaer }
21366ee6a368SSean Nyekjaer 
21376ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
21386ee6a368SSean Nyekjaer {
213931fe8d4eSLorenzo Bianconi 	struct st_sensors_platform_data *pdata;
214031fe8d4eSLorenzo Bianconi 	const struct st_lsm6dsx_reg *reg;
214103d4c566SAndy Shevchenko 	struct device *dev = hw->dev;
21426ee6a368SSean Nyekjaer 	unsigned long irq_type;
21436ee6a368SSean Nyekjaer 	bool irq_active_low;
21446ee6a368SSean Nyekjaer 	int err;
21456ee6a368SSean Nyekjaer 
21466ee6a368SSean Nyekjaer 	irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
21476ee6a368SSean Nyekjaer 
21486ee6a368SSean Nyekjaer 	switch (irq_type) {
21496ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_HIGH:
21506ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_RISING:
21516ee6a368SSean Nyekjaer 		irq_active_low = false;
21526ee6a368SSean Nyekjaer 		break;
21536ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_LOW:
21546ee6a368SSean Nyekjaer 	case IRQF_TRIGGER_FALLING:
21556ee6a368SSean Nyekjaer 		irq_active_low = true;
21566ee6a368SSean Nyekjaer 		break;
21576ee6a368SSean Nyekjaer 	default:
21586ee6a368SSean Nyekjaer 		dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
21596ee6a368SSean Nyekjaer 		return -EINVAL;
21606ee6a368SSean Nyekjaer 	}
21616ee6a368SSean Nyekjaer 
216231fe8d4eSLorenzo Bianconi 	reg = &hw->settings->irq_config.hla;
216331fe8d4eSLorenzo Bianconi 	err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
216431fe8d4eSLorenzo Bianconi 				 ST_LSM6DSX_SHIFT_VAL(irq_active_low,
216531fe8d4eSLorenzo Bianconi 						      reg->mask));
21666ee6a368SSean Nyekjaer 	if (err < 0)
21676ee6a368SSean Nyekjaer 		return err;
21686ee6a368SSean Nyekjaer 
216903d4c566SAndy Shevchenko 	pdata = (struct st_sensors_platform_data *)dev->platform_data;
217003d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
21716ee6a368SSean Nyekjaer 	    (pdata && pdata->open_drain)) {
217231fe8d4eSLorenzo Bianconi 		reg = &hw->settings->irq_config.od;
217331fe8d4eSLorenzo Bianconi 		err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
217431fe8d4eSLorenzo Bianconi 					 ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
21756ee6a368SSean Nyekjaer 		if (err < 0)
21766ee6a368SSean Nyekjaer 			return err;
21776ee6a368SSean Nyekjaer 
21786ee6a368SSean Nyekjaer 		irq_type |= IRQF_SHARED;
21796ee6a368SSean Nyekjaer 	}
21806ee6a368SSean Nyekjaer 
21816ee6a368SSean Nyekjaer 	err = devm_request_threaded_irq(hw->dev, hw->irq,
2182a3aa17d4SSean Nyekjaer 					NULL,
21836ee6a368SSean Nyekjaer 					st_lsm6dsx_handler_thread,
21846ee6a368SSean Nyekjaer 					irq_type | IRQF_ONESHOT,
21856ee6a368SSean Nyekjaer 					"lsm6dsx", hw);
21866ee6a368SSean Nyekjaer 	if (err) {
21876ee6a368SSean Nyekjaer 		dev_err(hw->dev, "failed to request trigger irq %d\n",
21886ee6a368SSean Nyekjaer 			hw->irq);
21896ee6a368SSean Nyekjaer 		return err;
21906ee6a368SSean Nyekjaer 	}
21916ee6a368SSean Nyekjaer 
21926ee6a368SSean Nyekjaer 	return 0;
21936ee6a368SSean Nyekjaer }
21946ee6a368SSean Nyekjaer 
219581956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
219651a8b707SLorenzo Bianconi 		     struct regmap *regmap)
2197290a6ce1SLorenzo Bianconi {
2198b7a73b33SLorenzo Bianconi 	struct st_sensors_platform_data *pdata = dev->platform_data;
2199c91c1c84SLorenzo Bianconi 	const struct st_lsm6dsx_shub_settings *hub_settings;
2200290a6ce1SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw;
220181956a93SLorenzo Bianconi 	const char *name = NULL;
2202290a6ce1SLorenzo Bianconi 	int i, err;
2203290a6ce1SLorenzo Bianconi 
2204290a6ce1SLorenzo Bianconi 	hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
2205290a6ce1SLorenzo Bianconi 	if (!hw)
2206290a6ce1SLorenzo Bianconi 		return -ENOMEM;
2207290a6ce1SLorenzo Bianconi 
2208290a6ce1SLorenzo Bianconi 	dev_set_drvdata(dev, (void *)hw);
2209290a6ce1SLorenzo Bianconi 
2210290a6ce1SLorenzo Bianconi 	mutex_init(&hw->fifo_lock);
2211335eaedcSLorenzo Bianconi 	mutex_init(&hw->conf_lock);
2212739aff87SLorenzo Bianconi 	mutex_init(&hw->page_lock);
2213290a6ce1SLorenzo Bianconi 
221491a6b841SLorenzo Bianconi 	hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
221591a6b841SLorenzo Bianconi 	if (!hw->buff)
221691a6b841SLorenzo Bianconi 		return -ENOMEM;
221791a6b841SLorenzo Bianconi 
2218290a6ce1SLorenzo Bianconi 	hw->dev = dev;
2219290a6ce1SLorenzo Bianconi 	hw->irq = irq;
222051a8b707SLorenzo Bianconi 	hw->regmap = regmap;
2221290a6ce1SLorenzo Bianconi 
222281956a93SLorenzo Bianconi 	err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
2223290a6ce1SLorenzo Bianconi 	if (err < 0)
2224290a6ce1SLorenzo Bianconi 		return err;
2225290a6ce1SLorenzo Bianconi 
22266ffb55e5SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
2227510c0106SLorenzo Bianconi 		hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
2228290a6ce1SLorenzo Bianconi 		if (!hw->iio_devs[i])
2229290a6ce1SLorenzo Bianconi 			return -ENOMEM;
2230290a6ce1SLorenzo Bianconi 	}
2231290a6ce1SLorenzo Bianconi 
2232290a6ce1SLorenzo Bianconi 	err = st_lsm6dsx_init_device(hw);
2233290a6ce1SLorenzo Bianconi 	if (err < 0)
2234290a6ce1SLorenzo Bianconi 		return err;
2235290a6ce1SLorenzo Bianconi 
2236c91c1c84SLorenzo Bianconi 	hub_settings = &hw->settings->shub_settings;
2237c91c1c84SLorenzo Bianconi 	if (hub_settings->master_en.addr) {
2238c91c1c84SLorenzo Bianconi 		err = st_lsm6dsx_shub_probe(hw, name);
2239c91c1c84SLorenzo Bianconi 		if (err < 0)
2240c91c1c84SLorenzo Bianconi 			return err;
2241c91c1c84SLorenzo Bianconi 	}
2242c91c1c84SLorenzo Bianconi 
2243290a6ce1SLorenzo Bianconi 	if (hw->irq > 0) {
22446ee6a368SSean Nyekjaer 		err = st_lsm6dsx_irq_setup(hw);
22456ee6a368SSean Nyekjaer 		if (err < 0)
22466ee6a368SSean Nyekjaer 			return err;
22476ee6a368SSean Nyekjaer 
2248290a6ce1SLorenzo Bianconi 		err = st_lsm6dsx_fifo_setup(hw);
2249290a6ce1SLorenzo Bianconi 		if (err < 0)
2250290a6ce1SLorenzo Bianconi 			return err;
2251290a6ce1SLorenzo Bianconi 	}
2252290a6ce1SLorenzo Bianconi 
2253290a6ce1SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
22546ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
22556ffb55e5SLorenzo Bianconi 			continue;
22566ffb55e5SLorenzo Bianconi 
2257290a6ce1SLorenzo Bianconi 		err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
2258290a6ce1SLorenzo Bianconi 		if (err)
2259290a6ce1SLorenzo Bianconi 			return err;
2260290a6ce1SLorenzo Bianconi 	}
2261290a6ce1SLorenzo Bianconi 
226203d4c566SAndy Shevchenko 	if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
2263b7a73b33SLorenzo Bianconi 	    (pdata && pdata->wakeup_source))
22644c997dfaSSean Nyekjaer 		device_init_wakeup(dev, true);
22654c997dfaSSean Nyekjaer 
2266290a6ce1SLorenzo Bianconi 	return 0;
2267290a6ce1SLorenzo Bianconi }
2268290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe);
2269290a6ce1SLorenzo Bianconi 
22703cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
2271d3f77058SLorenzo Bianconi {
2272d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2273d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2274d3f77058SLorenzo Bianconi 	int i, err = 0;
2275d3f77058SLorenzo Bianconi 
2276d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
22776ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
22786ffb55e5SLorenzo Bianconi 			continue;
22796ffb55e5SLorenzo Bianconi 
2280d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
2281d3f77058SLorenzo Bianconi 		if (!(hw->enable_mask & BIT(sensor->id)))
2282d3f77058SLorenzo Bianconi 			continue;
2283d3f77058SLorenzo Bianconi 
22844c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
22854c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
22864c997dfaSSean Nyekjaer 			/* Enable wake from IRQ */
22874c997dfaSSean Nyekjaer 			enable_irq_wake(hw->irq);
22884c997dfaSSean Nyekjaer 			continue;
22894c997dfaSSean Nyekjaer 		}
22904c997dfaSSean Nyekjaer 
2291bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2292bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2293bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2294bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, false);
2295bce0d57dSLorenzo Bianconi 		else
2296bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, false);
2297d3f77058SLorenzo Bianconi 		if (err < 0)
2298d3f77058SLorenzo Bianconi 			return err;
2299bce0d57dSLorenzo Bianconi 
2300bce0d57dSLorenzo Bianconi 		hw->suspend_mask |= BIT(sensor->id);
2301d3f77058SLorenzo Bianconi 	}
2302d3f77058SLorenzo Bianconi 
2303d3f77058SLorenzo Bianconi 	if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
2304d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_flush_fifo(hw);
2305d3f77058SLorenzo Bianconi 
2306d3f77058SLorenzo Bianconi 	return err;
2307d3f77058SLorenzo Bianconi }
2308d3f77058SLorenzo Bianconi 
23093cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
2310d3f77058SLorenzo Bianconi {
2311d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
2312d3f77058SLorenzo Bianconi 	struct st_lsm6dsx_sensor *sensor;
2313d3f77058SLorenzo Bianconi 	int i, err = 0;
2314d3f77058SLorenzo Bianconi 
2315d3f77058SLorenzo Bianconi 	for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
23166ffb55e5SLorenzo Bianconi 		if (!hw->iio_devs[i])
23176ffb55e5SLorenzo Bianconi 			continue;
23186ffb55e5SLorenzo Bianconi 
2319d3f77058SLorenzo Bianconi 		sensor = iio_priv(hw->iio_devs[i]);
23204c997dfaSSean Nyekjaer 		if (device_may_wakeup(dev) &&
23214c997dfaSSean Nyekjaer 		    sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
23224c997dfaSSean Nyekjaer 			disable_irq_wake(hw->irq);
23234c997dfaSSean Nyekjaer 
2324bce0d57dSLorenzo Bianconi 		if (!(hw->suspend_mask & BIT(sensor->id)))
2325d3f77058SLorenzo Bianconi 			continue;
2326d3f77058SLorenzo Bianconi 
2327bce0d57dSLorenzo Bianconi 		if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2328bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT1 ||
2329bce0d57dSLorenzo Bianconi 		    sensor->id == ST_LSM6DSX_ID_EXT2)
2330bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_shub_set_enable(sensor, true);
2331bce0d57dSLorenzo Bianconi 		else
2332bce0d57dSLorenzo Bianconi 			err = st_lsm6dsx_sensor_set_enable(sensor, true);
2333d3f77058SLorenzo Bianconi 		if (err < 0)
2334d3f77058SLorenzo Bianconi 			return err;
2335bce0d57dSLorenzo Bianconi 
2336bce0d57dSLorenzo Bianconi 		hw->suspend_mask &= ~BIT(sensor->id);
2337d3f77058SLorenzo Bianconi 	}
2338d3f77058SLorenzo Bianconi 
2339d3f77058SLorenzo Bianconi 	if (hw->enable_mask)
2340d3f77058SLorenzo Bianconi 		err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
2341d3f77058SLorenzo Bianconi 
2342d3f77058SLorenzo Bianconi 	return err;
2343d3f77058SLorenzo Bianconi }
2344d3f77058SLorenzo Bianconi 
2345d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = {
2346d3f77058SLorenzo Bianconi 	SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
2347d3f77058SLorenzo Bianconi };
2348d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
2349d3f77058SLorenzo Bianconi 
2350290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
2351290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
2352290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
2353290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2");
2354