staging: comedi: cb_pcimdas: fix analog input channel configuration
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 25 Feb 2015 23:28:38 +0000 (16:28 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 2 Mar 2015 02:56:30 +0000 (18:56 -0800)
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@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/cb_pcimdas.c

index 70dd2c9eecdba21174c2d9bc7595f2eb609a3654..ddaa61c1cc314ba309db6400f3366034c713571d 100644 (file)
@@ -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 */