[PATCH 2/7] staging: comedi: cb_pcimdas: support analog input programmable ranges

H Hartley Sweeten hsweeten at visionengravers.com
Wed Feb 25 23:28:39 UTC 2015


The hardware uses a switch on the board to select if the analog inputs
are bipolar or uinipolar. The gain is programmable to allow the following
input ranges:

  Gain  Bipolar   Unipolar
    0   +/-10V    0 to 10V
    1   +/-5V     0 to 5V
    2   +/-2.5V   0 to 2.5V
    3   +/-1.25V  0 to 1.25V

Add the necessary code to the driver to allow the user to select the
desired range.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/cb_pcimdas.c | 42 ++++++++++++++++++++++++++---
 1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index ddaa61c..5d08ca4 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -74,6 +74,24 @@
 #define RESID_COUNT_H 13
 #define RESID_COUNT_L 14
 
+static const struct comedi_lrange cb_pcimdas_ai_bip_range = {
+	4, {
+		BIP_RANGE(10),
+		BIP_RANGE(5),
+		BIP_RANGE(2.5),
+		BIP_RANGE(1.25)
+	}
+};
+
+static const struct comedi_lrange cb_pcimdas_ai_uni_range = {
+	4, {
+		UNI_RANGE(10),
+		UNI_RANGE(5),
+		UNI_RANGE(2.5),
+		UNI_RANGE(1.25)
+	}
+};
+
 /*
  * this structure is for data unique to this hardware driver.  If
  * several hardware drivers keep similar information in this structure,
@@ -105,9 +123,10 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
 			       struct comedi_insn *insn, unsigned int *data)
 {
 	struct cb_pcimdas_private *devpriv = dev->private;
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
 	int n;
 	unsigned int d;
-	int chan = CR_CHAN(insn->chanspec);
 	unsigned short chanlims;
 	int ret;
 
@@ -123,8 +142,8 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
 	/* set bursting off, conversions on */
 	outb(0x01, devpriv->BADR3 + 6);
 
-	/* set range to 10V. UP/BP is controlled by a switch on the board */
-	outb(0x00, devpriv->BADR3 + 7);
+	/* set range */
+	outb(range, devpriv->BADR3 + 7);
 
 	/*
 	 * write channel limits to multiplexer, set Low (bits 0-3) and
@@ -185,6 +204,20 @@ static bool cb_pcimdas_is_ai_se(struct comedi_device *dev)
 	return status & 0x20;
 }
 
+static bool cb_pcimdas_is_ai_uni(struct comedi_device *dev)
+{
+	struct cb_pcimdas_private *devpriv = dev->private;
+	unsigned int status;
+
+	/*
+	 * The Analog Input range polarity is set with the
+	 * Analog Input Polarity Switch on the board. The
+	 * inputs can be set to Unipolar or Bipolar ranges.
+	 */
+	status = inb(devpriv->BADR3 + 2);
+	return status & 0x40;
+}
+
 static int cb_pcimdas_auto_attach(struct comedi_device *dev,
 					    unsigned long context_unused)
 {
@@ -222,7 +255,8 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev,
 		s->n_chan	= 8;
 	}
 	s->maxdata = 0xffff;
-	s->range_table = &range_unknown;
+	s->range_table	= cb_pcimdas_is_ai_uni(dev) ? &cb_pcimdas_ai_uni_range
+						    : &cb_pcimdas_ai_bip_range;
 	s->len_chanlist = 1;	/*  This is the maximum chanlist length that */
 	/*  the board can handle */
 	s->insn_read = cb_pcimdas_ai_rinsn;
-- 
2.3.0



More information about the devel mailing list