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

iio: afe: rescale: Accept only offset channels

As noted by Jonathan Cameron: it is perfectly legal for a channel
to have an offset but no scale in addition to the raw interface.
The conversion will imply that scale is 1:1.

Make rescale_configure_channel() accept just scale, or just offset
to process a channel.

When a user asks for IIO_CHAN_INFO_OFFSET in rescale_read_raw()
we now have to deal with the fact that OFFSET could be present
but SCALE missing. Add code to simply scale 1:1 in this case.

Link: https://lore.kernel.org/linux-iio/CACRpkdZXBjHU4t-GVOCFxRO-AHGxKnxMeHD2s4Y4PuC29gBq6g@mail.gmail.com/


Fixes: 53ebee94 ("iio: afe: iio-rescale: Support processed channels")
Fixes: 9decacd8 ("iio: afe: rescale: Fix boolean logic bug")
Reported-by: default avatarJonathan Cameron <jic23@kernel.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarPeter Rosin <peda@axentia.se>
Link: https://lore.kernel.org/r/20230902-iio-rescale-only-offset-v2-1-988b807754c8@linaro.org


Cc: <Stable@vger.kernel.org>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 865b080e
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -214,9 +214,19 @@ static int rescale_read_raw(struct iio_dev *indio_dev,
				return ret < 0 ? ret : -EOPNOTSUPP;
		}

		if (iio_channel_has_info(rescale->source->channel,
					 IIO_CHAN_INFO_SCALE)) {
			ret = iio_read_channel_scale(rescale->source, &scale, &scale2);
			return rescale_process_offset(rescale, ret, scale, scale2,
						      schan_off, val, val2);
		}

		/*
		 * If we get here we have no scale so scale 1:1 but apply
		 * rescaler and offset, if any.
		 */
		return rescale_process_offset(rescale, IIO_VAL_FRACTIONAL, 1, 1,
					      schan_off, val, val2);
	default:
		return -EINVAL;
	}
@@ -280,8 +290,9 @@ static int rescale_configure_channel(struct device *dev,
	chan->type = rescale->cfg->type;

	if (iio_channel_has_info(schan, IIO_CHAN_INFO_RAW) &&
	    iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) {
		dev_info(dev, "using raw+scale source channel\n");
	    (iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE) ||
	     iio_channel_has_info(schan, IIO_CHAN_INFO_OFFSET))) {
		dev_info(dev, "using raw+scale/offset source channel\n");
	} else if (iio_channel_has_info(schan, IIO_CHAN_INFO_PROCESSED)) {
		dev_info(dev, "using processed channel\n");
		rescale->chan_processed = true;