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