lkml.org 
[lkml]   [2020]   [May]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 012/106] iio: imu: st_lsm6dsx: fix read misalignment on untagged FIFO
    Date
    From: Lorenzo Bianconi <lorenzo@kernel.org>

    commit 7762902c89c4c78d32ec562f1ada44d02039104b upstream.

    st_lsm6dsx suffers of a read misalignment on untagged FIFO when
    all 3 supported sensors (accel, gyro and ext device) are running
    at different ODRs (the use-case is reported in the LSM6DSM Application
    Note at pag 100).
    Fix the issue taking into account decimation factor reading the FIFO
    pattern.

    Fixes: e485e2a2cfd6 ("iio: imu: st_lsm6dsx: enable sensor-hub support for lsm6dsm")
    Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
    Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 ++
    drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 23 ++++++++++++++++-------
    2 files changed, 18 insertions(+), 7 deletions(-)

    --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
    +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
    @@ -337,6 +337,7 @@ enum st_lsm6dsx_fifo_mode {
    * @gain: Configured sensor sensitivity.
    * @odr: Output data rate of the sensor [Hz].
    * @watermark: Sensor watermark level.
    + * @decimator: Sensor decimation factor.
    * @sip: Number of samples in a given pattern.
    * @ts_ref: Sensor timestamp reference for hw one.
    * @ext_info: Sensor settings if it is connected to i2c controller
    @@ -350,6 +351,7 @@ struct st_lsm6dsx_sensor {
    u32 odr;

    u16 watermark;
    + u8 decimator;
    u8 sip;
    s64 ts_ref;

    --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
    +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
    @@ -93,6 +93,7 @@ st_lsm6dsx_get_decimator_val(struct st_l
    break;
    }

    + sensor->decimator = decimator;
    return i == max_size ? 0 : st_lsm6dsx_decimator_table[i].val;
    }

    @@ -337,7 +338,7 @@ static inline int st_lsm6dsx_read_block(
    int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw)
    {
    struct st_lsm6dsx_sensor *acc_sensor, *gyro_sensor, *ext_sensor = NULL;
    - int err, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
    + int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset;
    u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE;
    u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask;
    u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE];
    @@ -399,19 +400,20 @@ int st_lsm6dsx_read_fifo(struct st_lsm6d
    acc_sip = acc_sensor->sip;
    ts_sip = hw->ts_sip;
    offset = 0;
    + sip = 0;

    while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) {
    - if (gyro_sip > 0) {
    + if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
    memcpy(gyro_buff, &hw->buff[offset],
    ST_LSM6DSX_SAMPLE_SIZE);
    offset += ST_LSM6DSX_SAMPLE_SIZE;
    }
    - if (acc_sip > 0) {
    + if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
    memcpy(acc_buff, &hw->buff[offset],
    ST_LSM6DSX_SAMPLE_SIZE);
    offset += ST_LSM6DSX_SAMPLE_SIZE;
    }
    - if (ext_sip > 0) {
    + if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
    memcpy(ext_buff, &hw->buff[offset],
    ST_LSM6DSX_SAMPLE_SIZE);
    offset += ST_LSM6DSX_SAMPLE_SIZE;
    @@ -441,18 +443,25 @@ int st_lsm6dsx_read_fifo(struct st_lsm6d
    offset += ST_LSM6DSX_SAMPLE_SIZE;
    }

    - if (gyro_sip-- > 0)
    + if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) {
    iio_push_to_buffers_with_timestamp(
    hw->iio_devs[ST_LSM6DSX_ID_GYRO],
    gyro_buff, gyro_sensor->ts_ref + ts);
    - if (acc_sip-- > 0)
    + gyro_sip--;
    + }
    + if (acc_sip > 0 && !(sip % acc_sensor->decimator)) {
    iio_push_to_buffers_with_timestamp(
    hw->iio_devs[ST_LSM6DSX_ID_ACC],
    acc_buff, acc_sensor->ts_ref + ts);
    - if (ext_sip-- > 0)
    + acc_sip--;
    + }
    + if (ext_sip > 0 && !(sip % ext_sensor->decimator)) {
    iio_push_to_buffers_with_timestamp(
    hw->iio_devs[ST_LSM6DSX_ID_EXT0],
    ext_buff, ext_sensor->ts_ref + ts);
    + ext_sip--;
    + }
    + sip++;
    }
    }


    \
     
     \ /
      Last update: 2020-05-01 15:50    [W:3.295 / U:0.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site