On 05/23/2013 11:52 AM, Guillaume Ballet wrote: > On Wed, May 22, 2013 at 7:14 PM, Lars-Peter Clausen <lars@xxxxxxxxxx> wrote: >> On 05/22/2013 05:24 PM, Guillaume Ballet wrote: >> [...] >>>>> Hence my need to call iio_read_channel_processed >>>>> and not entrust anyone else with the conversion. >>>> >>>> Ah, ok, so your driver implements IIO_CHAN_INFO_PROCESSED instead of >>>> IIO_CHAN_INFO_RAW. And you want to be able to specify your value with >>>> sub-decimal precession, is this correct? >>> >>> Absolutely. >>> >>>> >>>>> >>>>> Could _you_ please explain what your concern with using the same format is? >>>> >>>> Because the definition of IIO_CHAN_INFO_PROCESSED is that the value has >>>> already the proper unit and no unit conversion is necessary. >>> >>> Now I see, thanks. >>> >>> Getting back to the precision issue, I see that in >>> iio_convert_raw_to_processed_unlocked() there is the following code: >>> >>> case IIO_VAL_INT_PLUS_MICRO: >>> if (scale_val2 < 0) >>> *processed = -raw64 * scale_val; >>> else >>> *processed = raw64 * scale_val; >>> *processed += div_s64(raw64 * (s64)scale_val2 * scale, >>> 1000000LL); >>> break; >>> case IIO_VAL_INT_PLUS_NANO: >>> if (scale_val2 < 0) >>> *processed = -raw64 * scale_val; >>> else >>> *processed = raw64 * scale_val; >>> *processed += div_s64(raw64 * (s64)scale_val2 * scale, >>> >>> with processed being of type int *. So the sub-decimal precision is >>> indeed lost. Is there a big issue with adapting the code to also >>> handle sub-decimal precision, then? >> >> Well it's not an issue per se, it's just that there are no in kernel users >> which would be able to make use of this. The iio_convert_raw_to_processed() >> function takes an additional scale parameter though which allows you to get >> a value with a high precession. E.g. if you read a voltage channel with >> scale set to 1000 you'll get the result in micro Volts instead of milli >> Volts. The same parameter could be added to iio_read_channel_processed() and >> you'd do similar calculations as in iio_convert_raw_to_processed(). Instead >> of 'raw64 * scale_val' you'd just use 'val' and instead of 'raw64 * >> scale_val2' you'd use 'val2'. >> >> E.g. for IIO_VAL_INT_PLUS_MICRO: >> if (val2 < 0) >> *processed = -val; >> else >> *processed = val; >> *processed += div_s64((s64)val2 * scale, 1000000LL); >> >> and so on. >> >> >> And I think for sysfs nodes it should already work fine, e.g. if you return >> IIO_VAL_INT_PLUS_MICRO. >> > > That makes sense. However, the following reasons make me think passing > the scale is not the correct way to proceed: > > - if IIO_INT_VAL_PLUS_NANO is returned (common when dealing with > current sources), 32 bits is a bit tight - which is why the read_raw > function pointer in iio_info has (val, val2) in the first place. > - People like me who do not use the iio_convert_raw_to_processed > path() but need to support IIO_CHAN_INFO_PROCESSED directly in their > driver have an issue: we would need to be passed the scale in the > read_raw function of iio_info. That would impact _all_ IIO drivers. IIO_CHAN_INFO_PROCESSED is by definition supposed to return the value in the proper unit. If that doesn't work for you use IIO_CHAN_INFO_RAW + IIO_CHAN_INFO_SCALE. Think of IIO_CHAN_INFO_PROCESSED as IIO_CHAN_INFO_RAW with the scale set to 1.0 > - The scale parameter to iio_convert_raw_to_processed() itself is an > int, and IIO_CHAN_INFO_SCALE can return a scale in the > IIO_VAL_INT_PLUS_NANO scheme. It means somewhere along the road, > precision is lost. The scale would be passed in by the consumer, so the consumer is able to specify the amount of precision it wants. - Lars -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html