staging: comedi: core: introduce comedi_offset_munge()
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 18 Sep 2013 18:49:33 +0000 (11:49 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 25 Sep 2013 22:45:42 +0000 (15:45 -0700)
commitf0b215d6e8df3b595758b673543a96a013721d8f
treeac59ff75cc3310faf838684094b616a89f15c6c4
parentb609a5959f5ee44342d08ad37faba11bfbeb8b92
staging: comedi: core: introduce comedi_offset_munge()

The comedi core expects the data to/from analog subdevices to be
in offset binary coding. This means that a value of '0' represents
the most negative and a value of 's->maxdata' the most positive
signal of the analog subdevice.

Many comedi drivers require the data written to the analog outputs,
or returned from the analog inputs, be in two's complement format.

Introduce a helper function to munge the data for analog subdevices.
This function simply inverts the sign bit and masks the result by
's->maxdata' to keep the result in range for the subdevice. The
strange:

  return val ^ s->maxdata ^ (s->maxdata >> 1);

is equivalent to:

  return (val ^ ((s->maxdata + 1) >> 1) & s->maxdata;

as long as s->maxdata is a value of the form (1 << n) - 1. This
avoids the 32-bit unsigned overflow for a s->maxdata of 0xffffffff.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/comedidev.h