[PATCH 1/7] staging: comedi: cb_pcimdas: fix analog input channel configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The hardware uses a switch on the board to set the number of analog
input channels to either 16 single-ended or 8 differential channels.
Currently the switch setting is checked for every (*insn_read) operation
to validate the channel number.

Check the switch setting during the driver attach and initialize the
subdevice accordingly. This allows the core to handle the validation.

Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx>
Cc: Ian Abbott <abbotti@xxxxxxxxx>
Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/staging/comedi/drivers/cb_pcimdas.c | 34 +++++++++++++++++++----------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
index 70dd2c9..ddaa61c 100644
--- a/drivers/staging/comedi/drivers/cb_pcimdas.c
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -109,20 +109,10 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
 	unsigned int d;
 	int chan = CR_CHAN(insn->chanspec);
 	unsigned short chanlims;
-	int maxchans;
 	int ret;
 
 	/*  only support sw initiated reads from a single channel */
 
-	/* check channel number */
-	if ((inb(devpriv->BADR3 + 2) & 0x20) == 0)	/* differential mode */
-		maxchans = s->n_chan / 2;
-	else
-		maxchans = s->n_chan;
-
-	if (chan > (maxchans - 1))
-		return -ETIMEDOUT;	/* *** Wrong error code. Fixme. */
-
 	/* configure for sw initiated read */
 	d = inb(devpriv->BADR3 + 5);
 	if ((d & 0x03) > 0) {	/* only reset if needed. */
@@ -181,6 +171,20 @@ static int cb_pcimdas_ao_insn_write(struct comedi_device *dev,
 	return insn->n;
 }
 
+static bool cb_pcimdas_is_ai_se(struct comedi_device *dev)
+{
+	struct cb_pcimdas_private *devpriv = dev->private;
+	unsigned int status;
+
+	/*
+	 * The number of Analog Input channels is set with the
+	 * Analog Input Mode Switch on the board. The board can
+	 * have 16 single-ended or 8 differential channels.
+	 */
+	status = inb(devpriv->BADR3 + 2);
+	return status & 0x20;
+}
+
 static int cb_pcimdas_auto_attach(struct comedi_device *dev,
 					    unsigned long context_unused)
 {
@@ -209,8 +213,14 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev,
 	/* dev->read_subdev=s; */
 	/*  analog input subdevice */
 	s->type = COMEDI_SUBD_AI;
-	s->subdev_flags = SDF_READABLE | SDF_GROUND;
-	s->n_chan = 16;
+	s->subdev_flags	= SDF_READABLE;
+	if (cb_pcimdas_is_ai_se(dev)) {
+		s->subdev_flags	|= SDF_GROUND;
+		s->n_chan	= 16;
+	} else {
+		s->subdev_flags	|= SDF_DIFF;
+		s->n_chan	= 8;
+	}
 	s->maxdata = 0xffff;
 	s->range_table = &range_unknown;
 	s->len_chanlist = 1;	/*  This is the maximum chanlist length that */
-- 
2.3.0

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux