1 /*
2 * Copyright (c) 2022 Esco Medical ApS
3 * Copyright (c) 2020 TDK Invensense
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #define DT_DRV_COMPAT invensense_icm42670
9
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/drivers/spi.h>
12 #include <zephyr/sys/byteorder.h>
13 #include "icm42670.h"
14 #include "icm42670_reg.h"
15 #include "icm42670_spi.h"
16 #include "icm42670_trigger.h"
17
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(ICM42670, CONFIG_SENSOR_LOG_LEVEL);
20
21 /*
22 * Gyro FS to scaling factor mapping.
23 * See datasheet section 3.1 for details
24 */
25 static const uint16_t icm42670_gyro_sensitivity_x10[] = {
26 164, /* BIT_GYRO_UI_FS_2000 */
27 328, /* BIT_GYRO_UI_FS_1000 */
28 655, /* BIT_GYRO_UI_FS_500 */
29 1310, /* BIT_GYRO_UI_FS_250 */
30 };
31
icm42670_set_accel_fs(const struct device * dev,uint16_t fs)32 static int icm42670_set_accel_fs(const struct device *dev, uint16_t fs)
33 {
34 const struct icm42670_config *cfg = dev->config;
35 struct icm42670_data *data = dev->data;
36 uint8_t temp;
37
38 if ((fs > 16) || (fs < 2)) {
39 LOG_ERR("Unsupported range");
40 return -ENOTSUP;
41 }
42
43 if (fs > 8) {
44 temp = BIT_ACCEL_UI_FS_16;
45 } else if (fs > 4) {
46 temp = BIT_ACCEL_UI_FS_8;
47 } else if (fs > 2) {
48 temp = BIT_ACCEL_UI_FS_4;
49 } else {
50 temp = BIT_ACCEL_UI_FS_2;
51 }
52
53 data->accel_sensitivity_shift = MIN_ACCEL_SENS_SHIFT + temp;
54
55 return icm42670_spi_update_register(&cfg->spi, REG_ACCEL_CONFIG0,
56 (uint8_t)MASK_ACCEL_UI_FS_SEL, temp);
57 }
58
icm42670_set_gyro_fs(const struct device * dev,uint16_t fs)59 static int icm42670_set_gyro_fs(const struct device *dev, uint16_t fs)
60 {
61 const struct icm42670_config *cfg = dev->config;
62 struct icm42670_data *data = dev->data;
63 uint8_t temp;
64
65 if ((fs > 2000) || (fs < 250)) {
66 LOG_ERR("Unsupported range");
67 return -ENOTSUP;
68 }
69
70 if (fs > 1000) {
71 temp = BIT_GYRO_UI_FS_2000;
72 } else if (fs > 500) {
73 temp = BIT_GYRO_UI_FS_1000;
74 } else if (fs > 250) {
75 temp = BIT_GYRO_UI_FS_500;
76 } else {
77 temp = BIT_GYRO_UI_FS_250;
78 }
79
80 data->gyro_sensitivity_x10 = icm42670_gyro_sensitivity_x10[temp];
81
82 return icm42670_spi_update_register(&cfg->spi, REG_GYRO_CONFIG0,
83 (uint8_t)MASK_GYRO_UI_FS_SEL, temp);
84 }
85
icm42670_set_accel_odr(const struct device * dev,uint16_t rate)86 static int icm42670_set_accel_odr(const struct device *dev, uint16_t rate)
87 {
88 const struct icm42670_config *cfg = dev->config;
89 uint8_t temp;
90
91 if ((rate > 1600) || (rate < 1)) {
92 LOG_ERR("Unsupported frequency");
93 return -ENOTSUP;
94 }
95
96 if (rate > 800) {
97 temp = BIT_ACCEL_ODR_1600;
98 } else if (rate > 400) {
99 temp = BIT_ACCEL_ODR_800;
100 } else if (rate > 200) {
101 temp = BIT_ACCEL_ODR_400;
102 } else if (rate > 100) {
103 temp = BIT_ACCEL_ODR_200;
104 } else if (rate > 50) {
105 temp = BIT_ACCEL_ODR_100;
106 } else if (rate > 25) {
107 temp = BIT_ACCEL_ODR_50;
108 } else if (rate > 12) {
109 temp = BIT_ACCEL_ODR_25;
110 } else if (rate > 6) {
111 temp = BIT_ACCEL_ODR_12;
112 } else if (rate > 3) {
113 temp = BIT_ACCEL_ODR_6;
114 } else if (rate > 1) {
115 temp = BIT_ACCEL_ODR_3;
116 } else {
117 temp = BIT_ACCEL_ODR_1;
118 }
119
120 return icm42670_spi_update_register(&cfg->spi, REG_ACCEL_CONFIG0, (uint8_t)MASK_ACCEL_ODR,
121 temp);
122 }
123
icm42670_set_gyro_odr(const struct device * dev,uint16_t rate)124 static int icm42670_set_gyro_odr(const struct device *dev, uint16_t rate)
125 {
126 const struct icm42670_config *cfg = dev->config;
127 uint8_t temp;
128
129 if ((rate > 1600) || (rate < 12)) {
130 LOG_ERR("Unsupported frequency");
131 return -ENOTSUP;
132 }
133
134 if (rate > 800) {
135 temp = BIT_GYRO_ODR_1600;
136 } else if (rate > 400) {
137 temp = BIT_GYRO_ODR_800;
138 } else if (rate > 200) {
139 temp = BIT_GYRO_ODR_400;
140 } else if (rate > 100) {
141 temp = BIT_GYRO_ODR_200;
142 } else if (rate > 50) {
143 temp = BIT_GYRO_ODR_100;
144 } else if (rate > 25) {
145 temp = BIT_GYRO_ODR_50;
146 } else if (rate > 12) {
147 temp = BIT_GYRO_ODR_25;
148 } else {
149 temp = BIT_GYRO_ODR_12;
150 }
151
152 return icm42670_spi_update_register(&cfg->spi, REG_GYRO_CONFIG0, (uint8_t)MASK_GYRO_ODR,
153 temp);
154 }
155
icm42670_enable_mclk(const struct device * dev)156 static int icm42670_enable_mclk(const struct device *dev)
157 {
158 const struct icm42670_config *cfg = dev->config;
159
160 /* switch on MCLK by setting the IDLE bit */
161 int res = icm42670_spi_single_write(&cfg->spi, REG_PWR_MGMT0, BIT_IDLE);
162
163 if (res) {
164 return res;
165 }
166
167 /* wait for the MCLK to stabilize by polling MCLK_RDY register */
168 for (int i = 0; i < MCLK_POLL_ATTEMPTS; i++) {
169 uint8_t value = 0;
170
171 k_usleep(MCLK_POLL_INTERVAL_US);
172 res = icm42670_spi_read(&cfg->spi, REG_MCLK_RDY, &value, 1);
173
174 if (res) {
175 return res;
176 }
177
178 if (FIELD_GET(BIT_MCLK_RDY, value)) {
179 return 0;
180 }
181 }
182
183 return -EIO;
184 }
185
icm42670_sensor_init(const struct device * dev)186 static int icm42670_sensor_init(const struct device *dev)
187 {
188 int res;
189 uint8_t value;
190 const struct icm42670_config *cfg = dev->config;
191
192 /* start up time for register read/write after POR is 1ms and supply ramp time is 3ms */
193 k_msleep(3);
194
195 /* perform a soft reset to ensure a clean slate, reset bit will auto-clear */
196 res = icm42670_spi_single_write(&cfg->spi, REG_SIGNAL_PATH_RESET, BIT_SOFT_RESET);
197
198 if (res) {
199 LOG_ERR("write REG_SIGNAL_PATH_RESET failed");
200 return res;
201 }
202
203 /* wait for soft reset to take effect */
204 k_msleep(SOFT_RESET_TIME_MS);
205
206 /* force SPI-4w hardware configuration (so that next read is correct) */
207 res = icm42670_spi_single_write(&cfg->spi, REG_DEVICE_CONFIG, BIT_SPI_AP_4WIRE);
208
209 if (res) {
210 return res;
211 }
212
213 /* always use internal RC oscillator */
214 res = icm42670_spi_single_write(&cfg->spi, REG_INTF_CONFIG1,
215 (uint8_t)FIELD_PREP(MASK_CLKSEL, BIT_CLKSEL_INT_RC));
216
217 if (res) {
218 return res;
219 }
220
221 /* clear reset done int flag */
222 res = icm42670_spi_read(&cfg->spi, REG_INT_STATUS, &value, 1);
223
224 if (res) {
225 return res;
226 }
227
228 if (FIELD_GET(BIT_STATUS_RESET_DONE_INT, value) != 1) {
229 LOG_ERR("unexpected RESET_DONE_INT value, %i", value);
230 return -EINVAL;
231 }
232
233 /* enable the master clock to ensure proper operation */
234 res = icm42670_enable_mclk(dev);
235
236 if (res) {
237 return res;
238 }
239
240 res = icm42670_spi_read(&cfg->spi, REG_WHO_AM_I, &value, 1);
241
242 if (res) {
243 return res;
244 }
245
246 if (value != WHO_AM_I_ICM42670) {
247 LOG_ERR("invalid WHO_AM_I value, was %i but expected %i", value, WHO_AM_I_ICM42670);
248 return -EINVAL;
249 }
250
251 LOG_DBG("device id: 0x%02X", value);
252
253 return 0;
254 }
255
icm42670_turn_on_sensor(const struct device * dev)256 static int icm42670_turn_on_sensor(const struct device *dev)
257 {
258 struct icm42670_data *data = dev->data;
259 const struct icm42670_config *cfg = dev->config;
260 uint8_t value;
261 int res;
262
263 value = FIELD_PREP(MASK_ACCEL_MODE, BIT_ACCEL_MODE_LNM) |
264 FIELD_PREP(MASK_GYRO_MODE, BIT_GYRO_MODE_LNM);
265
266 res = icm42670_spi_update_register(&cfg->spi, REG_PWR_MGMT0,
267 (uint8_t)(MASK_ACCEL_MODE | MASK_GYRO_MODE), value);
268
269 if (res) {
270 return res;
271 }
272
273 res = icm42670_set_accel_fs(dev, data->accel_fs);
274
275 if (res) {
276 return res;
277 }
278
279 res = icm42670_set_accel_odr(dev, data->accel_hz);
280
281 if (res) {
282 return res;
283 }
284
285 res = icm42670_set_gyro_fs(dev, data->gyro_fs);
286
287 if (res) {
288 return res;
289 }
290
291 res = icm42670_set_gyro_odr(dev, data->gyro_hz);
292
293 if (res) {
294 return res;
295 }
296
297 /*
298 * Accelerometer sensor need at least 10ms startup time
299 * Gyroscope sensor need at least 30ms startup time
300 */
301 k_msleep(100);
302
303 return 0;
304 }
305
icm42670_convert_accel(struct sensor_value * val,int16_t raw_val,uint16_t sensitivity_shift)306 static void icm42670_convert_accel(struct sensor_value *val, int16_t raw_val,
307 uint16_t sensitivity_shift)
308 {
309 /* see datasheet section 3.2 for details */
310 int64_t conv_val = ((int64_t)raw_val * SENSOR_G) >> sensitivity_shift;
311
312 val->val1 = conv_val / 1000000LL;
313 val->val2 = conv_val % 1000000LL;
314 }
315
icm42670_convert_gyro(struct sensor_value * val,int16_t raw_val,uint16_t sensitivity_x10)316 static void icm42670_convert_gyro(struct sensor_value *val, int16_t raw_val,
317 uint16_t sensitivity_x10)
318 {
319 /* see datasheet section 3.1 for details */
320 int64_t conv_val = ((int64_t)raw_val * SENSOR_PI * 10) / (sensitivity_x10 * 180LL);
321
322 val->val1 = conv_val / 1000000LL;
323 val->val2 = conv_val % 1000000LL;
324 }
325
icm42670_convert_temp(struct sensor_value * val,int16_t raw_val)326 static inline void icm42670_convert_temp(struct sensor_value *val, int16_t raw_val)
327 {
328 /* see datasheet section 15.9 for details */
329 val->val1 = (((int64_t)raw_val * 100) / 12800) + 25;
330 val->val2 = ((((int64_t)raw_val * 100) % 12800) * 1000000) / 12800;
331
332 if (val->val2 < 0) {
333 val->val1--;
334 val->val2 += 1000000;
335 } else if (val->val2 >= 1000000) {
336 val->val1++;
337 val->val2 -= 1000000;
338 }
339 }
340
icm42670_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)341 static int icm42670_channel_get(const struct device *dev, enum sensor_channel chan,
342 struct sensor_value *val)
343 {
344 int res = 0;
345 const struct icm42670_data *data = dev->data;
346
347 icm42670_lock(dev);
348
349 switch (chan) {
350 case SENSOR_CHAN_ACCEL_XYZ:
351 icm42670_convert_accel(&val[0], data->accel_x, data->accel_sensitivity_shift);
352 icm42670_convert_accel(&val[1], data->accel_y, data->accel_sensitivity_shift);
353 icm42670_convert_accel(&val[2], data->accel_z, data->accel_sensitivity_shift);
354 break;
355 case SENSOR_CHAN_ACCEL_X:
356 icm42670_convert_accel(val, data->accel_x, data->accel_sensitivity_shift);
357 break;
358 case SENSOR_CHAN_ACCEL_Y:
359 icm42670_convert_accel(val, data->accel_y, data->accel_sensitivity_shift);
360 break;
361 case SENSOR_CHAN_ACCEL_Z:
362 icm42670_convert_accel(val, data->accel_z, data->accel_sensitivity_shift);
363 break;
364 case SENSOR_CHAN_GYRO_XYZ:
365 icm42670_convert_gyro(&val[0], data->gyro_x, data->gyro_sensitivity_x10);
366 icm42670_convert_gyro(&val[1], data->gyro_y, data->gyro_sensitivity_x10);
367 icm42670_convert_gyro(&val[2], data->gyro_z, data->gyro_sensitivity_x10);
368 break;
369 case SENSOR_CHAN_GYRO_X:
370 icm42670_convert_gyro(val, data->gyro_x, data->gyro_sensitivity_x10);
371 break;
372 case SENSOR_CHAN_GYRO_Y:
373 icm42670_convert_gyro(val, data->gyro_y, data->gyro_sensitivity_x10);
374 break;
375 case SENSOR_CHAN_GYRO_Z:
376 icm42670_convert_gyro(val, data->gyro_z, data->gyro_sensitivity_x10);
377 break;
378 case SENSOR_CHAN_DIE_TEMP:
379 icm42670_convert_temp(val, data->temp);
380 break;
381 default:
382 res = -ENOTSUP;
383 break;
384 }
385
386 icm42670_unlock(dev);
387
388 return res;
389 }
390
icm42670_sample_fetch_accel(const struct device * dev)391 static int icm42670_sample_fetch_accel(const struct device *dev)
392 {
393 const struct icm42670_config *cfg = dev->config;
394 struct icm42670_data *data = dev->data;
395 uint8_t buffer[ACCEL_DATA_SIZE];
396
397 int res = icm42670_spi_read(&cfg->spi, REG_ACCEL_DATA_X1, buffer, ACCEL_DATA_SIZE);
398
399 if (res) {
400 return res;
401 }
402
403 data->accel_x = (int16_t)sys_get_be16(&buffer[0]);
404 data->accel_y = (int16_t)sys_get_be16(&buffer[2]);
405 data->accel_z = (int16_t)sys_get_be16(&buffer[4]);
406
407 return 0;
408 }
409
icm42670_sample_fetch_gyro(const struct device * dev)410 static int icm42670_sample_fetch_gyro(const struct device *dev)
411 {
412 const struct icm42670_config *cfg = dev->config;
413 struct icm42670_data *data = dev->data;
414 uint8_t buffer[GYRO_DATA_SIZE];
415
416 int res = icm42670_spi_read(&cfg->spi, REG_GYRO_DATA_X1, buffer, GYRO_DATA_SIZE);
417
418 if (res) {
419 return res;
420 }
421
422 data->gyro_x = (int16_t)sys_get_be16(&buffer[0]);
423 data->gyro_y = (int16_t)sys_get_be16(&buffer[2]);
424 data->gyro_z = (int16_t)sys_get_be16(&buffer[4]);
425
426 return 0;
427 }
428
icm42670_sample_fetch_temp(const struct device * dev)429 static int icm42670_sample_fetch_temp(const struct device *dev)
430 {
431 const struct icm42670_config *cfg = dev->config;
432 struct icm42670_data *data = dev->data;
433 uint8_t buffer[TEMP_DATA_SIZE];
434
435 int res = icm42670_spi_read(&cfg->spi, REG_TEMP_DATA1, buffer, TEMP_DATA_SIZE);
436
437 if (res) {
438 return res;
439 }
440
441 data->temp = (int16_t)sys_get_be16(&buffer[0]);
442
443 return 0;
444 }
445
icm42670_sample_fetch(const struct device * dev,enum sensor_channel chan)446 static int icm42670_sample_fetch(const struct device *dev, enum sensor_channel chan)
447 {
448 uint8_t status;
449 const struct icm42670_config *cfg = dev->config;
450
451 icm42670_lock(dev);
452
453 int res = icm42670_spi_read(&cfg->spi, REG_INT_STATUS_DRDY, &status, 1);
454
455 if (res) {
456 goto cleanup;
457 }
458
459 if (!FIELD_GET(BIT_INT_STATUS_DATA_DRDY, status)) {
460 res = -EBUSY;
461 goto cleanup;
462 }
463
464 switch (chan) {
465 case SENSOR_CHAN_ALL:
466 res |= icm42670_sample_fetch_accel(dev);
467 res |= icm42670_sample_fetch_gyro(dev);
468 res |= icm42670_sample_fetch_temp(dev);
469 break;
470 case SENSOR_CHAN_ACCEL_XYZ:
471 case SENSOR_CHAN_ACCEL_X:
472 case SENSOR_CHAN_ACCEL_Y:
473 case SENSOR_CHAN_ACCEL_Z:
474 res = icm42670_sample_fetch_accel(dev);
475 break;
476 case SENSOR_CHAN_GYRO_XYZ:
477 case SENSOR_CHAN_GYRO_X:
478 case SENSOR_CHAN_GYRO_Y:
479 case SENSOR_CHAN_GYRO_Z:
480 res = icm42670_sample_fetch_gyro(dev);
481 break;
482 case SENSOR_CHAN_DIE_TEMP:
483 res = icm42670_sample_fetch_temp(dev);
484 break;
485 default:
486 res = -ENOTSUP;
487 break;
488 }
489
490 cleanup:
491 icm42670_unlock(dev);
492 return res;
493 }
494
icm42670_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)495 static int icm42670_attr_set(const struct device *dev, enum sensor_channel chan,
496 enum sensor_attribute attr, const struct sensor_value *val)
497 {
498 int res = 0;
499 struct icm42670_data *data = dev->data;
500
501 __ASSERT_NO_MSG(val != NULL);
502
503 icm42670_lock(dev);
504
505 switch (chan) {
506 case SENSOR_CHAN_ACCEL_X:
507 case SENSOR_CHAN_ACCEL_Y:
508 case SENSOR_CHAN_ACCEL_Z:
509 case SENSOR_CHAN_ACCEL_XYZ:
510 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
511 res = icm42670_set_accel_odr(dev, data->accel_hz);
512
513 if (res) {
514 LOG_ERR("Incorrect sampling value");
515 } else {
516 data->accel_hz = val->val1;
517 }
518 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
519 res = icm42670_set_accel_fs(dev, data->accel_fs);
520
521 if (res) {
522 LOG_ERR("Incorrect fullscale value");
523 } else {
524 data->accel_fs = val->val1;
525 }
526 } else {
527 LOG_ERR("Unsupported attribute");
528 res = -ENOTSUP;
529 }
530 break;
531
532 case SENSOR_CHAN_GYRO_X:
533 case SENSOR_CHAN_GYRO_Y:
534 case SENSOR_CHAN_GYRO_Z:
535 case SENSOR_CHAN_GYRO_XYZ:
536 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
537 res = icm42670_set_gyro_odr(dev, data->gyro_hz);
538
539 if (res) {
540 LOG_ERR("Incorrect sampling value");
541 } else {
542 data->gyro_hz = val->val1;
543 }
544 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
545 res = icm42670_set_gyro_fs(dev, data->gyro_fs);
546
547 if (res) {
548 LOG_ERR("Incorrect fullscale value");
549 } else {
550 data->gyro_fs = val->val1;
551 }
552 } else {
553 LOG_ERR("Unsupported attribute");
554 res = -EINVAL;
555 }
556 break;
557
558 default:
559 LOG_ERR("Unsupported channel");
560 res = -EINVAL;
561 break;
562 }
563
564 icm42670_unlock(dev);
565
566 return res;
567 }
568
icm42670_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)569 static int icm42670_attr_get(const struct device *dev, enum sensor_channel chan,
570 enum sensor_attribute attr, struct sensor_value *val)
571 {
572 const struct icm42670_data *data = dev->data;
573 int res = 0;
574
575 __ASSERT_NO_MSG(val != NULL);
576
577 icm42670_lock(dev);
578
579 switch (chan) {
580 case SENSOR_CHAN_ACCEL_X:
581 case SENSOR_CHAN_ACCEL_Y:
582 case SENSOR_CHAN_ACCEL_Z:
583 case SENSOR_CHAN_ACCEL_XYZ:
584 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
585 val->val1 = data->accel_hz;
586 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
587 val->val1 = data->accel_fs;
588 } else {
589 LOG_ERR("Unsupported attribute");
590 res = -EINVAL;
591 }
592 break;
593
594 case SENSOR_CHAN_GYRO_X:
595 case SENSOR_CHAN_GYRO_Y:
596 case SENSOR_CHAN_GYRO_Z:
597 case SENSOR_CHAN_GYRO_XYZ:
598 if (attr == SENSOR_ATTR_SAMPLING_FREQUENCY) {
599 val->val1 = data->gyro_hz;
600 } else if (attr == SENSOR_ATTR_FULL_SCALE) {
601 val->val1 = data->gyro_fs;
602 } else {
603 LOG_ERR("Unsupported attribute");
604 res = -EINVAL;
605 }
606 break;
607
608 default:
609 LOG_ERR("Unsupported channel");
610 res = -EINVAL;
611 break;
612 }
613
614 icm42670_unlock(dev);
615
616 return res;
617 }
618
icm42670_init(const struct device * dev)619 static int icm42670_init(const struct device *dev)
620 {
621 struct icm42670_data *data = dev->data;
622 const struct icm42670_config *cfg = dev->config;
623
624 if (!spi_is_ready_dt(&cfg->spi)) {
625 LOG_ERR("SPI bus is not ready");
626 return -ENODEV;
627 }
628
629 data->accel_x = 0;
630 data->accel_y = 0;
631 data->accel_z = 0;
632 data->gyro_x = 0;
633 data->gyro_y = 0;
634 data->gyro_z = 0;
635 data->temp = 0;
636
637 if (icm42670_sensor_init(dev)) {
638 LOG_ERR("could not initialize sensor");
639 return -EIO;
640 }
641
642 #ifdef CONFIG_ICM42670_TRIGGER
643 if (icm42670_trigger_init(dev)) {
644 LOG_ERR("Failed to initialize interrupts.");
645 return -EIO;
646 }
647 #endif
648
649 int res = icm42670_turn_on_sensor(dev);
650
651 #ifdef CONFIG_ICM42670_TRIGGER
652 if (icm42670_trigger_enable_interrupt(dev)) {
653 LOG_ERR("Failed to enable interrupts");
654 return -EIO;
655 }
656 #endif
657
658 return res;
659 }
660
661 #ifndef CONFIG_ICM42670_TRIGGER
662
icm42670_lock(const struct device * dev)663 void icm42670_lock(const struct device *dev)
664 {
665 ARG_UNUSED(dev);
666 }
667
icm42670_unlock(const struct device * dev)668 void icm42670_unlock(const struct device *dev)
669 {
670 ARG_UNUSED(dev);
671 }
672
673 #endif
674
675 static const struct sensor_driver_api icm42670_driver_api = {
676 #ifdef CONFIG_ICM42670_TRIGGER
677 .trigger_set = icm42670_trigger_set,
678 #endif
679 .sample_fetch = icm42670_sample_fetch,
680 .channel_get = icm42670_channel_get,
681 .attr_set = icm42670_attr_set,
682 .attr_get = icm42670_attr_get,
683 };
684
685 /* device defaults to spi mode 0/3 support */
686 #define ICM42670_SPI_CFG \
687 SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_TRANSFER_MSB
688
689 #define ICM42670_INIT(inst) \
690 static struct icm42670_data icm42670_driver_##inst = { \
691 .accel_hz = DT_INST_PROP(inst, accel_hz), \
692 .accel_fs = DT_INST_PROP(inst, accel_fs), \
693 .gyro_hz = DT_INST_PROP(inst, gyro_hz), \
694 .gyro_fs = DT_INST_PROP(inst, gyro_fs), \
695 }; \
696 \
697 static const struct icm42670_config icm42670_cfg_##inst = { \
698 .spi = SPI_DT_SPEC_INST_GET(inst, ICM42670_SPI_CFG, 0U), \
699 .gpio_int = GPIO_DT_SPEC_INST_GET_OR(inst, int_gpios, { 0 }), \
700 }; \
701 \
702 SENSOR_DEVICE_DT_INST_DEFINE(inst, icm42670_init, NULL, &icm42670_driver_##inst, \
703 &icm42670_cfg_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
704 &icm42670_driver_api);
705
706 DT_INST_FOREACH_STATUS_OKAY(ICM42670_INIT)
707