Re: [PATCH v8 5/5] iio: imu: st_lsm6dsx: add motion report function and call from interrupt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 15/09/2019 15.18, Jonathan Cameron wrote:
On Sun, 15 Sep 2019 15:05:08 +0200
Lorenzo Bianconi <lorenzo@xxxxxxxxxx> wrote:

On Fri, 13 Sep 2019 11:07:08 +0200
Sean Nyekjaer <sean@xxxxxxxxxx> wrote:
Report iio motion events to iio subsystem

Signed-off-by: Sean Nyekjaer <sean@xxxxxxxxxx>
I got to the earlier thread rather late so hadn't replied to your
question on filtering events that haven't been enabled.

IIUC, how is possible to filter events? it seems not currently supported in
hw, right?
Filter them in software on their way to userspace.  So you'll get an interrupt
either way, but no need to tell userspace about event's it's not interested
in.

Fine by me, will submit a V9.

Which one is preferred:
in_accel_thresh_(x,y,z)_en -> in_accel_thresh_both_en
or keep in_accel_thresh_(x,y,z)_en and filter them in the driver?

We would wake on all events either way

/Sean



Hence I think it's just that change outstanding
+ I want to give Lorenzo time for a final look.

Jonathan the series seems fine to me now, there are some leftover nitpicks we can
cover with some follow-up patches.

Acks/Reviewed-bys?  Let's do this formally!

Jonathan


Regards,
Lorenzo


Thanks,

Jonathan
---
Changes since v4:
  * Updated bitmask as pr Jonathans comments

Changes since v5:
  * None

Changes since v6:
  * None

Changes since v7:
  * 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 449c2798f7ed..7c50fac7b85c 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 80a94335175f..66700c20920d 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>
@@ -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);




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux