Commit 635ef601 authored by Linus Walleij's avatar Linus Walleij Committed by Jonathan Cameron
Browse files

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: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/20210308100219.2732156-1-linus.walleij@linaro.org


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 86073fa2
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -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 @@ int iio_read_channel_processed(struct iio_channel *chan, int *val)

	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)
+15 −0
Original line number Diff line number Diff line
@@ -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.