1 /*
2  * Copyright (c) 2023 Google LLC
3  * Copyright (c) 2025 Croxel Inc.
4  * Copyright (c) 2025 CogniPilot Foundation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/drivers/sensor_clock.h>
10 
11 #include "icm45686.h"
12 #include "icm45686_reg.h"
13 #include "icm45686_decoder.h"
14 
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(ICM45686_DECODER, CONFIG_SENSOR_LOG_LEVEL);
17 
18 #define DT_DRV_COMPAT invensense_icm45686
19 
icm45686_get_shift(enum sensor_channel channel,int accel_fs,int gyro_fs,int8_t * shift)20 static int icm45686_get_shift(enum sensor_channel channel,
21 			      int accel_fs,
22 			      int gyro_fs,
23 			      int8_t *shift)
24 {
25 	switch (channel) {
26 	case SENSOR_CHAN_ACCEL_XYZ:
27 	case SENSOR_CHAN_ACCEL_X:
28 	case SENSOR_CHAN_ACCEL_Y:
29 	case SENSOR_CHAN_ACCEL_Z:
30 		switch (accel_fs) {
31 		case ICM45686_DT_ACCEL_FS_32:
32 			*shift = 9;
33 			return 0;
34 		case ICM45686_DT_ACCEL_FS_16:
35 			*shift = 8;
36 			return 0;
37 		case ICM45686_DT_ACCEL_FS_8:
38 			*shift = 7;
39 			return 0;
40 		case ICM45686_DT_ACCEL_FS_4:
41 			*shift = 6;
42 			return 0;
43 		case ICM45686_DT_ACCEL_FS_2:
44 			*shift = 5;
45 			return 0;
46 		default:
47 			return -EINVAL;
48 		}
49 	case SENSOR_CHAN_GYRO_XYZ:
50 	case SENSOR_CHAN_GYRO_X:
51 	case SENSOR_CHAN_GYRO_Y:
52 	case SENSOR_CHAN_GYRO_Z:
53 		switch (gyro_fs) {
54 		case ICM45686_DT_GYRO_FS_4000:
55 			*shift = 12;
56 			return 0;
57 		case ICM45686_DT_GYRO_FS_2000:
58 			*shift = 11;
59 			return 0;
60 		case ICM45686_DT_GYRO_FS_1000:
61 			*shift = 10;
62 			return 0;
63 		case ICM45686_DT_GYRO_FS_500:
64 			*shift = 9;
65 			return 0;
66 		case ICM45686_DT_GYRO_FS_250:
67 			*shift = 8;
68 			return 0;
69 		case ICM45686_DT_GYRO_FS_125:
70 			*shift = 7;
71 			return 0;
72 		case ICM45686_DT_GYRO_FS_62_5:
73 			*shift = 6;
74 			return 0;
75 		case ICM45686_DT_GYRO_FS_31_25:
76 			*shift = 5;
77 			return 0;
78 		default:
79 			return -EINVAL;
80 		}
81 	case SENSOR_CHAN_DIE_TEMP:
82 		*shift = 9;
83 		return 0;
84 	default:
85 		return -EINVAL;
86 	}
87 }
88 
icm45686_convert_raw_to_q31(struct icm45686_encoded_data * edata,enum sensor_channel chan,int32_t reading,q31_t * out)89 int icm45686_convert_raw_to_q31(struct icm45686_encoded_data *edata,
90 				enum sensor_channel chan,
91 				int32_t reading,
92 				q31_t *out)
93 {
94 	int32_t whole;
95 	int32_t fraction;
96 	int64_t intermediate;
97 	int8_t shift;
98 	int rc;
99 
100 	rc = icm45686_get_shift(chan, edata->header.accel_fs, edata->header.gyro_fs, &shift);
101 	if (rc != 0) {
102 		return rc;
103 	}
104 
105 	switch (chan) {
106 	case SENSOR_CHAN_ACCEL_XYZ:
107 	case SENSOR_CHAN_ACCEL_X:
108 	case SENSOR_CHAN_ACCEL_Y:
109 	case SENSOR_CHAN_ACCEL_Z:
110 		icm45686_accel_ms(edata->header.accel_fs, reading, false, &whole, &fraction);
111 		break;
112 	case SENSOR_CHAN_GYRO_XYZ:
113 	case SENSOR_CHAN_GYRO_X:
114 	case SENSOR_CHAN_GYRO_Y:
115 	case SENSOR_CHAN_GYRO_Z:
116 		icm45686_gyro_rads(edata->header.gyro_fs, reading, false, &whole, &fraction);
117 		break;
118 	case SENSOR_CHAN_DIE_TEMP:
119 		icm45686_temp_c(reading, &whole, &fraction);
120 		break;
121 	default:
122 		return -ENOTSUP;
123 	}
124 	intermediate = ((int64_t)whole * INT64_C(1000000) + fraction);
125 	if (shift < 0) {
126 		intermediate =
127 			intermediate * ((int64_t)INT32_MAX + 1) * (1 << -shift) / INT64_C(1000000);
128 	} else if (shift > 0) {
129 		intermediate =
130 			intermediate * ((int64_t)INT32_MAX + 1) / ((1 << shift) * INT64_C(1000000));
131 	}
132 	*out = CLAMP(intermediate, INT32_MIN, INT32_MAX);
133 
134 	return 0;
135 }
136 
icm45686_get_channel_position(enum sensor_channel chan)137 static int icm45686_get_channel_position(enum sensor_channel chan)
138 {
139 	switch (chan) {
140 	case SENSOR_CHAN_ACCEL_XYZ:
141 	case SENSOR_CHAN_ACCEL_X:
142 		return offsetof(struct icm45686_encoded_payload, accel.x) / sizeof(int16_t);
143 	case SENSOR_CHAN_ACCEL_Y:
144 		return offsetof(struct icm45686_encoded_payload, accel.y) / sizeof(int16_t);
145 	case SENSOR_CHAN_ACCEL_Z:
146 		return offsetof(struct icm45686_encoded_payload, accel.z) / sizeof(int16_t);
147 	case SENSOR_CHAN_GYRO_XYZ:
148 	case SENSOR_CHAN_GYRO_X:
149 		return offsetof(struct icm45686_encoded_payload, gyro.x) / sizeof(int16_t);
150 	case SENSOR_CHAN_GYRO_Y:
151 		return offsetof(struct icm45686_encoded_payload, gyro.y) / sizeof(int16_t);
152 	case SENSOR_CHAN_GYRO_Z:
153 		return offsetof(struct icm45686_encoded_payload, gyro.z) / sizeof(int16_t);
154 	case SENSOR_CHAN_DIE_TEMP:
155 		return offsetof(struct icm45686_encoded_payload, temp) / sizeof(int16_t);
156 	default:
157 		return 0;
158 	}
159 }
160 
icm45686_encode_channel(enum sensor_channel chan)161 static uint8_t icm45686_encode_channel(enum sensor_channel chan)
162 {
163 	uint8_t encode_bmask = 0;
164 
165 	switch (chan) {
166 	case SENSOR_CHAN_ACCEL_X:
167 	case SENSOR_CHAN_ACCEL_Y:
168 	case SENSOR_CHAN_ACCEL_Z:
169 	case SENSOR_CHAN_GYRO_X:
170 	case SENSOR_CHAN_GYRO_Y:
171 	case SENSOR_CHAN_GYRO_Z:
172 	case SENSOR_CHAN_DIE_TEMP:
173 		encode_bmask = BIT(icm45686_get_channel_position(chan));
174 		break;
175 	case SENSOR_CHAN_ACCEL_XYZ:
176 		encode_bmask = BIT(icm45686_get_channel_position(SENSOR_CHAN_ACCEL_X)) |
177 			       BIT(icm45686_get_channel_position(SENSOR_CHAN_ACCEL_Y)) |
178 			       BIT(icm45686_get_channel_position(SENSOR_CHAN_ACCEL_Z));
179 		break;
180 	case SENSOR_CHAN_GYRO_XYZ:
181 		encode_bmask = BIT(icm45686_get_channel_position(SENSOR_CHAN_GYRO_X)) |
182 			       BIT(icm45686_get_channel_position(SENSOR_CHAN_GYRO_Y)) |
183 			       BIT(icm45686_get_channel_position(SENSOR_CHAN_GYRO_Z));
184 		break;
185 	default:
186 		break;
187 	}
188 
189 	return encode_bmask;
190 }
191 
icm45686_encode(const struct device * dev,const struct sensor_chan_spec * const channels,const size_t num_channels,uint8_t * buf)192 int icm45686_encode(const struct device *dev,
193 		    const struct sensor_chan_spec *const channels,
194 		    const size_t num_channels,
195 		    uint8_t *buf)
196 {
197 	struct icm45686_encoded_data *edata = (struct icm45686_encoded_data *)buf;
198 	const struct icm45686_config *dev_config = dev->config;
199 	uint64_t cycles;
200 	int err;
201 
202 	edata->header.channels = 0;
203 
204 	for (size_t i = 0 ; i < num_channels ; i++) {
205 		edata->header.channels |= icm45686_encode_channel(channels[i].chan_type);
206 	}
207 
208 	err = sensor_clock_get_cycles(&cycles);
209 	if (err != 0) {
210 		return err;
211 	}
212 
213 	edata->header.events = 0;
214 	edata->header.accel_fs = dev_config->settings.accel.fs;
215 	edata->header.gyro_fs = dev_config->settings.gyro.fs;
216 	edata->header.timestamp = sensor_clock_cycles_to_ns(cycles);
217 
218 	return 0;
219 }
220 
icm45686_decoder_get_frame_count(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint16_t * frame_count)221 static int icm45686_decoder_get_frame_count(const uint8_t *buffer,
222 					    struct sensor_chan_spec chan_spec,
223 					    uint16_t *frame_count)
224 {
225 	struct icm45686_encoded_data *edata = (struct icm45686_encoded_data *)buffer;
226 
227 	if (chan_spec.chan_idx != 0) {
228 		return -ENOTSUP;
229 	}
230 
231 	uint8_t channel_request = icm45686_encode_channel(chan_spec.chan_type);
232 
233 	if ((edata->header.channels & channel_request) != channel_request) {
234 		return -ENODATA;
235 	}
236 
237 	if (!edata->header.events ||
238 	    (edata->header.events & REG_INT1_STATUS0_DRDY(true))) {
239 		switch (chan_spec.chan_type) {
240 		case SENSOR_CHAN_ACCEL_X:
241 		case SENSOR_CHAN_ACCEL_Y:
242 		case SENSOR_CHAN_ACCEL_Z:
243 		case SENSOR_CHAN_ACCEL_XYZ:
244 		case SENSOR_CHAN_GYRO_X:
245 		case SENSOR_CHAN_GYRO_Y:
246 		case SENSOR_CHAN_GYRO_Z:
247 		case SENSOR_CHAN_GYRO_XYZ:
248 		case SENSOR_CHAN_DIE_TEMP:
249 			*frame_count = 1;
250 			return 0;
251 		default:
252 			return -ENOTSUP;
253 		}
254 	}
255 
256 	if (edata->header.events & REG_INT1_STATUS0_FIFO_THS(true) ||
257 	    edata->header.events & REG_INT1_STATUS0_FIFO_FULL(true)) {
258 		switch (chan_spec.chan_type) {
259 		case SENSOR_CHAN_ACCEL_XYZ:
260 		case SENSOR_CHAN_GYRO_XYZ:
261 		case SENSOR_CHAN_DIE_TEMP:
262 			*frame_count = edata->header.fifo_count;
263 			return 0;
264 		/** We're skipping individual axis for fifo packets */
265 		default:
266 			return -ENOTSUP;
267 		}
268 	}
269 
270 	return -1;
271 }
272 
icm45686_decoder_get_size_info(struct sensor_chan_spec chan_spec,size_t * base_size,size_t * frame_size)273 static int icm45686_decoder_get_size_info(struct sensor_chan_spec chan_spec,
274 					  size_t *base_size,
275 					  size_t *frame_size)
276 {
277 	switch (chan_spec.chan_type) {
278 	case SENSOR_CHAN_ACCEL_XYZ:
279 	case SENSOR_CHAN_GYRO_XYZ:
280 		*base_size = sizeof(struct sensor_three_axis_data);
281 		*frame_size = sizeof(struct sensor_three_axis_sample_data);
282 		return 0;
283 	case SENSOR_CHAN_ACCEL_X:
284 	case SENSOR_CHAN_ACCEL_Y:
285 	case SENSOR_CHAN_ACCEL_Z:
286 	case SENSOR_CHAN_GYRO_X:
287 	case SENSOR_CHAN_GYRO_Y:
288 	case SENSOR_CHAN_GYRO_Z:
289 	case SENSOR_CHAN_DIE_TEMP:
290 		*base_size = sizeof(struct sensor_q31_data);
291 		*frame_size = sizeof(struct sensor_q31_sample_data);
292 		return 0;
293 	default:
294 		return -ENOTSUP;
295 	}
296 }
297 
icm45686_one_shot_decode(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint32_t * fit,uint16_t max_count,void * data_out)298 static int icm45686_one_shot_decode(const uint8_t *buffer,
299 				    struct sensor_chan_spec chan_spec,
300 				    uint32_t *fit,
301 				    uint16_t max_count,
302 				    void *data_out)
303 {
304 	struct icm45686_encoded_data *edata = (struct icm45686_encoded_data *)buffer;
305 	uint8_t channel_request;
306 	int err;
307 
308 	if (*fit != 0) {
309 		return 0;
310 	}
311 
312 	if (max_count == 0 || chan_spec.chan_idx != 0) {
313 		return -EINVAL;
314 	}
315 
316 	switch (chan_spec.chan_type) {
317 	case SENSOR_CHAN_ACCEL_X:
318 	case SENSOR_CHAN_ACCEL_Y:
319 	case SENSOR_CHAN_ACCEL_Z:
320 	case SENSOR_CHAN_GYRO_X:
321 	case SENSOR_CHAN_GYRO_Y:
322 	case SENSOR_CHAN_GYRO_Z:
323 	case SENSOR_CHAN_DIE_TEMP: {
324 		channel_request = icm45686_encode_channel(chan_spec.chan_type);
325 		if ((channel_request & edata->header.channels) != channel_request) {
326 			return -ENODATA;
327 		}
328 
329 		struct sensor_q31_data *out = data_out;
330 
331 		out->header.base_timestamp_ns = edata->header.timestamp;
332 		out->header.reading_count = 1;
333 
334 		err = icm45686_get_shift(chan_spec.chan_type,
335 					 edata->header.accel_fs,
336 					 edata->header.gyro_fs,
337 					 &out->shift);
338 		if (err != 0) {
339 			return -EINVAL;
340 		}
341 
342 		icm45686_convert_raw_to_q31(
343 			edata,
344 			chan_spec.chan_type,
345 			edata->payload.readings[icm45686_get_channel_position(chan_spec.chan_type)],
346 			&out->readings[0].value);
347 		*fit = 1;
348 		return 1;
349 	}
350 	case SENSOR_CHAN_ACCEL_XYZ:
351 	case SENSOR_CHAN_GYRO_XYZ: {
352 		channel_request = icm45686_encode_channel(chan_spec.chan_type);
353 		if ((channel_request & edata->header.channels) != channel_request) {
354 			return -ENODATA;
355 		}
356 
357 		struct sensor_three_axis_data *out = data_out;
358 		struct icm45686_encoded_payload *payload = &edata->payload;
359 
360 		out->header.base_timestamp_ns = edata->header.timestamp;
361 		out->header.reading_count = 1;
362 
363 		icm45686_convert_raw_to_q31(
364 			edata,
365 			chan_spec.chan_type - 3,
366 			payload->readings[icm45686_get_channel_position(chan_spec.chan_type - 3)],
367 			&out->readings[0].x);
368 		icm45686_convert_raw_to_q31(
369 			edata,
370 			chan_spec.chan_type - 2,
371 			payload->readings[icm45686_get_channel_position(chan_spec.chan_type - 2)],
372 			&out->readings[0].y);
373 		icm45686_convert_raw_to_q31(
374 			edata,
375 			chan_spec.chan_type - 1,
376 			payload->readings[icm45686_get_channel_position(chan_spec.chan_type - 1)],
377 			&out->readings[0].z);
378 		*fit = 1;
379 		return 1;
380 	}
381 	default:
382 		return -EINVAL;
383 	}
384 }
385 
icm45686_fifo_read_temp_from_packet(const uint8_t * pkt)386 static q31_t icm45686_fifo_read_temp_from_packet(const uint8_t *pkt)
387 {
388 	struct icm45686_encoded_fifo_payload *fdata = (struct icm45686_encoded_fifo_payload *)pkt;
389 
390 	int32_t whole;
391 	uint32_t fraction;
392 	int64_t intermediate;
393 	int8_t shift;
394 	int err;
395 
396 	err = icm45686_get_shift(SENSOR_CHAN_DIE_TEMP, 0, 0, &shift);
397 	if (err != 0) {
398 		return -1;
399 	}
400 
401 	icm45686_temp_c(fdata->temp, &whole, &fraction);
402 
403 	intermediate = ((int64_t)whole * INT64_C(1000000) + fraction);
404 	if (shift < 0) {
405 		intermediate =
406 			intermediate * ((int64_t)INT32_MAX + 1) * (1 << -shift) / INT64_C(1000000);
407 	} else if (shift > 0) {
408 		intermediate =
409 			intermediate * ((int64_t)INT32_MAX + 1) / ((1 << shift) * INT64_C(1000000));
410 	}
411 
412 	return CLAMP(intermediate, INT32_MIN, INT32_MAX);
413 }
414 
icm45686_fifo_read_imu_from_packet(const uint8_t * pkt,bool is_accel,uint8_t axis_offset,q31_t * out)415 static int icm45686_fifo_read_imu_from_packet(const uint8_t *pkt,
416 					      bool is_accel,
417 					      uint8_t axis_offset,
418 					      q31_t *out)
419 {
420 	uint32_t unsigned_value;
421 	int32_t signed_value;
422 	int offset = 1 + (axis_offset * 2)  + (is_accel ? 0 : 6);
423 	uint32_t mask = is_accel ? GENMASK(7, 4) : GENMASK(3, 0);
424 	uint8_t accel_fs = ICM45686_DT_ACCEL_FS_32;
425 	uint8_t gyro_fs = ICM45686_DT_GYRO_FS_4000;
426 
427 	int32_t whole;
428 	int32_t fraction;
429 	int64_t intermediate;
430 	int8_t shift;
431 
432 	unsigned_value = (pkt[offset] | (pkt[offset + 1] << 8));
433 	if (unsigned_value == FIFO_NO_DATA) {
434 		return -ENODATA;
435 	}
436 
437 	unsigned_value = (unsigned_value << 4) |
438 			 ((pkt[17 + axis_offset] & mask) >> (is_accel ? 4 : 0));
439 	signed_value = sign_extend(unsigned_value, 19);
440 
441 	if (!is_accel) {
442 		icm45686_get_shift(SENSOR_CHAN_GYRO_XYZ, accel_fs, gyro_fs, &shift);
443 		icm45686_gyro_rads(gyro_fs, signed_value, true, &whole, &fraction);
444 	} else {
445 		icm45686_get_shift(SENSOR_CHAN_ACCEL_XYZ, accel_fs, gyro_fs, &shift);
446 		icm45686_accel_ms(accel_fs, signed_value, true, &whole, &fraction);
447 	}
448 
449 	intermediate = ((int64_t)whole * INT64_C(1000000) + fraction);
450 	if (shift < 0) {
451 		intermediate =
452 			intermediate * ((int64_t)INT32_MAX + 1) * (1 << -shift) / INT64_C(1000000);
453 	} else if (shift > 0) {
454 		intermediate =
455 			intermediate * ((int64_t)INT32_MAX + 1) / ((1 << shift) * INT64_C(1000000));
456 	}
457 
458 	*out = CLAMP(intermediate, INT32_MIN, INT32_MAX);
459 
460 	return 0;
461 }
462 
icm45686_fifo_decode(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint32_t * fit,uint16_t max_count,void * data_out)463 static int icm45686_fifo_decode(const uint8_t *buffer,
464 				struct sensor_chan_spec chan_spec,
465 				uint32_t *fit,
466 				uint16_t max_count,
467 				void *data_out)
468 {
469 	struct icm45686_encoded_data *edata = (struct icm45686_encoded_data *)buffer;
470 	struct icm45686_encoded_fifo_payload *frame_begin = &edata->fifo_payload;
471 	int count = 0;
472 	int err;
473 
474 	if (*fit >= edata->header.fifo_count || chan_spec.chan_idx != 0) {
475 		return 0;
476 	}
477 
478 	while (count < max_count && (*fit < edata->header.fifo_count)) {
479 		struct icm45686_encoded_fifo_payload *fdata = &frame_begin[*fit];
480 
481 		/** This driver assumes 20-byte fifo packets, with both accel and gyro,
482 		 * and no auxiliary sensors.
483 		 */
484 		__ASSERT(!(fdata->header & FIFO_HEADER_EXT_HEADER_EN(true)) &&
485 			(fdata->header & FIFO_HEADER_ACCEL_EN(true)) &&
486 			(fdata->header & FIFO_HEADER_GYRO_EN(true)) &&
487 			(fdata->header & FIFO_HEADER_HIRES_EN(true)),
488 			"Unsupported FIFO packet format");
489 
490 		switch (chan_spec.chan_type) {
491 		case SENSOR_CHAN_ACCEL_XYZ:
492 		case SENSOR_CHAN_GYRO_XYZ: {
493 			struct sensor_three_axis_data *out = data_out;
494 			bool is_accel = chan_spec.chan_type == SENSOR_CHAN_ACCEL_XYZ;
495 
496 			icm45686_get_shift(chan_spec.chan_type,
497 					   edata->header.accel_fs,
498 					   edata->header.gyro_fs,
499 					   &out->shift);
500 
501 			out->header.base_timestamp_ns = edata->header.timestamp;
502 
503 			err = icm45686_fifo_read_imu_from_packet((uint8_t *)fdata,
504 								 is_accel,
505 								 0,
506 								 &out->readings[count].x);
507 			err |= icm45686_fifo_read_imu_from_packet((uint8_t *)fdata,
508 								  is_accel,
509 								  1,
510 								  &out->readings[count].y);
511 			err |= icm45686_fifo_read_imu_from_packet((uint8_t *)fdata,
512 								  is_accel,
513 								  2,
514 								  &out->readings[count].z);
515 			if (err != 0) {
516 				count--;
517 			}
518 			break;
519 		}
520 		case SENSOR_CHAN_DIE_TEMP: {
521 			struct sensor_q31_data *out = data_out;
522 
523 			icm45686_get_shift(chan_spec.chan_type,
524 					edata->header.accel_fs,
525 					edata->header.gyro_fs,
526 					&out->shift);
527 
528 			out->header.base_timestamp_ns = edata->header.timestamp;
529 			out->readings[count].temperature =
530 				icm45686_fifo_read_temp_from_packet((uint8_t *)fdata);
531 			break;
532 		}
533 		default:
534 			return 0;
535 		}
536 		*fit = *fit + 1;
537 		count++;
538 	}
539 
540 	return count;
541 }
542 
icm45686_decoder_decode(const uint8_t * buffer,struct sensor_chan_spec chan_spec,uint32_t * fit,uint16_t max_count,void * data_out)543 static int icm45686_decoder_decode(const uint8_t *buffer,
544 				   struct sensor_chan_spec chan_spec,
545 				   uint32_t *fit,
546 				   uint16_t max_count,
547 				   void *data_out)
548 {
549 	struct icm45686_encoded_data *edata = (struct icm45686_encoded_data *)buffer;
550 
551 	if (edata->header.events & REG_INT1_STATUS0_FIFO_THS(true) ||
552 	    edata->header.events & REG_INT1_STATUS0_FIFO_FULL(true)) {
553 		return icm45686_fifo_decode(buffer, chan_spec, fit, max_count, data_out);
554 	} else {
555 		return icm45686_one_shot_decode(buffer, chan_spec, fit, max_count, data_out);
556 	}
557 }
558 
icm45686_decoder_has_trigger(const uint8_t * buffer,enum sensor_trigger_type trigger)559 static bool icm45686_decoder_has_trigger(const uint8_t *buffer, enum sensor_trigger_type trigger)
560 {
561 	struct icm45686_encoded_data *edata = (struct icm45686_encoded_data *)buffer;
562 
563 	switch (trigger) {
564 	case SENSOR_TRIG_DATA_READY:
565 		return edata->header.events & REG_INT1_STATUS0_DRDY(true);
566 	case SENSOR_TRIG_FIFO_WATERMARK:
567 		return edata->header.events & REG_INT1_STATUS0_FIFO_THS(true);
568 	case SENSOR_TRIG_FIFO_FULL:
569 		return edata->header.events & REG_INT1_STATUS0_FIFO_FULL(true);
570 	default:
571 		break;
572 	}
573 
574 	return false;
575 }
576 
577 SENSOR_DECODER_API_DT_DEFINE() = {
578 	.get_frame_count = icm45686_decoder_get_frame_count,
579 	.get_size_info = icm45686_decoder_get_size_info,
580 	.decode = icm45686_decoder_decode,
581 	.has_trigger = icm45686_decoder_has_trigger,
582 };
583 
icm45686_get_decoder(const struct device * dev,const struct sensor_decoder_api ** decoder)584 int icm45686_get_decoder(const struct device *dev,
585 			 const struct sensor_decoder_api **decoder)
586 {
587 	ARG_UNUSED(dev);
588 	*decoder = &SENSOR_DECODER_NAME();
589 
590 	return 0;
591 }
592