Commit 76551a3c authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Jonathan Cameron
Browse files

iio: imu: st_lsm6dsx: specify slave odr in slv_odr



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: e485e2a2 ("iio: imu: st_lsm6dsx: enable sensor-hub support for lsm6dsm")
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 7762902c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -357,6 +357,7 @@ struct st_lsm6dsx_sensor {

	struct {
		const struct st_lsm6dsx_ext_dev_settings *settings;
		u32 slv_odr;
		u8 addr;
	} ext_info;
};
+22 −7
Original line number Diff line number Diff line
@@ -421,7 +421,8 @@ int st_lsm6dsx_shub_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable)

	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_lsm6dsx_sensor *sensor,
	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_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 *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_lsm6dsx_hw *hw,
			     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_lsm6dsx_hw *hw,
	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;