On Thursday, August 13, 2015 2:29 AM, Ian Abbott wrote:
> On 13/08/15 01:00, H Hartley Sweeten wrote:
>> The comedi_offset_munge() helper is used to convert unsigned int data
>> values from the comedi offset binary format to two's complement values
>> for hardware that needs the data in that format. The comedi data is
>> always checked against s->maxdata before writing to the hardware so
>> the current implementation always works correctly.
>>
>> It also works to convert the hardware two's complement data into the
>> offset binary format used by comedi. Unfortunately, some boards
>> return extra data in the upper bits. The current implementation
>> ends up leaving these bits in the converted value.
>>
>> Mask the converted value to ensure that any extra bits are removed.
>>
>> Signed-off-by: H Hartley Sweeten <hswee...@visionengravers.com>
>> Cc: Ian Abbott <abbo...@mev.co.uk>
>> Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
>> ---
>>   drivers/staging/comedi/comedidev.h | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/staging/comedi/comedidev.h 
>> b/drivers/staging/comedi/comedidev.h
>> index 28a5d3a..1c8ed5d 100644
>> --- a/drivers/staging/comedi/comedidev.h
>> +++ b/drivers/staging/comedi/comedidev.h
>> @@ -388,7 +388,7 @@ static inline bool comedi_chan_range_is_external(struct 
>> comedi_subdevice *s,
>>   static inline unsigned int comedi_offset_munge(struct comedi_subdevice *s,
>>                                             unsigned int val)
>>   {
>> -    return val ^ s->maxdata ^ (s->maxdata >> 1);
>> +    return (val ^ s->maxdata ^ (s->maxdata >> 1)) & s->maxdata;
>>   }
>>
>>   /**
>>
>
> I don't really like this.  I think the function should only be concerned 
> with converting samples between 2's complement and offset binary format 
> and leave any other manipulations up to the driver.  For example, the 
> amplc_pci230 driver needs to right-shift the raw register value from 
> PCI230 in addition to converting from 2's complement (although it does 
> not currently use comedi_offset_munge() to do it).  This change to 
> comedi_offset_munge() also hides whether there may or may not have been 
> extra bits that needed to be stripped.

I disagree.

The drivers should be dealing with any of the "extra" bits and any special 
shifting
of the data before calling comedi_offset_munge() to convert the data. This is
especially true in the (*insn_read) operations where the samples read from the
hardware are directly added to the returned data:

        val = inx(iobase);
        /* 
         * Handle any special "extra" bits in the sample data and/or any 
shifting
         * of the sample that only the driver knows about.
         */
        /* return the munged data to the user */
        data[i] = comedi_offset_munge(val);

This way the "val" does not require any extra masking before doing the 
conversion
and returning the data to the user. The right-shift operation is still handled 
by the
driver because it's the only one that knows this is needed.

Regards,
Hartley

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to