summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-06-05 22:38:37 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-06 19:01:35 (GMT)
commit7ecc5370de1562b2410604ed78aec087e55c06cf (patch)
tree6e3dea959d0b450ceb5a8e3d618b8a30682b140b /drivers
parent6092e9428de76606d4fd337422322aee857a3e1a (diff)
downloadlinux-fsl-qoriq-7ecc5370de1562b2410604ed78aec087e55c06cf.tar.xz
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 <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
index 86597fc..8028e47 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 <linux/interrupt.h>
@@ -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;