@@ -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 {
@@ -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>
@@ -287,6 +288,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),
},
},
{
@@ -412,6 +418,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),
},
},
{
@@ -550,6 +561,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),
},
},
{
@@ -816,6 +832,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),
},
},
{
@@ -970,6 +991,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),
}
},
};
@@ -1715,6 +1741,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;
@@ -1724,6 +1782,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);
Report iio motion events to iio subsystem Signed-off-by: Sean Nyekjaer <sean@geanix.com> --- Changes since v4: * Updated bitmask as pr Jonathans comments Changes since v5: * None Changes since v6: * 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(+)