On Sep 06, Lorenzo Bianconi wrote: > > Add event channels that controls the creation of motion events. > > > > Signed-off-by: Sean Nyekjaer <sean@xxxxxxxxxx> > > --- > > Changes since v3: > > * based channel struct on newer driver > > * use st_lsm6dsx_reg for relevant values > > > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 41 +++++ > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 157 +++++++++++++++++-- > > 2 files changed, 189 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h > > index 5e3cd96b0059..d04473861fba 100644 > > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h > > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h > > @@ -12,6 +12,7 @@ > > #define ST_LSM6DSX_H > > > > #include <linux/device.h> > > +#include <linux/iio/iio.h> > > > > #define ST_LSM6DS3_DEV_NAME "lsm6ds3" > > #define ST_LSM6DS3H_DEV_NAME "lsm6ds3h" > > @@ -54,6 +55,26 @@ enum st_lsm6dsx_hw_id { > > * ST_LSM6DSX_TAGGED_SAMPLE_SIZE) > > #define ST_LSM6DSX_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask)) > > > > [...] > > > @@ -508,6 +511,16 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { > > .mask = GENMASK(5, 3), > > }, > > }, > > + .event_settings = { > > + .enable_reg = { > > + .addr = 0x58, > > + .mask = BIT(7), > > + }, > > + .wakeup_reg = { > > + .addr = 0x5B, > > + .mask = GENMASK(5, 0), > > + }, > > + }, > > }, > > { > > .wai = 0x6c, > > @@ -1072,18 +1085,21 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, > > int err, delay; > > __le16 data; > > > > - err = st_lsm6dsx_sensor_set_enable(sensor, true); > > - if (err < 0) > > - return err; > > + if (!hw->enable_event) { > > I think we do not need this since it is ok if the acc is already enable right? > Just check to not disable it > > > + err = st_lsm6dsx_sensor_set_enable(sensor, true); > > + if (err < 0) > > + return err; > > > > - delay = 1000000 / sensor->odr; > > - usleep_range(delay, 2 * delay); > > + delay = 1000000 / sensor->odr; > > + usleep_range(delay, 2 * delay); > > + } > > > > err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); > > if (err < 0) > > return err; > > > > - st_lsm6dsx_sensor_set_enable(sensor, false); > > + if (!hw->enable_event) > > + st_lsm6dsx_sensor_set_enable(sensor, false); > > > > *val = (s16)le16_to_cpu(data); > > > > @@ -1156,6 +1172,121 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, > > return err; > > } > > > > +int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) > > +{ > > + int err; > > + u8 enable = 0; here you do something like: if (!hw->settings->event_settings.enable_reg.addr) return -ENOSUPP; > > + > > + enable = state ? hw->settings->event_settings.enable_reg.mask : 0; > > + > > + err = regmap_update_bits(hw->regmap, > > + hw->settings->event_settings.enable_reg.addr, > > + hw->settings->event_settings.enable_reg.mask, > > + enable); > > + if (err < 0) > > + return err; > > + > > + enable = state ? hw->irq_routing.mask : 0; > > + > > + /* Enable wakeup interrupt */ > > + err = regmap_update_bits(hw->regmap, hw->irq_routing.addr, > > + hw->irq_routing.mask, > > + enable); > > return regmap_update_bits(hw->regmap, hw->irq_routing.addr, > hw->irq_routing.mask, enable); > > > + > > + return err; > > +} > > + > > +static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, > > + const struct iio_chan_spec *chan, > > + enum iio_event_type type, > > + enum iio_event_direction dir, > > + enum iio_event_info info, > > + int *val, int *val2) > > +{ > > + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); > > + struct st_lsm6dsx_hw *hw = sensor->hw; > > + > > + if (type != IIO_EV_TYPE_THRESH) > > + return -EINVAL; > > + > > + *val2 = 0; > > + *val = hw->event_threshold; > > + > > + return IIO_VAL_INT; > > +} > > + > > +static int st_lsm6dsx_write_event(struct iio_dev *iio_dev, > > + const struct iio_chan_spec *chan, > > + enum iio_event_type type, > > + enum iio_event_direction dir, > > + enum iio_event_info info, > > + int val, int val2) > > +{ > > + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); > > + struct st_lsm6dsx_hw *hw = sensor->hw; > > + int err; > > + > > + if (type != IIO_EV_TYPE_THRESH) > > + return -EINVAL; > > + > > + if (val < 0 || val > 31) > > + return -EINVAL; > > + > > + err = regmap_update_bits(hw->regmap, > > + hw->settings->event_settings.wakeup_reg.addr, > > + hw->settings->event_settings.wakeup_reg.mask, > > + val); > > + if (err) > > + return -EINVAL; > > + > > + hw->event_threshold = val; > > + > > + return 0; > > +} > > + > > +static int st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, > > + const struct iio_chan_spec *chan, > > + enum iio_event_type type, > > + enum iio_event_direction dir) > > +{ > > + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); > > + struct st_lsm6dsx_hw *hw = sensor->hw; > > + > > + if (type != IIO_EV_TYPE_THRESH) > > + return -EINVAL; > > + > > + return hw->enable_event; > > +} > > + > > +static int st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, > > + const struct iio_chan_spec *chan, > > + enum iio_event_type type, > > + enum iio_event_direction dir, > > + int state) > > +{ > > + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); > > + struct st_lsm6dsx_hw *hw = sensor->hw; > > + int err = 0; > > + > > + if (type != IIO_EV_TYPE_THRESH) > > + return -EINVAL; > > + > > + if (state && hw->enable_event) > > + return 0; > > This does not make a lot of sense to me since you just check to not enable it > if it has been already done. Moreover you need to check if the particular > sensor supports this event (AFAIU just one sensor does right?) > > > + > > + err = st_lsm6dsx_event_setup(hw, state); > > + if (err < 0) > > + return err; > > + > > + err = st_lsm6dsx_sensor_set_enable(sensor, state); > > + if (err < 0) > > + return err; > > + > > + hw->enable_event = state; > > + > > + return 0; > > +} > > + > > int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) > > { > > struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); > > @@ -1240,6 +1371,10 @@ static const struct iio_info st_lsm6dsx_acc_info = { > > .attrs = &st_lsm6dsx_acc_attribute_group, > > .read_raw = st_lsm6dsx_read_raw, > > .write_raw = st_lsm6dsx_write_raw, > > + .read_event_value = st_lsm6dsx_read_event, > > + .write_event_value = st_lsm6dsx_write_event, > > + .read_event_config = st_lsm6dsx_read_event_config, > > + .write_event_config = st_lsm6dsx_write_event_config, > > .hwfifo_set_watermark = st_lsm6dsx_set_watermark, > > }; > > > > @@ -1285,9 +1420,13 @@ static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg) > > switch (drdy_pin) { > > case 1: > > *drdy_reg = hw->settings->int1_addr; > > + hw->irq_routing.addr = hw->settings->int1_func_addr; > > + hw->irq_routing.mask = hw->settings->int_func_mask; > > break; > > case 2: > > *drdy_reg = hw->settings->int2_addr; > > + hw->irq_routing.addr = hw->settings->int2_func_addr; > > + hw->irq_routing.mask = hw->settings->int_func_mask; > > break; > > default: > > dev_err(hw->dev, "unsupported data ready pin\n"); > > -- > > 2.23.0 > >
Attachment:
signature.asc
Description: PGP signature