From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Message-ID: <519CFCEB.1010606@metafoo.de> Date: Wed, 22 May 2013 19:14:19 +0200 From: Lars-Peter Clausen MIME-Version: 1.0 To: Guillaume Ballet CC: Jonathan Cameron , linux-iio@vger.kernel.org Subject: Re: Why is only one int returned in iio_read_channel_processed? References: <519C7C29.9040707@jic23.retrosnub.co.uk> <519C7F93.9010606@metafoo.de> <519C8923.7020902@jic23.retrosnub.co.uk> <519CAF57.5030301@metafoo.de> <519CCAA2.2070408@metafoo.de> <519CD307.8020404@metafoo.de> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 List-ID: 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. - Lars