iio: Provide iio_read_channel_processed_scale() API

Since the old iio_read_channel_processed() would
lose precision if we fall back to reading raw and
scaling, we introduce a new API that will pass in
a scale factor when reading a processed channel:
iio_read_channel_processed_scale().

Refactor iio_read_channel_processed() as a special
case with scale factor 1.

Cc: Peter Rosin <peda@axentia.se>
Cc: Chris Lesiak <chris.lesiak@licor.com>
Cc: Jonathan Cameron <jic23@kernel.org>
Cc: linux-iio@vger.kernel.org
Link: https://lore.kernel.org/linux-iio/20201224011607.1059534-1-linus.walleij@linaro.org/
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20210308100219.2732156-1-linus.walleij@linaro.org
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
Linus Walleij 2021-03-08 11:02:18 +01:00 committed by Jonathan Cameron
parent 86073fa2b5
commit 635ef601b2
2 changed files with 29 additions and 2 deletions

View File

@ -688,7 +688,8 @@ int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2)
}
EXPORT_SYMBOL_GPL(iio_read_channel_offset);
int iio_read_channel_processed(struct iio_channel *chan, int *val)
int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
unsigned int scale)
{
int ret;
@ -701,11 +702,15 @@ int iio_read_channel_processed(struct iio_channel *chan, int *val)
if (iio_channel_has_info(chan->channel, IIO_CHAN_INFO_PROCESSED)) {
ret = iio_channel_read(chan, val, NULL,
IIO_CHAN_INFO_PROCESSED);
if (ret)
goto err_unlock;
*val *= scale;
} else {
ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_RAW);
if (ret < 0)
goto err_unlock;
ret = iio_convert_raw_to_processed_unlocked(chan, *val, val, 1);
ret = iio_convert_raw_to_processed_unlocked(chan, *val, val,
scale);
}
err_unlock:
@ -713,6 +718,13 @@ err_unlock:
return ret;
}
EXPORT_SYMBOL_GPL(iio_read_channel_processed_scale);
int iio_read_channel_processed(struct iio_channel *chan, int *val)
{
/* This is just a special case with scale factor 1 */
return iio_read_channel_processed_scale(chan, val, 1);
}
EXPORT_SYMBOL_GPL(iio_read_channel_processed);
int iio_read_channel_scale(struct iio_channel *chan, int *val, int *val2)

View File

@ -241,6 +241,21 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
*/
int iio_read_channel_processed(struct iio_channel *chan, int *val);
/**
* iio_read_channel_processed_scale() - read and scale a processed value
* @chan: The channel being queried.
* @val: Value read back.
* @scale: Scale factor to apply during the conversion
*
* Returns an error code or 0.
*
* This function will read a processed value from a channel. This will work
* like @iio_read_channel_processed() but also scale with an additional
* scale factor while attempting to minimize any precision loss.
*/
int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
unsigned int scale);
/**
* iio_write_channel_attribute() - Write values to the device attribute.
* @chan: The channel being queried.