Commit 7ecc5370 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

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: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6092e942
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
* 0 = single-ended (16 channels) * 0 = single-ended (16 channels)
* 1 = differential (8 channels) * 1 = differential (8 channels)
* [3] - Analog input encoding (must match jumpers) * [3] - Analog input encoding (must match jumpers)
* 0 = straight binary * 0 = straight binary (0-5V input range)
* 1 = two's complement * 1 = two's complement (+-10V input range)
*/ */
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -63,10 +63,6 @@ static const struct pcmad_board_struct pcmad_boards[] = { ...@@ -63,10 +63,6 @@ static const struct pcmad_board_struct pcmad_boards[] = {
}, },
}; };
struct pcmad_priv_struct {
int twos_comp;
};
#define TIMEOUT 100 #define TIMEOUT 100
static int pcmad_ai_wait_for_eoc(struct comedi_device *dev, 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, ...@@ -81,13 +77,19 @@ static int pcmad_ai_wait_for_eoc(struct comedi_device *dev,
return -ETIME; 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, static int pcmad_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_subdevice *s,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
struct pcmad_priv_struct *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int range = CR_RANGE(insn->chanspec);
unsigned int val; unsigned int val;
int ret; int ret;
int i; int i;
...@@ -102,8 +104,10 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, ...@@ -102,8 +104,10 @@ static int pcmad_ai_insn_read(struct comedi_device *dev,
val = inb(dev->iobase + PCMAD_LSB) | val = inb(dev->iobase + PCMAD_LSB) |
(inb(dev->iobase + PCMAD_MSB) << 8); (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); val ^= ((s->maxdata + 1) >> 1);
}
data[i] = val; data[i] = val;
} }
...@@ -114,7 +118,6 @@ static int pcmad_ai_insn_read(struct comedi_device *dev, ...@@ -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) static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ {
const struct pcmad_board_struct *board = comedi_board(dev); const struct pcmad_board_struct *board = comedi_board(dev);
struct pcmad_priv_struct *devpriv;
struct comedi_subdevice *s; struct comedi_subdevice *s;
int ret; int ret;
...@@ -126,11 +129,6 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -126,11 +129,6 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
if (ret) if (ret)
return ret; return ret;
devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
if (!devpriv)
return -ENOMEM;
dev->private = devpriv;
s = &dev->subdevices[0]; s = &dev->subdevices[0];
s->type = COMEDI_SUBD_AI; s->type = COMEDI_SUBD_AI;
if (it->options[1]) { if (it->options[1]) {
...@@ -144,7 +142,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -144,7 +142,7 @@ static int pcmad_attach(struct comedi_device *dev, struct comedi_devconfig *it)
} }
s->len_chanlist = 1; s->len_chanlist = 1;
s->maxdata = board->ai_maxdata; 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; s->insn_read = pcmad_ai_insn_read;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment