From 05f958d003c9a9a215a5f8687a14534cc1dad271 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 31 Aug 2025 12:48:23 +0200 Subject: [PATCH] iio: Improve iio_read_channel_processed_scale() precision 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 Signed-off-by: Hans de Goede Link: https://patch.msgid.link/20250831104825.15097-5-hansg@kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/inkern.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 158d54de14a79..1e5eb5a412711 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -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) -- 2.47.3