From: Lorenzo Bianconi <[email protected]>

commit 76551a3c3df151750a842b003c6899e9c62e0fd2 upstream.

Introduce slv_odr in ext_info data structure in order to distinguish
between sensor hub trigger (accel sensor) odr and i2c slave odr and
properly compute samples in FIFO pattern

Fixes: e485e2a2cfd6 ("iio: imu: st_lsm6dsx: enable sensor-hub support for 
lsm6dsm")
Signed-off-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Jonathan Cameron <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

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

--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
@@ -357,6 +357,7 @@ struct st_lsm6dsx_sensor {
 
        struct {
                const struct st_lsm6dsx_ext_dev_settings *settings;
+               u32 slv_odr;
                u8 addr;
        } ext_info;
 };
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
@@ -421,7 +421,8 @@ int st_lsm6dsx_shub_set_enable(struct st
 
        settings = sensor->ext_info.settings;
        if (enable) {
-               err = st_lsm6dsx_shub_set_odr(sensor, sensor->odr);
+               err = st_lsm6dsx_shub_set_odr(sensor,
+                                             sensor->ext_info.slv_odr);
                if (err < 0)
                        return err;
        } else {
@@ -459,7 +460,7 @@ st_lsm6dsx_shub_read_oneshot(struct st_l
        if (err < 0)
                return err;
 
-       delay = 1000000000 / sensor->odr;
+       delay = 1000000000 / sensor->ext_info.slv_odr;
        usleep_range(delay, 2 * delay);
 
        len = min_t(int, sizeof(data), ch->scan_type.realbits >> 3);
@@ -500,8 +501,8 @@ st_lsm6dsx_shub_read_raw(struct iio_dev
                iio_device_release_direct_mode(iio_dev);
                break;
        case IIO_CHAN_INFO_SAMP_FREQ:
-               *val = sensor->odr / 1000;
-               *val2 = (sensor->odr % 1000) * 1000;
+               *val = sensor->ext_info.slv_odr / 1000;
+               *val2 = (sensor->ext_info.slv_odr % 1000) * 1000;
                ret = IIO_VAL_INT_PLUS_MICRO;
                break;
        case IIO_CHAN_INFO_SCALE:
@@ -535,8 +536,20 @@ st_lsm6dsx_shub_write_raw(struct iio_dev
 
                val = val * 1000 + val2 / 1000;
                err = st_lsm6dsx_shub_get_odr_val(sensor, val, &data);
-               if (!err)
-                       sensor->odr = val;
+               if (!err) {
+                       struct st_lsm6dsx_hw *hw = sensor->hw;
+                       struct st_lsm6dsx_sensor *ref_sensor;
+                       u8 odr_val;
+                       int odr;
+
+                       ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
+                       odr = st_lsm6dsx_check_odr(ref_sensor, val, &odr_val);
+                       if (odr < 0)
+                               return odr;
+
+                       sensor->ext_info.slv_odr = val;
+                       sensor->odr = odr;
+               }
                break;
        }
        default:
@@ -613,6 +626,7 @@ st_lsm6dsx_shub_alloc_iiodev(struct st_l
                             const struct st_lsm6dsx_ext_dev_settings *info,
                             u8 i2c_addr, const char *name)
 {
+       enum st_lsm6dsx_sensor_id ref_id = ST_LSM6DSX_ID_ACC;
        struct iio_chan_spec *ext_channels;
        struct st_lsm6dsx_sensor *sensor;
        struct iio_dev *iio_dev;
@@ -628,7 +642,8 @@ st_lsm6dsx_shub_alloc_iiodev(struct st_l
        sensor = iio_priv(iio_dev);
        sensor->id = id;
        sensor->hw = hw;
-       sensor->odr = info->odr_table.odr_avl[0].milli_hz;
+       sensor->odr = hw->settings->odr_table[ref_id].odr_avl[0].milli_hz;
+       sensor->ext_info.slv_odr = info->odr_table.odr_avl[0].milli_hz;
        sensor->gain = info->fs_table.fs_avl[0].gain;
        sensor->ext_info.settings = info;
        sensor->ext_info.addr = i2c_addr;


Reply via email to