@@ -243,81 +243,33 @@ static inline q31_t icm42688_read_temperature_from_packet(const uint8_t *pkt)
243243static int icm42688_read_imu_from_packet (const uint8_t * pkt , bool is_accel , int fs ,
244244 uint8_t axis_offset , q31_t * out )
245245{
246- int32_t value ;
247- int64_t scale = 0 ;
248- int32_t max = BIT ( 15 ) ;
246+ uint32_t unsigned_value ;
247+ int32_t signed_value ;
248+ bool is_hires = FIELD_GET ( FIFO_HEADER_ACCEL , pkt [ 0 ]) == 1 ;
249249 int offset = 1 + (axis_offset * 2 );
250250
251- if (is_accel ) {
252- switch (fs ) {
253- case ICM42688_DT_ACCEL_FS_2 :
254- scale = INT64_C (2 ) * BIT (31 - 5 ) * 9.80665 ;
255- break ;
256- case ICM42688_DT_ACCEL_FS_4 :
257- scale = INT64_C (4 ) * BIT (31 - 6 ) * 9.80665 ;
258- break ;
259- case ICM42688_DT_ACCEL_FS_8 :
260- scale = INT64_C (8 ) * BIT (31 - 7 ) * 9.80665 ;
261- break ;
262- case ICM42688_DT_ACCEL_FS_16 :
263- scale = INT64_C (16 ) * BIT (31 - 8 ) * 9.80665 ;
264- break ;
265- }
266- } else {
267- switch (fs ) {
268- case ICM42688_DT_GYRO_FS_2000 :
269- scale = 164 ;
270- break ;
271- case ICM42688_DT_GYRO_FS_1000 :
272- scale = 328 ;
273- break ;
274- case ICM42688_DT_GYRO_FS_500 :
275- scale = 655 ;
276- break ;
277- case ICM42688_DT_GYRO_FS_250 :
278- scale = 1310 ;
279- break ;
280- case ICM42688_DT_GYRO_FS_125 :
281- scale = 2620 ;
282- break ;
283- case ICM42688_DT_GYRO_FS_62_5 :
284- scale = 5243 ;
285- break ;
286- case ICM42688_DT_GYRO_FS_31_25 :
287- scale = 10486 ;
288- break ;
289- case ICM42688_DT_GYRO_FS_15_625 :
290- scale = 20972 ;
291- break ;
292- }
293- }
251+ const uint32_t scale [2 ][2 ] = {
252+ /* low-res, hi-res */
253+ {35744 , 8936 }, /* gyro */
254+ {40168 , 2511 }, /* accel */
255+ };
294256
295257 if (!is_accel && FIELD_GET (FIFO_HEADER_ACCEL , pkt [0 ]) == 1 ) {
296- offset += 7 ;
258+ offset += 6 ;
297259 }
298260
299- value = (int16_t ) sys_le16_to_cpu (( pkt [offset ] << 8 ) | pkt [offset + 1 ]) ;
261+ unsigned_value = (pkt [offset ] << 8 ) | pkt [offset + 1 ];
300262
301- if (FIELD_GET ( FIFO_HEADER_20 , pkt [ 0 ]) == 1 ) {
263+ if (is_hires ) {
302264 uint32_t mask = is_accel ? GENMASK (7 , 4 ) : GENMASK (3 , 0 );
303-
304- offset = 0x11 + axis_offset ;
305- value = (value << 4 ) | FIELD_GET (mask , pkt [offset ]);
306- /* In 20 bit mode, FS can only be +/-16g and +/-2000dps */
307- scale = is_accel ? (INT64_C (16 ) * BIT (8 ) * 9.80665 ) : 131 ;
308- max = is_accel ? BIT (18 ) : BIT (19 );
309- if (value == -524288 ) {
310- /* Invalid 20 bit value */
311- return - ENODATA ;
312- }
265+ offset = 17 + axis_offset ;
266+ unsigned_value = (unsigned_value << 4 ) | FIELD_GET (mask , pkt [offset ]);
267+ signed_value = unsigned_value | (0 - (unsigned_value & BIT (19 )));
313268 } else {
314- if (value <= -32767 ) {
315- /* Invalid 16 bit value */
316- return - ENODATA ;
317- }
269+ signed_value = unsigned_value | (0 - (unsigned_value & BIT (16 )));
318270 }
319271
320- * out = (q31_t )(value * scale / max );
272+ * out = (q31_t )(signed_value * scale [ is_accel ][ is_hires ] );
321273 return 0 ;
322274}
323275
@@ -434,7 +386,7 @@ static int icm42688_fifo_decode(const uint8_t *buffer, struct sensor_chan_spec c
434386 /* Decode gyro */
435387 struct sensor_three_axis_data * data =
436388 (struct sensor_three_axis_data * )data_out ;
437- uint64_t period_ns = accel_period_ns [edata -> gyro_odr ];
389+ uint64_t period_ns = gyro_period_ns [edata -> gyro_odr ];
438390
439391 icm42688_get_shift (SENSOR_CHAN_GYRO_XYZ , edata -> header .accel_fs ,
440392 edata -> header .gyro_fs , & data -> shift );
0 commit comments