Re: Why is only one int returned in iio_read_channel_processed?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
- 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.

Guillaume
--
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




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux