forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * STMicroelectronics st_lsm6dsx sensor driver
34 *
....@@ -9,6 +10,8 @@
910 * +-125/+-245/+-500/+-1000/+-2000 dps
1011 * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
1112 * allowing dynamic batching of sensor data.
13
+ * LSM9DSx series is similar but includes an additional magnetometer, handled
14
+ * by a different driver.
1215 *
1316 * Supported sensors:
1417 * - LSM6DS3:
....@@ -17,26 +20,42 @@
1720 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
1821 * - FIFO size: 8KB
1922 *
20
- * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC:
23
+ * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
2124 * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
2225 * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
2326 * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
2427 * - FIFO size: 4KB
2528 *
29
+ * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX:
30
+ * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416,
31
+ * 833
32
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
33
+ * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
34
+ * - FIFO size: 3KB
35
+ *
36
+ * - LSM9DS1/LSM6DS0:
37
+ * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
38
+ * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
39
+ * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
40
+ * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
41
+ * - FIFO size: 32
42
+ *
2643 * Copyright 2016 STMicroelectronics Inc.
2744 *
2845 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
2946 * Denis Ciocca <denis.ciocca@st.com>
30
- *
31
- * Licensed under the GPL-2.
3247 */
3348
3449 #include <linux/kernel.h>
3550 #include <linux/module.h>
3651 #include <linux/delay.h>
52
+#include <linux/iio/events.h>
3753 #include <linux/iio/iio.h>
3854 #include <linux/iio/sysfs.h>
55
+#include <linux/interrupt.h>
56
+#include <linux/irq.h>
3957 #include <linux/pm.h>
58
+#include <linux/property.h>
4059 #include <linux/regmap.h>
4160 #include <linux/bitfield.h>
4261
....@@ -44,167 +63,249 @@
4463
4564 #include "st_lsm6dsx.h"
4665
47
-#define ST_LSM6DSX_REG_INT1_ADDR 0x0d
48
-#define ST_LSM6DSX_REG_INT2_ADDR 0x0e
49
-#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
5066 #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
51
-#define ST_LSM6DSX_REG_RESET_ADDR 0x12
52
-#define ST_LSM6DSX_REG_RESET_MASK BIT(0)
53
-#define ST_LSM6DSX_REG_BDU_ADDR 0x12
54
-#define ST_LSM6DSX_REG_BDU_MASK BIT(6)
55
-#define ST_LSM6DSX_REG_INT2_ON_INT1_ADDR 0x13
56
-#define ST_LSM6DSX_REG_INT2_ON_INT1_MASK BIT(5)
5767
58
-#define ST_LSM6DSX_REG_ACC_ODR_ADDR 0x10
59
-#define ST_LSM6DSX_REG_ACC_ODR_MASK GENMASK(7, 4)
60
-#define ST_LSM6DSX_REG_ACC_FS_ADDR 0x10
61
-#define ST_LSM6DSX_REG_ACC_FS_MASK GENMASK(3, 2)
62
-#define ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR 0x28
63
-#define ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR 0x2a
64
-#define ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR 0x2c
68
+#define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */
6569
66
-#define ST_LSM6DSX_REG_GYRO_ODR_ADDR 0x11
67
-#define ST_LSM6DSX_REG_GYRO_ODR_MASK GENMASK(7, 4)
68
-#define ST_LSM6DSX_REG_GYRO_FS_ADDR 0x11
69
-#define ST_LSM6DSX_REG_GYRO_FS_MASK GENMASK(3, 2)
70
-#define ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR 0x22
71
-#define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
72
-#define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
73
-
74
-#define ST_LSM6DSX_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61)
75
-#define ST_LSM6DSX_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122)
76
-#define ST_LSM6DSX_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244)
77
-#define ST_LSM6DSX_ACC_FS_16G_GAIN IIO_G_TO_M_S_2(488)
78
-
79
-#define ST_LSM6DSX_GYRO_FS_245_GAIN IIO_DEGREE_TO_RAD(8750)
80
-#define ST_LSM6DSX_GYRO_FS_500_GAIN IIO_DEGREE_TO_RAD(17500)
81
-#define ST_LSM6DSX_GYRO_FS_1000_GAIN IIO_DEGREE_TO_RAD(35000)
82
-#define ST_LSM6DSX_GYRO_FS_2000_GAIN IIO_DEGREE_TO_RAD(70000)
83
-
84
-struct st_lsm6dsx_odr {
85
- u16 hz;
86
- u8 val;
70
+static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
71
+ ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
72
+ ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
73
+ ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
74
+ IIO_CHAN_SOFT_TIMESTAMP(3),
8775 };
8876
89
-#define ST_LSM6DSX_ODR_LIST_SIZE 6
90
-struct st_lsm6dsx_odr_table_entry {
91
- struct st_lsm6dsx_reg reg;
92
- struct st_lsm6dsx_odr odr_avl[ST_LSM6DSX_ODR_LIST_SIZE];
77
+static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
78
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
79
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
80
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
81
+ IIO_CHAN_SOFT_TIMESTAMP(3),
9382 };
9483
95
-static const struct st_lsm6dsx_odr_table_entry st_lsm6dsx_odr_table[] = {
96
- [ST_LSM6DSX_ID_ACC] = {
97
- .reg = {
98
- .addr = ST_LSM6DSX_REG_ACC_ODR_ADDR,
99
- .mask = ST_LSM6DSX_REG_ACC_ODR_MASK,
100
- },
101
- .odr_avl[0] = { 13, 0x01 },
102
- .odr_avl[1] = { 26, 0x02 },
103
- .odr_avl[2] = { 52, 0x03 },
104
- .odr_avl[3] = { 104, 0x04 },
105
- .odr_avl[4] = { 208, 0x05 },
106
- .odr_avl[5] = { 416, 0x06 },
107
- },
108
- [ST_LSM6DSX_ID_GYRO] = {
109
- .reg = {
110
- .addr = ST_LSM6DSX_REG_GYRO_ODR_ADDR,
111
- .mask = ST_LSM6DSX_REG_GYRO_ODR_MASK,
112
- },
113
- .odr_avl[0] = { 13, 0x01 },
114
- .odr_avl[1] = { 26, 0x02 },
115
- .odr_avl[2] = { 52, 0x03 },
116
- .odr_avl[3] = { 104, 0x04 },
117
- .odr_avl[4] = { 208, 0x05 },
118
- .odr_avl[5] = { 416, 0x06 },
119
- }
120
-};
121
-
122
-struct st_lsm6dsx_fs {
123
- u32 gain;
124
- u8 val;
125
-};
126
-
127
-#define ST_LSM6DSX_FS_LIST_SIZE 4
128
-struct st_lsm6dsx_fs_table_entry {
129
- struct st_lsm6dsx_reg reg;
130
- struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE];
131
-};
132
-
133
-static const struct st_lsm6dsx_fs_table_entry st_lsm6dsx_fs_table[] = {
134
- [ST_LSM6DSX_ID_ACC] = {
135
- .reg = {
136
- .addr = ST_LSM6DSX_REG_ACC_FS_ADDR,
137
- .mask = ST_LSM6DSX_REG_ACC_FS_MASK,
138
- },
139
- .fs_avl[0] = { ST_LSM6DSX_ACC_FS_2G_GAIN, 0x0 },
140
- .fs_avl[1] = { ST_LSM6DSX_ACC_FS_4G_GAIN, 0x2 },
141
- .fs_avl[2] = { ST_LSM6DSX_ACC_FS_8G_GAIN, 0x3 },
142
- .fs_avl[3] = { ST_LSM6DSX_ACC_FS_16G_GAIN, 0x1 },
143
- },
144
- [ST_LSM6DSX_ID_GYRO] = {
145
- .reg = {
146
- .addr = ST_LSM6DSX_REG_GYRO_FS_ADDR,
147
- .mask = ST_LSM6DSX_REG_GYRO_FS_MASK,
148
- },
149
- .fs_avl[0] = { ST_LSM6DSX_GYRO_FS_245_GAIN, 0x0 },
150
- .fs_avl[1] = { ST_LSM6DSX_GYRO_FS_500_GAIN, 0x1 },
151
- .fs_avl[2] = { ST_LSM6DSX_GYRO_FS_1000_GAIN, 0x2 },
152
- .fs_avl[3] = { ST_LSM6DSX_GYRO_FS_2000_GAIN, 0x3 },
153
- }
84
+static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
85
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
86
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
87
+ ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
88
+ IIO_CHAN_SOFT_TIMESTAMP(3),
15489 };
15590
15691 static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
15792 {
158
- .wai = 0x69,
159
- .max_fifo_size = 1365,
160
- .id = {
161
- [0] = ST_LSM6DS3_ID,
93
+ .wai = 0x68,
94
+ .reset = {
95
+ .addr = 0x22,
96
+ .mask = BIT(0),
16297 },
163
- .decimator = {
98
+ .boot = {
99
+ .addr = 0x22,
100
+ .mask = BIT(7),
101
+ },
102
+ .bdu = {
103
+ .addr = 0x22,
104
+ .mask = BIT(6),
105
+ },
106
+ .max_fifo_size = 32,
107
+ .id = {
108
+ {
109
+ .hw_id = ST_LSM9DS1_ID,
110
+ .name = ST_LSM9DS1_DEV_NAME,
111
+ }, {
112
+ .hw_id = ST_LSM6DS0_ID,
113
+ .name = ST_LSM6DS0_DEV_NAME,
114
+ },
115
+ },
116
+ .channels = {
164117 [ST_LSM6DSX_ID_ACC] = {
165
- .addr = 0x08,
166
- .mask = GENMASK(2, 0),
118
+ .chan = st_lsm6dsx_acc_channels,
119
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
167120 },
168121 [ST_LSM6DSX_ID_GYRO] = {
169
- .addr = 0x08,
170
- .mask = GENMASK(5, 3),
122
+ .chan = st_lsm6ds0_gyro_channels,
123
+ .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
171124 },
172125 },
173
- .fifo_ops = {
174
- .fifo_th = {
175
- .addr = 0x06,
176
- .mask = GENMASK(11, 0),
126
+ .odr_table = {
127
+ [ST_LSM6DSX_ID_ACC] = {
128
+ .reg = {
129
+ .addr = 0x20,
130
+ .mask = GENMASK(7, 5),
131
+ },
132
+ .odr_avl[0] = { 10000, 0x01 },
133
+ .odr_avl[1] = { 50000, 0x02 },
134
+ .odr_avl[2] = { 119000, 0x03 },
135
+ .odr_avl[3] = { 238000, 0x04 },
136
+ .odr_avl[4] = { 476000, 0x05 },
137
+ .odr_avl[5] = { 952000, 0x06 },
138
+ .odr_len = 6,
177139 },
178
- .fifo_diff = {
179
- .addr = 0x3a,
180
- .mask = GENMASK(11, 0),
140
+ [ST_LSM6DSX_ID_GYRO] = {
141
+ .reg = {
142
+ .addr = 0x10,
143
+ .mask = GENMASK(7, 5),
144
+ },
145
+ .odr_avl[0] = { 14900, 0x01 },
146
+ .odr_avl[1] = { 59500, 0x02 },
147
+ .odr_avl[2] = { 119000, 0x03 },
148
+ .odr_avl[3] = { 238000, 0x04 },
149
+ .odr_avl[4] = { 476000, 0x05 },
150
+ .odr_avl[5] = { 952000, 0x06 },
151
+ .odr_len = 6,
181152 },
182
- .th_wl = 3, /* 1LSB = 2B */
183153 },
184
- .ts_settings = {
185
- .timer_en = {
186
- .addr = 0x58,
187
- .mask = BIT(7),
154
+ .fs_table = {
155
+ [ST_LSM6DSX_ID_ACC] = {
156
+ .reg = {
157
+ .addr = 0x20,
158
+ .mask = GENMASK(4, 3),
159
+ },
160
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
161
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
162
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
163
+ .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 },
164
+ .fs_len = 4,
188165 },
189
- .hr_timer = {
190
- .addr = 0x5c,
166
+ [ST_LSM6DSX_ID_GYRO] = {
167
+ .reg = {
168
+ .addr = 0x10,
169
+ .mask = GENMASK(4, 3),
170
+ },
171
+
172
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
173
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
174
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
175
+ .fs_len = 3,
176
+ },
177
+ },
178
+ .irq_config = {
179
+ .irq1 = {
180
+ .addr = 0x0c,
181
+ .mask = BIT(3),
182
+ },
183
+ .irq2 = {
184
+ .addr = 0x0d,
185
+ .mask = BIT(3),
186
+ },
187
+ .hla = {
188
+ .addr = 0x22,
189
+ .mask = BIT(5),
190
+ },
191
+ .od = {
192
+ .addr = 0x22,
191193 .mask = BIT(4),
192
- },
193
- .fifo_en = {
194
- .addr = 0x07,
195
- .mask = BIT(7),
196
- },
197
- .decimator = {
198
- .addr = 0x09,
199
- .mask = GENMASK(5, 3),
200194 },
201195 },
202196 },
203197 {
204198 .wai = 0x69,
205
- .max_fifo_size = 682,
199
+ .reset = {
200
+ .addr = 0x12,
201
+ .mask = BIT(0),
202
+ },
203
+ .boot = {
204
+ .addr = 0x12,
205
+ .mask = BIT(7),
206
+ },
207
+ .bdu = {
208
+ .addr = 0x12,
209
+ .mask = BIT(6),
210
+ },
211
+ .max_fifo_size = 1365,
206212 .id = {
207
- [0] = ST_LSM6DS3H_ID,
213
+ {
214
+ .hw_id = ST_LSM6DS3_ID,
215
+ .name = ST_LSM6DS3_DEV_NAME,
216
+ },
217
+ },
218
+ .channels = {
219
+ [ST_LSM6DSX_ID_ACC] = {
220
+ .chan = st_lsm6dsx_acc_channels,
221
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
222
+ },
223
+ [ST_LSM6DSX_ID_GYRO] = {
224
+ .chan = st_lsm6dsx_gyro_channels,
225
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
226
+ },
227
+ },
228
+ .odr_table = {
229
+ [ST_LSM6DSX_ID_ACC] = {
230
+ .reg = {
231
+ .addr = 0x10,
232
+ .mask = GENMASK(7, 4),
233
+ },
234
+ .odr_avl[0] = { 12500, 0x01 },
235
+ .odr_avl[1] = { 26000, 0x02 },
236
+ .odr_avl[2] = { 52000, 0x03 },
237
+ .odr_avl[3] = { 104000, 0x04 },
238
+ .odr_avl[4] = { 208000, 0x05 },
239
+ .odr_avl[5] = { 416000, 0x06 },
240
+ .odr_len = 6,
241
+ },
242
+ [ST_LSM6DSX_ID_GYRO] = {
243
+ .reg = {
244
+ .addr = 0x11,
245
+ .mask = GENMASK(7, 4),
246
+ },
247
+ .odr_avl[0] = { 12500, 0x01 },
248
+ .odr_avl[1] = { 26000, 0x02 },
249
+ .odr_avl[2] = { 52000, 0x03 },
250
+ .odr_avl[3] = { 104000, 0x04 },
251
+ .odr_avl[4] = { 208000, 0x05 },
252
+ .odr_avl[5] = { 416000, 0x06 },
253
+ .odr_len = 6,
254
+ },
255
+ },
256
+ .fs_table = {
257
+ [ST_LSM6DSX_ID_ACC] = {
258
+ .reg = {
259
+ .addr = 0x10,
260
+ .mask = GENMASK(3, 2),
261
+ },
262
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
263
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
264
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
265
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
266
+ .fs_len = 4,
267
+ },
268
+ [ST_LSM6DSX_ID_GYRO] = {
269
+ .reg = {
270
+ .addr = 0x11,
271
+ .mask = GENMASK(3, 2),
272
+ },
273
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
274
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
275
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
276
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
277
+ .fs_len = 4,
278
+ },
279
+ },
280
+ .irq_config = {
281
+ .irq1 = {
282
+ .addr = 0x0d,
283
+ .mask = BIT(3),
284
+ },
285
+ .irq2 = {
286
+ .addr = 0x0e,
287
+ .mask = BIT(3),
288
+ },
289
+ .lir = {
290
+ .addr = 0x58,
291
+ .mask = BIT(0),
292
+ },
293
+ .irq1_func = {
294
+ .addr = 0x5e,
295
+ .mask = BIT(5),
296
+ },
297
+ .irq2_func = {
298
+ .addr = 0x5f,
299
+ .mask = BIT(5),
300
+ },
301
+ .hla = {
302
+ .addr = 0x12,
303
+ .mask = BIT(5),
304
+ },
305
+ .od = {
306
+ .addr = 0x12,
307
+ .mask = BIT(4),
308
+ },
208309 },
209310 .decimator = {
210311 [ST_LSM6DSX_ID_ACC] = {
....@@ -217,6 +318,8 @@
217318 },
218319 },
219320 .fifo_ops = {
321
+ .update_fifo = st_lsm6dsx_update_fifo,
322
+ .read_fifo = st_lsm6dsx_read_fifo,
220323 .fifo_th = {
221324 .addr = 0x06,
222325 .mask = GENMASK(11, 0),
....@@ -244,15 +347,306 @@
244347 .addr = 0x09,
245348 .mask = GENMASK(5, 3),
246349 },
350
+ },
351
+ .event_settings = {
352
+ .wakeup_reg = {
353
+ .addr = 0x5B,
354
+ .mask = GENMASK(5, 0),
355
+ },
356
+ .wakeup_src_reg = 0x1b,
357
+ .wakeup_src_status_mask = BIT(3),
358
+ .wakeup_src_z_mask = BIT(0),
359
+ .wakeup_src_y_mask = BIT(1),
360
+ .wakeup_src_x_mask = BIT(2),
361
+ },
362
+ },
363
+ {
364
+ .wai = 0x69,
365
+ .reset = {
366
+ .addr = 0x12,
367
+ .mask = BIT(0),
368
+ },
369
+ .boot = {
370
+ .addr = 0x12,
371
+ .mask = BIT(7),
372
+ },
373
+ .bdu = {
374
+ .addr = 0x12,
375
+ .mask = BIT(6),
376
+ },
377
+ .max_fifo_size = 682,
378
+ .id = {
379
+ {
380
+ .hw_id = ST_LSM6DS3H_ID,
381
+ .name = ST_LSM6DS3H_DEV_NAME,
382
+ },
383
+ },
384
+ .channels = {
385
+ [ST_LSM6DSX_ID_ACC] = {
386
+ .chan = st_lsm6dsx_acc_channels,
387
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
388
+ },
389
+ [ST_LSM6DSX_ID_GYRO] = {
390
+ .chan = st_lsm6dsx_gyro_channels,
391
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
392
+ },
393
+ },
394
+ .odr_table = {
395
+ [ST_LSM6DSX_ID_ACC] = {
396
+ .reg = {
397
+ .addr = 0x10,
398
+ .mask = GENMASK(7, 4),
399
+ },
400
+ .odr_avl[0] = { 12500, 0x01 },
401
+ .odr_avl[1] = { 26000, 0x02 },
402
+ .odr_avl[2] = { 52000, 0x03 },
403
+ .odr_avl[3] = { 104000, 0x04 },
404
+ .odr_avl[4] = { 208000, 0x05 },
405
+ .odr_avl[5] = { 416000, 0x06 },
406
+ .odr_len = 6,
407
+ },
408
+ [ST_LSM6DSX_ID_GYRO] = {
409
+ .reg = {
410
+ .addr = 0x11,
411
+ .mask = GENMASK(7, 4),
412
+ },
413
+ .odr_avl[0] = { 12500, 0x01 },
414
+ .odr_avl[1] = { 26000, 0x02 },
415
+ .odr_avl[2] = { 52000, 0x03 },
416
+ .odr_avl[3] = { 104000, 0x04 },
417
+ .odr_avl[4] = { 208000, 0x05 },
418
+ .odr_avl[5] = { 416000, 0x06 },
419
+ .odr_len = 6,
420
+ },
421
+ },
422
+ .fs_table = {
423
+ [ST_LSM6DSX_ID_ACC] = {
424
+ .reg = {
425
+ .addr = 0x10,
426
+ .mask = GENMASK(3, 2),
427
+ },
428
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
429
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
430
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
431
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
432
+ .fs_len = 4,
433
+ },
434
+ [ST_LSM6DSX_ID_GYRO] = {
435
+ .reg = {
436
+ .addr = 0x11,
437
+ .mask = GENMASK(3, 2),
438
+ },
439
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
440
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
441
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
442
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
443
+ .fs_len = 4,
444
+ },
445
+ },
446
+ .irq_config = {
447
+ .irq1 = {
448
+ .addr = 0x0d,
449
+ .mask = BIT(3),
450
+ },
451
+ .irq2 = {
452
+ .addr = 0x0e,
453
+ .mask = BIT(3),
454
+ },
455
+ .lir = {
456
+ .addr = 0x58,
457
+ .mask = BIT(0),
458
+ },
459
+ .irq1_func = {
460
+ .addr = 0x5e,
461
+ .mask = BIT(5),
462
+ },
463
+ .irq2_func = {
464
+ .addr = 0x5f,
465
+ .mask = BIT(5),
466
+ },
467
+ .hla = {
468
+ .addr = 0x12,
469
+ .mask = BIT(5),
470
+ },
471
+ .od = {
472
+ .addr = 0x12,
473
+ .mask = BIT(4),
474
+ },
475
+ },
476
+ .decimator = {
477
+ [ST_LSM6DSX_ID_ACC] = {
478
+ .addr = 0x08,
479
+ .mask = GENMASK(2, 0),
480
+ },
481
+ [ST_LSM6DSX_ID_GYRO] = {
482
+ .addr = 0x08,
483
+ .mask = GENMASK(5, 3),
484
+ },
485
+ },
486
+ .fifo_ops = {
487
+ .update_fifo = st_lsm6dsx_update_fifo,
488
+ .read_fifo = st_lsm6dsx_read_fifo,
489
+ .fifo_th = {
490
+ .addr = 0x06,
491
+ .mask = GENMASK(11, 0),
492
+ },
493
+ .fifo_diff = {
494
+ .addr = 0x3a,
495
+ .mask = GENMASK(11, 0),
496
+ },
497
+ .th_wl = 3, /* 1LSB = 2B */
498
+ },
499
+ .ts_settings = {
500
+ .timer_en = {
501
+ .addr = 0x58,
502
+ .mask = BIT(7),
503
+ },
504
+ .hr_timer = {
505
+ .addr = 0x5c,
506
+ .mask = BIT(4),
507
+ },
508
+ .fifo_en = {
509
+ .addr = 0x07,
510
+ .mask = BIT(7),
511
+ },
512
+ .decimator = {
513
+ .addr = 0x09,
514
+ .mask = GENMASK(5, 3),
515
+ },
516
+ },
517
+ .event_settings = {
518
+ .wakeup_reg = {
519
+ .addr = 0x5B,
520
+ .mask = GENMASK(5, 0),
521
+ },
522
+ .wakeup_src_reg = 0x1b,
523
+ .wakeup_src_status_mask = BIT(3),
524
+ .wakeup_src_z_mask = BIT(0),
525
+ .wakeup_src_y_mask = BIT(1),
526
+ .wakeup_src_x_mask = BIT(2),
247527 },
248528 },
249529 {
250530 .wai = 0x6a,
531
+ .reset = {
532
+ .addr = 0x12,
533
+ .mask = BIT(0),
534
+ },
535
+ .boot = {
536
+ .addr = 0x12,
537
+ .mask = BIT(7),
538
+ },
539
+ .bdu = {
540
+ .addr = 0x12,
541
+ .mask = BIT(6),
542
+ },
251543 .max_fifo_size = 682,
252544 .id = {
253
- [0] = ST_LSM6DSL_ID,
254
- [1] = ST_LSM6DSM_ID,
255
- [2] = ST_ISM330DLC_ID,
545
+ {
546
+ .hw_id = ST_LSM6DSL_ID,
547
+ .name = ST_LSM6DSL_DEV_NAME,
548
+ }, {
549
+ .hw_id = ST_LSM6DSM_ID,
550
+ .name = ST_LSM6DSM_DEV_NAME,
551
+ }, {
552
+ .hw_id = ST_ISM330DLC_ID,
553
+ .name = ST_ISM330DLC_DEV_NAME,
554
+ }, {
555
+ .hw_id = ST_LSM6DS3TRC_ID,
556
+ .name = ST_LSM6DS3TRC_DEV_NAME,
557
+ },
558
+ },
559
+ .channels = {
560
+ [ST_LSM6DSX_ID_ACC] = {
561
+ .chan = st_lsm6dsx_acc_channels,
562
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
563
+ },
564
+ [ST_LSM6DSX_ID_GYRO] = {
565
+ .chan = st_lsm6dsx_gyro_channels,
566
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
567
+ },
568
+ },
569
+ .odr_table = {
570
+ [ST_LSM6DSX_ID_ACC] = {
571
+ .reg = {
572
+ .addr = 0x10,
573
+ .mask = GENMASK(7, 4),
574
+ },
575
+ .odr_avl[0] = { 12500, 0x01 },
576
+ .odr_avl[1] = { 26000, 0x02 },
577
+ .odr_avl[2] = { 52000, 0x03 },
578
+ .odr_avl[3] = { 104000, 0x04 },
579
+ .odr_avl[4] = { 208000, 0x05 },
580
+ .odr_avl[5] = { 416000, 0x06 },
581
+ .odr_len = 6,
582
+ },
583
+ [ST_LSM6DSX_ID_GYRO] = {
584
+ .reg = {
585
+ .addr = 0x11,
586
+ .mask = GENMASK(7, 4),
587
+ },
588
+ .odr_avl[0] = { 12500, 0x01 },
589
+ .odr_avl[1] = { 26000, 0x02 },
590
+ .odr_avl[2] = { 52000, 0x03 },
591
+ .odr_avl[3] = { 104000, 0x04 },
592
+ .odr_avl[4] = { 208000, 0x05 },
593
+ .odr_avl[5] = { 416000, 0x06 },
594
+ .odr_len = 6,
595
+ },
596
+ },
597
+ .fs_table = {
598
+ [ST_LSM6DSX_ID_ACC] = {
599
+ .reg = {
600
+ .addr = 0x10,
601
+ .mask = GENMASK(3, 2),
602
+ },
603
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
604
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
605
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
606
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
607
+ .fs_len = 4,
608
+ },
609
+ [ST_LSM6DSX_ID_GYRO] = {
610
+ .reg = {
611
+ .addr = 0x11,
612
+ .mask = GENMASK(3, 2),
613
+ },
614
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
615
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
616
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
617
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
618
+ .fs_len = 4,
619
+ },
620
+ },
621
+ .irq_config = {
622
+ .irq1 = {
623
+ .addr = 0x0d,
624
+ .mask = BIT(3),
625
+ },
626
+ .irq2 = {
627
+ .addr = 0x0e,
628
+ .mask = BIT(3),
629
+ },
630
+ .lir = {
631
+ .addr = 0x58,
632
+ .mask = BIT(0),
633
+ },
634
+ .irq1_func = {
635
+ .addr = 0x5e,
636
+ .mask = BIT(5),
637
+ },
638
+ .irq2_func = {
639
+ .addr = 0x5f,
640
+ .mask = BIT(5),
641
+ },
642
+ .hla = {
643
+ .addr = 0x12,
644
+ .mask = BIT(5),
645
+ },
646
+ .od = {
647
+ .addr = 0x12,
648
+ .mask = BIT(4),
649
+ },
256650 },
257651 .decimator = {
258652 [ST_LSM6DSX_ID_ACC] = {
....@@ -263,8 +657,14 @@
263657 .addr = 0x08,
264658 .mask = GENMASK(5, 3),
265659 },
660
+ [ST_LSM6DSX_ID_EXT0] = {
661
+ .addr = 0x09,
662
+ .mask = GENMASK(2, 0),
663
+ },
266664 },
267665 .fifo_ops = {
666
+ .update_fifo = st_lsm6dsx_update_fifo,
667
+ .read_fifo = st_lsm6dsx_read_fifo,
268668 .fifo_th = {
269669 .addr = 0x06,
270670 .mask = GENMASK(10, 0),
....@@ -293,54 +693,673 @@
293693 .mask = GENMASK(5, 3),
294694 },
295695 },
696
+ .shub_settings = {
697
+ .page_mux = {
698
+ .addr = 0x01,
699
+ .mask = BIT(7),
700
+ },
701
+ .master_en = {
702
+ .addr = 0x1a,
703
+ .mask = BIT(0),
704
+ },
705
+ .pullup_en = {
706
+ .addr = 0x1a,
707
+ .mask = BIT(3),
708
+ },
709
+ .aux_sens = {
710
+ .addr = 0x04,
711
+ .mask = GENMASK(5, 4),
712
+ },
713
+ .wr_once = {
714
+ .addr = 0x07,
715
+ .mask = BIT(5),
716
+ },
717
+ .emb_func = {
718
+ .addr = 0x19,
719
+ .mask = BIT(2),
720
+ },
721
+ .num_ext_dev = 1,
722
+ .shub_out = {
723
+ .addr = 0x2e,
724
+ },
725
+ .slv0_addr = 0x02,
726
+ .dw_slv0_addr = 0x0e,
727
+ .pause = 0x7,
728
+ },
729
+ .event_settings = {
730
+ .enable_reg = {
731
+ .addr = 0x58,
732
+ .mask = BIT(7),
733
+ },
734
+ .wakeup_reg = {
735
+ .addr = 0x5B,
736
+ .mask = GENMASK(5, 0),
737
+ },
738
+ .wakeup_src_reg = 0x1b,
739
+ .wakeup_src_status_mask = BIT(3),
740
+ .wakeup_src_z_mask = BIT(0),
741
+ .wakeup_src_y_mask = BIT(1),
742
+ .wakeup_src_x_mask = BIT(2),
743
+ },
744
+ },
745
+ {
746
+ .wai = 0x6c,
747
+ .reset = {
748
+ .addr = 0x12,
749
+ .mask = BIT(0),
750
+ },
751
+ .boot = {
752
+ .addr = 0x12,
753
+ .mask = BIT(7),
754
+ },
755
+ .bdu = {
756
+ .addr = 0x12,
757
+ .mask = BIT(6),
758
+ },
759
+ .max_fifo_size = 512,
760
+ .id = {
761
+ {
762
+ .hw_id = ST_LSM6DSO_ID,
763
+ .name = ST_LSM6DSO_DEV_NAME,
764
+ }, {
765
+ .hw_id = ST_LSM6DSOX_ID,
766
+ .name = ST_LSM6DSOX_DEV_NAME,
767
+ },
768
+ },
769
+ .channels = {
770
+ [ST_LSM6DSX_ID_ACC] = {
771
+ .chan = st_lsm6dsx_acc_channels,
772
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
773
+ },
774
+ [ST_LSM6DSX_ID_GYRO] = {
775
+ .chan = st_lsm6dsx_gyro_channels,
776
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
777
+ },
778
+ },
779
+ .drdy_mask = {
780
+ .addr = 0x13,
781
+ .mask = BIT(3),
782
+ },
783
+ .odr_table = {
784
+ [ST_LSM6DSX_ID_ACC] = {
785
+ .reg = {
786
+ .addr = 0x10,
787
+ .mask = GENMASK(7, 4),
788
+ },
789
+ .odr_avl[0] = { 12500, 0x01 },
790
+ .odr_avl[1] = { 26000, 0x02 },
791
+ .odr_avl[2] = { 52000, 0x03 },
792
+ .odr_avl[3] = { 104000, 0x04 },
793
+ .odr_avl[4] = { 208000, 0x05 },
794
+ .odr_avl[5] = { 416000, 0x06 },
795
+ .odr_avl[6] = { 833000, 0x07 },
796
+ .odr_len = 7,
797
+ },
798
+ [ST_LSM6DSX_ID_GYRO] = {
799
+ .reg = {
800
+ .addr = 0x11,
801
+ .mask = GENMASK(7, 4),
802
+ },
803
+ .odr_avl[0] = { 12500, 0x01 },
804
+ .odr_avl[1] = { 26000, 0x02 },
805
+ .odr_avl[2] = { 52000, 0x03 },
806
+ .odr_avl[3] = { 104000, 0x04 },
807
+ .odr_avl[4] = { 208000, 0x05 },
808
+ .odr_avl[5] = { 416000, 0x06 },
809
+ .odr_avl[6] = { 833000, 0x07 },
810
+ .odr_len = 7,
811
+ },
812
+ },
813
+ .fs_table = {
814
+ [ST_LSM6DSX_ID_ACC] = {
815
+ .reg = {
816
+ .addr = 0x10,
817
+ .mask = GENMASK(3, 2),
818
+ },
819
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
820
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
821
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
822
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
823
+ .fs_len = 4,
824
+ },
825
+ [ST_LSM6DSX_ID_GYRO] = {
826
+ .reg = {
827
+ .addr = 0x11,
828
+ .mask = GENMASK(3, 2),
829
+ },
830
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
831
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
832
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
833
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
834
+ .fs_len = 4,
835
+ },
836
+ },
837
+ .irq_config = {
838
+ .irq1 = {
839
+ .addr = 0x0d,
840
+ .mask = BIT(3),
841
+ },
842
+ .irq2 = {
843
+ .addr = 0x0e,
844
+ .mask = BIT(3),
845
+ },
846
+ .lir = {
847
+ .addr = 0x56,
848
+ .mask = BIT(0),
849
+ },
850
+ .clear_on_read = {
851
+ .addr = 0x56,
852
+ .mask = BIT(6),
853
+ },
854
+ .irq1_func = {
855
+ .addr = 0x5e,
856
+ .mask = BIT(5),
857
+ },
858
+ .irq2_func = {
859
+ .addr = 0x5f,
860
+ .mask = BIT(5),
861
+ },
862
+ .hla = {
863
+ .addr = 0x12,
864
+ .mask = BIT(5),
865
+ },
866
+ .od = {
867
+ .addr = 0x12,
868
+ .mask = BIT(4),
869
+ },
870
+ },
871
+ .batch = {
872
+ [ST_LSM6DSX_ID_ACC] = {
873
+ .addr = 0x09,
874
+ .mask = GENMASK(3, 0),
875
+ },
876
+ [ST_LSM6DSX_ID_GYRO] = {
877
+ .addr = 0x09,
878
+ .mask = GENMASK(7, 4),
879
+ },
880
+ },
881
+ .fifo_ops = {
882
+ .update_fifo = st_lsm6dsx_update_fifo,
883
+ .read_fifo = st_lsm6dsx_read_tagged_fifo,
884
+ .fifo_th = {
885
+ .addr = 0x07,
886
+ .mask = GENMASK(8, 0),
887
+ },
888
+ .fifo_diff = {
889
+ .addr = 0x3a,
890
+ .mask = GENMASK(9, 0),
891
+ },
892
+ .th_wl = 1,
893
+ },
894
+ .ts_settings = {
895
+ .timer_en = {
896
+ .addr = 0x19,
897
+ .mask = BIT(5),
898
+ },
899
+ .decimator = {
900
+ .addr = 0x0a,
901
+ .mask = GENMASK(7, 6),
902
+ },
903
+ .freq_fine = 0x63,
904
+ },
905
+ .shub_settings = {
906
+ .page_mux = {
907
+ .addr = 0x01,
908
+ .mask = BIT(6),
909
+ },
910
+ .master_en = {
911
+ .sec_page = true,
912
+ .addr = 0x14,
913
+ .mask = BIT(2),
914
+ },
915
+ .pullup_en = {
916
+ .sec_page = true,
917
+ .addr = 0x14,
918
+ .mask = BIT(3),
919
+ },
920
+ .aux_sens = {
921
+ .addr = 0x14,
922
+ .mask = GENMASK(1, 0),
923
+ },
924
+ .wr_once = {
925
+ .addr = 0x14,
926
+ .mask = BIT(6),
927
+ },
928
+ .num_ext_dev = 3,
929
+ .shub_out = {
930
+ .sec_page = true,
931
+ .addr = 0x02,
932
+ },
933
+ .slv0_addr = 0x15,
934
+ .dw_slv0_addr = 0x21,
935
+ .batch_en = BIT(3),
936
+ },
937
+ .event_settings = {
938
+ .enable_reg = {
939
+ .addr = 0x58,
940
+ .mask = BIT(7),
941
+ },
942
+ .wakeup_reg = {
943
+ .addr = 0x5b,
944
+ .mask = GENMASK(5, 0),
945
+ },
946
+ .wakeup_src_reg = 0x1b,
947
+ .wakeup_src_status_mask = BIT(3),
948
+ .wakeup_src_z_mask = BIT(0),
949
+ .wakeup_src_y_mask = BIT(1),
950
+ .wakeup_src_x_mask = BIT(2),
951
+ },
952
+ },
953
+ {
954
+ .wai = 0x6b,
955
+ .reset = {
956
+ .addr = 0x12,
957
+ .mask = BIT(0),
958
+ },
959
+ .boot = {
960
+ .addr = 0x12,
961
+ .mask = BIT(7),
962
+ },
963
+ .bdu = {
964
+ .addr = 0x12,
965
+ .mask = BIT(6),
966
+ },
967
+ .max_fifo_size = 512,
968
+ .id = {
969
+ {
970
+ .hw_id = ST_ASM330LHH_ID,
971
+ .name = ST_ASM330LHH_DEV_NAME,
972
+ },
973
+ },
974
+ .channels = {
975
+ [ST_LSM6DSX_ID_ACC] = {
976
+ .chan = st_lsm6dsx_acc_channels,
977
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
978
+ },
979
+ [ST_LSM6DSX_ID_GYRO] = {
980
+ .chan = st_lsm6dsx_gyro_channels,
981
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
982
+ },
983
+ },
984
+ .drdy_mask = {
985
+ .addr = 0x13,
986
+ .mask = BIT(3),
987
+ },
988
+ .odr_table = {
989
+ [ST_LSM6DSX_ID_ACC] = {
990
+ .reg = {
991
+ .addr = 0x10,
992
+ .mask = GENMASK(7, 4),
993
+ },
994
+ .odr_avl[0] = { 12500, 0x01 },
995
+ .odr_avl[1] = { 26000, 0x02 },
996
+ .odr_avl[2] = { 52000, 0x03 },
997
+ .odr_avl[3] = { 104000, 0x04 },
998
+ .odr_avl[4] = { 208000, 0x05 },
999
+ .odr_avl[5] = { 416000, 0x06 },
1000
+ .odr_avl[6] = { 833000, 0x07 },
1001
+ .odr_len = 7,
1002
+ },
1003
+ [ST_LSM6DSX_ID_GYRO] = {
1004
+ .reg = {
1005
+ .addr = 0x11,
1006
+ .mask = GENMASK(7, 4),
1007
+ },
1008
+ .odr_avl[0] = { 12500, 0x01 },
1009
+ .odr_avl[1] = { 26000, 0x02 },
1010
+ .odr_avl[2] = { 52000, 0x03 },
1011
+ .odr_avl[3] = { 104000, 0x04 },
1012
+ .odr_avl[4] = { 208000, 0x05 },
1013
+ .odr_avl[5] = { 416000, 0x06 },
1014
+ .odr_avl[6] = { 833000, 0x07 },
1015
+ .odr_len = 7,
1016
+ },
1017
+ },
1018
+ .fs_table = {
1019
+ [ST_LSM6DSX_ID_ACC] = {
1020
+ .reg = {
1021
+ .addr = 0x10,
1022
+ .mask = GENMASK(3, 2),
1023
+ },
1024
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
1025
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
1026
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
1027
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
1028
+ .fs_len = 4,
1029
+ },
1030
+ [ST_LSM6DSX_ID_GYRO] = {
1031
+ .reg = {
1032
+ .addr = 0x11,
1033
+ .mask = GENMASK(3, 2),
1034
+ },
1035
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
1036
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
1037
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
1038
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
1039
+ .fs_len = 4,
1040
+ },
1041
+ },
1042
+ .irq_config = {
1043
+ .irq1 = {
1044
+ .addr = 0x0d,
1045
+ .mask = BIT(3),
1046
+ },
1047
+ .irq2 = {
1048
+ .addr = 0x0e,
1049
+ .mask = BIT(3),
1050
+ },
1051
+ .lir = {
1052
+ .addr = 0x56,
1053
+ .mask = BIT(0),
1054
+ },
1055
+ .clear_on_read = {
1056
+ .addr = 0x56,
1057
+ .mask = BIT(6),
1058
+ },
1059
+ .irq1_func = {
1060
+ .addr = 0x5e,
1061
+ .mask = BIT(5),
1062
+ },
1063
+ .irq2_func = {
1064
+ .addr = 0x5f,
1065
+ .mask = BIT(5),
1066
+ },
1067
+ .hla = {
1068
+ .addr = 0x12,
1069
+ .mask = BIT(5),
1070
+ },
1071
+ .od = {
1072
+ .addr = 0x12,
1073
+ .mask = BIT(4),
1074
+ },
1075
+ },
1076
+ .batch = {
1077
+ [ST_LSM6DSX_ID_ACC] = {
1078
+ .addr = 0x09,
1079
+ .mask = GENMASK(3, 0),
1080
+ },
1081
+ [ST_LSM6DSX_ID_GYRO] = {
1082
+ .addr = 0x09,
1083
+ .mask = GENMASK(7, 4),
1084
+ },
1085
+ },
1086
+ .fifo_ops = {
1087
+ .update_fifo = st_lsm6dsx_update_fifo,
1088
+ .read_fifo = st_lsm6dsx_read_tagged_fifo,
1089
+ .fifo_th = {
1090
+ .addr = 0x07,
1091
+ .mask = GENMASK(8, 0),
1092
+ },
1093
+ .fifo_diff = {
1094
+ .addr = 0x3a,
1095
+ .mask = GENMASK(9, 0),
1096
+ },
1097
+ .th_wl = 1,
1098
+ },
1099
+ .ts_settings = {
1100
+ .timer_en = {
1101
+ .addr = 0x19,
1102
+ .mask = BIT(5),
1103
+ },
1104
+ .decimator = {
1105
+ .addr = 0x0a,
1106
+ .mask = GENMASK(7, 6),
1107
+ },
1108
+ .freq_fine = 0x63,
1109
+ },
1110
+ .event_settings = {
1111
+ .enable_reg = {
1112
+ .addr = 0x58,
1113
+ .mask = BIT(7),
1114
+ },
1115
+ .wakeup_reg = {
1116
+ .addr = 0x5B,
1117
+ .mask = GENMASK(5, 0),
1118
+ },
1119
+ .wakeup_src_reg = 0x1b,
1120
+ .wakeup_src_status_mask = BIT(3),
1121
+ .wakeup_src_z_mask = BIT(0),
1122
+ .wakeup_src_y_mask = BIT(1),
1123
+ .wakeup_src_x_mask = BIT(2),
1124
+ },
1125
+ },
1126
+ {
1127
+ .wai = 0x6b,
1128
+ .reset = {
1129
+ .addr = 0x12,
1130
+ .mask = BIT(0),
1131
+ },
1132
+ .boot = {
1133
+ .addr = 0x12,
1134
+ .mask = BIT(7),
1135
+ },
1136
+ .bdu = {
1137
+ .addr = 0x12,
1138
+ .mask = BIT(6),
1139
+ },
1140
+ .max_fifo_size = 512,
1141
+ .id = {
1142
+ {
1143
+ .hw_id = ST_LSM6DSR_ID,
1144
+ .name = ST_LSM6DSR_DEV_NAME,
1145
+ }, {
1146
+ .hw_id = ST_ISM330DHCX_ID,
1147
+ .name = ST_ISM330DHCX_DEV_NAME,
1148
+ }, {
1149
+ .hw_id = ST_LSM6DSRX_ID,
1150
+ .name = ST_LSM6DSRX_DEV_NAME,
1151
+ },
1152
+ },
1153
+ .channels = {
1154
+ [ST_LSM6DSX_ID_ACC] = {
1155
+ .chan = st_lsm6dsx_acc_channels,
1156
+ .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
1157
+ },
1158
+ [ST_LSM6DSX_ID_GYRO] = {
1159
+ .chan = st_lsm6dsx_gyro_channels,
1160
+ .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
1161
+ },
1162
+ },
1163
+ .drdy_mask = {
1164
+ .addr = 0x13,
1165
+ .mask = BIT(3),
1166
+ },
1167
+ .odr_table = {
1168
+ [ST_LSM6DSX_ID_ACC] = {
1169
+ .reg = {
1170
+ .addr = 0x10,
1171
+ .mask = GENMASK(7, 4),
1172
+ },
1173
+ .odr_avl[0] = { 12500, 0x01 },
1174
+ .odr_avl[1] = { 26000, 0x02 },
1175
+ .odr_avl[2] = { 52000, 0x03 },
1176
+ .odr_avl[3] = { 104000, 0x04 },
1177
+ .odr_avl[4] = { 208000, 0x05 },
1178
+ .odr_avl[5] = { 416000, 0x06 },
1179
+ .odr_avl[6] = { 833000, 0x07 },
1180
+ .odr_len = 7,
1181
+ },
1182
+ [ST_LSM6DSX_ID_GYRO] = {
1183
+ .reg = {
1184
+ .addr = 0x11,
1185
+ .mask = GENMASK(7, 4),
1186
+ },
1187
+ .odr_avl[0] = { 12500, 0x01 },
1188
+ .odr_avl[1] = { 26000, 0x02 },
1189
+ .odr_avl[2] = { 52000, 0x03 },
1190
+ .odr_avl[3] = { 104000, 0x04 },
1191
+ .odr_avl[4] = { 208000, 0x05 },
1192
+ .odr_avl[5] = { 416000, 0x06 },
1193
+ .odr_avl[6] = { 833000, 0x07 },
1194
+ .odr_len = 7,
1195
+ },
1196
+ },
1197
+ .fs_table = {
1198
+ [ST_LSM6DSX_ID_ACC] = {
1199
+ .reg = {
1200
+ .addr = 0x10,
1201
+ .mask = GENMASK(3, 2),
1202
+ },
1203
+ .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 },
1204
+ .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 },
1205
+ .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 },
1206
+ .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 },
1207
+ .fs_len = 4,
1208
+ },
1209
+ [ST_LSM6DSX_ID_GYRO] = {
1210
+ .reg = {
1211
+ .addr = 0x11,
1212
+ .mask = GENMASK(3, 2),
1213
+ },
1214
+ .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 },
1215
+ .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 },
1216
+ .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 },
1217
+ .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 },
1218
+ .fs_len = 4,
1219
+ },
1220
+ },
1221
+ .irq_config = {
1222
+ .irq1 = {
1223
+ .addr = 0x0d,
1224
+ .mask = BIT(3),
1225
+ },
1226
+ .irq2 = {
1227
+ .addr = 0x0e,
1228
+ .mask = BIT(3),
1229
+ },
1230
+ .lir = {
1231
+ .addr = 0x56,
1232
+ .mask = BIT(0),
1233
+ },
1234
+ .clear_on_read = {
1235
+ .addr = 0x56,
1236
+ .mask = BIT(6),
1237
+ },
1238
+ .irq1_func = {
1239
+ .addr = 0x5e,
1240
+ .mask = BIT(5),
1241
+ },
1242
+ .irq2_func = {
1243
+ .addr = 0x5f,
1244
+ .mask = BIT(5),
1245
+ },
1246
+ .hla = {
1247
+ .addr = 0x12,
1248
+ .mask = BIT(5),
1249
+ },
1250
+ .od = {
1251
+ .addr = 0x12,
1252
+ .mask = BIT(4),
1253
+ },
1254
+ },
1255
+ .batch = {
1256
+ [ST_LSM6DSX_ID_ACC] = {
1257
+ .addr = 0x09,
1258
+ .mask = GENMASK(3, 0),
1259
+ },
1260
+ [ST_LSM6DSX_ID_GYRO] = {
1261
+ .addr = 0x09,
1262
+ .mask = GENMASK(7, 4),
1263
+ },
1264
+ },
1265
+ .fifo_ops = {
1266
+ .update_fifo = st_lsm6dsx_update_fifo,
1267
+ .read_fifo = st_lsm6dsx_read_tagged_fifo,
1268
+ .fifo_th = {
1269
+ .addr = 0x07,
1270
+ .mask = GENMASK(8, 0),
1271
+ },
1272
+ .fifo_diff = {
1273
+ .addr = 0x3a,
1274
+ .mask = GENMASK(9, 0),
1275
+ },
1276
+ .th_wl = 1,
1277
+ },
1278
+ .ts_settings = {
1279
+ .timer_en = {
1280
+ .addr = 0x19,
1281
+ .mask = BIT(5),
1282
+ },
1283
+ .decimator = {
1284
+ .addr = 0x0a,
1285
+ .mask = GENMASK(7, 6),
1286
+ },
1287
+ .freq_fine = 0x63,
1288
+ },
1289
+ .shub_settings = {
1290
+ .page_mux = {
1291
+ .addr = 0x01,
1292
+ .mask = BIT(6),
1293
+ },
1294
+ .master_en = {
1295
+ .sec_page = true,
1296
+ .addr = 0x14,
1297
+ .mask = BIT(2),
1298
+ },
1299
+ .pullup_en = {
1300
+ .sec_page = true,
1301
+ .addr = 0x14,
1302
+ .mask = BIT(3),
1303
+ },
1304
+ .aux_sens = {
1305
+ .addr = 0x14,
1306
+ .mask = GENMASK(1, 0),
1307
+ },
1308
+ .wr_once = {
1309
+ .addr = 0x14,
1310
+ .mask = BIT(6),
1311
+ },
1312
+ .num_ext_dev = 3,
1313
+ .shub_out = {
1314
+ .sec_page = true,
1315
+ .addr = 0x02,
1316
+ },
1317
+ .slv0_addr = 0x15,
1318
+ .dw_slv0_addr = 0x21,
1319
+ .batch_en = BIT(3),
1320
+ },
1321
+ .event_settings = {
1322
+ .enable_reg = {
1323
+ .addr = 0x58,
1324
+ .mask = BIT(7),
1325
+ },
1326
+ .wakeup_reg = {
1327
+ .addr = 0x5B,
1328
+ .mask = GENMASK(5, 0),
1329
+ },
1330
+ .wakeup_src_reg = 0x1b,
1331
+ .wakeup_src_status_mask = BIT(3),
1332
+ .wakeup_src_z_mask = BIT(0),
1333
+ .wakeup_src_y_mask = BIT(1),
1334
+ .wakeup_src_x_mask = BIT(2),
1335
+ }
2961336 },
2971337 };
2981338
299
-#define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \
300
-{ \
301
- .type = chan_type, \
302
- .address = addr, \
303
- .modified = 1, \
304
- .channel2 = mod, \
305
- .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
306
- BIT(IIO_CHAN_INFO_SCALE), \
307
- .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
308
- .scan_index = scan_idx, \
309
- .scan_type = { \
310
- .sign = 's', \
311
- .realbits = 16, \
312
- .storagebits = 16, \
313
- .endianness = IIO_LE, \
314
- }, \
1339
+int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
1340
+{
1341
+ const struct st_lsm6dsx_shub_settings *hub_settings;
1342
+ unsigned int data;
1343
+ int err;
1344
+
1345
+ hub_settings = &hw->settings->shub_settings;
1346
+ data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
1347
+ err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
1348
+ hub_settings->page_mux.mask, data);
1349
+ usleep_range(100, 150);
1350
+
1351
+ return err;
3151352 }
3161353
317
-static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
318
- ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_X_L_ADDR,
319
- IIO_MOD_X, 0),
320
- ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Y_L_ADDR,
321
- IIO_MOD_Y, 1),
322
- ST_LSM6DSX_CHANNEL(IIO_ACCEL, ST_LSM6DSX_REG_ACC_OUT_Z_L_ADDR,
323
- IIO_MOD_Z, 2),
324
- IIO_CHAN_SOFT_TIMESTAMP(3),
325
-};
326
-
327
-static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
328
- ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_X_L_ADDR,
329
- IIO_MOD_X, 0),
330
- ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR,
331
- IIO_MOD_Y, 1),
332
- ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR,
333
- IIO_MOD_Z, 2),
334
- IIO_CHAN_SOFT_TIMESTAMP(3),
335
-};
336
-
337
-static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id)
1354
+static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
1355
+ const char **name)
3381356 {
3391357 int err, i, j, data;
3401358
3411359 for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
3421360 for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
343
- if (id == st_lsm6dsx_sensor_settings[i].id[j])
1361
+ if (st_lsm6dsx_sensor_settings[i].id[j].name &&
1362
+ id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
3441363 break;
3451364 }
3461365 if (j < ST_LSM6DSX_MAX_ID)
....@@ -363,6 +1382,7 @@
3631382 return -ENODEV;
3641383 }
3651384
1385
+ *name = st_lsm6dsx_sensor_settings[i].id[j].name;
3661386 hw->settings = &st_lsm6dsx_sensor_settings[i];
3671387
3681388 return 0;
....@@ -371,22 +1391,23 @@
3711391 static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
3721392 u32 gain)
3731393 {
374
- struct st_lsm6dsx_hw *hw = sensor->hw;
375
- const struct st_lsm6dsx_reg *reg;
1394
+ const struct st_lsm6dsx_fs_table_entry *fs_table;
1395
+ unsigned int data;
3761396 int i, err;
377
- u8 val;
3781397
379
- for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
380
- if (st_lsm6dsx_fs_table[sensor->id].fs_avl[i].gain == gain)
1398
+ fs_table = &sensor->hw->settings->fs_table[sensor->id];
1399
+ for (i = 0; i < fs_table->fs_len; i++) {
1400
+ if (fs_table->fs_avl[i].gain == gain)
3811401 break;
1402
+ }
3821403
383
- if (i == ST_LSM6DSX_FS_LIST_SIZE)
1404
+ if (i == fs_table->fs_len)
3841405 return -EINVAL;
3851406
386
- val = st_lsm6dsx_fs_table[sensor->id].fs_avl[i].val;
387
- reg = &st_lsm6dsx_fs_table[sensor->id].reg;
388
- err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
389
- ST_LSM6DSX_SHIFT_VAL(val, reg->mask));
1407
+ data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
1408
+ fs_table->reg.mask);
1409
+ err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
1410
+ fs_table->reg.mask, data);
3901411 if (err < 0)
3911412 return err;
3921413
....@@ -395,67 +1416,135 @@
3951416 return 0;
3961417 }
3971418
398
-static int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr,
399
- u8 *val)
1419
+int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val)
4001420 {
1421
+ const struct st_lsm6dsx_odr_table_entry *odr_table;
4011422 int i;
4021423
403
- for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
404
- if (st_lsm6dsx_odr_table[sensor->id].odr_avl[i].hz == odr)
1424
+ odr_table = &sensor->hw->settings->odr_table[sensor->id];
1425
+ for (i = 0; i < odr_table->odr_len; i++) {
1426
+ /*
1427
+ * ext devices can run at different odr respect to
1428
+ * accel sensor
1429
+ */
1430
+ if (odr_table->odr_avl[i].milli_hz >= odr)
4051431 break;
1432
+ }
4061433
407
- if (i == ST_LSM6DSX_ODR_LIST_SIZE)
1434
+ if (i == odr_table->odr_len)
4081435 return -EINVAL;
4091436
410
- *val = st_lsm6dsx_odr_table[sensor->id].odr_avl[i].val;
411
-
412
- return 0;
1437
+ *val = odr_table->odr_avl[i].val;
1438
+ return odr_table->odr_avl[i].milli_hz;
4131439 }
4141440
415
-static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr)
1441
+static int
1442
+st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr,
1443
+ enum st_lsm6dsx_sensor_id id)
4161444 {
1445
+ struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
1446
+
1447
+ if (odr > 0) {
1448
+ if (hw->enable_mask & BIT(id))
1449
+ return max_t(u32, ref->odr, odr);
1450
+ else
1451
+ return odr;
1452
+ } else {
1453
+ return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
1454
+ }
1455
+}
1456
+
1457
+static int
1458
+st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr)
1459
+{
1460
+ struct st_lsm6dsx_sensor *ref_sensor = sensor;
4171461 struct st_lsm6dsx_hw *hw = sensor->hw;
4181462 const struct st_lsm6dsx_reg *reg;
419
- int err;
420
- u8 val;
421
-
422
- err = st_lsm6dsx_check_odr(sensor, odr, &val);
423
- if (err < 0)
424
- return err;
425
-
426
- reg = &st_lsm6dsx_odr_table[sensor->id].reg;
427
- return regmap_update_bits(hw->regmap, reg->addr, reg->mask,
428
- ST_LSM6DSX_SHIFT_VAL(val, reg->mask));
429
-}
430
-
431
-int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor)
432
-{
1463
+ unsigned int data;
1464
+ u8 val = 0;
4331465 int err;
4341466
435
- err = st_lsm6dsx_set_odr(sensor, sensor->odr);
436
- if (err < 0)
437
- return err;
1467
+ switch (sensor->id) {
1468
+ case ST_LSM6DSX_ID_GYRO:
1469
+ break;
1470
+ case ST_LSM6DSX_ID_EXT0:
1471
+ case ST_LSM6DSX_ID_EXT1:
1472
+ case ST_LSM6DSX_ID_EXT2:
1473
+ case ST_LSM6DSX_ID_ACC: {
1474
+ u32 odr;
1475
+ int i;
4381476
439
- sensor->hw->enable_mask |= BIT(sensor->id);
1477
+ /*
1478
+ * i2c embedded controller relies on the accelerometer sensor as
1479
+ * bus read/write trigger so we need to enable accel device
1480
+ * at odr = max(accel_odr, ext_odr) in order to properly
1481
+ * communicate with i2c slave devices
1482
+ */
1483
+ ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
1484
+ for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
1485
+ if (!hw->iio_devs[i] || i == sensor->id)
1486
+ continue;
4401487
441
- return 0;
1488
+ odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
1489
+ if (odr != req_odr)
1490
+ /* device already configured */
1491
+ return 0;
1492
+ }
1493
+ break;
1494
+ }
1495
+ default: /* should never occur */
1496
+ return -EINVAL;
1497
+ }
1498
+
1499
+ if (req_odr > 0) {
1500
+ err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
1501
+ if (err < 0)
1502
+ return err;
1503
+ }
1504
+
1505
+ reg = &hw->settings->odr_table[ref_sensor->id].reg;
1506
+ data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1507
+ return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
4421508 }
4431509
444
-int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor)
1510
+static int
1511
+__st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1512
+ bool enable)
4451513 {
4461514 struct st_lsm6dsx_hw *hw = sensor->hw;
447
- const struct st_lsm6dsx_reg *reg;
1515
+ u32 odr = enable ? sensor->odr : 0;
4481516 int err;
4491517
450
- reg = &st_lsm6dsx_odr_table[sensor->id].reg;
451
- err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
452
- ST_LSM6DSX_SHIFT_VAL(0, reg->mask));
1518
+ err = st_lsm6dsx_set_odr(sensor, odr);
4531519 if (err < 0)
4541520 return err;
4551521
456
- sensor->hw->enable_mask &= ~BIT(sensor->id);
1522
+ if (enable)
1523
+ hw->enable_mask |= BIT(sensor->id);
1524
+ else
1525
+ hw->enable_mask &= ~BIT(sensor->id);
4571526
4581527 return 0;
1528
+}
1529
+
1530
+static int
1531
+st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable)
1532
+{
1533
+ struct st_lsm6dsx_hw *hw = sensor->hw;
1534
+
1535
+ if (sensor->id == ST_LSM6DSX_ID_GYRO || enable)
1536
+ return 0;
1537
+
1538
+ return hw->enable_event;
1539
+}
1540
+
1541
+int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1542
+ bool enable)
1543
+{
1544
+ if (st_lsm6dsx_check_events(sensor, enable))
1545
+ return 0;
1546
+
1547
+ return __st_lsm6dsx_sensor_set_enable(sensor, enable);
4591548 }
4601549
4611550 static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
....@@ -465,18 +1554,26 @@
4651554 int err, delay;
4661555 __le16 data;
4671556
468
- err = st_lsm6dsx_sensor_enable(sensor);
1557
+ err = st_lsm6dsx_sensor_set_enable(sensor, true);
4691558 if (err < 0)
4701559 return err;
4711560
472
- delay = 1000000 / sensor->odr;
473
- usleep_range(delay, 2 * delay);
1561
+ /*
1562
+ * we need to wait for sensor settling time before
1563
+ * reading data in order to avoid corrupted samples
1564
+ */
1565
+ delay = 1000000000 / sensor->odr;
1566
+ usleep_range(3 * delay, 4 * delay);
4741567
475
- err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data));
1568
+ err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
4761569 if (err < 0)
4771570 return err;
4781571
479
- st_lsm6dsx_sensor_disable(sensor);
1572
+ if (!hw->enable_event) {
1573
+ err = st_lsm6dsx_sensor_set_enable(sensor, false);
1574
+ if (err < 0)
1575
+ return err;
1576
+ }
4801577
4811578 *val = (s16)le16_to_cpu(data);
4821579
....@@ -500,13 +1597,14 @@
5001597 iio_device_release_direct_mode(iio_dev);
5011598 break;
5021599 case IIO_CHAN_INFO_SAMP_FREQ:
503
- *val = sensor->odr;
504
- ret = IIO_VAL_INT;
1600
+ *val = sensor->odr / 1000;
1601
+ *val2 = (sensor->odr % 1000) * 1000;
1602
+ ret = IIO_VAL_INT_PLUS_MICRO;
5051603 break;
5061604 case IIO_CHAN_INFO_SCALE:
5071605 *val = 0;
5081606 *val2 = sensor->gain;
509
- ret = IIO_VAL_INT_PLUS_MICRO;
1607
+ ret = IIO_VAL_INT_PLUS_NANO;
5101608 break;
5111609 default:
5121610 ret = -EINVAL;
....@@ -534,8 +1632,11 @@
5341632 case IIO_CHAN_INFO_SAMP_FREQ: {
5351633 u8 data;
5361634
537
- err = st_lsm6dsx_check_odr(sensor, val, &data);
538
- if (!err)
1635
+ val = val * 1000 + val2 / 1000;
1636
+ val = st_lsm6dsx_check_odr(sensor, val, &data);
1637
+ if (val < 0)
1638
+ err = val;
1639
+ else
5391640 sensor->odr = val;
5401641 break;
5411642 }
....@@ -549,7 +1650,146 @@
5491650 return err;
5501651 }
5511652
552
-static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1653
+static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state)
1654
+{
1655
+ const struct st_lsm6dsx_reg *reg;
1656
+ unsigned int data;
1657
+ int err;
1658
+
1659
+ if (!hw->settings->irq_config.irq1_func.addr)
1660
+ return -ENOTSUPP;
1661
+
1662
+ reg = &hw->settings->event_settings.enable_reg;
1663
+ if (reg->addr) {
1664
+ data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask);
1665
+ err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
1666
+ reg->mask, data);
1667
+ if (err < 0)
1668
+ return err;
1669
+ }
1670
+
1671
+ /* Enable wakeup interrupt */
1672
+ data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask);
1673
+ return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr,
1674
+ hw->irq_routing->mask, data);
1675
+}
1676
+
1677
+static int st_lsm6dsx_read_event(struct iio_dev *iio_dev,
1678
+ const struct iio_chan_spec *chan,
1679
+ enum iio_event_type type,
1680
+ enum iio_event_direction dir,
1681
+ enum iio_event_info info,
1682
+ int *val, int *val2)
1683
+{
1684
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1685
+ struct st_lsm6dsx_hw *hw = sensor->hw;
1686
+
1687
+ if (type != IIO_EV_TYPE_THRESH)
1688
+ return -EINVAL;
1689
+
1690
+ *val2 = 0;
1691
+ *val = hw->event_threshold;
1692
+
1693
+ return IIO_VAL_INT;
1694
+}
1695
+
1696
+static int
1697
+st_lsm6dsx_write_event(struct iio_dev *iio_dev,
1698
+ const struct iio_chan_spec *chan,
1699
+ enum iio_event_type type,
1700
+ enum iio_event_direction dir,
1701
+ enum iio_event_info info,
1702
+ int val, int val2)
1703
+{
1704
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1705
+ struct st_lsm6dsx_hw *hw = sensor->hw;
1706
+ const struct st_lsm6dsx_reg *reg;
1707
+ unsigned int data;
1708
+ int err;
1709
+
1710
+ if (type != IIO_EV_TYPE_THRESH)
1711
+ return -EINVAL;
1712
+
1713
+ if (val < 0 || val > 31)
1714
+ return -EINVAL;
1715
+
1716
+ reg = &hw->settings->event_settings.wakeup_reg;
1717
+ data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1718
+ err = st_lsm6dsx_update_bits_locked(hw, reg->addr,
1719
+ reg->mask, data);
1720
+ if (err < 0)
1721
+ return -EINVAL;
1722
+
1723
+ hw->event_threshold = val;
1724
+
1725
+ return 0;
1726
+}
1727
+
1728
+static int
1729
+st_lsm6dsx_read_event_config(struct iio_dev *iio_dev,
1730
+ const struct iio_chan_spec *chan,
1731
+ enum iio_event_type type,
1732
+ enum iio_event_direction dir)
1733
+{
1734
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1735
+ struct st_lsm6dsx_hw *hw = sensor->hw;
1736
+
1737
+ if (type != IIO_EV_TYPE_THRESH)
1738
+ return -EINVAL;
1739
+
1740
+ return !!(hw->enable_event & BIT(chan->channel2));
1741
+}
1742
+
1743
+static int
1744
+st_lsm6dsx_write_event_config(struct iio_dev *iio_dev,
1745
+ const struct iio_chan_spec *chan,
1746
+ enum iio_event_type type,
1747
+ enum iio_event_direction dir, int state)
1748
+{
1749
+ struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1750
+ struct st_lsm6dsx_hw *hw = sensor->hw;
1751
+ u8 enable_event;
1752
+ int err;
1753
+
1754
+ if (type != IIO_EV_TYPE_THRESH)
1755
+ return -EINVAL;
1756
+
1757
+ if (state) {
1758
+ enable_event = hw->enable_event | BIT(chan->channel2);
1759
+
1760
+ /* do not enable events if they are already enabled */
1761
+ if (hw->enable_event)
1762
+ goto out;
1763
+ } else {
1764
+ enable_event = hw->enable_event & ~BIT(chan->channel2);
1765
+
1766
+ /* only turn off sensor if no events is enabled */
1767
+ if (enable_event)
1768
+ goto out;
1769
+ }
1770
+
1771
+ /* stop here if no changes have been made */
1772
+ if (hw->enable_event == enable_event)
1773
+ return 0;
1774
+
1775
+ err = st_lsm6dsx_event_setup(hw, state);
1776
+ if (err < 0)
1777
+ return err;
1778
+
1779
+ mutex_lock(&hw->conf_lock);
1780
+ if (enable_event || !(hw->fifo_mask & BIT(sensor->id)))
1781
+ err = __st_lsm6dsx_sensor_set_enable(sensor, state);
1782
+ mutex_unlock(&hw->conf_lock);
1783
+ if (err < 0)
1784
+ return err;
1785
+
1786
+out:
1787
+ hw->enable_event = enable_event;
1788
+
1789
+ return 0;
1790
+}
1791
+
1792
+int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
5531793 {
5541794 struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
5551795 struct st_lsm6dsx_hw *hw = sensor->hw;
....@@ -578,12 +1818,14 @@
5781818 char *buf)
5791819 {
5801820 struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
581
- enum st_lsm6dsx_sensor_id id = sensor->id;
1821
+ const struct st_lsm6dsx_odr_table_entry *odr_table;
5821822 int i, len = 0;
5831823
584
- for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
585
- len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
586
- st_lsm6dsx_odr_table[id].odr_avl[i].hz);
1824
+ odr_table = &sensor->hw->settings->odr_table[sensor->id];
1825
+ for (i = 0; i < odr_table->odr_len; i++)
1826
+ len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ",
1827
+ odr_table->odr_avl[i].milli_hz / 1000,
1828
+ odr_table->odr_avl[i].milli_hz % 1000);
5871829 buf[len - 1] = '\n';
5881830
5891831 return len;
....@@ -594,15 +1836,35 @@
5941836 char *buf)
5951837 {
5961838 struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
597
- enum st_lsm6dsx_sensor_id id = sensor->id;
1839
+ const struct st_lsm6dsx_fs_table_entry *fs_table;
1840
+ struct st_lsm6dsx_hw *hw = sensor->hw;
5981841 int i, len = 0;
5991842
600
- for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++)
601
- len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
602
- st_lsm6dsx_fs_table[id].fs_avl[i].gain);
1843
+ fs_table = &hw->settings->fs_table[sensor->id];
1844
+ for (i = 0; i < fs_table->fs_len; i++)
1845
+ len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ",
1846
+ fs_table->fs_avl[i].gain);
6031847 buf[len - 1] = '\n';
6041848
6051849 return len;
1850
+}
1851
+
1852
+static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev,
1853
+ struct iio_chan_spec const *chan,
1854
+ long mask)
1855
+{
1856
+ switch (mask) {
1857
+ case IIO_CHAN_INFO_SCALE:
1858
+ switch (chan->type) {
1859
+ case IIO_ANGL_VEL:
1860
+ case IIO_ACCEL:
1861
+ return IIO_VAL_INT_PLUS_NANO;
1862
+ default:
1863
+ return IIO_VAL_INT_PLUS_MICRO;
1864
+ }
1865
+ default:
1866
+ return IIO_VAL_INT_PLUS_MICRO;
1867
+ }
6061868 }
6071869
6081870 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
....@@ -625,7 +1887,12 @@
6251887 .attrs = &st_lsm6dsx_acc_attribute_group,
6261888 .read_raw = st_lsm6dsx_read_raw,
6271889 .write_raw = st_lsm6dsx_write_raw,
1890
+ .read_event_value = st_lsm6dsx_read_event,
1891
+ .write_event_value = st_lsm6dsx_write_event,
1892
+ .read_event_config = st_lsm6dsx_read_event_config,
1893
+ .write_event_config = st_lsm6dsx_write_event_config,
6281894 .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1895
+ .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
6291896 };
6301897
6311898 static struct attribute *st_lsm6dsx_gyro_attributes[] = {
....@@ -643,25 +1910,26 @@
6431910 .read_raw = st_lsm6dsx_read_raw,
6441911 .write_raw = st_lsm6dsx_write_raw,
6451912 .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1913
+ .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt,
6461914 };
6471915
648
-static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0};
649
-
650
-static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1916
+static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
6511917 {
652
- struct device_node *np = hw->dev->of_node;
1918
+ struct device *dev = hw->dev;
6531919
654
- if (!np)
1920
+ if (!dev_fwnode(dev))
6551921 return -EINVAL;
6561922
657
- return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
1923
+ return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin);
6581924 }
6591925
660
-static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
1926
+static int
1927
+st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw,
1928
+ const struct st_lsm6dsx_reg **drdy_reg)
6611929 {
6621930 int err = 0, drdy_pin;
6631931
664
- if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
1932
+ if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) {
6651933 struct st_sensors_platform_data *pdata;
6661934 struct device *dev = hw->dev;
6671935
....@@ -671,15 +1939,75 @@
6711939
6721940 switch (drdy_pin) {
6731941 case 1:
674
- *drdy_reg = ST_LSM6DSX_REG_INT1_ADDR;
1942
+ hw->irq_routing = &hw->settings->irq_config.irq1_func;
1943
+ *drdy_reg = &hw->settings->irq_config.irq1;
6751944 break;
6761945 case 2:
677
- *drdy_reg = ST_LSM6DSX_REG_INT2_ADDR;
1946
+ hw->irq_routing = &hw->settings->irq_config.irq2_func;
1947
+ *drdy_reg = &hw->settings->irq_config.irq2;
6781948 break;
6791949 default:
6801950 dev_err(hw->dev, "unsupported data ready pin\n");
6811951 err = -EINVAL;
6821952 break;
1953
+ }
1954
+
1955
+ return err;
1956
+}
1957
+
1958
+static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1959
+{
1960
+ const struct st_lsm6dsx_shub_settings *hub_settings;
1961
+ struct st_sensors_platform_data *pdata;
1962
+ struct device *dev = hw->dev;
1963
+ unsigned int data;
1964
+ int err = 0;
1965
+
1966
+ hub_settings = &hw->settings->shub_settings;
1967
+
1968
+ pdata = (struct st_sensors_platform_data *)dev->platform_data;
1969
+ if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) ||
1970
+ (pdata && pdata->pullups)) {
1971
+ if (hub_settings->pullup_en.sec_page) {
1972
+ err = st_lsm6dsx_set_page(hw, true);
1973
+ if (err < 0)
1974
+ return err;
1975
+ }
1976
+
1977
+ data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
1978
+ err = regmap_update_bits(hw->regmap,
1979
+ hub_settings->pullup_en.addr,
1980
+ hub_settings->pullup_en.mask, data);
1981
+
1982
+ if (hub_settings->pullup_en.sec_page)
1983
+ st_lsm6dsx_set_page(hw, false);
1984
+
1985
+ if (err < 0)
1986
+ return err;
1987
+ }
1988
+
1989
+ if (hub_settings->aux_sens.addr) {
1990
+ /* configure aux sensors */
1991
+ err = st_lsm6dsx_set_page(hw, true);
1992
+ if (err < 0)
1993
+ return err;
1994
+
1995
+ data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
1996
+ err = regmap_update_bits(hw->regmap,
1997
+ hub_settings->aux_sens.addr,
1998
+ hub_settings->aux_sens.mask, data);
1999
+
2000
+ st_lsm6dsx_set_page(hw, false);
2001
+
2002
+ if (err < 0)
2003
+ return err;
2004
+ }
2005
+
2006
+ if (hub_settings->emb_func.addr) {
2007
+ data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask);
2008
+ err = regmap_update_bits(hw->regmap,
2009
+ hub_settings->emb_func.addr,
2010
+ hub_settings->emb_func.mask, data);
6832011 }
6842012
6852013 return err;
....@@ -720,37 +2048,118 @@
7202048 if (err < 0)
7212049 return err;
7222050 }
2051
+
2052
+ /* calibrate timestamp sensitivity */
2053
+ hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY;
2054
+ if (ts_settings->freq_fine) {
2055
+ err = regmap_read(hw->regmap, ts_settings->freq_fine, &val);
2056
+ if (err < 0)
2057
+ return err;
2058
+
2059
+ /*
2060
+ * linearize the AN5192 formula:
2061
+ * 1 / (1 + x) ~= 1 - x (Taylor’s Series)
2062
+ * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val))
2063
+ * ttrim[ns] ~= 25000 - 37.5 * val
2064
+ * ttrim[ns] ~= 25000 - (37500 * val) / 1000
2065
+ */
2066
+ hw->ts_gain -= ((s8)val * 37500) / 1000;
2067
+ }
2068
+
2069
+ return 0;
2070
+}
2071
+
2072
+static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw)
2073
+{
2074
+ const struct st_lsm6dsx_reg *reg;
2075
+ int err;
2076
+
2077
+ /*
2078
+ * flush hw FIFO before device reset in order to avoid
2079
+ * possible races on interrupt line 1. If the first interrupt
2080
+ * line is asserted during hw reset the device will work in
2081
+ * I3C-only mode (if it is supported)
2082
+ */
2083
+ err = st_lsm6dsx_flush_fifo(hw);
2084
+ if (err < 0 && err != -ENOTSUPP)
2085
+ return err;
2086
+
2087
+ /* device sw reset */
2088
+ reg = &hw->settings->reset;
2089
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2090
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2091
+ if (err < 0)
2092
+ return err;
2093
+
2094
+ msleep(50);
2095
+
2096
+ /* reload trimming parameter */
2097
+ reg = &hw->settings->boot;
2098
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2099
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2100
+ if (err < 0)
2101
+ return err;
2102
+
2103
+ msleep(50);
2104
+
7232105 return 0;
7242106 }
7252107
7262108 static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
7272109 {
728
- u8 drdy_int_reg;
2110
+ const struct st_lsm6dsx_reg *reg;
7292111 int err;
7302112
731
- err = regmap_write(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR,
732
- ST_LSM6DSX_REG_RESET_MASK);
2113
+ err = st_lsm6dsx_reset_device(hw);
7332114 if (err < 0)
7342115 return err;
7352116
736
- msleep(200);
737
-
7382117 /* enable Block Data Update */
739
- err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR,
740
- ST_LSM6DSX_REG_BDU_MASK,
741
- FIELD_PREP(ST_LSM6DSX_REG_BDU_MASK, 1));
2118
+ reg = &hw->settings->bdu;
2119
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2120
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
7422121 if (err < 0)
7432122 return err;
7442123
7452124 /* enable FIFO watermak interrupt */
746
- err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg);
2125
+ err = st_lsm6dsx_get_drdy_reg(hw, &reg);
7472126 if (err < 0)
7482127 return err;
7492128
750
- err = regmap_update_bits(hw->regmap, drdy_int_reg,
751
- ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
752
- FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
753
- 1));
2129
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2130
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2131
+ if (err < 0)
2132
+ return err;
2133
+
2134
+ /* enable Latched interrupts for device events */
2135
+ if (hw->settings->irq_config.lir.addr) {
2136
+ reg = &hw->settings->irq_config.lir;
2137
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2138
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2139
+ if (err < 0)
2140
+ return err;
2141
+
2142
+ /* enable clear on read for latched interrupts */
2143
+ if (hw->settings->irq_config.clear_on_read.addr) {
2144
+ reg = &hw->settings->irq_config.clear_on_read;
2145
+ err = regmap_update_bits(hw->regmap,
2146
+ reg->addr, reg->mask,
2147
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2148
+ if (err < 0)
2149
+ return err;
2150
+ }
2151
+ }
2152
+
2153
+ /* enable drdy-mas if available */
2154
+ if (hw->settings->drdy_mask.addr) {
2155
+ reg = &hw->settings->drdy_mask;
2156
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2157
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2158
+ if (err < 0)
2159
+ return err;
2160
+ }
2161
+
2162
+ err = st_lsm6dsx_init_shub(hw);
7542163 if (err < 0)
7552164 return err;
7562165
....@@ -769,30 +2178,25 @@
7692178 return NULL;
7702179
7712180 iio_dev->modes = INDIO_DIRECT_MODE;
772
- iio_dev->dev.parent = hw->dev;
7732181 iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
2182
+ iio_dev->channels = hw->settings->channels[id].chan;
2183
+ iio_dev->num_channels = hw->settings->channels[id].len;
7742184
7752185 sensor = iio_priv(iio_dev);
7762186 sensor->id = id;
7772187 sensor->hw = hw;
778
- sensor->odr = st_lsm6dsx_odr_table[id].odr_avl[0].hz;
779
- sensor->gain = st_lsm6dsx_fs_table[id].fs_avl[0].gain;
2188
+ sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz;
2189
+ sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
7802190 sensor->watermark = 1;
7812191
7822192 switch (id) {
7832193 case ST_LSM6DSX_ID_ACC:
784
- iio_dev->channels = st_lsm6dsx_acc_channels;
785
- iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels);
7862194 iio_dev->info = &st_lsm6dsx_acc_info;
787
-
7882195 scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
7892196 name);
7902197 break;
7912198 case ST_LSM6DSX_ID_GYRO:
792
- iio_dev->channels = st_lsm6dsx_gyro_channels;
793
- iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels);
7942199 iio_dev->info = &st_lsm6dsx_gyro_info;
795
-
7962200 scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
7972201 name);
7982202 break;
....@@ -804,10 +2208,155 @@
8042208 return iio_dev;
8052209 }
8062210
807
-int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
2211
+static bool
2212
+st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw)
2213
+{
2214
+ const struct st_lsm6dsx_event_settings *event_settings;
2215
+ int err, data;
2216
+ s64 timestamp;
2217
+
2218
+ if (!hw->enable_event)
2219
+ return false;
2220
+
2221
+ event_settings = &hw->settings->event_settings;
2222
+ err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg,
2223
+ &data, sizeof(data));
2224
+ if (err < 0)
2225
+ return false;
2226
+
2227
+ timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
2228
+ if ((data & hw->settings->event_settings.wakeup_src_z_mask) &&
2229
+ (hw->enable_event & BIT(IIO_MOD_Z)))
2230
+ iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
2231
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
2232
+ 0,
2233
+ IIO_MOD_Z,
2234
+ IIO_EV_TYPE_THRESH,
2235
+ IIO_EV_DIR_EITHER),
2236
+ timestamp);
2237
+
2238
+ if ((data & hw->settings->event_settings.wakeup_src_y_mask) &&
2239
+ (hw->enable_event & BIT(IIO_MOD_Y)))
2240
+ iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
2241
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
2242
+ 0,
2243
+ IIO_MOD_Y,
2244
+ IIO_EV_TYPE_THRESH,
2245
+ IIO_EV_DIR_EITHER),
2246
+ timestamp);
2247
+
2248
+ if ((data & hw->settings->event_settings.wakeup_src_x_mask) &&
2249
+ (hw->enable_event & BIT(IIO_MOD_X)))
2250
+ iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC],
2251
+ IIO_MOD_EVENT_CODE(IIO_ACCEL,
2252
+ 0,
2253
+ IIO_MOD_X,
2254
+ IIO_EV_TYPE_THRESH,
2255
+ IIO_EV_DIR_EITHER),
2256
+ timestamp);
2257
+
2258
+ return data & event_settings->wakeup_src_status_mask;
2259
+}
2260
+
2261
+static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private)
2262
+{
2263
+ struct st_lsm6dsx_hw *hw = private;
2264
+ int fifo_len = 0, len;
2265
+ bool event;
2266
+
2267
+ event = st_lsm6dsx_report_motion_event(hw);
2268
+
2269
+ if (!hw->settings->fifo_ops.read_fifo)
2270
+ return event ? IRQ_HANDLED : IRQ_NONE;
2271
+
2272
+ /*
2273
+ * If we are using edge IRQs, new samples can arrive while
2274
+ * processing current interrupt since there are no hw
2275
+ * guarantees the irq line stays "low" long enough to properly
2276
+ * detect the new interrupt. In this case the new sample will
2277
+ * be missed.
2278
+ * Polling FIFO status register allow us to read new
2279
+ * samples even if the interrupt arrives while processing
2280
+ * previous data and the timeslot where the line is "low" is
2281
+ * too short to be properly detected.
2282
+ */
2283
+ do {
2284
+ mutex_lock(&hw->fifo_lock);
2285
+ len = hw->settings->fifo_ops.read_fifo(hw);
2286
+ mutex_unlock(&hw->fifo_lock);
2287
+
2288
+ if (len > 0)
2289
+ fifo_len += len;
2290
+ } while (len > 0);
2291
+
2292
+ return fifo_len || event ? IRQ_HANDLED : IRQ_NONE;
2293
+}
2294
+
2295
+static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw)
2296
+{
2297
+ struct st_sensors_platform_data *pdata;
2298
+ const struct st_lsm6dsx_reg *reg;
2299
+ struct device *dev = hw->dev;
2300
+ unsigned long irq_type;
2301
+ bool irq_active_low;
2302
+ int err;
2303
+
2304
+ irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
2305
+
2306
+ switch (irq_type) {
2307
+ case IRQF_TRIGGER_HIGH:
2308
+ case IRQF_TRIGGER_RISING:
2309
+ irq_active_low = false;
2310
+ break;
2311
+ case IRQF_TRIGGER_LOW:
2312
+ case IRQF_TRIGGER_FALLING:
2313
+ irq_active_low = true;
2314
+ break;
2315
+ default:
2316
+ dev_info(hw->dev, "mode %lx unsupported\n", irq_type);
2317
+ return -EINVAL;
2318
+ }
2319
+
2320
+ reg = &hw->settings->irq_config.hla;
2321
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2322
+ ST_LSM6DSX_SHIFT_VAL(irq_active_low,
2323
+ reg->mask));
2324
+ if (err < 0)
2325
+ return err;
2326
+
2327
+ pdata = (struct st_sensors_platform_data *)dev->platform_data;
2328
+ if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) ||
2329
+ (pdata && pdata->open_drain)) {
2330
+ reg = &hw->settings->irq_config.od;
2331
+ err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
2332
+ ST_LSM6DSX_SHIFT_VAL(1, reg->mask));
2333
+ if (err < 0)
2334
+ return err;
2335
+
2336
+ irq_type |= IRQF_SHARED;
2337
+ }
2338
+
2339
+ err = devm_request_threaded_irq(hw->dev, hw->irq,
2340
+ NULL,
2341
+ st_lsm6dsx_handler_thread,
2342
+ irq_type | IRQF_ONESHOT,
2343
+ "lsm6dsx", hw);
2344
+ if (err) {
2345
+ dev_err(hw->dev, "failed to request trigger irq %d\n",
2346
+ hw->irq);
2347
+ return err;
2348
+ }
2349
+
2350
+ return 0;
2351
+}
2352
+
2353
+int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
8082354 struct regmap *regmap)
8092355 {
2356
+ struct st_sensors_platform_data *pdata = dev->platform_data;
2357
+ const struct st_lsm6dsx_shub_settings *hub_settings;
8102358 struct st_lsm6dsx_hw *hw;
2359
+ const char *name = NULL;
8112360 int i, err;
8122361
8132362 hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
....@@ -818,6 +2367,7 @@
8182367
8192368 mutex_init(&hw->fifo_lock);
8202369 mutex_init(&hw->conf_lock);
2370
+ mutex_init(&hw->page_lock);
8212371
8222372 hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
8232373 if (!hw->buff)
....@@ -827,11 +2377,11 @@
8272377 hw->irq = irq;
8282378 hw->regmap = regmap;
8292379
830
- err = st_lsm6dsx_check_whoami(hw, hw_id);
2380
+ err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
8312381 if (err < 0)
8322382 return err;
8332383
834
- for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
2384
+ for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
8352385 hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
8362386 if (!hw->iio_devs[i])
8372387 return -ENOMEM;
....@@ -841,17 +2391,39 @@
8412391 if (err < 0)
8422392 return err;
8432393
2394
+ hub_settings = &hw->settings->shub_settings;
2395
+ if (hub_settings->master_en.addr) {
2396
+ err = st_lsm6dsx_shub_probe(hw, name);
2397
+ if (err < 0)
2398
+ return err;
2399
+ }
2400
+
8442401 if (hw->irq > 0) {
2402
+ err = st_lsm6dsx_irq_setup(hw);
2403
+ if (err < 0)
2404
+ return err;
2405
+
8452406 err = st_lsm6dsx_fifo_setup(hw);
8462407 if (err < 0)
8472408 return err;
8482409 }
8492410
2411
+ err = iio_read_mount_matrix(hw->dev, "mount-matrix", &hw->orientation);
2412
+ if (err)
2413
+ return err;
2414
+
8502415 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
2416
+ if (!hw->iio_devs[i])
2417
+ continue;
2418
+
8512419 err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
8522420 if (err)
8532421 return err;
8542422 }
2423
+
2424
+ if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) ||
2425
+ (pdata && pdata->wakeup_source))
2426
+ device_init_wakeup(dev, true);
8552427
8562428 return 0;
8572429 }
....@@ -861,22 +2433,36 @@
8612433 {
8622434 struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
8632435 struct st_lsm6dsx_sensor *sensor;
864
- const struct st_lsm6dsx_reg *reg;
8652436 int i, err = 0;
8662437
8672438 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
2439
+ if (!hw->iio_devs[i])
2440
+ continue;
2441
+
8682442 sensor = iio_priv(hw->iio_devs[i]);
8692443 if (!(hw->enable_mask & BIT(sensor->id)))
8702444 continue;
8712445
872
- reg = &st_lsm6dsx_odr_table[sensor->id].reg;
873
- err = regmap_update_bits(hw->regmap, reg->addr, reg->mask,
874
- ST_LSM6DSX_SHIFT_VAL(0, reg->mask));
2446
+ if (device_may_wakeup(dev) &&
2447
+ sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) {
2448
+ /* Enable wake from IRQ */
2449
+ enable_irq_wake(hw->irq);
2450
+ continue;
2451
+ }
2452
+
2453
+ if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2454
+ sensor->id == ST_LSM6DSX_ID_EXT1 ||
2455
+ sensor->id == ST_LSM6DSX_ID_EXT2)
2456
+ err = st_lsm6dsx_shub_set_enable(sensor, false);
2457
+ else
2458
+ err = st_lsm6dsx_sensor_set_enable(sensor, false);
8752459 if (err < 0)
8762460 return err;
2461
+
2462
+ hw->suspend_mask |= BIT(sensor->id);
8772463 }
8782464
879
- if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
2465
+ if (hw->fifo_mask)
8802466 err = st_lsm6dsx_flush_fifo(hw);
8812467
8822468 return err;
....@@ -889,17 +2475,31 @@
8892475 int i, err = 0;
8902476
8912477 for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
892
- sensor = iio_priv(hw->iio_devs[i]);
893
- if (!(hw->enable_mask & BIT(sensor->id)))
2478
+ if (!hw->iio_devs[i])
8942479 continue;
8952480
896
- err = st_lsm6dsx_set_odr(sensor, sensor->odr);
2481
+ sensor = iio_priv(hw->iio_devs[i]);
2482
+ if (device_may_wakeup(dev) &&
2483
+ sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event)
2484
+ disable_irq_wake(hw->irq);
2485
+
2486
+ if (!(hw->suspend_mask & BIT(sensor->id)))
2487
+ continue;
2488
+
2489
+ if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
2490
+ sensor->id == ST_LSM6DSX_ID_EXT1 ||
2491
+ sensor->id == ST_LSM6DSX_ID_EXT2)
2492
+ err = st_lsm6dsx_shub_set_enable(sensor, true);
2493
+ else
2494
+ err = st_lsm6dsx_sensor_set_enable(sensor, true);
8972495 if (err < 0)
8982496 return err;
2497
+
2498
+ hw->suspend_mask &= ~BIT(sensor->id);
8992499 }
9002500
901
- if (hw->enable_mask)
902
- err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
2501
+ if (hw->fifo_mask)
2502
+ err = st_lsm6dsx_resume_fifo(hw);
9032503
9042504 return err;
9052505 }