Re: [PATCH 2/4] iio: add processed write API

Andy Shevchenko
2025-09-16T13:03:11Z

On Tue, Sep 16, 2025 at 12:24:07PM +0200, Romain Gantois wrote:
> Add a function to allow IIO consumers to write a processed value to a
> channel.

...

> +static int iio_convert_processed_to_raw_unlocked(struct iio_channel *chan,
> + int processed, int *raw,
> + unsigned int scale)
> +{
> + int scale_type, scale_val, scale_val2;
> + int offset_type, offset_val, offset_val2;
> + s64 tmp_num, tmp_den;
> +
> + scale_type = iio_channel_read(chan, &scale_val, &scale_val2,
> + IIO_CHAN_INFO_SCALE);
> + if (scale_type >= 0) {
> + switch (scale_type) {
> + case IIO_VAL_INT:
> + tmp_num = processed;
> + tmp_den = scale_val;
> + break;
> + case IIO_VAL_INT_PLUS_MICRO:
> + tmp_num = (s64)processed * 1000000LL;

If you go with this, in IIO we heavily use units.h and here something like
(s64)MICRO would be appropriate. Similar to the rest of the code where one
or another constant may be used.

> + if (scale_val2 < 0) {
> + tmp_den = (s64)scale_val * 1000000LL - (s64)scale_val2;
> + tmp_den *= -1;
> + } else {
> + tmp_den = (s64)scale_val * 1000000LL + (s64)scale_val2;
> + }
> +
> + break;
> + case IIO_VAL_INT_PLUS_NANO:
> + tmp_num = (s64)processed * 1000000000LL;
> +
> + if (scale_val2 < 0) {
> + tmp_den = (s64)scale_val * 1000000000LL - (s64)scale_val2;
> + tmp_den *= -1;
> + } else {
> + tmp_den = (s64)scale_val * 1000000000LL + (s64)scale_val2;
> + }
> +
> + break;
> + case IIO_VAL_FRACTIONAL:
> + tmp_num = (s64)processed * (s64)scale_val2;
> + tmp_den = scale_val;
> + break;
> + case IIO_VAL_FRACTIONAL_LOG2:
> + tmp_num = (s64)processed << scale_val2;
> + tmp_den = scale_val;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + tmp_den *= scale;
> +
> + *raw = div64_s64(tmp_num, tmp_den);
> + }
> +
> + offset_type = iio_channel_read(chan, &offset_val, &offset_val2,
> + IIO_CHAN_INFO_OFFSET);
> + if (offset_type >= 0) {
> + switch (offset_type) {
> + case IIO_VAL_INT:
> + case IIO_VAL_INT_PLUS_MICRO:
> + case IIO_VAL_INT_PLUS_NANO:
> + break;
> + case IIO_VAL_FRACTIONAL:
> + offset_val /= offset_val2;
> + break;
> + case IIO_VAL_FRACTIONAL_LOG2:
> + offset_val >>= offset_val2;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + *raw -= offset_val;
> + }
> +
> + return 0;
> +}

...

> +/**
> + * iio_write_channel_processed_scale() - scale and write processed value to a given channel
> + * @chan: The channel being queried.
> + * @val: Value to write.
> + * @scale: Scale factor to apply during the conversion
> + *
> + * Returns an error code or 0.
> + *
> + * This function writes a processed value to a channel. A processed value means
> + * that this value will have the correct unit and not some device internal
> + * representation. If the device does not support writing a processed value, the
> + * function will query the channel's scale and offset and write an appropriately
> + * transformed raw value.
> + */

This needs a run via kernel-doc validator (warning: Missing Return section).
Also note, in accordance with kernel-doc documentation the Return section must
be last in the big description.

--
With Best Regards,
Andy Shevchenko