]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iio: adc: ad7380: fix event threshold shift
authorDavid Lechner <dlechner@baylibre.com>
Wed, 2 Apr 2025 23:55:58 +0000 (18:55 -0500)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 7 Apr 2025 18:32:50 +0000 (19:32 +0100)
Add required bit shift to the event threshold read function to get
correct scaling.

When alert support was added, the write function correctly included the
required shift needed to convert the threshold register value to the
same scale as the raw ADC value. However, the shift got missed in the
read function.

Fixes: 27d1a4dbe1e1 ("iio: adc: ad7380: add alert support")
Signed-off-by: David Lechner <dlechner@baylibre.com>
Reviewed-by: Julien Stephan <jstephan@baylibre.com>
Link: https://patch.msgid.link/20250402-iio-adc-ad7380-fix-event-threshold-shift-v1-1-ad4975c296b2@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/ad7380.c

index a2b41980c942e4cd1575bfe4f3846e297ad5d01d..aef85093eb16cbe9cc062f8cb4239e955c8a21b6 100644 (file)
@@ -1610,11 +1610,25 @@ static int ad7380_write_event_config(struct iio_dev *indio_dev,
        return ret;
 }
 
-static int ad7380_get_alert_th(struct ad7380_state *st,
+static int ad7380_get_alert_th(struct iio_dev *indio_dev,
+                              const struct iio_chan_spec *chan,
                               enum iio_event_direction dir,
                               int *val)
 {
-       int ret, tmp;
+       struct ad7380_state *st = iio_priv(indio_dev);
+       const struct iio_scan_type *scan_type;
+       int ret, tmp, shift;
+
+       scan_type = iio_get_current_scan_type(indio_dev, chan);
+       if (IS_ERR(scan_type))
+               return PTR_ERR(scan_type);
+
+       /*
+        * The register value is 12-bits and is compared to the most significant
+        * bits of raw value, therefore a shift is required to convert this to
+        * the same scale as the raw value.
+        */
+       shift = scan_type->realbits - 12;
 
        switch (dir) {
        case IIO_EV_DIR_RISING:
@@ -1624,7 +1638,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
                if (ret)
                        return ret;
 
-               *val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp);
+               *val = FIELD_GET(AD7380_ALERT_HIGH_TH, tmp) << shift;
                return IIO_VAL_INT;
        case IIO_EV_DIR_FALLING:
                ret = regmap_read(st->regmap,
@@ -1633,7 +1647,7 @@ static int ad7380_get_alert_th(struct ad7380_state *st,
                if (ret)
                        return ret;
 
-               *val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp);
+               *val = FIELD_GET(AD7380_ALERT_LOW_TH, tmp) << shift;
                return IIO_VAL_INT;
        default:
                return -EINVAL;
@@ -1647,7 +1661,6 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
                                   enum iio_event_info info,
                                   int *val, int *val2)
 {
-       struct ad7380_state *st = iio_priv(indio_dev);
        int ret;
 
        switch (info) {
@@ -1655,7 +1668,7 @@ static int ad7380_read_event_value(struct iio_dev *indio_dev,
                if (!iio_device_claim_direct(indio_dev))
                        return -EBUSY;
 
-               ret = ad7380_get_alert_th(st, dir, val);
+               ret = ad7380_get_alert_th(indio_dev, chan, dir, val);
 
                iio_device_release_direct(indio_dev);
                return ret;