Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 53ebee949980 ("iio: afe: iio-rescale: Support processed channels")
Fixes: 9decacd8b3a4 ("iio: afe: rescale: Fix boolean logic bug")
Reported-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Peter 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: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Linus Walleij and committed by
Jonathan Cameron
bee44839 865b080e

+15 -4
+15 -4
drivers/iio/afe/iio-rescale.c
··· 214 214 return ret < 0 ? ret : -EOPNOTSUPP; 215 215 } 216 216 217 - ret = iio_read_channel_scale(rescale->source, &scale, &scale2); 218 - return rescale_process_offset(rescale, ret, scale, scale2, 217 + if (iio_channel_has_info(rescale->source->channel, 218 + IIO_CHAN_INFO_SCALE)) { 219 + ret = iio_read_channel_scale(rescale->source, &scale, &scale2); 220 + return rescale_process_offset(rescale, ret, scale, scale2, 221 + schan_off, val, val2); 222 + } 223 + 224 + /* 225 + * If we get here we have no scale so scale 1:1 but apply 226 + * rescaler and offset, if any. 227 + */ 228 + return rescale_process_offset(rescale, IIO_VAL_FRACTIONAL, 1, 1, 219 229 schan_off, val, val2); 220 230 default: 221 231 return -EINVAL; ··· 290 280 chan->type = rescale->cfg->type; 291 281 292 282 if (iio_channel_has_info(schan, IIO_CHAN_INFO_RAW) && 293 - iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE)) { 294 - dev_info(dev, "using raw+scale source channel\n"); 283 + (iio_channel_has_info(schan, IIO_CHAN_INFO_SCALE) || 284 + iio_channel_has_info(schan, IIO_CHAN_INFO_OFFSET))) { 285 + dev_info(dev, "using raw+scale/offset source channel\n"); 295 286 } else if (iio_channel_has_info(schan, IIO_CHAN_INFO_PROCESSED)) { 296 287 dev_info(dev, "using processed channel\n"); 297 288 rescale->chan_processed = true;