1 /*
2 * Copyright (c) 2024 TDK Invensense
3 * Copyright (c) 2022 Esco Medical ApS
4 * Copyright (c) 2020 TDK Invensense
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/init.h>
12 #include <zephyr/drivers/gpio.h>
13 #include <zephyr/pm/device.h>
14 #include <zephyr/sys/byteorder.h>
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/drivers/sensor/icm42670.h>
17 #include <zephyr/drivers/sensor/tdk_apex.h>
18
19 #include "icm42670.h"
20 #include "icm42670_trigger.h"
21
22 #include <zephyr/logging/log.h>
23 LOG_MODULE_REGISTER(ICM42670, CONFIG_SENSOR_LOG_LEVEL);
24
25 /* Convert DT enum to sensor ODR selection */
26 #define ICM42670_CONVERT_ENUM_TO_ODR_POS (4)
27
28 /* Maximum bytes to read/write on ICM42670 serial interface */
29 #define ICM42670_SERIAL_INTERFACE_MAX_READ (1024 * 32)
30 #define ICM42670_SERIAL_INTERFACE_MAX_WRITE (1024 * 32)
31
icm42670_reg_read(const struct device * dev,uint8_t reg,uint8_t * buf,uint32_t size)32 static inline int icm42670_reg_read(const struct device *dev, uint8_t reg, uint8_t *buf,
33 uint32_t size)
34 {
35 const struct icm42670_config *cfg = dev->config;
36
37 return cfg->bus_io->read(&cfg->bus, reg, buf, size);
38 }
39
inv_io_hal_read_reg(struct inv_imu_serif * serif,uint8_t reg,uint8_t * rbuffer,uint32_t rlen)40 static inline int inv_io_hal_read_reg(struct inv_imu_serif *serif, uint8_t reg, uint8_t *rbuffer,
41 uint32_t rlen)
42 {
43 return icm42670_reg_read(serif->context, reg, rbuffer, rlen);
44 }
45
icm42670_reg_write(const struct device * dev,uint8_t reg,const uint8_t * buf,uint32_t size)46 static inline int icm42670_reg_write(const struct device *dev, uint8_t reg, const uint8_t *buf,
47 uint32_t size)
48 {
49 const struct icm42670_config *cfg = dev->config;
50
51 return cfg->bus_io->write(&cfg->bus, reg, (uint8_t *)buf, size);
52 }
53
inv_io_hal_write_reg(struct inv_imu_serif * serif,uint8_t reg,const uint8_t * wbuffer,uint32_t wlen)54 static inline int inv_io_hal_write_reg(struct inv_imu_serif *serif, uint8_t reg,
55 const uint8_t *wbuffer, uint32_t wlen)
56 {
57 return icm42670_reg_write(serif->context, reg, wbuffer, wlen);
58 }
59
inv_imu_sleep_us(uint32_t us)60 void inv_imu_sleep_us(uint32_t us)
61 {
62 k_sleep(K_USEC(us));
63 }
64
inv_imu_get_time_us(void)65 uint64_t inv_imu_get_time_us(void)
66 {
67 /* returns the elapsed time since the system booted, in milliseconds */
68 return k_uptime_get() * 1000;
69 }
70
convert_dt_enum_to_freq(uint8_t val)71 static uint16_t convert_dt_enum_to_freq(uint8_t val)
72 {
73 uint16_t freq;
74
75 switch (val) {
76 case 0:
77 freq = 0;
78 break;
79 case 1:
80 freq = 1600;
81 break;
82 case 2:
83 freq = 800;
84 break;
85 case 3:
86 freq = 400;
87 break;
88 case 4:
89 freq = 200;
90 break;
91 case 5:
92 freq = 100;
93 break;
94 case 6:
95 freq = 50;
96 break;
97 case 7:
98 freq = 25;
99 break;
100 case 8:
101 freq = 12;
102 break;
103 case 9:
104 freq = 6;
105 break;
106 case 10:
107 freq = 3;
108 break;
109 case 11:
110 freq = 1;
111 break;
112 default:
113 freq = 0;
114 break;
115 }
116 return freq;
117 }
118
convert_freq_to_bitfield(uint32_t val,uint16_t * freq)119 static uint32_t convert_freq_to_bitfield(uint32_t val, uint16_t *freq)
120 {
121 uint32_t odr_bitfield = 0;
122
123 if (val < 3 && val >= 1) {
124 odr_bitfield = ACCEL_CONFIG0_ODR_1_5625_HZ; /*(= GYRO_CONFIG0_ODR_1_5625_HZ )*/
125 *freq = 1;
126 } else if (val < 6 && val >= 3) {
127 odr_bitfield = ACCEL_CONFIG0_ODR_3_125_HZ; /*(= GYRO_CONFIG0_ODR_3_125_HZ )*/
128 *freq = 3;
129 } else if (val < 12 && val >= 6) {
130 odr_bitfield = ACCEL_CONFIG0_ODR_6_25_HZ; /*(= GYRO_CONFIG0_ODR_6_25_HZ )*/
131 *freq = 6;
132 } else if (val < 25 && val >= 12) {
133 odr_bitfield = ACCEL_CONFIG0_ODR_12_5_HZ; /*(= GYRO_CONFIG0_ODR_12_5_HZ )*/
134 *freq = 12;
135 } else if (val < 50 && val >= 25) {
136 odr_bitfield = ACCEL_CONFIG0_ODR_25_HZ; /*(= GYRO_CONFIG0_ODR_25_HZ )*/
137 *freq = 25;
138 } else if (val < 100 && val >= 50) {
139 odr_bitfield = ACCEL_CONFIG0_ODR_50_HZ; /*(GYRO_CONFIG0_ODR_50_HZ)*/
140 *freq = 50;
141 } else if (val < 200 && val >= 100) {
142 odr_bitfield = ACCEL_CONFIG0_ODR_100_HZ; /*(= GYRO_CONFIG0_ODR_100_HZ )*/
143 *freq = 100;
144 } else if (val < 400 && val >= 200) {
145 odr_bitfield = ACCEL_CONFIG0_ODR_200_HZ; /*(= GYRO_CONFIG0_ODR_200_HZ )*/
146 *freq = 200;
147 } else if (val < 800 && val >= 400) {
148 odr_bitfield = ACCEL_CONFIG0_ODR_400_HZ; /*(= GYRO_CONFIG0_ODR_400_HZ )*/
149 *freq = 400;
150 } else if (val < 1600 && val >= 800) {
151 odr_bitfield = ACCEL_CONFIG0_ODR_800_HZ; /*(= GYRO_CONFIG0_ODR_800_HZ )*/
152 *freq = 800;
153 } else if (val == 1600) {
154 odr_bitfield = ACCEL_CONFIG0_ODR_1600_HZ; /*(= GYRO_CONFIG0_ODR_1600_HZ )*/
155 *freq = 1600;
156 }
157 return odr_bitfield;
158 }
159
convert_acc_fs_to_bitfield(uint32_t val,uint8_t * fs)160 static uint32_t convert_acc_fs_to_bitfield(uint32_t val, uint8_t *fs)
161 {
162 uint32_t bitfield = 0;
163
164 if (val < 4 && val >= 2) {
165 bitfield = ACCEL_CONFIG0_FS_SEL_2g;
166 *fs = 2;
167 } else if (val < 8 && val >= 4) {
168 bitfield = ACCEL_CONFIG0_FS_SEL_4g;
169 *fs = 4;
170 } else if (val < 16 && val >= 8) {
171 bitfield = ACCEL_CONFIG0_FS_SEL_8g;
172 *fs = 8;
173 } else if (val == 16) {
174 bitfield = ACCEL_CONFIG0_FS_SEL_16g;
175 *fs = 16;
176 }
177 return bitfield;
178 }
179
convert_gyr_fs_to_bitfield(uint32_t val,uint16_t * fs)180 static uint32_t convert_gyr_fs_to_bitfield(uint32_t val, uint16_t *fs)
181 {
182 uint32_t bitfield = 0;
183
184 if (val < 500 && val >= 250) {
185 bitfield = GYRO_CONFIG0_FS_SEL_250dps;
186 *fs = 250;
187 } else if (val < 1000 && val >= 500) {
188 bitfield = GYRO_CONFIG0_FS_SEL_500dps;
189 *fs = 500;
190 } else if (val < 2000 && val >= 1000) {
191 bitfield = GYRO_CONFIG0_FS_SEL_1000dps;
192 *fs = 1000;
193 } else if (val == 2000) {
194 bitfield = GYRO_CONFIG0_FS_SEL_2000dps;
195 *fs = 2000;
196 }
197 return bitfield;
198 }
199
convert_ln_bw_to_bitfield(uint32_t val)200 static uint32_t convert_ln_bw_to_bitfield(uint32_t val)
201 {
202 uint32_t bitfield = 0xFF;
203
204 if (val < 25 && val >= 16) {
205 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_16; /* (= GYRO_CONFIG1_GYRO_FILT_BW_16) */
206 } else if (val < 34 && val >= 25) {
207 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_25; /* (= GYRO_CONFIG1_GYRO_FILT_BW_25) */
208 } else if (val < 53 && val >= 34) {
209 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_34; /* (= GYRO_CONFIG1_GYRO_FILT_BW_34) */
210 } else if (val < 73 && val >= 53) {
211 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_53; /* (= GYRO_CONFIG1_GYRO_FILT_BW_53) */
212 } else if (val < 121 && val >= 73) {
213 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_73; /* (= GYRO_CONFIG1_GYRO_FILT_BW_73) */
214 } else if (val < 180 && val >= 121) {
215 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_121; /* (= GYRO_CONFIG1_GYRO_FILT_BW_121) */
216 } else if (val == 180) {
217 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_180; /* (= GYRO_CONFIG1_GYRO_FILT_BW_180) */
218 } else if (val == 0) {
219 bitfield = ACCEL_CONFIG1_ACCEL_FILT_BW_NO_FILTER;
220 /*(= GYRO_CONFIG1_GYRO_FILT_BW_NO_FILTER)*/
221 }
222 return bitfield;
223 }
224
convert_lp_avg_to_bitfield(uint32_t val)225 static uint32_t convert_lp_avg_to_bitfield(uint32_t val)
226 {
227 uint32_t bitfield = 0xFF;
228
229 if (val < 4 && val >= 2) {
230 bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_2;
231 } else if (val < 8 && val >= 4) {
232 bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_4;
233 } else if (val < 16 && val >= 8) {
234 bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_8;
235 } else if (val < 32 && val >= 16) {
236 bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_16;
237 } else if (val < 64 && val >= 32) {
238 bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_32;
239 } else if (val == 64) {
240 bitfield = ACCEL_CONFIG1_ACCEL_FILT_AVG_64;
241 }
242 return bitfield;
243 }
244
convert_bitfield_to_acc_fs(uint8_t bitfield)245 static uint8_t convert_bitfield_to_acc_fs(uint8_t bitfield)
246 {
247 uint8_t acc_fs = 0;
248
249 if (bitfield == ACCEL_CONFIG0_FS_SEL_2g) {
250 acc_fs = 2;
251 } else if (bitfield == ACCEL_CONFIG0_FS_SEL_4g) {
252 acc_fs = 4;
253 } else if (bitfield == ACCEL_CONFIG0_FS_SEL_8g) {
254 acc_fs = 8;
255 } else if (bitfield == ACCEL_CONFIG0_FS_SEL_16g) {
256 acc_fs = 16;
257 }
258 return acc_fs;
259 }
260
convert_bitfield_to_gyr_fs(uint8_t bitfield)261 static uint16_t convert_bitfield_to_gyr_fs(uint8_t bitfield)
262 {
263 uint16_t gyr_fs = 0;
264
265 if (bitfield == GYRO_CONFIG0_FS_SEL_250dps) {
266 gyr_fs = 250;
267 } else if (bitfield == GYRO_CONFIG0_FS_SEL_500dps) {
268 gyr_fs = 500;
269 } else if (bitfield == GYRO_CONFIG0_FS_SEL_1000dps) {
270 gyr_fs = 1000;
271 } else if (bitfield == GYRO_CONFIG0_FS_SEL_2000dps) {
272 gyr_fs = 2000;
273 }
274 return gyr_fs;
275 }
276
icm42670_set_accel_power_mode(struct icm42670_data * drv_data,const struct sensor_value * val)277 static int icm42670_set_accel_power_mode(struct icm42670_data *drv_data,
278 const struct sensor_value *val)
279 {
280 if ((val->val1 == ICM42670_LOW_POWER_MODE) &&
281 (drv_data->accel_pwr_mode != ICM42670_LOW_POWER_MODE)) {
282 if (drv_data->accel_hz != 0) {
283 if (drv_data->accel_hz <= 400) {
284 inv_imu_enable_accel_low_power_mode(&drv_data->driver);
285 } else {
286 LOG_ERR("Not supported ATTR value");
287 return -EINVAL;
288 }
289 }
290 drv_data->accel_pwr_mode = val->val1;
291 } else if ((val->val1 == ICM42670_LOW_NOISE_MODE) &&
292 (drv_data->accel_pwr_mode != ICM42670_LOW_NOISE_MODE)) {
293 if (drv_data->accel_hz != 0) {
294 if (drv_data->accel_hz >= 12) {
295 inv_imu_enable_accel_low_noise_mode(&drv_data->driver);
296 } else {
297 LOG_ERR("Not supported ATTR value");
298 return -EINVAL;
299 }
300 }
301 drv_data->accel_pwr_mode = val->val1;
302 } else {
303 LOG_ERR("Not supported ATTR value");
304 return -EINVAL;
305 }
306 return 0;
307 }
308
icm42670_set_accel_odr(struct icm42670_data * drv_data,const struct sensor_value * val)309 static int icm42670_set_accel_odr(struct icm42670_data *drv_data, const struct sensor_value *val)
310 {
311 if (val->val1 <= 1600 && val->val1 >= 1) {
312 if (drv_data->accel_hz == 0) {
313 inv_imu_set_accel_frequency(
314 &drv_data->driver,
315 convert_freq_to_bitfield(val->val1, &drv_data->accel_hz));
316 if (drv_data->accel_pwr_mode == ICM42670_LOW_POWER_MODE) {
317 inv_imu_enable_accel_low_power_mode(&drv_data->driver);
318 } else if (drv_data->accel_pwr_mode == ICM42670_LOW_NOISE_MODE) {
319 inv_imu_enable_accel_low_noise_mode(&drv_data->driver);
320 }
321 } else {
322 inv_imu_set_accel_frequency(
323 &drv_data->driver,
324 convert_freq_to_bitfield(val->val1, &drv_data->accel_hz));
325 }
326 } else if (val->val1 == 0) {
327 inv_imu_disable_accel(&drv_data->driver);
328 drv_data->accel_hz = val->val1;
329 } else {
330 LOG_ERR("Incorrect sampling value");
331 return -EINVAL;
332 }
333 return 0;
334 }
335
icm42670_set_accel_fs(struct icm42670_data * drv_data,const struct sensor_value * val)336 static int icm42670_set_accel_fs(struct icm42670_data *drv_data, const struct sensor_value *val)
337 {
338 if (val->val1 > 16 || val->val1 < 2) {
339 LOG_ERR("Incorrect fullscale value");
340 return -EINVAL;
341 }
342 inv_imu_set_accel_fsr(&drv_data->driver,
343 convert_acc_fs_to_bitfield(val->val1, &drv_data->accel_fs));
344 LOG_DBG("Set accel full scale to: %d G", drv_data->accel_fs);
345 return 0;
346 }
347
icm42670_accel_config(struct icm42670_data * drv_data,enum sensor_attribute attr,const struct sensor_value * val)348 static int icm42670_accel_config(struct icm42670_data *drv_data, enum sensor_attribute attr,
349 const struct sensor_value *val)
350 {
351 if (attr == SENSOR_ATTR_CONFIGURATION) {
352 icm42670_set_accel_power_mode(drv_data, val);
353
354 } else if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
355 icm42670_set_accel_odr(drv_data, val);
356
357 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
358 icm42670_set_accel_fs(drv_data, val);
359
360 } else if ((enum sensor_attribute_icm42670)attr == SENSOR_ATTR_BW_FILTER_LPF) {
361 if (val->val1 > 180) {
362 LOG_ERR("Incorrect low pass filter bandwidth value");
363 return -EINVAL;
364 }
365 inv_imu_set_accel_ln_bw(&drv_data->driver, convert_ln_bw_to_bitfield(val->val1));
366
367 } else if ((enum sensor_attribute_icm42670)attr == SENSOR_ATTR_AVERAGING) {
368 if (val->val1 > 64 || val->val1 < 2) {
369 LOG_ERR("Incorrect averaging filter value");
370 return -EINVAL;
371 }
372 inv_imu_set_accel_lp_avg(&drv_data->driver, convert_lp_avg_to_bitfield(val->val1));
373 } else {
374 LOG_ERR("Unsupported attribute");
375 return -EINVAL;
376 }
377 return 0;
378 }
379
icm42670_set_gyro_odr(struct icm42670_data * drv_data,const struct sensor_value * val)380 static int icm42670_set_gyro_odr(struct icm42670_data *drv_data, const struct sensor_value *val)
381 {
382 if (val->val1 <= 1600 && val->val1 > 12) {
383 if (drv_data->gyro_hz == 0) {
384 inv_imu_set_gyro_frequency(
385 &drv_data->driver,
386 convert_freq_to_bitfield(val->val1, &drv_data->gyro_hz));
387 inv_imu_enable_gyro_low_noise_mode(&drv_data->driver);
388 } else {
389 inv_imu_set_gyro_frequency(
390 &drv_data->driver,
391 convert_freq_to_bitfield(val->val1, &drv_data->gyro_hz));
392 }
393 } else if (val->val1 == 0) {
394 inv_imu_disable_gyro(&drv_data->driver);
395 drv_data->gyro_hz = val->val1;
396 } else {
397 LOG_ERR("Incorrect sampling value");
398 return -EINVAL;
399 }
400 return 0;
401 }
402
icm42670_set_gyro_fs(struct icm42670_data * drv_data,const struct sensor_value * val)403 static int icm42670_set_gyro_fs(struct icm42670_data *drv_data, const struct sensor_value *val)
404 {
405 if (val->val1 > 2000 || val->val1 < 250) {
406 LOG_ERR("Incorrect fullscale value");
407 return -EINVAL;
408 }
409 inv_imu_set_gyro_fsr(&drv_data->driver,
410 convert_gyr_fs_to_bitfield(val->val1, &drv_data->gyro_fs));
411 LOG_DBG("Set gyro fullscale to: %d dps", drv_data->gyro_fs);
412 return 0;
413 }
414
icm42670_gyro_config(struct icm42670_data * drv_data,enum sensor_attribute attr,const struct sensor_value * val)415 static int icm42670_gyro_config(struct icm42670_data *drv_data, enum sensor_attribute attr,
416 const struct sensor_value *val)
417 {
418 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
419 icm42670_set_gyro_odr(drv_data, val);
420
421 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
422 icm42670_set_gyro_fs(drv_data, val);
423
424 } else if ((enum sensor_attribute_icm42670)attr == SENSOR_ATTR_BW_FILTER_LPF) {
425 if (val->val1 > 180) {
426 LOG_ERR("Incorrect low pass filter bandwidth value");
427 return -EINVAL;
428 }
429 inv_imu_set_gyro_ln_bw(&drv_data->driver, convert_ln_bw_to_bitfield(val->val1));
430
431 } else {
432 LOG_ERR("Unsupported attribute");
433 return -EINVAL;
434 }
435 return 0;
436 }
437
icm42670_sensor_init(const struct device * dev)438 static int icm42670_sensor_init(const struct device *dev)
439 {
440 struct icm42670_data *data = dev->data;
441 int err = 0;
442
443 /* Initialize serial interface and device */
444 data->serif.context = (struct device *)dev;
445 data->serif.read_reg = inv_io_hal_read_reg;
446 data->serif.write_reg = inv_io_hal_write_reg;
447 data->serif.max_read = ICM42670_SERIAL_INTERFACE_MAX_READ;
448 data->serif.max_write = ICM42670_SERIAL_INTERFACE_MAX_WRITE;
449 #if CONFIG_SPI
450 data->serif.serif_type = UI_SPI4;
451 #endif
452 #if CONFIG_I2C
453 data->serif.serif_type = UI_I2C;
454 #endif
455 err = inv_imu_init(&data->driver, &data->serif, NULL);
456 if (err < 0) {
457 LOG_ERR("Init failed: %d", err);
458 return err;
459 }
460
461 err = inv_imu_get_who_am_i(&data->driver, &data->chip_id);
462 if (err < 0) {
463 LOG_ERR("ID read failed: %d", err);
464 return err;
465 }
466
467 if (data->chip_id != data->imu_whoami) {
468 LOG_ERR("invalid WHO_AM_I value, was 0x%x but expected 0x%x for %s", data->chip_id,
469 data->imu_whoami, data->imu_name);
470 return -ENOTSUP;
471 }
472
473 LOG_DBG("\"%s\" %s OK", dev->name, data->imu_name);
474 return 0;
475 }
476
icm42670_turn_on_sensor(const struct device * dev)477 static int icm42670_turn_on_sensor(const struct device *dev)
478 {
479 struct icm42670_data *data = dev->data;
480 const struct icm42670_config *cfg = dev->config;
481 int err = 0;
482
483 err = inv_imu_set_accel_fsr(&data->driver,
484 (cfg->accel_fs << ACCEL_CONFIG0_ACCEL_UI_FS_SEL_POS));
485 data->accel_fs =
486 convert_bitfield_to_acc_fs((cfg->accel_fs << ACCEL_CONFIG0_ACCEL_UI_FS_SEL_POS));
487 if ((err < 0) || (data->accel_fs == 0)) {
488 LOG_ERR("Failed to configure accel FSR");
489 return -EIO;
490 }
491 LOG_DBG("Set accel full scale to: %d G", data->accel_fs);
492
493 err = inv_imu_set_gyro_fsr(&data->driver,
494 (cfg->gyro_fs << GYRO_CONFIG0_GYRO_UI_FS_SEL_POS));
495 data->gyro_fs =
496 convert_bitfield_to_gyr_fs((cfg->gyro_fs << GYRO_CONFIG0_GYRO_UI_FS_SEL_POS));
497 if ((err < 0) || (data->gyro_fs == 0)) {
498 LOG_ERR("Failed to configure gyro FSR");
499 return -EIO;
500 }
501 LOG_DBG("Set gyro full scale to: %d dps", data->gyro_fs);
502
503 err = inv_imu_set_accel_lp_avg(&data->driver,
504 (cfg->accel_avg << ACCEL_CONFIG1_ACCEL_UI_AVG_POS));
505 err |= inv_imu_set_accel_ln_bw(&data->driver,
506 (cfg->accel_filt_bw << ACCEL_CONFIG1_ACCEL_UI_FILT_BW_POS));
507 err |= inv_imu_set_gyro_ln_bw(&data->driver,
508 (cfg->gyro_filt_bw << GYRO_CONFIG1_GYRO_UI_FILT_BW_POS));
509 if (err < 0) {
510 LOG_ERR("Failed to configure filtering.");
511 return -EIO;
512 }
513
514 if (cfg->accel_hz != 0) {
515 err |= inv_imu_set_accel_frequency(
516 &data->driver, cfg->accel_hz + ICM42670_CONVERT_ENUM_TO_ODR_POS);
517 if ((cfg->accel_pwr_mode == ICM42670_LOW_NOISE_MODE) &&
518 (convert_dt_enum_to_freq(cfg->accel_hz) >= 12)) {
519 err |= inv_imu_enable_accel_low_noise_mode(&data->driver);
520 } else if ((cfg->accel_pwr_mode == ICM42670_LOW_POWER_MODE) &&
521 (convert_dt_enum_to_freq(cfg->accel_hz) <= 400)) {
522 err |= inv_imu_enable_accel_low_power_mode(&data->driver);
523 } else {
524 LOG_ERR("Not supported power mode value");
525 }
526 }
527 if (cfg->gyro_hz != 0) {
528 err |= inv_imu_set_gyro_frequency(&data->driver,
529 cfg->gyro_hz + ICM42670_CONVERT_ENUM_TO_ODR_POS);
530 err |= inv_imu_enable_gyro_low_noise_mode(&data->driver);
531 }
532
533 if (err < 0) {
534 LOG_ERR("Failed to configure ODR.");
535 return -EIO;
536 }
537
538 data->accel_pwr_mode = cfg->accel_pwr_mode;
539 data->accel_hz = convert_dt_enum_to_freq(cfg->accel_hz);
540 data->gyro_hz = convert_dt_enum_to_freq(cfg->gyro_hz);
541
542 /*
543 * Accelerometer sensor need at least 10ms startup time
544 * Gyroscope sensor need at least 30ms startup time
545 */
546 k_msleep(100);
547
548 return 0;
549 }
550
icm42670_convert_accel(struct sensor_value * val,int16_t raw_val,uint16_t fs)551 static void icm42670_convert_accel(struct sensor_value *val, int16_t raw_val, uint16_t fs)
552 {
553 int64_t conv_val;
554
555 /* 16 bit accelerometer. 2^15 bits represent the range in G */
556 /* see datasheet section 3.2 for details */
557 conv_val = (int64_t)raw_val * SENSOR_G * fs / INT16_MAX;
558
559 val->val1 = conv_val / 1000000;
560 val->val2 = conv_val % 1000000;
561 }
562
icm42670_convert_gyro(struct sensor_value * val,int16_t raw_val,uint16_t fs)563 static void icm42670_convert_gyro(struct sensor_value *val, int16_t raw_val, uint16_t fs)
564 {
565 int64_t conv_val;
566
567 /* 16 bit gyroscope. 2^15 bits represent the range in degrees/s */
568 /* see datasheet section 3.1 for details */
569 conv_val = ((int64_t)raw_val * fs * SENSOR_PI) / (INT16_MAX * 180U);
570
571 val->val1 = conv_val / 1000000;
572 val->val2 = conv_val % 1000000;
573 }
574
icm42670_convert_temp(struct sensor_value * val,int16_t raw_val)575 static void icm42670_convert_temp(struct sensor_value *val, int16_t raw_val)
576 {
577 int64_t conv_val;
578
579 /* see datasheet section 15.9 for details */
580 conv_val = 25 * 1000000 + ((int64_t)raw_val * 1000000 / 2);
581 val->val1 = conv_val / 1000000;
582 val->val2 = conv_val % 1000000;
583 }
584
icm42670_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)585 static int icm42670_channel_get(const struct device *dev, enum sensor_channel chan,
586 struct sensor_value *val)
587 {
588 int res = 0;
589 struct icm42670_data *data = dev->data;
590 #ifdef CONFIG_TDK_APEX
591 const struct icm42670_config *cfg = dev->config;
592 #endif
593
594 icm42670_lock(dev);
595
596 if (chan == SENSOR_CHAN_ACCEL_XYZ) {
597 icm42670_convert_accel(&val[0], data->accel_x, data->accel_fs);
598 icm42670_convert_accel(&val[1], data->accel_y, data->accel_fs);
599 icm42670_convert_accel(&val[2], data->accel_z, data->accel_fs);
600 } else if (chan == SENSOR_CHAN_ACCEL_X) {
601 icm42670_convert_accel(val, data->accel_x, data->accel_fs);
602 } else if (chan == SENSOR_CHAN_ACCEL_Y) {
603 icm42670_convert_accel(val, data->accel_y, data->accel_fs);
604 } else if (chan == SENSOR_CHAN_ACCEL_Z) {
605 icm42670_convert_accel(val, data->accel_z, data->accel_fs);
606 } else if (chan == SENSOR_CHAN_GYRO_XYZ) {
607 icm42670_convert_gyro(&val[0], data->gyro_x, data->gyro_fs);
608 icm42670_convert_gyro(&val[1], data->gyro_y, data->gyro_fs);
609 icm42670_convert_gyro(&val[2], data->gyro_z, data->gyro_fs);
610 } else if (chan == SENSOR_CHAN_GYRO_X) {
611 icm42670_convert_gyro(val, data->gyro_x, data->gyro_fs);
612 } else if (chan == SENSOR_CHAN_GYRO_Y) {
613 icm42670_convert_gyro(val, data->gyro_y, data->gyro_fs);
614 } else if (chan == SENSOR_CHAN_GYRO_Z) {
615 icm42670_convert_gyro(val, data->gyro_z, data->gyro_fs);
616 } else if (chan == SENSOR_CHAN_DIE_TEMP) {
617 icm42670_convert_temp(val, data->temp);
618 #ifdef CONFIG_TDK_APEX
619 } else if ((enum sensor_channel_tdk_apex)chan == SENSOR_CHAN_APEX_MOTION) {
620 if (cfg->apex == TDK_APEX_PEDOMETER) {
621 val[0].val1 = data->pedometer_cnt;
622 val[1].val1 = data->pedometer_activity;
623 icm42670_apex_pedometer_cadence_convert(&val[2], data->pedometer_cadence,
624 data->dmp_odr_hz);
625 } else if (cfg->apex == TDK_APEX_WOM) {
626 val[0].val1 = (data->apex_status & ICM42670_APEX_STATUS_MASK_WOM_X) ? 1 : 0;
627 val[1].val1 = (data->apex_status & ICM42670_APEX_STATUS_MASK_WOM_Y) ? 1 : 0;
628 val[2].val1 = (data->apex_status & ICM42670_APEX_STATUS_MASK_WOM_Z) ? 1 : 0;
629 } else if ((cfg->apex == TDK_APEX_TILT) || (cfg->apex == TDK_APEX_SMD)) {
630 val[0].val1 = data->apex_status;
631 }
632 #endif
633 } else {
634 res = -ENOTSUP;
635 }
636
637 icm42670_unlock(dev);
638
639 return res;
640 }
641
642 #ifdef CONFIG_ICM42670_TRIGGER
icm42670_fetch_from_fifo(const struct device * dev)643 static int icm42670_fetch_from_fifo(const struct device *dev)
644 {
645 struct icm42670_data *data = dev->data;
646 int status = 0;
647 uint8_t int_status;
648 uint16_t packet_size = FIFO_HEADER_SIZE + FIFO_ACCEL_DATA_SIZE + FIFO_GYRO_DATA_SIZE +
649 FIFO_TEMP_DATA_SIZE + FIFO_TS_FSYNC_SIZE;
650 uint16_t fifo_idx = 0;
651
652 /* Ensure data ready status bit is set */
653 status |= inv_imu_read_reg(&data->driver, INT_STATUS, 1, &int_status);
654 if (status != 0) {
655 return status;
656 }
657
658 if ((int_status & INT_STATUS_FIFO_THS_INT_MASK) ||
659 (int_status & INT_STATUS_FIFO_FULL_INT_MASK)) {
660 uint16_t packet_count;
661
662 /* Make sure RCOSC is enabled to guarrantee FIFO read */
663 status |= inv_imu_switch_on_mclk(&data->driver);
664
665 /* Read FIFO frame count */
666 status |= inv_imu_get_frame_count(&data->driver, &packet_count);
667
668 /* Check for error */
669 if (status != 0) {
670 status |= inv_imu_switch_off_mclk(&data->driver);
671 return status;
672 }
673
674 /* Read FIFO data */
675 status |= inv_imu_read_reg(&data->driver, FIFO_DATA, packet_size * packet_count,
676 (uint8_t *)&data->driver.fifo_data);
677
678 /* Check for error */
679 if (status != 0) {
680 status |= inv_imu_reset_fifo(&data->driver);
681 status |= inv_imu_switch_off_mclk(&data->driver);
682 return status;
683 }
684
685 for (uint16_t i = 0; i < packet_count; i++) {
686 inv_imu_sensor_event_t event;
687
688 status |= inv_imu_decode_fifo_frame(
689 &data->driver, &data->driver.fifo_data[fifo_idx], &event);
690 fifo_idx += packet_size;
691
692 /* Check for error */
693 if (status != 0) {
694 status |= inv_imu_reset_fifo(&data->driver);
695 status |= inv_imu_switch_off_mclk(&data->driver);
696 return status;
697 }
698
699 if (event.sensor_mask & (1 << INV_SENSOR_ACCEL)) {
700 data->accel_x = event.accel[0];
701 data->accel_y = event.accel[1];
702 data->accel_z = event.accel[2];
703 }
704 if (event.sensor_mask & (1 << INV_SENSOR_GYRO)) {
705 data->gyro_x = event.gyro[0];
706 data->gyro_y = event.gyro[1];
707 data->gyro_z = event.gyro[2];
708 }
709 if (event.sensor_mask & (1 << INV_SENSOR_TEMPERATURE)) {
710 data->temp = event.temperature;
711 }
712 /*
713 * TODO use the sensor streaming interface with RTIO to handle multiple
714 * samples in FIFO
715 */
716
717 } /* end of FIFO read for loop */
718
719 status |= inv_imu_switch_off_mclk(&data->driver);
720 if (status < 0) {
721 return status;
722 }
723 } /*else: FIFO threshold was not reached and FIFO was not full */
724
725 return 0;
726 }
727 #endif
728
729 #ifndef CONFIG_ICM42670_TRIGGER
icm42670_sample_fetch_accel(const struct device * dev)730 static int icm42670_sample_fetch_accel(const struct device *dev)
731 {
732 struct icm42670_data *data = dev->data;
733 uint8_t buffer[ACCEL_DATA_SIZE];
734
735 int res = inv_imu_read_reg(&data->driver, ACCEL_DATA_X1, ACCEL_DATA_SIZE, buffer);
736
737 if (res) {
738 return res;
739 }
740
741 data->accel_x = (int16_t)sys_get_be16(&buffer[0]);
742 data->accel_y = (int16_t)sys_get_be16(&buffer[2]);
743 data->accel_z = (int16_t)sys_get_be16(&buffer[4]);
744
745 return 0;
746 }
747
icm42670_sample_fetch_gyro(const struct device * dev)748 static int icm42670_sample_fetch_gyro(const struct device *dev)
749 {
750 struct icm42670_data *data = dev->data;
751 uint8_t buffer[GYRO_DATA_SIZE];
752
753 int res = inv_imu_read_reg(&data->driver, GYRO_DATA_X1, GYRO_DATA_SIZE, buffer);
754
755 if (res) {
756 return res;
757 }
758
759 data->gyro_x = (int16_t)sys_get_be16(&buffer[0]);
760 data->gyro_y = (int16_t)sys_get_be16(&buffer[2]);
761 data->gyro_z = (int16_t)sys_get_be16(&buffer[4]);
762
763 return 0;
764 }
765
icm42670_sample_fetch_temp(const struct device * dev)766 static int icm42670_sample_fetch_temp(const struct device *dev)
767 {
768 struct icm42670_data *data = dev->data;
769 uint8_t buffer[TEMP_DATA_SIZE];
770
771 int res = inv_imu_read_reg(&data->driver, TEMP_DATA1, TEMP_DATA_SIZE, buffer);
772
773 if (res) {
774 return res;
775 }
776
777 data->temp = (int16_t)sys_get_be16(&buffer[0]);
778
779 return 0;
780 }
781
icm42670_fetch_from_registers(const struct device * dev,enum sensor_channel chan)782 static int icm42670_fetch_from_registers(const struct device *dev, enum sensor_channel chan)
783 {
784 struct icm42670_data *data = dev->data;
785 int res = 0;
786 uint8_t int_status;
787
788 LOG_ERR("Fetch from reg");
789
790 icm42670_lock(dev);
791
792 /* Ensure data ready status bit is set */
793 int err = inv_imu_read_reg(&data->driver, INT_STATUS_DRDY, 1, &int_status);
794
795 if (int_status & INT_STATUS_DRDY_DATA_RDY_INT_MASK) {
796 switch (chan) {
797 case SENSOR_CHAN_ALL:
798 err |= icm42670_sample_fetch_accel(dev);
799 err |= icm42670_sample_fetch_gyro(dev);
800 err |= icm42670_sample_fetch_temp(dev);
801 break;
802 case SENSOR_CHAN_ACCEL_XYZ:
803 case SENSOR_CHAN_ACCEL_X:
804 case SENSOR_CHAN_ACCEL_Y:
805 case SENSOR_CHAN_ACCEL_Z:
806 err |= icm42670_sample_fetch_accel(dev);
807 break;
808 case SENSOR_CHAN_GYRO_XYZ:
809 case SENSOR_CHAN_GYRO_X:
810 case SENSOR_CHAN_GYRO_Y:
811 case SENSOR_CHAN_GYRO_Z:
812 err |= icm42670_sample_fetch_gyro(dev);
813 break;
814 case SENSOR_CHAN_DIE_TEMP:
815 err |= icm42670_sample_fetch_temp(dev);
816 break;
817 default:
818 res = -ENOTSUP;
819 break;
820 }
821 }
822
823 icm42670_unlock(dev);
824
825 if (err < 0) {
826 res = -EIO;
827 }
828 return res;
829 }
830 #endif
831
icm42670_sample_fetch(const struct device * dev,enum sensor_channel chan)832 static int icm42670_sample_fetch(const struct device *dev, enum sensor_channel chan)
833 {
834 int status = -ENOTSUP;
835
836 icm42670_lock(dev);
837
838 #ifdef CONFIG_TDK_APEX
839 if ((enum sensor_channel_tdk_apex)chan == SENSOR_CHAN_APEX_MOTION) {
840 status = icm42670_apex_fetch_from_dmp(dev);
841 }
842 #endif
843
844 if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_ACCEL_XYZ) ||
845 (chan == SENSOR_CHAN_ACCEL_X) || (chan == SENSOR_CHAN_ACCEL_Y) ||
846 (chan == SENSOR_CHAN_ACCEL_Z) || (chan == SENSOR_CHAN_GYRO_XYZ) ||
847 (chan == SENSOR_CHAN_GYRO_X) || (chan == SENSOR_CHAN_GYRO_Y) ||
848 (chan == SENSOR_CHAN_GYRO_Z) || (chan == SENSOR_CHAN_DIE_TEMP)) {
849 #ifdef CONFIG_ICM42670_TRIGGER
850 status = icm42670_fetch_from_fifo(dev);
851 #else
852 status = icm42670_fetch_from_registers(dev, chan);
853 #endif
854 }
855
856 icm42670_unlock(dev);
857 return status;
858 }
859
icm42670_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)860 static int icm42670_attr_set(const struct device *dev, enum sensor_channel chan,
861 enum sensor_attribute attr, const struct sensor_value *val)
862 {
863 struct icm42670_data *drv_data = dev->data;
864
865 __ASSERT_NO_MSG(val != NULL);
866
867 icm42670_lock(dev);
868
869 if ((enum sensor_channel_tdk_apex)chan == SENSOR_CHAN_APEX_MOTION) {
870 if (attr == SENSOR_ATTR_CONFIGURATION) {
871 #ifdef CONFIG_TDK_APEX
872 if (val->val1 == TDK_APEX_PEDOMETER) {
873 icm42670_apex_enable(&drv_data->driver);
874 icm42670_apex_enable_pedometer(dev, &drv_data->driver);
875 } else if (val->val1 == TDK_APEX_TILT) {
876 icm42670_apex_enable(&drv_data->driver);
877 icm42670_apex_enable_tilt(&drv_data->driver);
878 } else if (val->val1 == TDK_APEX_SMD) {
879 icm42670_apex_enable(&drv_data->driver);
880 icm42670_apex_enable_smd(&drv_data->driver);
881 } else if (val->val1 == TDK_APEX_WOM) {
882 icm42670_apex_enable_wom(&drv_data->driver);
883 } else {
884 LOG_ERR("Not supported ATTR value");
885 }
886 #endif
887 } else {
888 LOG_ERR("Not supported ATTR");
889 return -EINVAL;
890 }
891 } else if ((chan == SENSOR_CHAN_ACCEL_XYZ) || (chan == SENSOR_CHAN_ACCEL_X) ||
892 (chan == SENSOR_CHAN_ACCEL_Y) || (chan == SENSOR_CHAN_ACCEL_Z)) {
893 icm42670_accel_config(drv_data, attr, val);
894
895 } else if ((chan == SENSOR_CHAN_GYRO_XYZ) || (chan == SENSOR_CHAN_GYRO_X) ||
896 (chan == SENSOR_CHAN_GYRO_Y) || (chan == SENSOR_CHAN_GYRO_Z)) {
897 icm42670_gyro_config(drv_data, attr, val);
898
899 } else {
900 LOG_ERR("Unsupported channel");
901 (void)drv_data;
902 return -EINVAL;
903 }
904
905 icm42670_unlock(dev);
906
907 return 0;
908 }
909
icm42670_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)910 static int icm42670_attr_get(const struct device *dev, enum sensor_channel chan,
911 enum sensor_attribute attr, struct sensor_value *val)
912 {
913 const struct icm42670_data *data = dev->data;
914 const struct icm42670_config *cfg = dev->config;
915 int res = 0;
916
917 __ASSERT_NO_MSG(val != NULL);
918
919 icm42670_lock(dev);
920
921 switch (chan) {
922 case SENSOR_CHAN_ACCEL_X:
923 case SENSOR_CHAN_ACCEL_Y:
924 case SENSOR_CHAN_ACCEL_Z:
925 case SENSOR_CHAN_ACCEL_XYZ:
926 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
927 val->val1 = data->accel_hz;
928 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
929 val->val1 = data->accel_fs;
930 } else {
931 LOG_ERR("Unsupported attribute");
932 res = -EINVAL;
933 }
934 break;
935
936 case SENSOR_CHAN_GYRO_X:
937 case SENSOR_CHAN_GYRO_Y:
938 case SENSOR_CHAN_GYRO_Z:
939 case SENSOR_CHAN_GYRO_XYZ:
940 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
941 val->val1 = data->gyro_hz;
942 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
943 val->val1 = data->gyro_fs;
944 } else {
945 LOG_ERR("Unsupported attribute");
946 res = -EINVAL;
947 }
948 break;
949
950 case SENSOR_CHAN_APEX_MOTION:
951 if (attr == SENSOR_ATTR_CONFIGURATION) {
952 val->val1 = cfg->apex;
953 }
954 break;
955
956 default:
957 LOG_ERR("Unsupported channel");
958 res = -EINVAL;
959 break;
960 }
961
962 icm42670_unlock(dev);
963
964 return res;
965 }
966
icm42670_bus_check(const struct device * dev)967 static inline int icm42670_bus_check(const struct device *dev)
968 {
969 const struct icm42670_config *cfg = dev->config;
970
971 return cfg->bus_io->check(&cfg->bus);
972 }
973
icm42670_init(const struct device * dev)974 static int icm42670_init(const struct device *dev)
975 {
976 struct icm42670_data *data = dev->data;
977 int res = 0;
978
979 if (icm42670_bus_check(dev) < 0) {
980 LOG_ERR("bus check failed");
981 return -ENODEV;
982 }
983
984 data->accel_x = 0;
985 data->accel_y = 0;
986 data->accel_z = 0;
987 data->gyro_x = 0;
988 data->gyro_y = 0;
989 data->gyro_z = 0;
990 data->temp = 0;
991
992 if (icm42670_sensor_init(dev)) {
993 LOG_ERR("could not initialize sensor");
994 return -EIO;
995 }
996
997 #ifdef CONFIG_ICM42670_TRIGGER
998 res |= icm42670_trigger_enable_interrupt(dev);
999 res |= icm42670_trigger_init(dev);
1000 if (res < 0) {
1001 LOG_ERR("Failed to initialize interrupt.");
1002 return res;
1003 }
1004 #endif
1005
1006 res |= icm42670_turn_on_sensor(dev);
1007
1008 return res;
1009 }
1010
1011 #ifndef CONFIG_ICM42670_TRIGGER
1012
icm42670_lock(const struct device * dev)1013 void icm42670_lock(const struct device *dev)
1014 {
1015 ARG_UNUSED(dev);
1016 }
1017
icm42670_unlock(const struct device * dev)1018 void icm42670_unlock(const struct device *dev)
1019 {
1020 ARG_UNUSED(dev);
1021 }
1022
1023 #endif
1024
1025 static DEVICE_API(sensor, icm42670_driver_api) = {
1026 #ifdef CONFIG_ICM42670_TRIGGER
1027 .trigger_set = icm42670_trigger_set,
1028 #endif
1029 .sample_fetch = icm42670_sample_fetch,
1030 .channel_get = icm42670_channel_get,
1031 .attr_set = icm42670_attr_set,
1032 .attr_get = icm42670_attr_get,
1033 };
1034
1035 /* device defaults to spi mode 0/3 support */
1036 #define ICM42670_SPI_CFG (SPI_WORD_SET(8) | SPI_TRANSFER_MSB | SPI_MODE_CPOL | SPI_MODE_CPHA)
1037
1038 /* Initializes a common struct icm42670_config */
1039 #define ICM42670_CONFIG_COMMON(inst) \
1040 IF_ENABLED(CONFIG_ICM42670_TRIGGER, \
1041 (.gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, {0}),)) \
1042 .accel_fs = DT_INST_ENUM_IDX(inst, accel_fs), \
1043 .accel_hz = DT_INST_ENUM_IDX(inst, accel_hz), \
1044 .accel_avg = DT_INST_ENUM_IDX(inst, accel_avg), \
1045 .accel_filt_bw = DT_INST_ENUM_IDX(inst, accel_filt_bw_hz), \
1046 .gyro_fs = DT_INST_ENUM_IDX(inst, gyro_fs), \
1047 .gyro_hz = DT_INST_ENUM_IDX(inst, gyro_hz), \
1048 .gyro_filt_bw = DT_INST_ENUM_IDX(inst, gyro_filt_bw_hz), \
1049 .accel_pwr_mode = DT_INST_ENUM_IDX(inst, power_mode), \
1050 .apex = DT_INST_ENUM_IDX(inst, apex),
1051
1052 /* Initializes the bus members for an instance on a SPI bus. */
1053 #define ICM42670_CONFIG_SPI(inst) \
1054 {.bus.spi = SPI_DT_SPEC_INST_GET(inst, ICM42670_SPI_CFG, 0), \
1055 .bus_io = &icm42670_bus_io_spi, \
1056 ICM42670_CONFIG_COMMON(inst)}
1057
1058 /* Initializes the bus members for an instance on an I2C bus. */
1059 #define ICM42670_CONFIG_I2C(inst) \
1060 {.bus.i2c = I2C_DT_SPEC_INST_GET(inst), \
1061 .bus_io = &icm42670_bus_io_i2c, \
1062 ICM42670_CONFIG_COMMON(inst)}
1063
1064 /*
1065 * Main instantiation macro, which selects the correct bus-specific
1066 * instantiation macros for the instance.
1067 */
1068 #define ICM42670_DEFINE(inst, name, whoami) \
1069 static struct icm42670_data icm42670_data_##inst = { \
1070 .imu_name = name, \
1071 .imu_whoami = whoami, \
1072 }; \
1073 static const struct icm42670_config icm42670_config_##inst = \
1074 COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
1075 (ICM42670_CONFIG_SPI(inst)), \
1076 (ICM42670_CONFIG_I2C(inst))); \
1077 SENSOR_DEVICE_DT_INST_DEFINE(inst, icm42670_init, NULL, &icm42670_data_##inst, \
1078 &icm42670_config_##inst, POST_KERNEL, \
1079 CONFIG_SENSOR_INIT_PRIORITY, &icm42670_driver_api);
1080
1081 #define DT_DRV_COMPAT invensense_icm42670p
1082 #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
1083 DT_INST_FOREACH_STATUS_OKAY_VARGS(ICM42670_DEFINE, INV_ICM42670P_STRING_ID, INV_ICM42670P_WHOAMI);
1084 #endif
1085 #undef DT_DRV_COMPAT
1086
1087 #define DT_DRV_COMPAT invensense_icm42670s
1088 #if DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT)
1089 DT_INST_FOREACH_STATUS_OKAY_VARGS(ICM42670_DEFINE, INV_ICM42670S_STRING_ID, INV_ICM42670S_WHOAMI);
1090 #endif
1091