1 /* ST Microelectronics LSM6DSV16X 6-axis IMU sensor driver
2 *
3 * Copyright (c) 2023 STMicroelectronics
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Datasheet:
8 * https://www.st.com/resource/en/datasheet/lsm6dsv16x.pdf
9 */
10
11 #define DT_DRV_COMPAT st_lsm6dsv16x
12
13 #include <zephyr/drivers/sensor.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/device.h>
16 #include <zephyr/init.h>
17 #include <string.h>
18 #include <zephyr/sys/__assert.h>
19 #include <zephyr/logging/log.h>
20
21 #include "lsm6dsv16x.h"
22 #include "lsm6dsv16x_decoder.h"
23 #include "lsm6dsv16x_rtio.h"
24
25 LOG_MODULE_REGISTER(LSM6DSV16X, CONFIG_SENSOR_LOG_LEVEL);
26
27 /*
28 * values taken from lsm6dsv16x_data_rate_t in hal/st module. The mode/accuracy
29 * should be selected through accel-odr property in DT
30 */
31 static const float lsm6dsv16x_odr_map[3][13] = {
32 /* High Accuracy off */
33 {0.0f, 1.875f, 7.5f, 15.0f, 30.0f, 60.0f,
34 120.0f, 240.0f, 480.0f, 960.0f, 1920.0f,
35 3840.0f, 7680.0f},
36
37 /* High Accuracy 1 */
38 {0.0f, 1.875f, 7.5f, 15.625f, 31.25f, 62.5f,
39 125.0f, 250.0f, 500.0f, 1000.0f, 2000.0f,
40 4000.0f, 8000.0f},
41
42 /* High Accuracy 2 */
43 {0.0f, 1.875f, 7.5f, 12.5f, 25.0f, 50.0f,
44 100.0f, 200.0f, 400.0f, 800.0f, 1600.0f,
45 3200.0f, 6400.0f},
46 };
47
lsm6dsv16x_freq_to_odr_val(const struct device * dev,uint16_t freq)48 static int lsm6dsv16x_freq_to_odr_val(const struct device *dev, uint16_t freq)
49 {
50 const struct lsm6dsv16x_config *cfg = dev->config;
51 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
52 lsm6dsv16x_data_rate_t odr;
53 int8_t mode;
54 size_t i;
55
56 if (lsm6dsv16x_xl_data_rate_get(ctx, &odr) < 0) {
57 return -EINVAL;
58 }
59
60 mode = (odr >> 4) & 0xf;
61
62 for (i = 0; i < ARRAY_SIZE(lsm6dsv16x_odr_map[mode]); i++) {
63 if (freq <= lsm6dsv16x_odr_map[mode][i]) {
64 LOG_DBG("mode: %d - odr: %d", mode, i);
65 return i;
66 }
67 }
68
69 return -EINVAL;
70 }
71
72 static const uint16_t lsm6dsv16x_accel_fs_map[] = {2, 4, 8, 16};
73
lsm6dsv16x_accel_range_to_fs_val(int32_t range)74 static int lsm6dsv16x_accel_range_to_fs_val(int32_t range)
75 {
76 size_t i;
77
78 for (i = 0; i < ARRAY_SIZE(lsm6dsv16x_accel_fs_map); i++) {
79 if (range == lsm6dsv16x_accel_fs_map[i]) {
80 return i;
81 }
82 }
83
84 return -EINVAL;
85 }
86
87 static const uint16_t lsm6dsv16x_gyro_fs_map[] = {125, 250, 500, 1000, 2000, 0, 0,
88 0, 0, 0, 0, 0, 4000};
89 static const uint16_t lsm6dsv16x_gyro_fs_sens[] = {1, 2, 4, 8, 16, 0, 0, 0, 0, 0, 0, 0, 32};
90
lsm6dsv16x_calc_accel_gain(uint8_t fs)91 int lsm6dsv16x_calc_accel_gain(uint8_t fs)
92 {
93 return lsm6dsv16x_accel_fs_map[fs] * GAIN_UNIT_XL / 2;
94 }
95
lsm6dsv16x_calc_gyro_gain(uint8_t fs)96 int lsm6dsv16x_calc_gyro_gain(uint8_t fs)
97 {
98 return lsm6dsv16x_gyro_fs_sens[fs] * GAIN_UNIT_G;
99 }
100
lsm6dsv16x_gyro_range_to_fs_val(int32_t range)101 static int lsm6dsv16x_gyro_range_to_fs_val(int32_t range)
102 {
103 size_t i;
104
105 for (i = 0; i < ARRAY_SIZE(lsm6dsv16x_gyro_fs_map); i++) {
106 if (range == lsm6dsv16x_gyro_fs_map[i]) {
107 return i;
108 }
109 }
110
111 return -EINVAL;
112 }
113
lsm6dsv16x_accel_set_fs_raw(const struct device * dev,uint8_t fs)114 static int lsm6dsv16x_accel_set_fs_raw(const struct device *dev, uint8_t fs)
115 {
116 const struct lsm6dsv16x_config *cfg = dev->config;
117 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
118 struct lsm6dsv16x_data *data = dev->data;
119 lsm6dsv16x_xl_full_scale_t val;
120
121 switch (fs) {
122 case 0:
123 val = LSM6DSV16X_2g;
124 break;
125 case 1:
126 val = LSM6DSV16X_4g;
127 break;
128 case 2:
129 val = LSM6DSV16X_8g;
130 break;
131 case 3:
132 val = LSM6DSV16X_16g;
133 break;
134 default:
135 return -EIO;
136 }
137
138 if (lsm6dsv16x_xl_full_scale_set(ctx, val) < 0) {
139 return -EIO;
140 }
141
142 data->accel_fs = fs;
143
144 return 0;
145 }
146
lsm6dsv16x_accel_set_odr_raw(const struct device * dev,uint8_t odr)147 static int lsm6dsv16x_accel_set_odr_raw(const struct device *dev, uint8_t odr)
148 {
149 const struct lsm6dsv16x_config *cfg = dev->config;
150 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
151 struct lsm6dsv16x_data *data = dev->data;
152
153 if (lsm6dsv16x_xl_data_rate_set(ctx, odr) < 0) {
154 return -EIO;
155 }
156
157 data->accel_freq = odr;
158
159 return 0;
160 }
161
lsm6dsv16x_gyro_set_fs_raw(const struct device * dev,uint8_t fs)162 static int lsm6dsv16x_gyro_set_fs_raw(const struct device *dev, uint8_t fs)
163 {
164 const struct lsm6dsv16x_config *cfg = dev->config;
165 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
166 struct lsm6dsv16x_data *data = dev->data;
167
168 if (lsm6dsv16x_gy_full_scale_set(ctx, fs) < 0) {
169 return -EIO;
170 }
171
172 data->gyro_fs = fs;
173 return 0;
174 }
175
lsm6dsv16x_gyro_set_odr_raw(const struct device * dev,uint8_t odr)176 static int lsm6dsv16x_gyro_set_odr_raw(const struct device *dev, uint8_t odr)
177 {
178 const struct lsm6dsv16x_config *cfg = dev->config;
179 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
180
181 if (lsm6dsv16x_gy_data_rate_set(ctx, odr) < 0) {
182 return -EIO;
183 }
184
185 return 0;
186 }
187
lsm6dsv16x_accel_odr_set(const struct device * dev,uint16_t freq)188 static int lsm6dsv16x_accel_odr_set(const struct device *dev, uint16_t freq)
189 {
190 int odr;
191
192 odr = lsm6dsv16x_freq_to_odr_val(dev, freq);
193 if (odr < 0) {
194 return odr;
195 }
196
197 if (lsm6dsv16x_accel_set_odr_raw(dev, odr) < 0) {
198 LOG_DBG("failed to set accelerometer sampling rate");
199 return -EIO;
200 }
201
202 return 0;
203 }
204
lsm6dsv16x_accel_range_set(const struct device * dev,int32_t range)205 static int lsm6dsv16x_accel_range_set(const struct device *dev, int32_t range)
206 {
207 int fs;
208 struct lsm6dsv16x_data *data = dev->data;
209
210 fs = lsm6dsv16x_accel_range_to_fs_val(range);
211 if (fs < 0) {
212 return fs;
213 }
214
215 if (lsm6dsv16x_accel_set_fs_raw(dev, fs) < 0) {
216 LOG_DBG("failed to set accelerometer full-scale");
217 return -EIO;
218 }
219
220 data->acc_gain = lsm6dsv16x_calc_accel_gain(fs);
221 return 0;
222 }
223
lsm6dsv16x_accel_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)224 static int lsm6dsv16x_accel_config(const struct device *dev,
225 enum sensor_channel chan,
226 enum sensor_attribute attr,
227 const struct sensor_value *val)
228 {
229 const struct lsm6dsv16x_config *cfg = dev->config;
230 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
231 lsm6dsv16x_xl_mode_t mode;
232
233 switch (attr) {
234 case SENSOR_ATTR_FULL_SCALE:
235 return lsm6dsv16x_accel_range_set(dev, sensor_ms2_to_g(val));
236 case SENSOR_ATTR_SAMPLING_FREQUENCY:
237 return lsm6dsv16x_accel_odr_set(dev, val->val1);
238 case SENSOR_ATTR_CONFIGURATION:
239 switch (val->val1) {
240 case 0: /* High Performance */
241 mode = LSM6DSV16X_XL_HIGH_PERFORMANCE_MD;
242 break;
243 case 1: /* High Accuracy */
244 mode = LSM6DSV16X_XL_HIGH_ACCURACY_ODR_MD;
245 break;
246 case 3: /* ODR triggered */
247 mode = LSM6DSV16X_XL_ODR_TRIGGERED_MD;
248 break;
249 case 4: /* Low Power 2 */
250 mode = LSM6DSV16X_XL_LOW_POWER_2_AVG_MD;
251 break;
252 case 5: /* Low Power 4 */
253 mode = LSM6DSV16X_XL_LOW_POWER_4_AVG_MD;
254 break;
255 case 6: /* Low Power 8 */
256 mode = LSM6DSV16X_XL_LOW_POWER_8_AVG_MD;
257 break;
258 case 7: /* Normal */
259 mode = LSM6DSV16X_XL_NORMAL_MD;
260 break;
261 default:
262 return -EIO;
263 }
264
265 return lsm6dsv16x_xl_mode_set(ctx, mode);
266 default:
267 LOG_DBG("Accel attribute not supported.");
268 return -ENOTSUP;
269 }
270
271 return 0;
272 }
273
lsm6dsv16x_gyro_odr_set(const struct device * dev,uint16_t freq)274 static int lsm6dsv16x_gyro_odr_set(const struct device *dev, uint16_t freq)
275 {
276 int odr;
277
278 if (freq < 8) {
279 return -EIO;
280 }
281
282 odr = lsm6dsv16x_freq_to_odr_val(dev, freq);
283 if (odr < 0) {
284 return odr;
285 }
286
287 if (lsm6dsv16x_gyro_set_odr_raw(dev, odr) < 0) {
288 LOG_DBG("failed to set gyroscope sampling rate");
289 return -EIO;
290 }
291
292 return 0;
293 }
294
lsm6dsv16x_gyro_range_set(const struct device * dev,int32_t range)295 static int lsm6dsv16x_gyro_range_set(const struct device *dev, int32_t range)
296 {
297 int fs;
298 struct lsm6dsv16x_data *data = dev->data;
299
300 fs = lsm6dsv16x_gyro_range_to_fs_val(range);
301 if (fs < 0) {
302 return fs;
303 }
304
305 if (lsm6dsv16x_gyro_set_fs_raw(dev, fs) < 0) {
306 LOG_DBG("failed to set gyroscope full-scale");
307 return -EIO;
308 }
309
310 data->gyro_gain = lsm6dsv16x_calc_gyro_gain(fs);
311 return 0;
312 }
313
lsm6dsv16x_gyro_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)314 static int lsm6dsv16x_gyro_config(const struct device *dev,
315 enum sensor_channel chan,
316 enum sensor_attribute attr,
317 const struct sensor_value *val)
318 {
319 const struct lsm6dsv16x_config *cfg = dev->config;
320 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
321 lsm6dsv16x_gy_mode_t mode;
322
323 switch (attr) {
324 case SENSOR_ATTR_FULL_SCALE:
325 return lsm6dsv16x_gyro_range_set(dev, sensor_rad_to_degrees(val));
326 case SENSOR_ATTR_SAMPLING_FREQUENCY:
327 return lsm6dsv16x_gyro_odr_set(dev, val->val1);
328 case SENSOR_ATTR_CONFIGURATION:
329 switch (val->val1) {
330 case 0: /* High Performance */
331 mode = LSM6DSV16X_GY_HIGH_PERFORMANCE_MD;
332 break;
333 case 1: /* High Accuracy */
334 mode = LSM6DSV16X_GY_HIGH_ACCURACY_ODR_MD;
335 break;
336 case 4: /* Sleep */
337 mode = LSM6DSV16X_GY_SLEEP_MD;
338 break;
339 case 5: /* Low Power */
340 mode = LSM6DSV16X_GY_LOW_POWER_MD;
341 break;
342 default:
343 return -EIO;
344 }
345
346 return lsm6dsv16x_gy_mode_set(ctx, mode);
347 default:
348 LOG_DBG("Gyro attribute not supported.");
349 return -ENOTSUP;
350 }
351
352 return 0;
353 }
354
lsm6dsv16x_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)355 static int lsm6dsv16x_attr_set(const struct device *dev,
356 enum sensor_channel chan,
357 enum sensor_attribute attr,
358 const struct sensor_value *val)
359 {
360 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
361 struct lsm6dsv16x_data *data = dev->data;
362 #endif /* CONFIG_LSM6DSV16X_SENSORHUB */
363
364 switch (chan) {
365 case SENSOR_CHAN_ACCEL_XYZ:
366 return lsm6dsv16x_accel_config(dev, chan, attr, val);
367 case SENSOR_CHAN_GYRO_XYZ:
368 return lsm6dsv16x_gyro_config(dev, chan, attr, val);
369 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
370 case SENSOR_CHAN_MAGN_XYZ:
371 case SENSOR_CHAN_PRESS:
372 case SENSOR_CHAN_HUMIDITY:
373 if (!data->shub_inited) {
374 LOG_ERR("shub not inited.");
375 return -ENOTSUP;
376 }
377
378 return lsm6dsv16x_shub_config(dev, chan, attr, val);
379 #endif /* CONFIG_LSM6DSV16X_SENSORHUB */
380 default:
381 LOG_WRN("attr_set() not supported on this channel.");
382 return -ENOTSUP;
383 }
384
385 return 0;
386 }
387
lsm6dsv16x_accel_get_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)388 static int lsm6dsv16x_accel_get_config(const struct device *dev,
389 enum sensor_channel chan,
390 enum sensor_attribute attr,
391 struct sensor_value *val)
392 {
393 const struct lsm6dsv16x_config *cfg = dev->config;
394 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
395 struct lsm6dsv16x_data *data = dev->data;
396
397 switch (attr) {
398 case SENSOR_ATTR_FULL_SCALE:
399 sensor_g_to_ms2(lsm6dsv16x_accel_fs_map[data->accel_fs], val);
400 break;
401 case SENSOR_ATTR_SAMPLING_FREQUENCY: {
402 lsm6dsv16x_data_rate_t odr;
403 int8_t mode;
404
405 if (lsm6dsv16x_xl_data_rate_get(ctx, &odr) < 0) {
406 return -EINVAL;
407 }
408
409 mode = (odr >> 4) & 0xf;
410
411 val->val1 = lsm6dsv16x_odr_map[mode][data->accel_freq];
412 val->val2 = 0;
413 break;
414 }
415 case SENSOR_ATTR_CONFIGURATION: {
416 lsm6dsv16x_xl_mode_t mode;
417
418 lsm6dsv16x_xl_mode_get(ctx, &mode);
419
420 switch (mode) {
421 case LSM6DSV16X_XL_HIGH_PERFORMANCE_MD:
422 val->val1 = 0;
423 break;
424 case LSM6DSV16X_XL_HIGH_ACCURACY_ODR_MD:
425 val->val1 = 1;
426 break;
427 case LSM6DSV16X_XL_ODR_TRIGGERED_MD:
428 val->val1 = 3;
429 break;
430 case LSM6DSV16X_XL_LOW_POWER_2_AVG_MD:
431 val->val1 = 4;
432 break;
433 case LSM6DSV16X_XL_LOW_POWER_4_AVG_MD:
434 val->val1 = 5;
435 break;
436 case LSM6DSV16X_XL_LOW_POWER_8_AVG_MD:
437 val->val1 = 6;
438 break;
439 case LSM6DSV16X_XL_NORMAL_MD:
440 val->val1 = 7;
441 break;
442 default:
443 return -EIO;
444 }
445
446 break;
447 }
448 default:
449 LOG_DBG("Attr attribute not supported.");
450 return -ENOTSUP;
451 }
452
453 return 0;
454 }
455
lsm6dsv16x_gyro_get_config(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)456 static int lsm6dsv16x_gyro_get_config(const struct device *dev,
457 enum sensor_channel chan,
458 enum sensor_attribute attr,
459 struct sensor_value *val)
460 {
461 const struct lsm6dsv16x_config *cfg = dev->config;
462 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
463 struct lsm6dsv16x_data *data = dev->data;
464
465 switch (attr) {
466 case SENSOR_ATTR_FULL_SCALE:
467 sensor_degrees_to_rad(lsm6dsv16x_gyro_fs_map[data->gyro_fs], val);
468 break;
469 case SENSOR_ATTR_SAMPLING_FREQUENCY: {
470 lsm6dsv16x_data_rate_t odr;
471 int8_t mode;
472
473 if (lsm6dsv16x_gy_data_rate_get(ctx, &odr) < 0) {
474 return -EINVAL;
475 }
476
477 mode = (odr >> 4) & 0xf;
478
479 val->val1 = lsm6dsv16x_odr_map[mode][data->gyro_freq];
480 val->val2 = 0;
481 break;
482 }
483 case SENSOR_ATTR_CONFIGURATION: {
484 lsm6dsv16x_gy_mode_t mode;
485
486 lsm6dsv16x_gy_mode_get(ctx, &mode);
487
488 switch (mode) {
489 case LSM6DSV16X_GY_HIGH_PERFORMANCE_MD:
490 val->val1 = 0;
491 break;
492 case LSM6DSV16X_GY_HIGH_ACCURACY_ODR_MD:
493 val->val1 = 1;
494 break;
495 case LSM6DSV16X_GY_SLEEP_MD:
496 val->val1 = 4;
497 break;
498 case LSM6DSV16X_GY_LOW_POWER_MD:
499 val->val1 = 5;
500 break;
501 default:
502 return -EIO;
503 }
504
505 break;
506 }
507 default:
508 LOG_DBG("Gyro attribute not supported.");
509 return -ENOTSUP;
510 }
511
512 return 0;
513 }
514
lsm6dsv16x_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)515 static int lsm6dsv16x_attr_get(const struct device *dev,
516 enum sensor_channel chan,
517 enum sensor_attribute attr,
518 struct sensor_value *val)
519 {
520 switch (chan) {
521 case SENSOR_CHAN_ACCEL_XYZ:
522 return lsm6dsv16x_accel_get_config(dev, chan, attr, val);
523 case SENSOR_CHAN_GYRO_XYZ:
524 return lsm6dsv16x_gyro_get_config(dev, chan, attr, val);
525 default:
526 LOG_WRN("attr_get() not supported on this channel.");
527 return -ENOTSUP;
528 }
529
530 return 0;
531 }
532
lsm6dsv16x_sample_fetch_accel(const struct device * dev)533 static int lsm6dsv16x_sample_fetch_accel(const struct device *dev)
534 {
535 const struct lsm6dsv16x_config *cfg = dev->config;
536 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
537 struct lsm6dsv16x_data *data = dev->data;
538
539 if (lsm6dsv16x_acceleration_raw_get(ctx, data->acc) < 0) {
540 LOG_DBG("Failed to read sample");
541 return -EIO;
542 }
543
544 return 0;
545 }
546
lsm6dsv16x_sample_fetch_gyro(const struct device * dev)547 static int lsm6dsv16x_sample_fetch_gyro(const struct device *dev)
548 {
549 const struct lsm6dsv16x_config *cfg = dev->config;
550 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
551 struct lsm6dsv16x_data *data = dev->data;
552
553 if (lsm6dsv16x_angular_rate_raw_get(ctx, data->gyro) < 0) {
554 LOG_DBG("Failed to read sample");
555 return -EIO;
556 }
557
558 return 0;
559 }
560
561 #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
lsm6dsv16x_sample_fetch_temp(const struct device * dev)562 static int lsm6dsv16x_sample_fetch_temp(const struct device *dev)
563 {
564 const struct lsm6dsv16x_config *cfg = dev->config;
565 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
566 struct lsm6dsv16x_data *data = dev->data;
567
568 if (lsm6dsv16x_temperature_raw_get(ctx, &data->temp_sample) < 0) {
569 LOG_DBG("Failed to read sample");
570 return -EIO;
571 }
572
573 return 0;
574 }
575 #endif
576
577 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
lsm6dsv16x_sample_fetch_shub(const struct device * dev)578 static int lsm6dsv16x_sample_fetch_shub(const struct device *dev)
579 {
580 if (lsm6dsv16x_shub_fetch_external_devs(dev) < 0) {
581 LOG_DBG("failed to read ext shub devices");
582 return -EIO;
583 }
584
585 return 0;
586 }
587 #endif /* CONFIG_LSM6DSV16X_SENSORHUB */
588
lsm6dsv16x_sample_fetch(const struct device * dev,enum sensor_channel chan)589 static int lsm6dsv16x_sample_fetch(const struct device *dev,
590 enum sensor_channel chan)
591 {
592 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
593 struct lsm6dsv16x_data *data = dev->data;
594 #endif /* CONFIG_LSM6DSV16X_SENSORHUB */
595
596 switch (chan) {
597 case SENSOR_CHAN_ACCEL_XYZ:
598 lsm6dsv16x_sample_fetch_accel(dev);
599 break;
600 case SENSOR_CHAN_GYRO_XYZ:
601 lsm6dsv16x_sample_fetch_gyro(dev);
602 break;
603 #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
604 case SENSOR_CHAN_DIE_TEMP:
605 lsm6dsv16x_sample_fetch_temp(dev);
606 break;
607 #endif
608 case SENSOR_CHAN_ALL:
609 lsm6dsv16x_sample_fetch_accel(dev);
610 lsm6dsv16x_sample_fetch_gyro(dev);
611 #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
612 lsm6dsv16x_sample_fetch_temp(dev);
613 #endif
614 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
615 if (data->shub_inited) {
616 lsm6dsv16x_sample_fetch_shub(dev);
617 }
618 #endif
619 break;
620 default:
621 return -ENOTSUP;
622 }
623
624 return 0;
625 }
626
lsm6dsv16x_accel_convert(struct sensor_value * val,int raw_val,uint32_t sensitivity)627 static inline void lsm6dsv16x_accel_convert(struct sensor_value *val, int raw_val,
628 uint32_t sensitivity)
629 {
630 int64_t dval;
631
632 /* Sensitivity is exposed in ug/LSB */
633 /* Convert to m/s^2 */
634 dval = (int64_t)(raw_val) * sensitivity;
635 sensor_ug_to_ms2(dval, val);
636 }
637
lsm6dsv16x_accel_get_channel(enum sensor_channel chan,struct sensor_value * val,struct lsm6dsv16x_data * data,uint32_t sensitivity)638 static inline int lsm6dsv16x_accel_get_channel(enum sensor_channel chan,
639 struct sensor_value *val,
640 struct lsm6dsv16x_data *data,
641 uint32_t sensitivity)
642 {
643 uint8_t i;
644
645 switch (chan) {
646 case SENSOR_CHAN_ACCEL_X:
647 lsm6dsv16x_accel_convert(val, data->acc[0], sensitivity);
648 break;
649 case SENSOR_CHAN_ACCEL_Y:
650 lsm6dsv16x_accel_convert(val, data->acc[1], sensitivity);
651 break;
652 case SENSOR_CHAN_ACCEL_Z:
653 lsm6dsv16x_accel_convert(val, data->acc[2], sensitivity);
654 break;
655 case SENSOR_CHAN_ACCEL_XYZ:
656 for (i = 0; i < 3; i++) {
657 lsm6dsv16x_accel_convert(val++, data->acc[i], sensitivity);
658 }
659 break;
660 default:
661 return -ENOTSUP;
662 }
663
664 return 0;
665 }
666
lsm6dsv16x_accel_channel_get(enum sensor_channel chan,struct sensor_value * val,struct lsm6dsv16x_data * data)667 static int lsm6dsv16x_accel_channel_get(enum sensor_channel chan,
668 struct sensor_value *val,
669 struct lsm6dsv16x_data *data)
670 {
671 return lsm6dsv16x_accel_get_channel(chan, val, data, data->acc_gain);
672 }
673
lsm6dsv16x_gyro_convert(struct sensor_value * val,int raw_val,uint32_t sensitivity)674 static inline void lsm6dsv16x_gyro_convert(struct sensor_value *val, int raw_val,
675 uint32_t sensitivity)
676 {
677 int64_t dval;
678
679 /* Sensitivity is exposed in udps/LSB */
680 /* So, calculate value in 10 udps unit and then to rad/s */
681 dval = (int64_t)(raw_val) * sensitivity / 10;
682 sensor_10udegrees_to_rad(dval, val);
683 }
684
lsm6dsv16x_gyro_get_channel(enum sensor_channel chan,struct sensor_value * val,struct lsm6dsv16x_data * data,uint32_t sensitivity)685 static inline int lsm6dsv16x_gyro_get_channel(enum sensor_channel chan,
686 struct sensor_value *val,
687 struct lsm6dsv16x_data *data,
688 uint32_t sensitivity)
689 {
690 uint8_t i;
691
692 switch (chan) {
693 case SENSOR_CHAN_GYRO_X:
694 lsm6dsv16x_gyro_convert(val, data->gyro[0], sensitivity);
695 break;
696 case SENSOR_CHAN_GYRO_Y:
697 lsm6dsv16x_gyro_convert(val, data->gyro[1], sensitivity);
698 break;
699 case SENSOR_CHAN_GYRO_Z:
700 lsm6dsv16x_gyro_convert(val, data->gyro[2], sensitivity);
701 break;
702 case SENSOR_CHAN_GYRO_XYZ:
703 for (i = 0; i < 3; i++) {
704 lsm6dsv16x_gyro_convert(val++, data->gyro[i], sensitivity);
705 }
706 break;
707 default:
708 return -ENOTSUP;
709 }
710
711 return 0;
712 }
713
lsm6dsv16x_gyro_channel_get(enum sensor_channel chan,struct sensor_value * val,struct lsm6dsv16x_data * data)714 static int lsm6dsv16x_gyro_channel_get(enum sensor_channel chan,
715 struct sensor_value *val,
716 struct lsm6dsv16x_data *data)
717 {
718 return lsm6dsv16x_gyro_get_channel(chan, val, data, data->gyro_gain);
719 }
720
721 #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
lsm6dsv16x_gyro_channel_get_temp(struct sensor_value * val,struct lsm6dsv16x_data * data)722 static void lsm6dsv16x_gyro_channel_get_temp(struct sensor_value *val,
723 struct lsm6dsv16x_data *data)
724 {
725 /* convert units to micro Celsius. Raw temperature samples are
726 * expressed in 256 LSB/deg_C units. And LSB output is 0 at 25 C.
727 */
728 int64_t temp_sample = data->temp_sample;
729 int64_t micro_c = (temp_sample * 1000000LL) / 256;
730
731 val->val1 = (int32_t)(micro_c / 1000000) + 25;
732 val->val2 = (int32_t)(micro_c % 1000000);
733 }
734 #endif
735
736 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
lsm6dsv16x_magn_convert(struct sensor_value * val,int raw_val,uint16_t sensitivity)737 static inline void lsm6dsv16x_magn_convert(struct sensor_value *val, int raw_val,
738 uint16_t sensitivity)
739 {
740 double dval;
741
742 /* Sensitivity is exposed in ugauss/LSB */
743 dval = (double)(raw_val * sensitivity);
744 val->val1 = (int32_t)dval / 1000000;
745 val->val2 = (int32_t)dval % 1000000;
746 }
747
lsm6dsv16x_magn_get_channel(enum sensor_channel chan,struct sensor_value * val,struct lsm6dsv16x_data * data)748 static inline int lsm6dsv16x_magn_get_channel(enum sensor_channel chan,
749 struct sensor_value *val,
750 struct lsm6dsv16x_data *data)
751 {
752 int16_t sample[3];
753 int idx;
754
755 idx = lsm6dsv16x_shub_get_idx(data->dev, SENSOR_CHAN_MAGN_XYZ);
756 if (idx < 0) {
757 LOG_DBG("external magn not supported");
758 return -ENOTSUP;
759 }
760
761
762 sample[0] = (int16_t)(data->ext_data[idx][0] |
763 (data->ext_data[idx][1] << 8));
764 sample[1] = (int16_t)(data->ext_data[idx][2] |
765 (data->ext_data[idx][3] << 8));
766 sample[2] = (int16_t)(data->ext_data[idx][4] |
767 (data->ext_data[idx][5] << 8));
768
769 switch (chan) {
770 case SENSOR_CHAN_MAGN_X:
771 lsm6dsv16x_magn_convert(val, sample[0], data->magn_gain);
772 break;
773 case SENSOR_CHAN_MAGN_Y:
774 lsm6dsv16x_magn_convert(val, sample[1], data->magn_gain);
775 break;
776 case SENSOR_CHAN_MAGN_Z:
777 lsm6dsv16x_magn_convert(val, sample[2], data->magn_gain);
778 break;
779 case SENSOR_CHAN_MAGN_XYZ:
780 lsm6dsv16x_magn_convert(val, sample[0], data->magn_gain);
781 lsm6dsv16x_magn_convert(val + 1, sample[1], data->magn_gain);
782 lsm6dsv16x_magn_convert(val + 2, sample[2], data->magn_gain);
783 break;
784 default:
785 return -ENOTSUP;
786 }
787
788 return 0;
789 }
790
lsm6dsv16x_hum_convert(struct sensor_value * val,struct lsm6dsv16x_data * data)791 static inline void lsm6dsv16x_hum_convert(struct sensor_value *val,
792 struct lsm6dsv16x_data *data)
793 {
794 float rh;
795 int16_t raw_val;
796 struct hts221_data *ht = &data->hts221;
797 int idx;
798
799 idx = lsm6dsv16x_shub_get_idx(data->dev, SENSOR_CHAN_HUMIDITY);
800 if (idx < 0) {
801 LOG_DBG("external press/temp not supported");
802 return;
803 }
804
805 raw_val = (int16_t)(data->ext_data[idx][0] |
806 (data->ext_data[idx][1] << 8));
807
808 /* find relative humidty by linear interpolation */
809 rh = (ht->y1 - ht->y0) * raw_val + ht->x1 * ht->y0 - ht->x0 * ht->y1;
810 rh /= (ht->x1 - ht->x0);
811
812 /* convert humidity to integer and fractional part */
813 val->val1 = rh;
814 val->val2 = rh * 1000000;
815 }
816
lsm6dsv16x_press_convert(struct sensor_value * val,struct lsm6dsv16x_data * data)817 static inline void lsm6dsv16x_press_convert(struct sensor_value *val,
818 struct lsm6dsv16x_data *data)
819 {
820 int32_t raw_val;
821 int idx;
822
823 idx = lsm6dsv16x_shub_get_idx(data->dev, SENSOR_CHAN_PRESS);
824 if (idx < 0) {
825 LOG_DBG("external press/temp not supported");
826 return;
827 }
828
829 raw_val = (int32_t)(data->ext_data[idx][0] |
830 (data->ext_data[idx][1] << 8) |
831 (data->ext_data[idx][2] << 16));
832
833 /* Pressure sensitivity is 4096 LSB/hPa */
834 /* Convert raw_val to val in kPa */
835 val->val1 = (raw_val >> 12) / 10;
836 val->val2 = (raw_val >> 12) % 10 * 100000 +
837 (((int32_t)((raw_val) & 0x0FFF) * 100000L) >> 12);
838 }
839
lsm6dsv16x_temp_convert(struct sensor_value * val,struct lsm6dsv16x_data * data)840 static inline void lsm6dsv16x_temp_convert(struct sensor_value *val,
841 struct lsm6dsv16x_data *data)
842 {
843 int16_t raw_val;
844 int idx;
845
846 idx = lsm6dsv16x_shub_get_idx(data->dev, SENSOR_CHAN_PRESS);
847 if (idx < 0) {
848 LOG_DBG("external press/temp not supported");
849 return;
850 }
851
852 raw_val = (int16_t)(data->ext_data[idx][3] |
853 (data->ext_data[idx][4] << 8));
854
855 /* Temperature sensitivity is 100 LSB/deg C */
856 val->val1 = raw_val / 100;
857 val->val2 = (int32_t)raw_val % 100 * (10000);
858 }
859 #endif
860
lsm6dsv16x_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)861 static int lsm6dsv16x_channel_get(const struct device *dev,
862 enum sensor_channel chan,
863 struct sensor_value *val)
864 {
865 struct lsm6dsv16x_data *data = dev->data;
866
867 switch (chan) {
868 case SENSOR_CHAN_ACCEL_X:
869 case SENSOR_CHAN_ACCEL_Y:
870 case SENSOR_CHAN_ACCEL_Z:
871 case SENSOR_CHAN_ACCEL_XYZ:
872 lsm6dsv16x_accel_channel_get(chan, val, data);
873 break;
874 case SENSOR_CHAN_GYRO_X:
875 case SENSOR_CHAN_GYRO_Y:
876 case SENSOR_CHAN_GYRO_Z:
877 case SENSOR_CHAN_GYRO_XYZ:
878 lsm6dsv16x_gyro_channel_get(chan, val, data);
879 break;
880 #if defined(CONFIG_LSM6DSV16X_ENABLE_TEMP)
881 case SENSOR_CHAN_DIE_TEMP:
882 lsm6dsv16x_gyro_channel_get_temp(val, data);
883 break;
884 #endif
885 #if defined(CONFIG_LSM6DSV16X_SENSORHUB)
886 case SENSOR_CHAN_MAGN_X:
887 case SENSOR_CHAN_MAGN_Y:
888 case SENSOR_CHAN_MAGN_Z:
889 case SENSOR_CHAN_MAGN_XYZ:
890 if (!data->shub_inited) {
891 LOG_ERR("attr_set() shub not inited.");
892 return -ENOTSUP;
893 }
894
895 lsm6dsv16x_magn_get_channel(chan, val, data);
896 break;
897
898 case SENSOR_CHAN_HUMIDITY:
899 if (!data->shub_inited) {
900 LOG_ERR("attr_set() shub not inited.");
901 return -ENOTSUP;
902 }
903
904 lsm6dsv16x_hum_convert(val, data);
905 break;
906
907 case SENSOR_CHAN_PRESS:
908 if (!data->shub_inited) {
909 LOG_ERR("attr_set() shub not inited.");
910 return -ENOTSUP;
911 }
912
913 lsm6dsv16x_press_convert(val, data);
914 break;
915
916 case SENSOR_CHAN_AMBIENT_TEMP:
917 if (!data->shub_inited) {
918 LOG_ERR("attr_set() shub not inited.");
919 return -ENOTSUP;
920 }
921
922 lsm6dsv16x_temp_convert(val, data);
923 break;
924 #endif
925 default:
926 return -ENOTSUP;
927 }
928
929 return 0;
930 }
931
932 static DEVICE_API(sensor, lsm6dsv16x_driver_api) = {
933 .attr_set = lsm6dsv16x_attr_set,
934 .attr_get = lsm6dsv16x_attr_get,
935 #if CONFIG_LSM6DSV16X_TRIGGER
936 .trigger_set = lsm6dsv16x_trigger_set,
937 #endif
938 .sample_fetch = lsm6dsv16x_sample_fetch,
939 .channel_get = lsm6dsv16x_channel_get,
940 #ifdef CONFIG_SENSOR_ASYNC_API
941 .get_decoder = lsm6dsv16x_get_decoder,
942 .submit = lsm6dsv16x_submit,
943 #endif
944 };
945
lsm6dsv16x_init_chip(const struct device * dev)946 static int lsm6dsv16x_init_chip(const struct device *dev)
947 {
948 const struct lsm6dsv16x_config *cfg = dev->config;
949 stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
950 struct lsm6dsv16x_data *lsm6dsv16x = dev->data;
951 uint8_t chip_id;
952 uint8_t odr, fs;
953
954 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
955 if (cfg->i3c.bus != NULL) {
956 /*
957 * Need to grab the pointer to the I3C device descriptor
958 * before we can talk to the sensor.
959 */
960 lsm6dsv16x->i3c_dev = i3c_device_find(cfg->i3c.bus, &cfg->i3c.dev_id);
961 if (lsm6dsv16x->i3c_dev == NULL) {
962 LOG_ERR("Cannot find I3C device descriptor");
963 return -ENODEV;
964 }
965 }
966 #endif
967
968 /* All registers except 0x01 are different between banks, including the WHO_AM_I
969 * register and the register used for a SW reset. If the lsm6dsv16x wasn't on the user
970 * bank when it reset, then both the chip id check and the sw reset will fail unless we
971 * set the bank now.
972 */
973 if (lsm6dsv16x_mem_bank_set(ctx, LSM6DSV16X_MAIN_MEM_BANK) < 0) {
974 LOG_DBG("Failed to set user bank");
975 return -EIO;
976 }
977
978 if (lsm6dsv16x_device_id_get(ctx, &chip_id) < 0) {
979 LOG_DBG("Failed reading chip id");
980 return -EIO;
981 }
982
983 LOG_INF("chip id 0x%x", chip_id);
984
985 if (chip_id != LSM6DSV16X_ID) {
986 LOG_DBG("Invalid chip id 0x%x", chip_id);
987 return -EIO;
988 }
989
990 /* Resetting the whole device while using I3C will also reset the DA, therefore perform
991 * only a software reset if the bus is I3C. It should be assumed that the device was
992 * already fully reset by the I3C CCC RSTACT (whole chip) done as apart of the I3C Bus
993 * initialization.
994 */
995 if (ON_I3C_BUS(cfg)) {
996 /* Restore default configuration */
997 lsm6dsv16x_reset_set(ctx, LSM6DSV16X_RESTORE_CAL_PARAM);
998
999 /* wait 150us as reported in AN5763 */
1000 k_sleep(K_USEC(150));
1001 } else {
1002 /* reset device (sw_por) */
1003 if (lsm6dsv16x_reset_set(ctx, LSM6DSV16X_GLOBAL_RST) < 0) {
1004 return -EIO;
1005 }
1006
1007 /* wait 30ms as reported in AN5763 */
1008 k_sleep(K_MSEC(30));
1009 }
1010
1011 fs = cfg->accel_range;
1012 LOG_DBG("accel range is %d", fs);
1013 if (lsm6dsv16x_accel_set_fs_raw(dev, fs) < 0) {
1014 LOG_ERR("failed to set accelerometer range %d", fs);
1015 return -EIO;
1016 }
1017 lsm6dsv16x->acc_gain = lsm6dsv16x_calc_accel_gain(fs);
1018
1019 odr = cfg->accel_odr;
1020 LOG_DBG("accel odr is %d", odr);
1021 if (lsm6dsv16x_accel_set_odr_raw(dev, odr) < 0) {
1022 LOG_ERR("failed to set accelerometer odr %d", odr);
1023 return -EIO;
1024 }
1025
1026 fs = cfg->gyro_range;
1027 LOG_DBG("gyro range is %d", fs);
1028 if (lsm6dsv16x_gyro_set_fs_raw(dev, fs) < 0) {
1029 LOG_ERR("failed to set gyroscope range %d", fs);
1030 return -EIO;
1031 }
1032 lsm6dsv16x->gyro_gain = lsm6dsv16x_calc_gyro_gain(fs);
1033
1034 odr = cfg->gyro_odr;
1035 LOG_DBG("gyro odr is %d", odr);
1036 lsm6dsv16x->gyro_freq = odr;
1037 if (lsm6dsv16x_gyro_set_odr_raw(dev, odr) < 0) {
1038 LOG_ERR("failed to set gyroscope odr %d", odr);
1039 return -EIO;
1040 }
1041
1042 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i3c)
1043 if (IS_ENABLED(CONFIG_LSM6DSV16X_STREAM) && (ON_I3C_BUS(cfg))) {
1044 /*
1045 * Set MRL to the Max Size of the FIFO so the entire FIFO can be read
1046 * out at once
1047 */
1048 struct i3c_ccc_mrl setmrl = {
1049 .len = 0x0700,
1050 .ibi_len = lsm6dsv16x->i3c_dev->data_length.max_ibi,
1051 };
1052 if (i3c_ccc_do_setmrl(lsm6dsv16x->i3c_dev, &setmrl) < 0) {
1053 LOG_ERR("failed to set mrl");
1054 return -EIO;
1055 }
1056 }
1057 #endif
1058
1059 if (lsm6dsv16x_block_data_update_set(ctx, 1) < 0) {
1060 LOG_DBG("failed to set BDU mode");
1061 return -EIO;
1062 }
1063
1064 return 0;
1065 }
1066
lsm6dsv16x_init(const struct device * dev)1067 static int lsm6dsv16x_init(const struct device *dev)
1068 {
1069 #ifdef CONFIG_LSM6DSV16X_TRIGGER
1070 const struct lsm6dsv16x_config *cfg = dev->config;
1071 #endif
1072 struct lsm6dsv16x_data *data = dev->data;
1073
1074 LOG_INF("Initialize device %s", dev->name);
1075 data->dev = dev;
1076
1077 if (lsm6dsv16x_init_chip(dev) < 0) {
1078 LOG_DBG("failed to initialize chip");
1079 return -EIO;
1080 }
1081
1082 #ifdef CONFIG_LSM6DSV16X_TRIGGER
1083 if (cfg->trig_enabled) {
1084 if (lsm6dsv16x_init_interrupt(dev) < 0) {
1085 LOG_ERR("Failed to initialize interrupt.");
1086 return -EIO;
1087 }
1088 }
1089 #endif
1090
1091 #ifdef CONFIG_LSM6DSV16X_SENSORHUB
1092 data->shub_inited = true;
1093 if (lsm6dsv16x_shub_init(dev) < 0) {
1094 LOG_INF("shub: no external chips found");
1095 data->shub_inited = false;
1096 }
1097 #endif
1098
1099 return 0;
1100 }
1101
1102 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
1103 #warning "LSM6DSV16X driver enabled without any devices"
1104 #endif
1105
1106 /*
1107 * Device creation macro, shared by LSM6DSV16X_DEFINE_SPI() and
1108 * LSM6DSV16X_DEFINE_I2C().
1109 */
1110
1111 #define LSM6DSV16X_DEVICE_INIT(inst) \
1112 SENSOR_DEVICE_DT_INST_DEFINE(inst, \
1113 lsm6dsv16x_init, \
1114 NULL, \
1115 &lsm6dsv16x_data_##inst, \
1116 &lsm6dsv16x_config_##inst, \
1117 POST_KERNEL, \
1118 CONFIG_SENSOR_INIT_PRIORITY, \
1119 &lsm6dsv16x_driver_api);
1120
1121 #ifdef CONFIG_LSM6DSV16X_TRIGGER
1122 #define LSM6DSV16X_CFG_IRQ(inst) \
1123 .trig_enabled = true, \
1124 .int1_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int1_gpios, { 0 }), \
1125 .int2_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, int2_gpios, { 0 }), \
1126 .drdy_pulsed = DT_INST_PROP(inst, drdy_pulsed), \
1127 .drdy_pin = DT_INST_PROP(inst, drdy_pin)
1128 #else
1129 #define LSM6DSV16X_CFG_IRQ(inst)
1130 #endif /* CONFIG_LSM6DSV16X_TRIGGER */
1131
1132 #define LSM6DSV16X_CONFIG_COMMON(inst) \
1133 .accel_odr = DT_INST_PROP(inst, accel_odr), \
1134 .accel_range = DT_INST_PROP(inst, accel_range), \
1135 .gyro_odr = DT_INST_PROP(inst, gyro_odr), \
1136 .gyro_range = DT_INST_PROP(inst, gyro_range), \
1137 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, \
1138 (.fifo_wtm = DT_INST_PROP(inst, fifo_watermark), \
1139 .accel_batch = DT_INST_PROP(inst, accel_fifo_batch_rate), \
1140 .gyro_batch = DT_INST_PROP(inst, gyro_fifo_batch_rate), \
1141 .sflp_odr = DT_INST_PROP(inst, sflp_odr), \
1142 .sflp_fifo_en = DT_INST_PROP(inst, sflp_fifo_enable), \
1143 .temp_batch = DT_INST_PROP(inst, temp_fifo_batch_rate),)) \
1144 IF_ENABLED(UTIL_OR(DT_INST_NODE_HAS_PROP(inst, int1_gpios), \
1145 DT_INST_NODE_HAS_PROP(inst, int2_gpios)), \
1146 (LSM6DSV16X_CFG_IRQ(inst)))
1147
1148 /*
1149 * Instantiation macros used when a device is on a SPI bus.
1150 */
1151
1152 #define LSM6DSV16X_SPI_OP (SPI_WORD_SET(8) | \
1153 SPI_OP_MODE_MASTER | \
1154 SPI_MODE_CPOL | \
1155 SPI_MODE_CPHA) \
1156
1157 #define LSM6DSV16X_SPI_RTIO_DEFINE(inst) \
1158 SPI_DT_IODEV_DEFINE(lsm6dsv16x_iodev_##inst, \
1159 DT_DRV_INST(inst), LSM6DSV16X_SPI_OP, 0U); \
1160 RTIO_DEFINE(lsm6dsv16x_rtio_ctx_##inst, 4, 4);
1161
1162 #define LSM6DSV16X_CONFIG_SPI(inst) \
1163 { \
1164 STMEMSC_CTX_SPI(&lsm6dsv16x_config_##inst.stmemsc_cfg), \
1165 .stmemsc_cfg = { \
1166 .spi = SPI_DT_SPEC_INST_GET(inst, \
1167 LSM6DSV16X_SPI_OP, \
1168 0), \
1169 }, \
1170 LSM6DSV16X_CONFIG_COMMON(inst) \
1171 }
1172
1173 #define LSM6DSV16X_DEFINE_SPI(inst) \
1174 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, (LSM6DSV16X_SPI_RTIO_DEFINE(inst))); \
1175 static struct lsm6dsv16x_data lsm6dsv16x_data_##inst = { \
1176 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, \
1177 (.rtio_ctx = &lsm6dsv16x_rtio_ctx_##inst, \
1178 .iodev = &lsm6dsv16x_iodev_##inst, \
1179 .bus_type = BUS_SPI,)) \
1180 }; \
1181 static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \
1182 LSM6DSV16X_CONFIG_SPI(inst); \
1183
1184 /*
1185 * Instantiation macros used when a device is on an I2C bus.
1186 */
1187
1188 #define LSM6DSV16X_I2C_RTIO_DEFINE(inst) \
1189 I2C_DT_IODEV_DEFINE(lsm6dsv16x_iodev_##inst, DT_DRV_INST(inst));\
1190 RTIO_DEFINE(lsm6dsv16x_rtio_ctx_##inst, 4, 4);
1191
1192 #define LSM6DSV16X_CONFIG_I2C(inst) \
1193 { \
1194 STMEMSC_CTX_I2C(&lsm6dsv16x_config_##inst.stmemsc_cfg), \
1195 .stmemsc_cfg = { \
1196 .i2c = I2C_DT_SPEC_INST_GET(inst), \
1197 }, \
1198 LSM6DSV16X_CONFIG_COMMON(inst) \
1199 }
1200
1201
1202 #define LSM6DSV16X_DEFINE_I2C(inst) \
1203 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, (LSM6DSV16X_I2C_RTIO_DEFINE(inst))); \
1204 static struct lsm6dsv16x_data lsm6dsv16x_data_##inst = { \
1205 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, \
1206 (.rtio_ctx = &lsm6dsv16x_rtio_ctx_##inst, \
1207 .iodev = &lsm6dsv16x_iodev_##inst, \
1208 .bus_type = BUS_I2C,)) \
1209 }; \
1210 static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \
1211 LSM6DSV16X_CONFIG_I2C(inst); \
1212
1213 /*
1214 * Instantiation macros used when a device is on an I3C bus.
1215 */
1216
1217 #define LSM6DSV16X_I3C_RTIO_DEFINE(inst) \
1218 I3C_DT_IODEV_DEFINE(lsm6dsv16x_i3c_iodev_##inst, DT_DRV_INST(inst)); \
1219 RTIO_DEFINE(lsm6dsv16x_rtio_ctx_##inst, 4, 4);
1220
1221 #define LSM6DSV16X_CONFIG_I3C(inst) \
1222 { \
1223 STMEMSC_CTX_I3C(&lsm6dsv16x_config_##inst.stmemsc_cfg), \
1224 .stmemsc_cfg = { \
1225 .i3c = &lsm6dsv16x_data_##inst.i3c_dev, \
1226 }, \
1227 .i3c.bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
1228 .i3c.dev_id = I3C_DEVICE_ID_DT_INST(inst), \
1229 IF_ENABLED(CONFIG_LSM6DSV16X_TRIGGER, \
1230 (.int_en_i3c = DT_INST_PROP(inst, int_en_i3c), \
1231 .bus_act_sel = DT_INST_ENUM_IDX(inst, bus_act_sel_us),)) \
1232 LSM6DSV16X_CONFIG_COMMON(inst) \
1233 }
1234
1235 #define LSM6DSV16X_DEFINE_I3C(inst) \
1236 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, (LSM6DSV16X_I3C_RTIO_DEFINE(inst))); \
1237 static struct lsm6dsv16x_data lsm6dsv16x_data_##inst = { \
1238 IF_ENABLED(CONFIG_LSM6DSV16X_STREAM, \
1239 (.rtio_ctx = &lsm6dsv16x_rtio_ctx_##inst, \
1240 .iodev = &lsm6dsv16x_i3c_iodev_##inst, \
1241 .bus_type = BUS_I3C,)) \
1242 }; \
1243 static const struct lsm6dsv16x_config lsm6dsv16x_config_##inst = \
1244 LSM6DSV16X_CONFIG_I3C(inst); \
1245
1246 #define LSM6DSV16X_DEFINE_I3C_OR_I2C(inst) \
1247 COND_CODE_0(DT_INST_PROP_BY_IDX(inst, reg, 1), \
1248 (LSM6DSV16X_DEFINE_I2C(inst)), \
1249 (LSM6DSV16X_DEFINE_I3C(inst)))
1250
1251 /*
1252 * Main instantiation macro. Use of COND_CODE_1() selects the right
1253 * bus-specific macro at preprocessor time.
1254 */
1255
1256 #define LSM6DSV16X_DEFINE(inst) \
1257 COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
1258 (LSM6DSV16X_DEFINE_SPI(inst)), \
1259 (COND_CODE_1(DT_INST_ON_BUS(inst, i3c), \
1260 (LSM6DSV16X_DEFINE_I3C_OR_I2C(inst)), \
1261 (LSM6DSV16X_DEFINE_I2C(inst))))); \
1262 LSM6DSV16X_DEVICE_INIT(inst)
1263
1264 DT_INST_FOREACH_STATUS_OKAY(LSM6DSV16X_DEFINE)
1265