diff options
author | Lorenzo Bianconi <lorenzo@kernel.org> | 2019-11-28 17:55:18 +0200 |
---|---|---|
committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2019-12-08 18:10:30 +0000 |
commit | 5685b145c138b2ca696076106d0fb87b7b90b14a (patch) | |
tree | fe9291b3f199955da5e0b2a265c789609ef719eb /drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | |
parent | iio: imu: inv_mpu6050: fix temperature reporting using bad unit (diff) | |
download | linux-dev-5685b145c138b2ca696076106d0fb87b7b90b14a.tar.xz linux-dev-5685b145c138b2ca696076106d0fb87b7b90b14a.zip |
iio: imu: st_lsm6dsx: fix decimation factor estimation
Fix decimation factor and sip estimation for LSM6DSM series
(max value for decimation factor is 32).
If gyro and accel sensors are enabled at 12.5Hz and 416Hz
respectively, decimation factor lookup will fail, producing
unaligned data.
Remove unused decimator filed in st_lsm6dsx_sensor structure.
Fixes: f8710f0357bc ("iio: imu: st_lsm6dsx: express odr in mHZ")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c')
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index d416990ae309..a70b04f14187 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -78,14 +78,20 @@ struct st_lsm6dsx_decimator_entry st_lsm6dsx_decimator_table[] = { { 32, 0x7 }, }; -static int st_lsm6dsx_get_decimator_val(u8 val) +static int +st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr) { const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table); + u32 decimator = max_odr / sensor->odr; int i; - for (i = 0; i < max_size; i++) - if (st_lsm6dsx_decimator_table[i].decimator == val) + if (decimator > 1) + decimator = round_down(decimator, 2); + + for (i = 0; i < max_size; i++) { + if (st_lsm6dsx_decimator_table[i].decimator == decimator) break; + } return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val; } @@ -111,6 +117,13 @@ static void st_lsm6dsx_get_max_min_odr(struct st_lsm6dsx_hw *hw, } } +static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr) +{ + u8 sip = sensor->odr / min_odr; + + return sip > 1 ? round_down(sip, 2) : sip; +} + static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) { const struct st_lsm6dsx_reg *ts_dec_reg; @@ -131,12 +144,10 @@ static int st_lsm6dsx_update_decimators(struct st_lsm6dsx_hw *hw) sensor = iio_priv(hw->iio_devs[i]); /* update fifo decimators and sample in pattern */ if (hw->enable_mask & BIT(sensor->id)) { - sensor->sip = sensor->odr / min_odr; - sensor->decimator = max_odr / sensor->odr; - data = st_lsm6dsx_get_decimator_val(sensor->decimator); + sensor->sip = st_lsm6dsx_get_sip(sensor, min_odr); + data = st_lsm6dsx_get_decimator_val(sensor, max_odr); } else { sensor->sip = 0; - sensor->decimator = 0; data = 0; } ts_sip = max_t(u16, ts_sip, sensor->sip); |