From: H Hartley Sweeten Date: Wed, 5 Jun 2013 22:38:37 +0000 (-0700) Subject: staging: comedi: pcmad: properly handle analog input encoding configuration X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=7ecc5370de1562b2410604ed78aec087e55c06cf;p=linux-beck.git staging: comedi: pcmad: properly handle analog input encoding configuration The comedi_config utility is used to attach to this board. One of the configuration options passed by the user sets the analog input encoding for straight binary or two's complement data. The hardware produces straight binary data when jumpered for 5V unipolar inputs and two's complement data when jumpered for +-10V bipolar inputs. Use the configuration option to correctly set the comedi_subdevice range_table. We can then use a helper function to determine what the range is when reading the analog inputs. This allows removing the 'twos_comp' variable from the private data (which was actually never used). Since the private data is now empty, remove it completely. Signed-off-by: H Hartley Sweeten Cc: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c index 86597fcf23bf..8028e476bff3 100644 --- a/drivers/staging/comedi/drivers/pcmad.c +++ b/drivers/staging/comedi/drivers/pcmad.c @@ -34,8 +34,8 @@ * 0 = single-ended (16 channels) * 1 = differential (8 channels) * [3] - Analog input encoding (must match jumpers) - * 0 = straight binary - * 1 = two's complement + * 0 = straight binary (0-5V input range) + * 1 = two's complement (+-10V input range) */ #include @@ -63,10 +63,6 @@ static const struct pcmad_board_struct pcmad_boards[] = { }, }; -struct pcmad_priv_struct { - int twos_comp; -}; - #define TIMEOUT 100 static int pcmad_ai_wait_for_eoc(struct comedi_device *dev, @@ -81,13 +77,19 @@ static int pcmad_ai_wait_for_eoc(struct comedi_device *dev, return -ETIME; } +static bool pcmad_range_is_bipolar(struct comedi_subdevice *s, + unsigned int range) +{ + return s->range_table->range[range].min < 0; +} + static int pcmad_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - struct pcmad_priv_struct *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); unsigned int val; int ret; int i; @@ -102,8 +104,10 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, val = inb(dev->iobase + PCMAD_LSB) | (inb(dev->iobase + PCMAD_MSB) << 8); - if (devpriv->twos_comp) + if (pcmad_range_is_bipolar(s, range)) { + /* munge the two's complement value */ val ^= ((s->maxdata + 1) >> 1); + } data[i] = val; } @@ -114,7 +118,6 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct pcmad_board_struct *board = comedi_board(dev); - struct pcmad_priv_struct *devpriv; struct comedi_subdevice *s; int ret; @@ -126,11 +129,6 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret) return ret; - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); - if (!devpriv) - return -ENOMEM; - dev->private = devpriv; - s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; if (it->options[1]) { @@ -144,7 +142,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) } s->len_chanlist = 1; s->maxdata = board->ai_maxdata; - s->range_table = &range_unknown; + s->range_table = it->options[2] ? &range_bipolar10 : &range_unipolar5; s->insn_read = pcmad_ai_insn_read; return 0;