[PATCH v4 3/4] iio: accel: adxl345: Implement event scaling for ABI compliance
From: Taha Ed-Dafili <hidden>
Date: 2026-02-21 14:13:13
Also in:
linux-iio, lkml
Subsystem:
analog devices inc iio drivers, iio subsystem and drivers, the rest · Maintainers:
Nuno Sá, Michael Hennerich, Jonathan Cameron, Linus Torvalds
The ADXL345 uses a fixed threshold resolution of 62.5 mg/LSB for event-related registers. Previously, the driver reported raw values without a scale factor. Implement IIO_EV_INFO_SCALE for all event types to provide the conversion factor (0.612915 m/s^2) as required by the IIO ABI. Consequently, remove the obsolete comment in adxl345_read_event_value() which stated that the scale factor is not applied. Add explicit write rejection for IIO_EV_INFO_SCALE in adxl345_write_event_value() returning -EINVAL. Suggested-by: Jonathan Cameron <jic23@kernel.org> Signed-off-by: Taha Ed-Dafili <redacted> --- drivers/iio/accel/adxl345_core.c | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/accel/adxl345_core.c b/drivers/iio/accel/adxl345_core.c
index 78e3f799ecc1..eac4ab052fa2 100644
--- a/drivers/iio/accel/adxl345_core.c
+++ b/drivers/iio/accel/adxl345_core.c@@ -213,7 +213,8 @@ static const struct iio_event_spec adxl345_events[] = { .dir = IIO_EV_DIR_RISING, .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | - BIT(IIO_EV_INFO_VALUE), + BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_SCALE), }, { /* activity, ac bit set */
@@ -221,22 +222,27 @@ static const struct iio_event_spec adxl345_events[] = { .dir = IIO_EV_DIR_RISING, .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | - BIT(IIO_EV_INFO_VALUE), + BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_SCALE), }, { /* single tap */ .type = IIO_EV_TYPE_GESTURE, .dir = IIO_EV_DIR_SINGLETAP, .mask_separate = BIT(IIO_EV_INFO_ENABLE), - .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + .mask_shared_by_type = + BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_SCALE) | BIT(IIO_EV_INFO_TIMEOUT), }, { /* double tap */ .type = IIO_EV_TYPE_GESTURE, .dir = IIO_EV_DIR_DOUBLETAP, - .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | - BIT(IIO_EV_INFO_RESET_TIMEOUT) | + .mask_shared_by_type = + BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_SCALE) | + BIT(IIO_EV_INFO_RESET_TIMEOUT) | BIT(IIO_EV_INFO_TAP2_MIN_DELAY), }, };
@@ -275,6 +281,7 @@ static const struct iio_event_spec adxl345_fake_chan_events[] = { .mask_separate = BIT(IIO_EV_INFO_ENABLE), .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_SCALE) | BIT(IIO_EV_INFO_PERIOD), }, {
@@ -284,6 +291,7 @@ static const struct iio_event_spec adxl345_fake_chan_events[] = { .mask_separate = BIT(IIO_EV_INFO_ENABLE), .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_SCALE) | BIT(IIO_EV_INFO_PERIOD), }, };
@@ -1341,6 +1349,16 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, unsigned int tap_threshold; int ret; + /* + * The event threshold LSB is fixed at 62.5 mg/LSB + * 0.0625 * 9.80665 = 0.612915625 m/s^2 + */ + if (info == IIO_EV_INFO_SCALE) { + *val = 0; + *val2 = 612915; + return IIO_VAL_INT_PLUS_MICRO; + } + switch (type) { case IIO_EV_TYPE_MAG: return adxl345_read_mag_value(st, dir, info,
@@ -1355,12 +1373,6 @@ static int adxl345_read_event_value(struct iio_dev *indio_dev, case IIO_EV_TYPE_GESTURE: switch (info) { case IIO_EV_INFO_VALUE: - /* - * The scale factor would be 62.5mg/LSB (i.e. 0xFF = 16g) but - * not applied here. In context of this general purpose sensor, - * what imports is rather signal intensity than the absolute - * measured g value. - */ ret = regmap_read(st->regmap, ADXL345_REG_THRESH_TAP, &tap_threshold); if (ret)
@@ -1401,6 +1413,9 @@ static int adxl345_write_event_value(struct iio_dev *indio_dev, if (ret) return ret; + if (info == IIO_EV_INFO_SCALE) + return -EINVAL; + switch (type) { case IIO_EV_TYPE_MAG: ret = adxl345_write_mag_value(st, dir, info,
--
2.47.3