Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <flavra@baylibre.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Francesco Lavra and committed by
Jonathan Cameron
ce40e01d 317c9bef

+56 -2
+1
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
··· 263 263 264 264 enum st_lsm6dsx_event_id { 265 265 ST_LSM6DSX_EVENT_WAKEUP, 266 + ST_LSM6DSX_EVENT_TAP, 266 267 ST_LSM6DSX_EVENT_MAX 267 268 }; 268 269
+55 -2
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
··· 103 103 }, 104 104 }; 105 105 106 + static const struct iio_event_spec st_lsm6dsx_ev_motion_tap[] = { 107 + { 108 + .type = IIO_EV_TYPE_THRESH, 109 + .dir = IIO_EV_DIR_EITHER, 110 + .mask_separate = BIT(IIO_EV_INFO_VALUE) | 111 + BIT(IIO_EV_INFO_ENABLE), 112 + }, 113 + { 114 + .type = IIO_EV_TYPE_GESTURE, 115 + .dir = IIO_EV_DIR_SINGLETAP, 116 + .mask_separate = BIT(IIO_EV_INFO_VALUE) | 117 + BIT(IIO_EV_INFO_ENABLE), 118 + }, 119 + }; 120 + 106 121 static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { 107 122 ST_LSM6DSX_CHANNEL_ACC(0x28, IIO_MOD_X, 0, st_lsm6dsx_ev_motion), 108 123 ST_LSM6DSX_CHANNEL_ACC(0x2a, IIO_MOD_Y, 1, st_lsm6dsx_ev_motion), 109 124 ST_LSM6DSX_CHANNEL_ACC(0x2c, IIO_MOD_Z, 2, st_lsm6dsx_ev_motion), 125 + IIO_CHAN_SOFT_TIMESTAMP(3), 126 + }; 127 + 128 + static const struct iio_chan_spec st_lsm6dsx_acc_tap_channels[] = { 129 + ST_LSM6DSX_CHANNEL_ACC(0x28, IIO_MOD_X, 0, st_lsm6dsx_ev_motion_tap), 130 + ST_LSM6DSX_CHANNEL_ACC(0x2a, IIO_MOD_Y, 1, st_lsm6dsx_ev_motion_tap), 131 + ST_LSM6DSX_CHANNEL_ACC(0x2c, IIO_MOD_Z, 2, st_lsm6dsx_ev_motion_tap), 110 132 IIO_CHAN_SOFT_TIMESTAMP(3), 111 133 }; 112 134 ··· 1277 1255 }, 1278 1256 .channels = { 1279 1257 [ST_LSM6DSX_ID_ACC] = { 1280 - .chan = st_lsm6dsx_acc_channels, 1281 - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 1258 + .chan = st_lsm6dsx_acc_tap_channels, 1259 + .len = ARRAY_SIZE(st_lsm6dsx_acc_tap_channels), 1282 1260 }, 1283 1261 [ST_LSM6DSX_ID_GYRO] = { 1284 1262 .chan = st_lsm6dsx_gyro_channels, ··· 1456 1434 .status_z_mask = BIT(0), 1457 1435 .status_y_mask = BIT(1), 1458 1436 .status_x_mask = BIT(2), 1437 + }, 1438 + [ST_LSM6DSX_EVENT_TAP] = { 1439 + .x_value = { 1440 + .addr = 0x57, 1441 + .mask = GENMASK(4, 0), 1442 + }, 1443 + .y_value = { 1444 + .addr = 0x58, 1445 + .mask = GENMASK(4, 0), 1446 + }, 1447 + .z_value = { 1448 + .addr = 0x59, 1449 + .mask = GENMASK(4, 0), 1450 + }, 1451 + .enable_mask = BIT(6), 1452 + .enable_axis_reg = 0x56, 1453 + .enable_x_mask = BIT(3), 1454 + .enable_y_mask = BIT(2), 1455 + .enable_z_mask = BIT(1), 1456 + .status = { 1457 + .addr = 0x46, 1458 + .mask = BIT(5), 1459 + }, 1460 + .status_x_mask = BIT(2), 1461 + .status_y_mask = BIT(1), 1462 + .status_z_mask = BIT(0), 1459 1463 }, 1460 1464 }, 1461 1465 }, ··· 1997 1949 switch (type) { 1998 1950 case IIO_EV_TYPE_THRESH: 1999 1951 return ST_LSM6DSX_EVENT_WAKEUP; 1952 + case IIO_EV_TYPE_GESTURE: 1953 + return ST_LSM6DSX_EVENT_TAP; 2000 1954 default: 2001 1955 return ST_LSM6DSX_EVENT_MAX; 2002 1956 } ··· 2660 2610 events_found = st_lsm6dsx_report_events(hw, ST_LSM6DSX_EVENT_WAKEUP, 2661 2611 IIO_EV_TYPE_THRESH, 2662 2612 IIO_EV_DIR_EITHER); 2613 + events_found |= st_lsm6dsx_report_events(hw, ST_LSM6DSX_EVENT_TAP, 2614 + IIO_EV_TYPE_GESTURE, 2615 + IIO_EV_DIR_SINGLETAP); 2663 2616 2664 2617 return events_found; 2665 2618 }