]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iio: Improve iio_read_channel_processed_scale() precision
authorHans de Goede <hansg@kernel.org>
Sun, 31 Aug 2025 10:48:23 +0000 (12:48 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Wed, 10 Sep 2025 18:47:04 +0000 (19:47 +0100)
Before this change iio_read_channel_processed_scale() always assumes that
channels which advertise IIO_CHAN_INFO_PROCESSED capability return
IIO_VAL_INT on success.

Ignoring any fractional values from drivers which return
IIO_VAL_INT_PLUS_MICRO / IIO_VAL_INT_PLUS_NANO. These fractional values
might become non fractional after scaling so these should be taken into
account for better precision.

Use the new iio_multiply_value() helper to do proper scaling taking
the fractionional values into account.

Reviewed-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Hans de Goede <hansg@kernel.org>
Link: https://patch.msgid.link/20250831104825.15097-5-hansg@kernel.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/inkern.c

index 158d54de14a799bb52b18af471509c0b5222f3c3..1e5eb5a412711ebcd625441846ab97933b4cac80 100644 (file)
@@ -726,20 +726,19 @@ int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
                                     unsigned int scale)
 {
        struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(chan->indio_dev);
-       int ret;
+       int ret, pval, pval2;
 
        guard(mutex)(&iio_dev_opaque->info_exist_lock);
        if (!chan->indio_dev->info)
                return -ENODEV;
 
        if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
-               ret = iio_channel_read(chan, val, NULL,
+               ret = iio_channel_read(chan, &pval, &pval2,
                                       IIO_CHAN_INFO_PROCESSED);
                if (ret < 0)
                        return ret;
-               *val *= scale;
 
-               return ret;
+               return iio_multiply_value(val, scale, ret, pval, pval2);
        } else {
                ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
                if (ret < 0)