From: Lorenzo Bianconi <lorenzo@kernel.org>
To: Sean Nyekjaer <sean@geanix.com>
Cc: linux-iio@vger.kernel.org, jic23@kernel.org,
lorenzo.bianconi83@gmail.com, martin@geanix.com
Subject: Re: [PATCH 2/5] iio: imu: st_lsm6dsx: add motion events
Date: Tue, 18 Jun 2019 22:21:43 +0200 [thread overview]
Message-ID: <20190618202142.GA930@localhost.localdomain> (raw)
In-Reply-To: <e41ada28-a8b5-2911-7dd0-d8833debdcee@geanix.com>
[-- Attachment #1: Type: text/plain, Size: 10669 bytes --]
On Jun 18, Sean Nyekjaer wrote:
>
>
> On 18/06/2019 17.49, Lorenzo Bianconi wrote:
> > > Add event channels that controls the creation of motion events.
> > >
> > > Signed-off-by: Sean Nyekjaer <sean@geanix.com>
> > > ---
> > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +
> > > drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 148 ++++++++++++++++++-
> > > 2 files changed, 144 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> > > index a5e373680e9c..966cc6e91c7f 100644
> > > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> > > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
> > > @@ -155,6 +155,8 @@ struct st_lsm6dsx_hw {
> > > u8 enable_mask;
> > > u8 ts_sip;
> > > u8 sip;
> > > + u8 event_threshold;
> > > + bool enable_event;
> > > u8 *buff;
> > > diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > index b5d3fa354de7..351c46f01662 100644
> > > --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> > > @@ -78,6 +78,17 @@
> > > #define ST_LSM6DSX_REG_GYRO_OUT_Y_L_ADDR 0x24
> > > #define ST_LSM6DSX_REG_GYRO_OUT_Z_L_ADDR 0x26
> > > +#define ST_LSM6DSX_REG_TAP_CFG_ADDR 0x58
> > > +#define ST_LSM6DSX_REG_TAP_CFG_INT_EN_MASK BIT(7)
> > > +#define ST_LSM6DSX_REG_TAP_CFG_INACT_EN_MASK GENMASK(6, 5)
> > > +
> > > +#define ST_LSM6DSX_DEFAULT_WAKE_THRESH 0
> > > +#define ST_LSM6DSX_REG_WAKE_UP_THS_ADDR 0x5B
> > > +#define ST_LSM6DSX_REG_WAKE_UP_THS_THRES_MASK GENMASK(5, 0)
> >
> > Could you please verify this registermap is used for all supported devices?
> > (e.g. LSM6DS3 or LSM6DS3H)
>
> They have the same registers and the bits meaning the same.
> But I can't test on those devices...
I do think so since BIT(7) of 0x58 TAP_CFG in LSM6DS3/LSM6DS3H is used to
enable hw timestamp...moreover I think there are other differences
>
> >
> > > +
> > > +#define ST_LSM6DSX_REG_MD1_CFG_ADDR 0x5E
> > > +#define ST_LSM6DSX_REG_MD1_CFG_INT1_WU_MASK BIT(5)
> > > +
> > > #define ST_LSM6DSX_ACC_FS_2G_GAIN IIO_G_TO_M_S_2(61)
> > > #define ST_LSM6DSX_ACC_FS_4G_GAIN IIO_G_TO_M_S_2(122)
> > > #define ST_LSM6DSX_ACC_FS_8G_GAIN IIO_G_TO_M_S_2(244)
> > > @@ -303,6 +314,13 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
> > > },
> > > };
> > > +static const struct iio_event_spec st_lsm6dsx_event = {
> > > + .type = IIO_EV_TYPE_THRESH,
> > > + .dir = IIO_EV_DIR_EITHER,
> > > + .mask_separate = BIT(IIO_EV_INFO_VALUE) |
> > > + BIT(IIO_EV_INFO_ENABLE)
> > > +};
> > > +
> > > #define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \
> > > { \
> > > .type = chan_type, \
> > > @@ -319,6 +337,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
> > > .storagebits = 16, \
> > > .endianness = IIO_LE, \
> > > }, \
> > > + .event_spec = &st_lsm6dsx_event, \
> > > + .num_event_specs = 1, \
> > > }
> >
> > ST_LSM6DSX_CHANNEL is used even for sensor-hub so I do not think you can use in
> > this way
>
> I see, will need to come up with a solution to avoid the event channels on
> the gyro.
>
> >
> > > static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
> > > @@ -435,6 +455,20 @@ static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 odr)
> > > ST_LSM6DSX_SHIFT_VAL(val, reg->mask));
> > > }
> > > +static int st_lsm6dsx_set_event_threshold(struct st_lsm6dsx_hw *hw, u8 threshold)
> > > +{
> > > + int err = 0;
> > > +
> > > + err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_WAKE_UP_THS_ADDR,
> > > + ST_LSM6DSX_REG_WAKE_UP_THS_THRES_MASK,
> > > + threshold);
> > > +
> > > + if (!err)
> > > + hw->event_threshold = threshold;
> > > +
> > > + return err;
> >
> > I think we can just move this configuration in st_lsm6dsx_write_event()
>
> We could, should I then call st_lsm6dsx_write_event() from the probe
> function?
nope, just run regmap_update_bits() in st_lsm6dsx_write_event (You do not need
to call st_lsm6dsx_set_event_threshold during the probe since the default value
is already 0)
>
> >
> > > +}
> > > +
> > > int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor)
> > > {
> > > int err;
> > > @@ -472,18 +506,21 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
> > > int err, delay;
> > > __le16 data;
> > > - err = st_lsm6dsx_sensor_enable(sensor);
> > > - if (err < 0)
> > > - return err;
> > > + if (!hw->enable_event) {
> > > + err = st_lsm6dsx_sensor_enable(sensor);
> > > + if (err < 0)
> > > + return err;
> > > - delay = 1000000 / sensor->odr;
> > > - usleep_range(delay, 2 * delay);
> > > + delay = 1000000 / sensor->odr;
> > > + usleep_range(delay, 2 * delay);
> > > + }
> > > err = regmap_bulk_read(hw->regmap, addr, &data, sizeof(data));
> > > if (err < 0)
> > > return err;
> > > - st_lsm6dsx_sensor_disable(sensor);
> > > + if (!hw->enable_event)
> > > + st_lsm6dsx_sensor_disable(sensor);
> > > *val = (s16)le16_to_cpu(data);
> > > @@ -556,6 +593,75 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
> > > 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);
> > > +
> > > + *val2 = 0;
> > > + *val = sensor->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;
> > > +
> > > + if (!hw->enable_event)
> > > + return -EBUSY;
> > > +
> > > + if ((val < 0) || (val > 31))
> >
> > unnecessary brackets
>
> Will remove them :-)
>
> >
> > > + return -EINVAL;
> > > +
> > > + if (st_lsm6dsx_set_event_threshold(sensor->hw, val))
> > > + return -EINVAL;
> > > +
> > > + 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;
> > > +
> > > + 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;
> > > +
> > > + if (state && hw->enable_event)
> > > + return 0;
> > > +
> > > + hw->enable_event = state;
> > > + if (state)
> > > + st_lsm6dsx_sensor_enable(sensor);
> >
> > please correct me if I am wrong but in this way we break normal operation (e.g.
> > if we are reading acc data from the FIFO). You need to check enabled_mask.
>
> Will change to the enabled_mask
>
> > Moreover we should check event type
>
> Do we, we only have one type?
for the moment...
>
> >
> > > + else
> > > + st_lsm6dsx_sensor_disable(sensor);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > static int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
> > > {
> > > struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
> > > @@ -632,6 +738,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,
> > > };
> > > @@ -761,6 +871,8 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
> > > if (err < 0)
> > > return err;
> > > + st_lsm6dsx_set_event_threshold(hw, ST_LSM6DSX_DEFAULT_WAKE_THRESH);
> >
> > we do not need this since default value is already 0
>
> I actually think we do need it, if we come up from a reboot we don't know
> the value stored in the register.
Nope, we perform a sw reset during probe since the default value are loaded
>
> >
> > > +
> > > return st_lsm6dsx_init_hw_timer(hw);
> > > }
> > > @@ -811,6 +923,27 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
> > > return iio_dev;
> > > }
> > > +int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw)
> > > +{
> > > + int err;
> > > +
> > > + /* Enable inactivity function - low power ACC, GYRO powered-down */
> > > + err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_TAP_CFG_ADDR,
> > > + ST_LSM6DSX_REG_TAP_CFG_INT_EN_MASK |
> > > + ST_LSM6DSX_REG_TAP_CFG_INACT_EN_MASK,
> > > + ST_LSM6DSX_REG_TAP_CFG_INT_EN_MASK |
> > > + ST_LSM6DSX_REG_TAP_CFG_INACT_EN_MASK);
> > > + if (err < 0)
> > > + return err;
> > > +
> > > + /* Enable wakeup interrupt */
> > > + err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_MD1_CFG_ADDR,
> > > + ST_LSM6DSX_REG_MD1_CFG_INT1_WU_MASK,
> > > + ST_LSM6DSX_REG_MD1_CFG_INT1_WU_MASK);
> > > +
> > > + return err;
> > > +}
> > > +
> > > static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private)
> > > {
> > > struct st_lsm6dsx_hw *hw = private;
> > > @@ -932,6 +1065,9 @@ int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
> > > err = st_lsm6dsx_fifo_setup(hw);
> > > if (err < 0)
> > > return err;
> > > + err = st_lsm6dsx_event_setup(hw);
> > > + if (err < 0)
> > > + return err;
> > > }
> > > for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
> > > --
> > > 2.22.0
> > >
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
next prev parent reply other threads:[~2019-06-18 20:21 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-18 12:59 [PATCH 0/5] iio: imu: st_lsm6dsx: add event reporting and wakeup Sean Nyekjaer
2019-06-18 12:59 ` [PATCH 1/5] iio: imu: st_lsm6dsx: move interrupt thread to core Sean Nyekjaer
2019-06-18 15:57 ` Lorenzo Bianconi
2019-06-18 16:56 ` Sean Nyekjær
2019-06-19 5:58 ` Lorenzo Bianconi
2019-06-19 6:01 ` Sean Nyekjaer
2019-06-18 12:59 ` [PATCH 2/5] iio: imu: st_lsm6dsx: add motion events Sean Nyekjaer
2019-06-18 15:49 ` Lorenzo Bianconi
2019-06-18 19:14 ` Sean Nyekjaer
2019-06-18 20:21 ` Lorenzo Bianconi [this message]
2019-06-19 6:30 ` Sean Nyekjaer
2019-06-18 12:59 ` [PATCH 3/5] iio: imu: st_lsm6dsx: add wakeup-source option Sean Nyekjaer
2019-06-18 15:51 ` Lorenzo Bianconi
2019-06-18 19:19 ` Sean Nyekjaer
2019-06-18 20:27 ` Lorenzo Bianconi
2019-07-01 11:06 ` Sean Nyekjaer
2019-06-18 12:59 ` [PATCH 4/5] iio: imu: st_lsm6dsx: always enter interrupt thread Sean Nyekjaer
2019-06-18 15:55 ` Lorenzo Bianconi
2019-06-18 19:31 ` Sean Nyekjaer
2019-06-18 20:24 ` Lorenzo Bianconi
2019-06-22 9:55 ` Jonathan Cameron
2019-06-22 12:23 ` Lorenzo Bianconi
2019-06-18 12:59 ` [PATCH 5/5] iio: imu: st_lsm6dsx: add motion report function and call from interrupt Sean Nyekjaer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190618202142.GA930@localhost.localdomain \
--to=lorenzo@kernel.org \
--cc=jic23@kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=lorenzo.bianconi83@gmail.com \
--cc=martin@geanix.com \
--cc=sean@geanix.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.