Convert the drivers with simple, per channel programmable i/o, to use the
comedi_dio_insn_config() helper function.

All of these pass a 'mask' of '0' to comedi_dio_insn_config() this causes
the per channel mask to be used to configure the i/o direction.

Signed-off-by: H Hartley Sweeten <hswee...@visionengravers.com>
Cc: Ian Abbott <abbo...@mev.co.uk>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/staging/comedi/drivers/cb_pcidas64.c   | 25 +++------
 drivers/staging/comedi/drivers/comedi_bond.c   | 51 +++++++-----------
 drivers/staging/comedi/drivers/ni_65xx.c       | 42 ++++++---------
 drivers/staging/comedi/drivers/ni_670x.c       | 25 +++------
 drivers/staging/comedi/drivers/ni_daq_700.c    | 24 ++++-----
 drivers/staging/comedi/drivers/ni_mio_common.c | 57 +++++----------------
 drivers/staging/comedi/drivers/ni_pcidio.c     | 26 +++-------
 drivers/staging/comedi/drivers/pcmmio.c        | 71 ++++++--------------------
 drivers/staging/comedi/drivers/pcmuio.c        | 24 +++------
 drivers/staging/comedi/drivers/rtd520.c        | 20 ++------
 drivers/staging/comedi/drivers/s626.c          | 22 ++------
 drivers/staging/comedi/drivers/ssv_dnp.c       | 69 ++++++++-----------------
 drivers/staging/comedi/drivers/usbdux.c        | 19 ++-----
 drivers/staging/comedi/drivers/usbduxsigma.c   | 20 ++------
 14 files changed, 136 insertions(+), 359 deletions(-)

diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c 
b/drivers/staging/comedi/drivers/cb_pcidas64.c
index e6e4561..388dbd7 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -3510,31 +3510,20 @@ static int do_wbits(struct comedi_device *dev, struct 
comedi_subdevice *s,
 
 static int dio_60xx_config_insn(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
        struct pcidas64_private *devpriv = dev->private;
-       unsigned int mask;
-
-       mask = 1 << CR_CHAN(insn->chanspec);
+       int ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~mask;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= mask;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return 2;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
        writeb(s->io_bits,
               devpriv->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
 
-       return 1;
+       return insn->n;
 }
 
 static int dio_60xx_wbits(struct comedi_device *dev, struct comedi_subdevice 
*s,
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c 
b/drivers/staging/comedi/drivers/comedi_bond.c
index 7e20bf0..6ef1f75 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -132,47 +132,32 @@ static int bonding_dio_insn_bits(struct comedi_device 
*dev,
 
 static int bonding_dio_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
 {
        struct comedi_bond_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
-       unsigned int io;
        struct BondedDevice *bdev;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int old_io_bits = s->io_bits;
+       int ret;
 
        if (chan < 0 || chan >= devpriv->nchans)
                return -EINVAL;
-       bdev = devpriv->chanIdDevMap[chan];
 
-       /* The input or output configuration of each digital line is
-        * configured by a special insn_config instruction.  chanspec
-        * contains the channel to be changed, and data[0] contains the
-        * value COMEDI_INPUT or COMEDI_OUTPUT. */
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               io = COMEDI_OUTPUT;     /* is this really necessary? */
-               io_bits |= 1 << chan;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               io = COMEDI_INPUT;      /* is this really necessary? */
-               io_bits &= ~(1 << chan);
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-               break;
+       /* Update our internal state */
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
+
+       /* Update the BondedDevice device */
+       bdev = devpriv->chanIdDevMap[chan];
+       ret = comedi_dio_config(bdev->dev, bdev->subdev,
+                               chan - bdev->chanid_offset, data[0]);
+       if (ret < 0) {
+               s->io_bits = old_io_bits;
+               return ret;
        }
-       /* 'real' channel id for this subdev.. */
-       chan -= bdev->chanid_offset;
-       ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, io);
-       if (ret != 1)
-               return -EINVAL;
-       /* Finally, save the new io_bits values since we didn't get
-          an error above. */
-       s->io_bits = io_bits;
+
        return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c 
b/drivers/staging/comedi/drivers/ni_65xx.c
index 3ba4c57..19a5d74 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -268,7 +268,6 @@ struct ni_65xx_private {
        unsigned int filter_interval;
        unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS];
        unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
-       unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
 };
 
 struct ni_65xx_subdevice_private {
@@ -327,40 +326,31 @@ static int ni_65xx_dio_insn_config(struct comedi_device 
*dev,
                                   struct comedi_insn *insn, unsigned int *data)
 {
        struct ni_65xx_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned port;
+       int ret;
+
+       port = sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
 
-       if (insn->n < 1)
-               return -EINVAL;
-       port = sprivate(s)->base_port +
-           ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
        switch (data[0]) {
        case INSN_CONFIG_FILTER:
                return ni_65xx_config_filter(dev, s, insn, data);
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               if (s->type != COMEDI_SUBD_DIO)
-                       return -EINVAL;
-               devpriv->dio_direction[port] = COMEDI_OUTPUT;
-               writeb(0, devpriv->mite->daq_io_addr + Port_Select(port));
-               return 1;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               if (s->type != COMEDI_SUBD_DIO)
-                       return -EINVAL;
-               devpriv->dio_direction[port] = COMEDI_INPUT;
-               writeb(1, devpriv->mite->daq_io_addr + Port_Select(port));
-               return 1;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
+       default:
                if (s->type != COMEDI_SUBD_DIO)
                        return -EINVAL;
-               data[1] = devpriv->dio_direction[port];
-               return insn->n;
-               break;
-       default:
+
+               ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+               if (ret)
+                       return ret;
                break;
        }
-       return -EINVAL;
+
+       if (s->io_bits & (1 << chan))
+               writeb(0, devpriv->mite->daq_io_addr + Port_Select(port));
+       else
+               writeb(1, devpriv->mite->daq_io_addr + Port_Select(port));
+
+       return insn->n;
 }
 
 static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/ni_670x.c 
b/drivers/staging/comedi/drivers/ni_670x.c
index 0201625..e2926ce 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -158,27 +158,16 @@ static int ni_670x_dio_insn_bits(struct comedi_device 
*dev,
 
 static int ni_670x_dio_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
-                                  struct comedi_insn *insn, unsigned int *data)
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
 {
        struct ni_670x_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
+       int ret;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= 1 << chan;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~(1 << chan);
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
        writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c 
b/drivers/staging/comedi/drivers/ni_daq_700.c
index 4165965..b92091a 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -90,21 +90,17 @@ static int daq700_dio_insn_bits(struct comedi_device *dev,
 
 static int daq700_dio_insn_config(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       unsigned int chan = 1 << CR_CHAN(insn->chanspec);
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & chan) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               break;
-       default:
-               return -EINVAL;
-       }
+       int ret;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
+
+       /* The DIO channels are not configurable */
+       s->io_bits = 0x00ff;
 
        return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c 
b/drivers/staging/comedi/drivers/ni_mio_common.c
index 04f4b7d..4e02770 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -3528,37 +3528,21 @@ static int ni_ao_reset(struct comedi_device *dev, 
struct comedi_subdevice *s)
 
 static int ni_dio_insn_config(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
        struct ni_private *devpriv = dev->private;
+       int ret;
 
-#ifdef DEBUG_DIO
-       printk("ni_dio_insn_config() chan=%d io=%d\n",
-              CR_CHAN(insn->chanspec), data[0]);
-#endif
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= 1 << CR_CHAN(insn->chanspec);
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (s->
-                    io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
-                   COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
        devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
        devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
        devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
 
-       return 1;
+       return insn->n;
 }
 
 static int ni_dio_insn_bits(struct comedi_device *dev,
@@ -3596,32 +3580,15 @@ static int ni_m_series_dio_insn_config(struct 
comedi_device *dev,
                                       unsigned int *data)
 {
        struct ni_private *devpriv __maybe_unused = dev->private;
+       int ret;
 
-#ifdef DEBUG_DIO
-       printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
-              CR_CHAN(insn->chanspec), data[0]);
-#endif
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= 1 << CR_CHAN(insn->chanspec);
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (s->
-                    io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
-                   COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
        ni_writel(s->io_bits, M_Offset_DIO_Direction);
 
-       return 1;
+       return insn->n;
 }
 
 static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c 
b/drivers/staging/comedi/drivers/ni_pcidio.c
index 8ac7a7c..e14eefc 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -643,29 +643,15 @@ static int ni_pcidio_insn_config(struct comedi_device 
*dev,
                                 struct comedi_insn *insn, unsigned int *data)
 {
        struct nidio96_private *devpriv = dev->private;
+       int ret;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
-       if (insn->n != 1)
-               return -EINVAL;
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= 1 << CR_CHAN(insn->chanspec);
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (s->
-                    io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
-                   COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
        writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
 
-       return 1;
+       return insn->n;
 }
 
 static int ni_pcidio_insn_bits(struct comedi_device *dev,
diff --git a/drivers/staging/comedi/drivers/pcmmio.c 
b/drivers/staging/comedi/drivers/pcmmio.c
index fab93a7..aa3c030 100644
--- a/drivers/staging/comedi/drivers/pcmmio.c
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -310,68 +310,27 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/* The input or output configuration of each digital line is
- * configured by a special insn_config instruction.  chanspec
- * contains the channel to be changed, and data[0] contains the
- * value COMEDI_INPUT or COMEDI_OUTPUT. */
 static int pcmmio_dio_insn_config(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
-           chan % 8;
-       unsigned long ioaddr;
-       unsigned char byte;
-
-       /* Compute ioaddr for this channel */
-       ioaddr = subpriv->iobases[byte_no];
-
-       /* NOTE:
-          writing a 0 an IO channel's bit sets the channel to INPUT
-          and pulls the line high as well
-
-          writing a 1 to an IO channel's  bit pulls the line low
-
-          All channels are implicitly always in OUTPUT mode -- but when
-          they are high they can be considered to be in INPUT mode..
-
-          Thus, we only force channels low if the config request was INPUT,
-          otherwise we do nothing to the hardware.    */
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               /* save to io_bits -- don't actually do anything since
-                  all input channels are also output channels... */
-               s->io_bits |= 1 << chan;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               /* write a 0 to the actual register representing the channel
-                  to set it to 'input'.  0 means "float high". */
-               byte = inb(ioaddr);
-               byte &= ~(1 << bit_no);
-                               /**< set input channel to '0' */
-
-               /*
-                * write out byte -- this is the only time we actually affect
-                * the hardware as all channels are implicitly output
-                * -- but input channels are set to float-high
-                */
-               outb(byte, ioaddr);
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int byte_no = chan / 8;
+       int bit_no = chan % 8;
+       int ret;
 
-               /* save to io_bits */
-               s->io_bits &= ~(1 << chan);
-               break;
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
-       case INSN_CONFIG_DIO_QUERY:
-               /* retrieve from shadow register */
-               data[1] =
-                   (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
+       if (data[0] == INSN_CONFIG_DIO_INPUT) {
+               unsigned long ioaddr = subpriv->iobases[byte_no];
+               unsigned char val;
 
-       default:
-               return -EINVAL;
-               break;
+               val = inb(ioaddr);
+               val &= ~(1 << bit_no);
+               outb(val, ioaddr);
        }
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/pcmuio.c 
b/drivers/staging/comedi/drivers/pcmuio.c
index 13f1943..f942455 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -233,27 +233,19 @@ static int pcmuio_dio_insn_bits(struct comedi_device *dev,
 
 static int pcmuio_dio_insn_config(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
        int asic = s->index / 2;
        int port = (s->index % 2) ? 3 : 0;
+       int ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= chan_mask;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~chan_mask;
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
+
+       if (data[0] == INSN_CONFIG_DIO_INPUT)
                pcmuio_write(dev, s->io_bits, asic, 0, port);
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & chan_mask) ? COMEDI_OUTPUT : 
COMEDI_INPUT;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
 
        return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/rtd520.c 
b/drivers/staging/comedi/drivers/rtd520.c
index 635c8f5..93c980c 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -1238,23 +1238,11 @@ static int rtd_dio_insn_config(struct comedi_device 
*dev,
                               unsigned int *data)
 {
        struct rtd_private *devpriv = dev->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int mask = 1 << chan;
+       int ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= mask;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~mask;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
        /* TODO support digital match interrupts and strobes */
 
diff --git a/drivers/staging/comedi/drivers/s626.c 
b/drivers/staging/comedi/drivers/s626.c
index b0ba9b9..d22b95d 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -1662,24 +1662,12 @@ static int s626_dio_insn_config(struct comedi_device 
*dev,
                                unsigned int *data)
 {
        unsigned long group = (unsigned long)s->private;
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int mask = 1 << chan;
+       int ret;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       case COMEDI_INPUT:
-               s->io_bits &= ~mask;
-               break;
-       case COMEDI_OUTPUT:
-               s->io_bits |= mask;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
        DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c 
b/drivers/staging/comedi/drivers/ssv_dnp.c
index 4da4d32..6c56864 100644
--- a/drivers/staging/comedi/drivers/ssv_dnp.c
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -93,68 +93,39 @@ static int dnp_dio_insn_bits(struct comedi_device *dev,
 
 }
 
-/* ------------------------------------------------------------------------- */
-/* Configure the direction of the bidirectional digital i/o pins. chanspec   */
-/* contains the channel to be changed and data[0] contains either            */
-/* COMEDI_INPUT or COMEDI_OUTPUT.                                            */
-/* ------------------------------------------------------------------------- */
-
 static int dnp_dio_insn_config(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       unsigned int val;
+       int ret;
 
-       u8 register_buffer;
-
-       /* reduces chanspec to lower 16 bits */
-       int chan = CR_CHAN(insn->chanspec);
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-       case INSN_CONFIG_DIO_INPUT:
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
-       /* Test: which port does the channel belong to?                       */
-
-       /* We have to pay attention with port C: this is the meaning of PCMR: */
-       /* Bit in PCMR:              7 6 5 4 3 2 1 0                          */
-       /* Corresponding port C pin: d 3 d 2 d 1 d 0   d= don't touch         */
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
-       if ((chan >= 0) && (chan <= 7)) {
-               /* this is port A */
+       if (chan < 8) {                 /* Port A */
+               mask = 1 << chan;
                outb(PAMR, CSCIR);
-       } else if ((chan >= 8) && (chan <= 15)) {
-               /* this is port B */
-               chan -= 8;
+       } else if (chan < 16) {         /* Port B */
+               mask = 1 << (chan - 8);
                outb(PBMR, CSCIR);
-       } else if ((chan >= 16) && (chan <= 19)) {
-               /* this is port C; multiplication with 2 brings bits into     */
-               /* correct position for PCMR!                                 */
-               chan -= 16;
-               chan *= 2;
+       } else {                        /* Port C */
+               mask = 1 << ((chan - 16) * 2);
                outb(PCMR, CSCIR);
-       } else {
-               return -EINVAL;
        }
 
-       /* read 'old' direction of the port and set bits (out=1, in=0)        */
-       register_buffer = inb(CSCDR);
+       val = inb(CSCDR);
        if (data[0] == COMEDI_OUTPUT)
-               register_buffer |= (1 << chan);
+               val |= mask;
        else
-               register_buffer &= ~(1 << chan);
-
-       outb(register_buffer, CSCDR);
+               val &= ~mask;
+       outb(val, CSCDR);
 
-       return 1;
+       return insn->n;
 
 }
 
diff --git a/drivers/staging/comedi/drivers/usbdux.c 
b/drivers/staging/comedi/drivers/usbdux.c
index 689b452..7e91f15 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1113,22 +1113,11 @@ static int usbdux_dio_insn_config(struct comedi_device 
*dev,
                                  struct comedi_insn *insn,
                                  unsigned int *data)
 {
-       unsigned int mask = 1 << CR_CHAN(insn->chanspec);
+       int ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= mask;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~mask;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
        /*
         * We don't tell the firmware here as it would take 8 frames
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c 
b/drivers/staging/comedi/drivers/usbduxsigma.c
index fca89c3..c47f408 100644
--- a/drivers/staging/comedi/drivers/usbduxsigma.c
+++ b/drivers/staging/comedi/drivers/usbduxsigma.c
@@ -1040,23 +1040,11 @@ static int usbduxsigma_dio_insn_config(struct 
comedi_device *dev,
                                       struct comedi_insn *insn,
                                       unsigned int *data)
 {
-       unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int mask = 1 << chan;
+       int ret;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= mask;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~mask;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0);
+       if (ret)
+               return ret;
 
        /*
         * We don't tell the firmware here as it would take 8 frames
-- 
1.8.3.2

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

Reply via email to