From: Francesco Lavra Date: Mon, 1 Dec 2025 10:00:18 +0000 (+0100) Subject: iio: imu: st_lsm6dsx: add tap event detection X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ce40e01d7ce2a15ba14fde314df30787fa1d58cb;p=thirdparty%2Fkernel%2Flinux.git iio: imu: st_lsm6dsx: add tap event detection In order to allow sensors to advertise tap event capability and report tap events, define a new struct iio_event_spec array that includes a tap event spec, and a new struct iio_chan_spec array that references the new iio_event_spec array; for the LSM6DSV chip family, use the new iio_chan_spec array and define an event source for tap events. Tested on LSMDSV16X. Signed-off-by: Francesco Lavra Reviewed-by: Andy Shevchenko Acked-by: Lorenzo Bianconi Signed-off-by: Jonathan Cameron --- diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 555b826185a4..07b1773c87bd 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -263,6 +263,7 @@ struct st_lsm6dsx_shub_settings { enum st_lsm6dsx_event_id { ST_LSM6DSX_EVENT_WAKEUP, + ST_LSM6DSX_EVENT_TAP, ST_LSM6DSX_EVENT_MAX }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index f28607a31f18..a39d25434015 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -103,6 +103,21 @@ static const struct iio_event_spec st_lsm6dsx_ev_motion[] = { }, }; +static const struct iio_event_spec st_lsm6dsx_ev_motion_tap[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_GESTURE, + .dir = IIO_EV_DIR_SINGLETAP, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { ST_LSM6DSX_CHANNEL_ACC(0x28, IIO_MOD_X, 0, st_lsm6dsx_ev_motion), ST_LSM6DSX_CHANNEL_ACC(0x2a, IIO_MOD_Y, 1, st_lsm6dsx_ev_motion), @@ -110,6 +125,13 @@ static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3), }; +static const struct iio_chan_spec st_lsm6dsx_acc_tap_channels[] = { + ST_LSM6DSX_CHANNEL_ACC(0x28, IIO_MOD_X, 0, st_lsm6dsx_ev_motion_tap), + ST_LSM6DSX_CHANNEL_ACC(0x2a, IIO_MOD_Y, 1, st_lsm6dsx_ev_motion_tap), + ST_LSM6DSX_CHANNEL_ACC(0x2c, IIO_MOD_Z, 2, st_lsm6dsx_ev_motion_tap), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), @@ -1255,8 +1277,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { }, .channels = { [ST_LSM6DSX_ID_ACC] = { - .chan = st_lsm6dsx_acc_channels, - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + .chan = st_lsm6dsx_acc_tap_channels, + .len = ARRAY_SIZE(st_lsm6dsx_acc_tap_channels), }, [ST_LSM6DSX_ID_GYRO] = { .chan = st_lsm6dsx_gyro_channels, @@ -1435,6 +1457,32 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .status_y_mask = BIT(1), .status_x_mask = BIT(2), }, + [ST_LSM6DSX_EVENT_TAP] = { + .x_value = { + .addr = 0x57, + .mask = GENMASK(4, 0), + }, + .y_value = { + .addr = 0x58, + .mask = GENMASK(4, 0), + }, + .z_value = { + .addr = 0x59, + .mask = GENMASK(4, 0), + }, + .enable_mask = BIT(6), + .enable_axis_reg = 0x56, + .enable_x_mask = BIT(3), + .enable_y_mask = BIT(2), + .enable_z_mask = BIT(1), + .status = { + .addr = 0x46, + .mask = BIT(5), + }, + .status_x_mask = BIT(2), + .status_y_mask = BIT(1), + .status_z_mask = BIT(0), + }, }, }, }, @@ -1949,6 +1997,8 @@ st_lsm6dsx_get_event_id(enum iio_event_type type) switch (type) { case IIO_EV_TYPE_THRESH: return ST_LSM6DSX_EVENT_WAKEUP; + case IIO_EV_TYPE_GESTURE: + return ST_LSM6DSX_EVENT_TAP; default: return ST_LSM6DSX_EVENT_MAX; } @@ -2610,6 +2660,9 @@ static bool st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) events_found = st_lsm6dsx_report_events(hw, ST_LSM6DSX_EVENT_WAKEUP, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER); + events_found |= st_lsm6dsx_report_events(hw, ST_LSM6DSX_EVENT_TAP, + IIO_EV_TYPE_GESTURE, + IIO_EV_DIR_SINGLETAP); return events_found; }