.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * STMicroelectronics st_lsm6dsx sensor driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
9 | 10 | * +-125/+-245/+-500/+-1000/+-2000 dps |
---|
10 | 11 | * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer |
---|
11 | 12 | * allowing dynamic batching of sensor data. |
---|
| 13 | + * LSM9DSx series is similar but includes an additional magnetometer, handled |
---|
| 14 | + * by a different driver. |
---|
12 | 15 | * |
---|
13 | 16 | * Supported sensors: |
---|
14 | 17 | * - LSM6DS3: |
---|
.. | .. |
---|
17 | 20 | * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 |
---|
18 | 21 | * - FIFO size: 8KB |
---|
19 | 22 | * |
---|
20 | | - * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC: |
---|
| 23 | + * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C: |
---|
21 | 24 | * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 |
---|
22 | 25 | * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 |
---|
23 | 26 | * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 |
---|
24 | 27 | * - FIFO size: 4KB |
---|
25 | 28 | * |
---|
| 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 | + * |
---|
26 | 43 | * Copyright 2016 STMicroelectronics Inc. |
---|
27 | 44 | * |
---|
28 | 45 | * Lorenzo Bianconi <lorenzo.bianconi@st.com> |
---|
29 | 46 | * Denis Ciocca <denis.ciocca@st.com> |
---|
30 | | - * |
---|
31 | | - * Licensed under the GPL-2. |
---|
32 | 47 | */ |
---|
33 | 48 | |
---|
34 | 49 | #include <linux/kernel.h> |
---|
35 | 50 | #include <linux/module.h> |
---|
36 | 51 | #include <linux/delay.h> |
---|
| 52 | +#include <linux/iio/events.h> |
---|
37 | 53 | #include <linux/iio/iio.h> |
---|
38 | 54 | #include <linux/iio/sysfs.h> |
---|
| 55 | +#include <linux/interrupt.h> |
---|
| 56 | +#include <linux/irq.h> |
---|
39 | 57 | #include <linux/pm.h> |
---|
| 58 | +#include <linux/property.h> |
---|
40 | 59 | #include <linux/regmap.h> |
---|
41 | 60 | #include <linux/bitfield.h> |
---|
42 | 61 | |
---|
.. | .. |
---|
44 | 63 | |
---|
45 | 64 | #include "st_lsm6dsx.h" |
---|
46 | 65 | |
---|
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) |
---|
50 | 66 | #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) |
---|
57 | 67 | |
---|
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 */ |
---|
65 | 69 | |
---|
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), |
---|
87 | 75 | }; |
---|
88 | 76 | |
---|
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), |
---|
93 | 82 | }; |
---|
94 | 83 | |
---|
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), |
---|
154 | 89 | }; |
---|
155 | 90 | |
---|
156 | 91 | static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { |
---|
157 | 92 | { |
---|
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), |
---|
162 | 97 | }, |
---|
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 = { |
---|
164 | 117 | [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), |
---|
167 | 120 | }, |
---|
168 | 121 | [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), |
---|
171 | 124 | }, |
---|
172 | 125 | }, |
---|
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, |
---|
177 | 139 | }, |
---|
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, |
---|
181 | 152 | }, |
---|
182 | | - .th_wl = 3, /* 1LSB = 2B */ |
---|
183 | 153 | }, |
---|
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, |
---|
188 | 165 | }, |
---|
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, |
---|
191 | 193 | .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), |
---|
200 | 194 | }, |
---|
201 | 195 | }, |
---|
202 | 196 | }, |
---|
203 | 197 | { |
---|
204 | 198 | .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, |
---|
206 | 212 | .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 | + }, |
---|
208 | 309 | }, |
---|
209 | 310 | .decimator = { |
---|
210 | 311 | [ST_LSM6DSX_ID_ACC] = { |
---|
.. | .. |
---|
217 | 318 | }, |
---|
218 | 319 | }, |
---|
219 | 320 | .fifo_ops = { |
---|
| 321 | + .update_fifo = st_lsm6dsx_update_fifo, |
---|
| 322 | + .read_fifo = st_lsm6dsx_read_fifo, |
---|
220 | 323 | .fifo_th = { |
---|
221 | 324 | .addr = 0x06, |
---|
222 | 325 | .mask = GENMASK(11, 0), |
---|
.. | .. |
---|
244 | 347 | .addr = 0x09, |
---|
245 | 348 | .mask = GENMASK(5, 3), |
---|
246 | 349 | }, |
---|
| 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), |
---|
247 | 527 | }, |
---|
248 | 528 | }, |
---|
249 | 529 | { |
---|
250 | 530 | .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 | + }, |
---|
251 | 543 | .max_fifo_size = 682, |
---|
252 | 544 | .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 | + }, |
---|
256 | 650 | }, |
---|
257 | 651 | .decimator = { |
---|
258 | 652 | [ST_LSM6DSX_ID_ACC] = { |
---|
.. | .. |
---|
263 | 657 | .addr = 0x08, |
---|
264 | 658 | .mask = GENMASK(5, 3), |
---|
265 | 659 | }, |
---|
| 660 | + [ST_LSM6DSX_ID_EXT0] = { |
---|
| 661 | + .addr = 0x09, |
---|
| 662 | + .mask = GENMASK(2, 0), |
---|
| 663 | + }, |
---|
266 | 664 | }, |
---|
267 | 665 | .fifo_ops = { |
---|
| 666 | + .update_fifo = st_lsm6dsx_update_fifo, |
---|
| 667 | + .read_fifo = st_lsm6dsx_read_fifo, |
---|
268 | 668 | .fifo_th = { |
---|
269 | 669 | .addr = 0x06, |
---|
270 | 670 | .mask = GENMASK(10, 0), |
---|
.. | .. |
---|
293 | 693 | .mask = GENMASK(5, 3), |
---|
294 | 694 | }, |
---|
295 | 695 | }, |
---|
| 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 | + } |
---|
296 | 1336 | }, |
---|
297 | 1337 | }; |
---|
298 | 1338 | |
---|
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; |
---|
315 | 1352 | } |
---|
316 | 1353 | |
---|
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) |
---|
338 | 1356 | { |
---|
339 | 1357 | int err, i, j, data; |
---|
340 | 1358 | |
---|
341 | 1359 | for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { |
---|
342 | 1360 | 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) |
---|
344 | 1363 | break; |
---|
345 | 1364 | } |
---|
346 | 1365 | if (j < ST_LSM6DSX_MAX_ID) |
---|
.. | .. |
---|
363 | 1382 | return -ENODEV; |
---|
364 | 1383 | } |
---|
365 | 1384 | |
---|
| 1385 | + *name = st_lsm6dsx_sensor_settings[i].id[j].name; |
---|
366 | 1386 | hw->settings = &st_lsm6dsx_sensor_settings[i]; |
---|
367 | 1387 | |
---|
368 | 1388 | return 0; |
---|
.. | .. |
---|
371 | 1391 | static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, |
---|
372 | 1392 | u32 gain) |
---|
373 | 1393 | { |
---|
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; |
---|
376 | 1396 | int i, err; |
---|
377 | | - u8 val; |
---|
378 | 1397 | |
---|
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) |
---|
381 | 1401 | break; |
---|
| 1402 | + } |
---|
382 | 1403 | |
---|
383 | | - if (i == ST_LSM6DSX_FS_LIST_SIZE) |
---|
| 1404 | + if (i == fs_table->fs_len) |
---|
384 | 1405 | return -EINVAL; |
---|
385 | 1406 | |
---|
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); |
---|
390 | 1411 | if (err < 0) |
---|
391 | 1412 | return err; |
---|
392 | 1413 | |
---|
.. | .. |
---|
395 | 1416 | return 0; |
---|
396 | 1417 | } |
---|
397 | 1418 | |
---|
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) |
---|
400 | 1420 | { |
---|
| 1421 | + const struct st_lsm6dsx_odr_table_entry *odr_table; |
---|
401 | 1422 | int i; |
---|
402 | 1423 | |
---|
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) |
---|
405 | 1431 | break; |
---|
| 1432 | + } |
---|
406 | 1433 | |
---|
407 | | - if (i == ST_LSM6DSX_ODR_LIST_SIZE) |
---|
| 1434 | + if (i == odr_table->odr_len) |
---|
408 | 1435 | return -EINVAL; |
---|
409 | 1436 | |
---|
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; |
---|
413 | 1439 | } |
---|
414 | 1440 | |
---|
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) |
---|
416 | 1444 | { |
---|
| 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; |
---|
417 | 1461 | struct st_lsm6dsx_hw *hw = sensor->hw; |
---|
418 | 1462 | 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; |
---|
433 | 1465 | int err; |
---|
434 | 1466 | |
---|
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; |
---|
438 | 1476 | |
---|
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; |
---|
440 | 1487 | |
---|
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); |
---|
442 | 1508 | } |
---|
443 | 1509 | |
---|
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) |
---|
445 | 1513 | { |
---|
446 | 1514 | struct st_lsm6dsx_hw *hw = sensor->hw; |
---|
447 | | - const struct st_lsm6dsx_reg *reg; |
---|
| 1515 | + u32 odr = enable ? sensor->odr : 0; |
---|
448 | 1516 | int err; |
---|
449 | 1517 | |
---|
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); |
---|
453 | 1519 | if (err < 0) |
---|
454 | 1520 | return err; |
---|
455 | 1521 | |
---|
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); |
---|
457 | 1526 | |
---|
458 | 1527 | 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); |
---|
459 | 1548 | } |
---|
460 | 1549 | |
---|
461 | 1550 | static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, |
---|
.. | .. |
---|
465 | 1554 | int err, delay; |
---|
466 | 1555 | __le16 data; |
---|
467 | 1556 | |
---|
468 | | - err = st_lsm6dsx_sensor_enable(sensor); |
---|
| 1557 | + err = st_lsm6dsx_sensor_set_enable(sensor, true); |
---|
469 | 1558 | if (err < 0) |
---|
470 | 1559 | return err; |
---|
471 | 1560 | |
---|
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); |
---|
474 | 1567 | |
---|
475 | | - err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data)); |
---|
| 1568 | + err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); |
---|
476 | 1569 | if (err < 0) |
---|
477 | 1570 | return err; |
---|
478 | 1571 | |
---|
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 | + } |
---|
480 | 1577 | |
---|
481 | 1578 | *val = (s16)le16_to_cpu(data); |
---|
482 | 1579 | |
---|
.. | .. |
---|
500 | 1597 | iio_device_release_direct_mode(iio_dev); |
---|
501 | 1598 | break; |
---|
502 | 1599 | 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; |
---|
505 | 1603 | break; |
---|
506 | 1604 | case IIO_CHAN_INFO_SCALE: |
---|
507 | 1605 | *val = 0; |
---|
508 | 1606 | *val2 = sensor->gain; |
---|
509 | | - ret = IIO_VAL_INT_PLUS_MICRO; |
---|
| 1607 | + ret = IIO_VAL_INT_PLUS_NANO; |
---|
510 | 1608 | break; |
---|
511 | 1609 | default: |
---|
512 | 1610 | ret = -EINVAL; |
---|
.. | .. |
---|
534 | 1632 | case IIO_CHAN_INFO_SAMP_FREQ: { |
---|
535 | 1633 | u8 data; |
---|
536 | 1634 | |
---|
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 |
---|
539 | 1640 | sensor->odr = val; |
---|
540 | 1641 | break; |
---|
541 | 1642 | } |
---|
.. | .. |
---|
549 | 1650 | return err; |
---|
550 | 1651 | } |
---|
551 | 1652 | |
---|
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) |
---|
553 | 1793 | { |
---|
554 | 1794 | struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); |
---|
555 | 1795 | struct st_lsm6dsx_hw *hw = sensor->hw; |
---|
.. | .. |
---|
578 | 1818 | char *buf) |
---|
579 | 1819 | { |
---|
580 | 1820 | 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; |
---|
582 | 1822 | int i, len = 0; |
---|
583 | 1823 | |
---|
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); |
---|
587 | 1829 | buf[len - 1] = '\n'; |
---|
588 | 1830 | |
---|
589 | 1831 | return len; |
---|
.. | .. |
---|
594 | 1836 | char *buf) |
---|
595 | 1837 | { |
---|
596 | 1838 | 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; |
---|
598 | 1841 | int i, len = 0; |
---|
599 | 1842 | |
---|
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); |
---|
603 | 1847 | buf[len - 1] = '\n'; |
---|
604 | 1848 | |
---|
605 | 1849 | 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 | + } |
---|
606 | 1868 | } |
---|
607 | 1869 | |
---|
608 | 1870 | static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); |
---|
.. | .. |
---|
625 | 1887 | .attrs = &st_lsm6dsx_acc_attribute_group, |
---|
626 | 1888 | .read_raw = st_lsm6dsx_read_raw, |
---|
627 | 1889 | .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, |
---|
628 | 1894 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, |
---|
| 1895 | + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, |
---|
629 | 1896 | }; |
---|
630 | 1897 | |
---|
631 | 1898 | static struct attribute *st_lsm6dsx_gyro_attributes[] = { |
---|
.. | .. |
---|
643 | 1910 | .read_raw = st_lsm6dsx_read_raw, |
---|
644 | 1911 | .write_raw = st_lsm6dsx_write_raw, |
---|
645 | 1912 | .hwfifo_set_watermark = st_lsm6dsx_set_watermark, |
---|
| 1913 | + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, |
---|
646 | 1914 | }; |
---|
647 | 1915 | |
---|
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) |
---|
651 | 1917 | { |
---|
652 | | - struct device_node *np = hw->dev->of_node; |
---|
| 1918 | + struct device *dev = hw->dev; |
---|
653 | 1919 | |
---|
654 | | - if (!np) |
---|
| 1920 | + if (!dev_fwnode(dev)) |
---|
655 | 1921 | return -EINVAL; |
---|
656 | 1922 | |
---|
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); |
---|
658 | 1924 | } |
---|
659 | 1925 | |
---|
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) |
---|
661 | 1929 | { |
---|
662 | 1930 | int err = 0, drdy_pin; |
---|
663 | 1931 | |
---|
664 | | - if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) { |
---|
| 1932 | + if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) { |
---|
665 | 1933 | struct st_sensors_platform_data *pdata; |
---|
666 | 1934 | struct device *dev = hw->dev; |
---|
667 | 1935 | |
---|
.. | .. |
---|
671 | 1939 | |
---|
672 | 1940 | switch (drdy_pin) { |
---|
673 | 1941 | 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; |
---|
675 | 1944 | break; |
---|
676 | 1945 | 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; |
---|
678 | 1948 | break; |
---|
679 | 1949 | default: |
---|
680 | 1950 | dev_err(hw->dev, "unsupported data ready pin\n"); |
---|
681 | 1951 | err = -EINVAL; |
---|
682 | 1952 | 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); |
---|
683 | 2011 | } |
---|
684 | 2012 | |
---|
685 | 2013 | return err; |
---|
.. | .. |
---|
720 | 2048 | if (err < 0) |
---|
721 | 2049 | return err; |
---|
722 | 2050 | } |
---|
| 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 | + |
---|
723 | 2105 | return 0; |
---|
724 | 2106 | } |
---|
725 | 2107 | |
---|
726 | 2108 | static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) |
---|
727 | 2109 | { |
---|
728 | | - u8 drdy_int_reg; |
---|
| 2110 | + const struct st_lsm6dsx_reg *reg; |
---|
729 | 2111 | int err; |
---|
730 | 2112 | |
---|
731 | | - err = regmap_write(hw->regmap, ST_LSM6DSX_REG_RESET_ADDR, |
---|
732 | | - ST_LSM6DSX_REG_RESET_MASK); |
---|
| 2113 | + err = st_lsm6dsx_reset_device(hw); |
---|
733 | 2114 | if (err < 0) |
---|
734 | 2115 | return err; |
---|
735 | 2116 | |
---|
736 | | - msleep(200); |
---|
737 | | - |
---|
738 | 2117 | /* 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)); |
---|
742 | 2121 | if (err < 0) |
---|
743 | 2122 | return err; |
---|
744 | 2123 | |
---|
745 | 2124 | /* enable FIFO watermak interrupt */ |
---|
746 | | - err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg); |
---|
| 2125 | + err = st_lsm6dsx_get_drdy_reg(hw, ®); |
---|
747 | 2126 | if (err < 0) |
---|
748 | 2127 | return err; |
---|
749 | 2128 | |
---|
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); |
---|
754 | 2163 | if (err < 0) |
---|
755 | 2164 | return err; |
---|
756 | 2165 | |
---|
.. | .. |
---|
769 | 2178 | return NULL; |
---|
770 | 2179 | |
---|
771 | 2180 | iio_dev->modes = INDIO_DIRECT_MODE; |
---|
772 | | - iio_dev->dev.parent = hw->dev; |
---|
773 | 2181 | 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; |
---|
774 | 2184 | |
---|
775 | 2185 | sensor = iio_priv(iio_dev); |
---|
776 | 2186 | sensor->id = id; |
---|
777 | 2187 | 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; |
---|
780 | 2190 | sensor->watermark = 1; |
---|
781 | 2191 | |
---|
782 | 2192 | switch (id) { |
---|
783 | 2193 | case ST_LSM6DSX_ID_ACC: |
---|
784 | | - iio_dev->channels = st_lsm6dsx_acc_channels; |
---|
785 | | - iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_acc_channels); |
---|
786 | 2194 | iio_dev->info = &st_lsm6dsx_acc_info; |
---|
787 | | - |
---|
788 | 2195 | scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", |
---|
789 | 2196 | name); |
---|
790 | 2197 | break; |
---|
791 | 2198 | case ST_LSM6DSX_ID_GYRO: |
---|
792 | | - iio_dev->channels = st_lsm6dsx_gyro_channels; |
---|
793 | | - iio_dev->num_channels = ARRAY_SIZE(st_lsm6dsx_gyro_channels); |
---|
794 | 2199 | iio_dev->info = &st_lsm6dsx_gyro_info; |
---|
795 | | - |
---|
796 | 2200 | scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", |
---|
797 | 2201 | name); |
---|
798 | 2202 | break; |
---|
.. | .. |
---|
804 | 2208 | return iio_dev; |
---|
805 | 2209 | } |
---|
806 | 2210 | |
---|
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, |
---|
808 | 2354 | struct regmap *regmap) |
---|
809 | 2355 | { |
---|
| 2356 | + struct st_sensors_platform_data *pdata = dev->platform_data; |
---|
| 2357 | + const struct st_lsm6dsx_shub_settings *hub_settings; |
---|
810 | 2358 | struct st_lsm6dsx_hw *hw; |
---|
| 2359 | + const char *name = NULL; |
---|
811 | 2360 | int i, err; |
---|
812 | 2361 | |
---|
813 | 2362 | hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); |
---|
.. | .. |
---|
818 | 2367 | |
---|
819 | 2368 | mutex_init(&hw->fifo_lock); |
---|
820 | 2369 | mutex_init(&hw->conf_lock); |
---|
| 2370 | + mutex_init(&hw->page_lock); |
---|
821 | 2371 | |
---|
822 | 2372 | hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); |
---|
823 | 2373 | if (!hw->buff) |
---|
.. | .. |
---|
827 | 2377 | hw->irq = irq; |
---|
828 | 2378 | hw->regmap = regmap; |
---|
829 | 2379 | |
---|
830 | | - err = st_lsm6dsx_check_whoami(hw, hw_id); |
---|
| 2380 | + err = st_lsm6dsx_check_whoami(hw, hw_id, &name); |
---|
831 | 2381 | if (err < 0) |
---|
832 | 2382 | return err; |
---|
833 | 2383 | |
---|
834 | | - for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
---|
| 2384 | + for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { |
---|
835 | 2385 | hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); |
---|
836 | 2386 | if (!hw->iio_devs[i]) |
---|
837 | 2387 | return -ENOMEM; |
---|
.. | .. |
---|
841 | 2391 | if (err < 0) |
---|
842 | 2392 | return err; |
---|
843 | 2393 | |
---|
| 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 | + |
---|
844 | 2401 | if (hw->irq > 0) { |
---|
| 2402 | + err = st_lsm6dsx_irq_setup(hw); |
---|
| 2403 | + if (err < 0) |
---|
| 2404 | + return err; |
---|
| 2405 | + |
---|
845 | 2406 | err = st_lsm6dsx_fifo_setup(hw); |
---|
846 | 2407 | if (err < 0) |
---|
847 | 2408 | return err; |
---|
848 | 2409 | } |
---|
849 | 2410 | |
---|
| 2411 | + err = iio_read_mount_matrix(hw->dev, "mount-matrix", &hw->orientation); |
---|
| 2412 | + if (err) |
---|
| 2413 | + return err; |
---|
| 2414 | + |
---|
850 | 2415 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
---|
| 2416 | + if (!hw->iio_devs[i]) |
---|
| 2417 | + continue; |
---|
| 2418 | + |
---|
851 | 2419 | err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); |
---|
852 | 2420 | if (err) |
---|
853 | 2421 | return err; |
---|
854 | 2422 | } |
---|
| 2423 | + |
---|
| 2424 | + if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) || |
---|
| 2425 | + (pdata && pdata->wakeup_source)) |
---|
| 2426 | + device_init_wakeup(dev, true); |
---|
855 | 2427 | |
---|
856 | 2428 | return 0; |
---|
857 | 2429 | } |
---|
.. | .. |
---|
861 | 2433 | { |
---|
862 | 2434 | struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); |
---|
863 | 2435 | struct st_lsm6dsx_sensor *sensor; |
---|
864 | | - const struct st_lsm6dsx_reg *reg; |
---|
865 | 2436 | int i, err = 0; |
---|
866 | 2437 | |
---|
867 | 2438 | for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { |
---|
| 2439 | + if (!hw->iio_devs[i]) |
---|
| 2440 | + continue; |
---|
| 2441 | + |
---|
868 | 2442 | sensor = iio_priv(hw->iio_devs[i]); |
---|
869 | 2443 | if (!(hw->enable_mask & BIT(sensor->id))) |
---|
870 | 2444 | continue; |
---|
871 | 2445 | |
---|
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); |
---|
875 | 2459 | if (err < 0) |
---|
876 | 2460 | return err; |
---|
| 2461 | + |
---|
| 2462 | + hw->suspend_mask |= BIT(sensor->id); |
---|
877 | 2463 | } |
---|
878 | 2464 | |
---|
879 | | - if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) |
---|
| 2465 | + if (hw->fifo_mask) |
---|
880 | 2466 | err = st_lsm6dsx_flush_fifo(hw); |
---|
881 | 2467 | |
---|
882 | 2468 | return err; |
---|
.. | .. |
---|
889 | 2475 | int i, err = 0; |
---|
890 | 2476 | |
---|
891 | 2477 | 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]) |
---|
894 | 2479 | continue; |
---|
895 | 2480 | |
---|
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); |
---|
897 | 2495 | if (err < 0) |
---|
898 | 2496 | return err; |
---|
| 2497 | + |
---|
| 2498 | + hw->suspend_mask &= ~BIT(sensor->id); |
---|
899 | 2499 | } |
---|
900 | 2500 | |
---|
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); |
---|
903 | 2503 | |
---|
904 | 2504 | return err; |
---|
905 | 2505 | } |
---|