1 /*
2  * Copyright (c) 2021 Bosch Sensortec GmbH
3  * Copyright (c) 2022 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_DRIVERS_SENSOR_BMI270_BMI270_H_
9 #define ZEPHYR_DRIVERS_SENSOR_BMI270_BMI270_H_
10 
11 #include <stdint.h>
12 #include <zephyr/device.h>
13 #include <zephyr/sys/atomic.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/types.h>
16 #include <zephyr/drivers/sensor.h>
17 #include <zephyr/drivers/spi.h>
18 #include <zephyr/drivers/i2c.h>
19 #include <zephyr/devicetree.h>
20 #include <zephyr/drivers/gpio.h>
21 
22 #define BMI270_REG_CHIP_ID         0x00
23 #define BMI270_REG_ERROR           0x02
24 #define BMI270_REG_STATUS          0x03
25 #define BMI270_REG_AUX_X_LSB       0x04
26 #define BMI270_REG_ACC_X_LSB       0x0C
27 #define BMI270_REG_GYR_X_LSB       0x12
28 #define BMI270_REG_SENSORTIME_0    0x18
29 #define BMI270_REG_EVENT           0x1B
30 #define BMI270_REG_INT_STATUS_0    0x1C
31 #define BMI270_REG_SC_OUT_0        0x1E
32 #define BMI270_REG_WR_GEST_ACT     0x20
33 #define BMI270_REG_INTERNAL_STATUS 0x21
34 #define BMI270_REG_TEMPERATURE_0   0x22
35 #define BMI270_REG_FIFO_LENGTH_0   0x24
36 #define BMI270_REG_FIFO_DATA       0x26
37 #define BMI270_REG_FEAT_PAGE       0x2F
38 #define BMI270_REG_FEATURES_0      0x30
39 #define BMI270_REG_ACC_CONF        0x40
40 #define BMI270_REG_ACC_RANGE       0x41
41 #define BMI270_REG_GYR_CONF        0x42
42 #define BMI270_REG_GYR_RANGE       0x43
43 #define BMI270_REG_AUX_CONF        0x44
44 #define BMI270_REG_FIFO_DOWNS      0x45
45 #define BMI270_REG_FIFO_WTM_0      0x46
46 #define BMI270_REG_FIFO_CONFIG_0   0x48
47 #define BMI270_REG_SATURATION      0x4A
48 #define BMI270_REG_AUX_DEV_ID      0x4B
49 #define BMI270_REG_AUX_IF_CONF     0x4C
50 #define BMI270_REG_AUX_RD_ADDR     0x4D
51 #define BMI270_REG_AUX_WR_ADDR     0x4E
52 #define BMI270_REG_AUX_WR_DATA     0x4F
53 #define BMI270_REG_ERR_REG_MSK     0x52
54 #define BMI270_REG_INT1_IO_CTRL    0x53
55 #define BMI270_REG_INT2_IO_CTRL    0x54
56 #define BMI270_REG_INT_LATCH       0x55
57 #define BMI270_REG_INT1_MAP_FEAT   0x56
58 #define BMI270_REG_INT2_MAP_FEAT   0x57
59 #define BMI270_REG_INT_MAP_DATA    0x58
60 #define BMI270_REG_INIT_CTRL       0x59
61 #define BMI270_REG_INIT_ADDR_0     0x5B
62 #define BMI270_REG_INIT_DATA       0x5E
63 #define BMI270_REG_INTERNAL_ERROR  0x5F
64 #define BMI270_REG_AUX_IF_TRIM     0x68
65 #define BMI270_REG_GYR_CRT_CONF    0x69
66 #define BMI270_REG_NVM_CONF        0x6A
67 #define BMI270_REG_IF_CONF         0x6B
68 #define BMI270_REG_DRV             0x6C
69 #define BMI270_REG_ACC_SELF_TEST   0x6D
70 #define BMI270_REG_GYR_SELF_TEST   0x6E
71 #define BMI270_REG_NV_CONF         0x70
72 #define BMI270_REG_OFFSET_0        0x71
73 #define BMI270_REG_PWR_CONF        0x7C
74 #define BMI270_REG_PWR_CTRL        0x7D
75 #define BMI270_REG_CMD             0x7E
76 #define BMI270_REG_MASK            GENMASK(6, 0)
77 
78 #define BMI270_ANYMO_1_DURATION_POS	0
79 #define BMI270_ANYMO_1_DURATION_MASK	BIT_MASK(12)
80 #define BMI270_ANYMO_1_DURATION(n)	((n) << BMI270_ANYMO_1_DURATION_POS)
81 #define BMI270_ANYMO_1_SELECT_X		BIT(13)
82 #define BMI270_ANYMO_1_SELECT_Y		BIT(14)
83 #define BMI270_ANYMO_1_SELECT_Z		BIT(15)
84 #define BMI270_ANYMO_1_SELECT_XYZ	(BMI270_ANYMO_1_SELECT_X | \
85 					 BMI270_ANYMO_1_SELECT_Y | \
86 					 BMI270_ANYMO_1_SELECT_Y)
87 #define BMI270_ANYMO_2_THRESHOLD_POS	0
88 #define BMI270_ANYMO_2_THRESHOLD_MASK	BIT_MASK(10)
89 #define BMI270_ANYMO_2_THRESHOLD(n)	((n) << BMI270_ANYMO_2_THRESHOLD_POS)
90 #define BMI270_ANYMO_2_OUT_CONF_POS	11
91 #define BMI270_ANYMO_2_OUT_CONF_MASK	(BIT(11) | BIT(12) | BIT(13) | BIT(14))
92 #define BMI270_ANYMO_2_ENABLE		BIT(15)
93 #define BMI270_ANYMO_2_OUT_CONF_OFF	(0x00 << BMI270_ANYMO_2_OUT_CONF_POS)
94 #define BMI270_ANYMO_2_OUT_CONF_BIT_0	(0x01 << BMI270_ANYMO_2_OUT_CONF_POS)
95 #define BMI270_ANYMO_2_OUT_CONF_BIT_1	(0x02 << BMI270_ANYMO_2_OUT_CONF_POS)
96 #define BMI270_ANYMO_2_OUT_CONF_BIT_2	(0x03 << BMI270_ANYMO_2_OUT_CONF_POS)
97 #define BMI270_ANYMO_2_OUT_CONF_BIT_3	(0x04 << BMI270_ANYMO_2_OUT_CONF_POS)
98 #define BMI270_ANYMO_2_OUT_CONF_BIT_4	(0x05 << BMI270_ANYMO_2_OUT_CONF_POS)
99 #define BMI270_ANYMO_2_OUT_CONF_BIT_5	(0x06 << BMI270_ANYMO_2_OUT_CONF_POS)
100 #define BMI270_ANYMO_2_OUT_CONF_BIT_6	(0x07 << BMI270_ANYMO_2_OUT_CONF_POS)
101 #define BMI270_ANYMO_2_OUT_CONF_BIT_8	(0x08 << BMI270_ANYMO_2_OUT_CONF_POS)
102 
103 #define BMI270_INT_IO_CTRL_LVL		BIT(1) /* Output level (0 = active low, 1 = active high) */
104 #define BMI270_INT_IO_CTRL_OD		BIT(2) /* Open-drain (0 = push-pull, 1 = open-drain)*/
105 #define BMI270_INT_IO_CTRL_OUTPUT_EN	BIT(3) /* Output enabled */
106 #define BMI270_INT_IO_CTRL_INPUT_EN	BIT(4) /* Input enabled */
107 
108 /* Applies to INT1_MAP_FEAT, INT2_MAP_FEAT, INT_STATUS_0 */
109 #define BMI270_INT_MAP_SIG_MOTION        BIT(0)
110 #define BMI270_INT_MAP_STEP_COUNTER      BIT(1)
111 #define BMI270_INT_MAP_ACTIVITY          BIT(2)
112 #define BMI270_INT_MAP_WRIST_WEAR_WAKEUP BIT(3)
113 #define BMI270_INT_MAP_WRIST_GESTURE     BIT(4)
114 #define BMI270_INT_MAP_NO_MOTION         BIT(5)
115 #define BMI270_INT_MAP_ANY_MOTION        BIT(6)
116 
117 #define BMI270_INT_MAP_DATA_FFULL_INT1		BIT(0)
118 #define BMI270_INT_MAP_DATA_FWM_INT1		BIT(1)
119 #define BMI270_INT_MAP_DATA_DRDY_INT1		BIT(2)
120 #define BMI270_INT_MAP_DATA_ERR_INT1		BIT(3)
121 #define BMI270_INT_MAP_DATA_FFULL_INT2		BIT(4)
122 #define BMI270_INT_MAP_DATA_FWM_INT2		BIT(5)
123 #define BMI270_INT_MAP_DATA_DRDY_INT2		BIT(6)
124 #define BMI270_INT_MAP_DATA_ERR_INT2		BIT(7)
125 
126 #define BMI270_INT_STATUS_ANY_MOTION		BIT(6)
127 
128 #define BMI270_CHIP_ID 0x24
129 
130 #define BMI270_CMD_G_TRIGGER  0x02
131 #define BMI270_CMD_USR_GAIN   0x03
132 #define BMI270_CMD_NVM_PROG   0xA0
133 #define BMI270_CMD_FIFO_FLUSH OxB0
134 #define BMI270_CMD_SOFT_RESET 0xB6
135 
136 #define BMI270_POWER_ON_TIME                500
137 #define BMI270_SOFT_RESET_TIME              2000
138 #define BMI270_ACC_SUS_TO_NOR_START_UP_TIME 2000
139 #define BMI270_GYR_SUS_TO_NOR_START_UP_TIME 45000
140 #define BMI270_GYR_FAST_START_UP_TIME       2000
141 #define BMI270_TRANSC_DELAY_SUSPEND         450
142 #define BMI270_TRANSC_DELAY_NORMAL          2
143 
144 #define BMI270_PREPARE_CONFIG_LOAD  0x00
145 #define BMI270_COMPLETE_CONFIG_LOAD 0x01
146 
147 #define BMI270_INST_MESSAGE_MSK        0x0F
148 #define BMI270_INST_MESSAGE_NOT_INIT   0x00
149 #define BMI270_INST_MESSAGE_INIT_OK    0x01
150 #define BMI270_INST_MESSAGE_INIT_ERR   0x02
151 #define BMI270_INST_MESSAGE_DRV_ERR    0x03
152 #define BMI270_INST_MESSAGE_SNS_STOP   0x04
153 #define BMI270_INST_MESSAGE_NVM_ERR    0x05
154 #define BMI270_INST_MESSAGE_STRTUP_ERR 0x06
155 #define BMI270_INST_MESSAGE_COMPAT_ERR 0x07
156 
157 #define BMI270_INST_AXES_REMAP_ERROR 0x20
158 #define BMI270_INST_ODR_50HZ_ERROR   0x40
159 
160 #define BMI270_PWR_CONF_ADV_PWR_SAVE_MSK 0x01
161 #define BMI270_PWR_CONF_ADV_PWR_SAVE_EN  0x01
162 #define BMI270_PWR_CONF_ADV_PWR_SAVE_DIS 0x00
163 
164 #define BMI270_PWR_CONF_FIFO_SELF_WKUP_MSK 0x02
165 #define BMI270_PWR_CONF_FIFO_SELF_WKUP_POS 0x01
166 #define BMI270_PWR_CONF_FIFO_SELF_WKUP_EN  0x01
167 #define BMI270_PWR_CONF_FIFO_SELF_WKUP_DIS 0x00
168 
169 #define BMI270_PWR_CONF_FUP_EN_MSK 0x04
170 #define BMI270_PWR_CONF_FUP_EN_POS 0x02
171 #define BMI270_PWR_CONF_FUP_EN     0x01
172 #define BMI270_PWR_CONF_FUP_DIS    0x00
173 
174 #define BMI270_PWR_CTRL_MSK     0x0F
175 #define BMI270_PWR_CTRL_AUX_EN  0x01
176 #define BMI270_PWR_CTRL_GYR_EN  0x02
177 #define BMI270_PWR_CTRL_ACC_EN  0x04
178 #define BMI270_PWR_CTRL_TEMP_EN 0x08
179 
180 #define BMI270_ACC_ODR_MSK      0x0F
181 #define BMI270_ACC_ODR_25D32_HZ 0x01
182 #define BMI270_ACC_ODR_25D16_HZ 0x02
183 #define BMI270_ACC_ODR_25D8_HZ  0x03
184 #define BMI270_ACC_ODR_25D4_HZ  0x04
185 #define BMI270_ACC_ODR_25D2_HZ  0x05
186 #define BMI270_ACC_ODR_25_HZ    0x06
187 #define BMI270_ACC_ODR_50_HZ    0x07
188 #define BMI270_ACC_ODR_100_HZ   0x08
189 #define BMI270_ACC_ODR_200_HZ   0x09
190 #define BMI270_ACC_ODR_400_HZ   0x0A
191 #define BMI270_ACC_ODR_800_HZ   0x0B
192 #define BMI270_ACC_ODR_1600_HZ  0x0C
193 
194 #define BMI270_ACC_BWP_MSK        0x30
195 #define BMI270_ACC_BWP_POS        4
196 #define BMI270_ACC_BWP_OSR4_AVG1  0x00
197 #define BMI270_ACC_BWP_OSR2_AVG2  0x01
198 #define BMI270_ACC_BWP_NORM_AVG4  0x02
199 #define BMI270_ACC_BWP_CIC_AVG8   0x03
200 #define BMI270_ACC_BWP_RES_AVG16  0x04
201 #define BMI270_ACC_BWP_RES_AVG32  0x05
202 #define BMI270_ACC_BWP_RES_AVG64  0x06
203 #define BMI270_ACC_BWP_RES_AVG128 0x07
204 
205 #define BMI270_ACC_FILT_MSK      0x80
206 #define BMI270_ACC_FILT_POS      7
207 #define BMI270_ACC_FILT_PWR_OPT  0x00
208 #define BMI270_ACC_FILT_PERF_OPT 0x01
209 
210 #define BMI270_ACC_RANGE_MSK 0x03
211 #define BMI270_ACC_RANGE_2G  0x00
212 #define BMI270_ACC_RANGE_4G  0x01
213 #define BMI270_ACC_RANGE_8G  0x02
214 #define BMI270_ACC_RANGE_16G 0x03
215 
216 #define BMI270_GYR_ODR_MSK     0x0F
217 #define BMI270_GYR_ODR_25_HZ   0x06
218 #define BMI270_GYR_ODR_50_HZ   0x07
219 #define BMI270_GYR_ODR_100_HZ  0x08
220 #define BMI270_GYR_ODR_200_HZ  0x09
221 #define BMI270_GYR_ODR_400_HZ  0x0A
222 #define BMI270_GYR_ODR_800_HZ  0x0B
223 #define BMI270_GYR_ODR_1600_HZ 0x0C
224 #define BMI270_GYR_ODR_3200_HZ 0x0D
225 
226 #define BMI270_GYR_BWP_MSK  0x30
227 #define BMI270_GYR_BWP_POS  4
228 #define BMI270_GYR_BWP_OSR4 0x00
229 #define BMI270_GYR_BWP_OSR2 0x01
230 #define BMI270_GYR_BWP_NORM 0x02
231 
232 #define BMI270_GYR_FILT_NOISE_MSK      0x40
233 #define BMI270_GYR_FILT_NOISE_POS      6
234 #define BMI270_GYR_FILT_NOISE_PWR      0x00
235 #define BMI270_GYR_FILT_NOISE_PERF     0x01
236 
237 #define BMI270_GYR_FILT_MSK      0x80
238 #define BMI270_GYR_FILT_POS      7
239 #define BMI270_GYR_FILT_PWR_OPT  0x00
240 #define BMI270_GYR_FILT_PERF_OPT 0x01
241 
242 #define BMI270_GYR_RANGE_MSK     0x07
243 #define BMI270_GYR_RANGE_2000DPS 0x00
244 #define BMI270_GYR_RANGE_1000DPS 0x01
245 #define BMI270_GYR_RANGE_500DPS  0x02
246 #define BMI270_GYR_RANGE_250DPS  0x03
247 #define BMI270_GYR_RANGE_125DPS  0x04
248 
249 #define BMI270_GYR_OIS_RANGE_MSK     0x80
250 #define BMI270_GYR_OIS_RANGE_POS     3
251 #define BMI270_GYR_OIS_RANGE_250DPS  0x00
252 #define BMI270_GYR_OIS_RANGE_2000DPS 0x01
253 
254 #define BMI270_SET_BITS(reg_data, bitname, data)		  \
255 	((reg_data & ~(bitname##_MSK)) | ((data << bitname##_POS) \
256 					  & bitname##_MSK))
257 #define BMI270_SET_BITS_POS_0(reg_data, bitname, data) \
258 	((reg_data & ~(bitname##_MSK)) | (data & bitname##_MSK))
259 
260 struct bmi270_data {
261 	int16_t ax, ay, az, gx, gy, gz;
262 	uint8_t acc_range, acc_odr, gyr_odr;
263 	uint16_t gyr_range;
264 
265 #if CONFIG_BMI270_TRIGGER
266 	const struct device *dev;
267 	struct k_mutex trigger_mutex;
268 	sensor_trigger_handler_t motion_handler;
269 	const struct sensor_trigger *motion_trigger;
270 	sensor_trigger_handler_t drdy_handler;
271 	const struct sensor_trigger *drdy_trigger;
272 	struct gpio_callback int1_cb;
273 	struct gpio_callback int2_cb;
274 	atomic_t int_flags;
275 	uint16_t anymo_1;
276 	uint16_t anymo_2;
277 
278 #if CONFIG_BMI270_TRIGGER_OWN_THREAD
279 	struct k_sem trig_sem;
280 
281 	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_BMI270_THREAD_STACK_SIZE);
282 	struct k_thread thread;
283 
284 #elif CONFIG_BMI270_TRIGGER_GLOBAL_THREAD
285 	struct k_work trig_work;
286 #endif
287 #endif /* CONFIG_BMI270_TRIGGER */
288 };
289 
290 struct bmi270_feature_reg {
291 	/* Which feature page the register resides in */
292 	uint8_t page;
293 	uint8_t addr;
294 };
295 
296 struct bmi270_feature_config {
297 	const char *name;
298 	const uint8_t *config_file;
299 	size_t config_file_len;
300 	struct bmi270_feature_reg *anymo_1;
301 	struct bmi270_feature_reg *anymo_2;
302 };
303 
304 union bmi270_bus {
305 #if CONFIG_BMI270_BUS_SPI
306 	struct spi_dt_spec spi;
307 #endif
308 #if CONFIG_BMI270_BUS_I2C
309 	struct i2c_dt_spec i2c;
310 #endif
311 };
312 
313 typedef int (*bmi270_bus_check_fn)(const union bmi270_bus *bus);
314 typedef int (*bmi270_bus_init_fn)(const union bmi270_bus *bus);
315 typedef int (*bmi270_reg_read_fn)(const union bmi270_bus *bus,
316 				  uint8_t start,
317 				  uint8_t *data,
318 				  uint16_t len);
319 typedef int (*bmi270_reg_write_fn)(const union bmi270_bus *bus,
320 				   uint8_t start,
321 				   const uint8_t *data,
322 				   uint16_t len);
323 
324 struct bmi270_bus_io {
325 	bmi270_bus_check_fn check;
326 	bmi270_reg_read_fn read;
327 	bmi270_reg_write_fn write;
328 	bmi270_bus_init_fn init;
329 };
330 
331 struct bmi270_config {
332 	union bmi270_bus bus;
333 	const struct bmi270_bus_io *bus_io;
334 	const struct bmi270_feature_config *feature;
335 #if CONFIG_BMI270_TRIGGER
336 	struct gpio_dt_spec int1;
337 	struct gpio_dt_spec int2;
338 #endif
339 };
340 
341 #if CONFIG_BMI270_BUS_SPI
342 #define BMI270_SPI_OPERATION (SPI_WORD_SET(8) | SPI_TRANSFER_MSB)
343 #define BMI270_SPI_ACC_DELAY_US 2
344 extern const struct bmi270_bus_io bmi270_bus_io_spi;
345 #endif
346 
347 #if CONFIG_BMI270_BUS_I2C
348 extern const struct bmi270_bus_io bmi270_bus_io_i2c;
349 #endif
350 
351 int bmi270_reg_read(const struct device *dev, uint8_t reg, uint8_t *data, uint16_t length);
352 
353 int bmi270_reg_write(const struct device *dev, uint8_t reg,
354 		     const uint8_t *data, uint16_t length);
355 
356 int bmi270_reg_write_with_delay(const struct device *dev,
357 				uint8_t reg,
358 				const uint8_t *data,
359 				uint16_t length,
360 				uint32_t delay_us);
361 
362 #ifdef CONFIG_BMI270_TRIGGER
363 int bmi270_trigger_set(const struct device *dev,
364 		       const struct sensor_trigger *trig,
365 		       sensor_trigger_handler_t handler);
366 
367 int bmi270_init_interrupts(const struct device *dev);
368 #endif
369 
370 #endif /* ZEPHYR_DRIVERS_SENSOR_BMI270_BMI270_H_ */
371