Report iio motion events to iio subsystem Signed-off-by: Sean Nyekjaer <sean@xxxxxxxxxx> --- Changes since v4: * Updated bitmask as pr Jonathans comments Changes since v5: * None drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 5 ++ drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 70 ++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index d04473861fba..015b837f366f 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -186,6 +186,11 @@ struct st_lsm6dsx_shub_settings { struct st_lsm6dsx_event_settings { struct st_lsm6dsx_reg enable_reg; struct st_lsm6dsx_reg wakeup_reg; + u8 wakeup_src_reg; + u8 wakeup_src_status_mask; + u8 wakeup_src_z_mask; + u8 wakeup_src_y_mask; + u8 wakeup_src_x_mask; }; enum st_lsm6dsx_ext_sensor_id { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 5b8bcd9cc4d2..bd5c7c65a519 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -48,6 +48,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/delay.h> +#include <linux/iio/events.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/interrupt.h> @@ -283,6 +284,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x5B, .mask = GENMASK(5, 0), }, + .wakeup_src_reg = 0x1b, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), }, }, { @@ -404,6 +410,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x5B, .mask = GENMASK(5, 0), }, + .wakeup_src_reg = 0x1b, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), }, }, { @@ -538,6 +549,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x5B, .mask = GENMASK(5, 0), }, + .wakeup_src_reg = 0x1b, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), }, }, { @@ -788,6 +804,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x5B, .mask = GENMASK(5, 0), }, + .wakeup_src_reg = 0x1b, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), }, }, { @@ -934,6 +955,11 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x5B, .mask = GENMASK(5, 0), }, + .wakeup_src_reg = 0x1b, + .wakeup_src_status_mask = BIT(3), + .wakeup_src_z_mask = BIT(0), + .wakeup_src_y_mask = BIT(1), + .wakeup_src_x_mask = BIT(2), } }, }; @@ -1659,6 +1685,38 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, return iio_dev; } +void st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw, int data) +{ + s64 timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); + + if (data & hw->settings->event_settings.wakeup_src_z_mask) + iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_Z, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); + + if (data & hw->settings->event_settings.wakeup_src_x_mask) + iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_Y, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); + + if (data & hw->settings->event_settings.wakeup_src_x_mask) + iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], + IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_X, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + timestamp); +} + static irqreturn_t st_lsm6dsx_handler_irq(int irq, void *private) { return IRQ_WAKE_THREAD; @@ -1668,6 +1726,18 @@ static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) { struct st_lsm6dsx_hw *hw = private; int count; + int data, err; + + if (hw->enable_event) { + err = regmap_read(hw->regmap, + hw->settings->event_settings.wakeup_src_reg, + &data); + if (err < 0) + return IRQ_NONE; + + if (data & hw->settings->event_settings.wakeup_src_status_mask) + st_lsm6dsx_report_motion_event(hw, data); + } mutex_lock(&hw->fifo_lock); count = hw->settings->fifo_ops.read_fifo(hw); -- 2.23.0