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