staging: comedi: drivers: use comedi_dio_insn_config() for complex cases
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Mon, 5 Aug 2013 22:01:25 +0000 (15:01 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 12 Aug 2013 22:04:02 +0000 (15:04 -0700)
Convert the drivers with complex, port programmable i/o, to use the
comedi_dio_insn_config() helper function.

All of these drivers have some sort of 'port' programmable i/o where multiple
i/o channels are configured as a group. The 'mask' associated with the group
is passed to comedi_dio_insn_config() so that all the channels are configured.

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>
15 files changed:
drivers/staging/comedi/drivers/8255.c
drivers/staging/comedi/drivers/addi_apci_16xx.c
drivers/staging/comedi/drivers/addi_apci_3xxx.c
drivers/staging/comedi/drivers/adv_pci1723.c
drivers/staging/comedi/drivers/amplc_dio200_common.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/comedi/drivers/dt2801.c
drivers/staging/comedi/drivers/dt3000.c
drivers/staging/comedi/drivers/gsc_hpdi.c
drivers/staging/comedi/drivers/ii_pci20kc.c
drivers/staging/comedi/drivers/me4000.c
drivers/staging/comedi/drivers/me_daq.c
drivers/staging/comedi/drivers/ni_at_ao.c
drivers/staging/comedi/drivers/pcm3724.c
drivers/staging/comedi/drivers/s526.c

index 1fa29ac4eb5df194ef44afcf41ae35c21b0e9d95..2f070fdbbb1d3b206b6e17f5f10bea0ec6e3a02a 100644 (file)
@@ -184,39 +184,29 @@ static void subdev_8255_do_config(struct comedi_device *dev,
 
 static int subdev_8255_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 bits;
+       int ret;
 
-       mask = 1 << CR_CHAN(insn->chanspec);
-       if (mask & 0x0000ff)
-               bits = 0x0000ff;
-       else if (mask & 0x00ff00)
-               bits = 0x00ff00;
-       else if (mask & 0x0f0000)
-               bits = 0x0f0000;
+       if (chan < 8)
+               mask = 0x0000ff;
+       else if (chan < 16)
+               mask = 0x00ff00;
+       else if (chan < 20)
+               mask = 0x0f0000;
        else
-               bits = 0xf00000;
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+               mask = 0xf00000;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        subdev_8255_do_config(dev, s);
 
-       return 1;
+       return insn->n;
 }
 
 static int subdev_8255_cmdtest(struct comedi_device *dev,
index 43296a6e7d4e664393337dbaaae4ea86bf247092..96523744b8de57cc5203d7c7667b60f67f4b647c 100644 (file)
@@ -60,36 +60,22 @@ static int apci16xx_insn_config(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int chan_mask = 1 << CR_CHAN(insn->chanspec);
-       unsigned int bits;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       int ret;
 
-       /*
-        * Each 8-bit "port" is configurable as either input or
-        * output. Changing the configuration of any channel in
-        * a port changes the entire port.
-        */
-       if (chan_mask & 0x000000ff)
-               bits = 0x000000ff;
-       else if (chan_mask & 0x0000ff00)
-               bits = 0x0000ff00;
-       else if (chan_mask & 0x00ff0000)
-               bits = 0x00ff0000;
+       if (chan < 8)
+               mask = 0x000000ff;
+       else if (chan < 16)
+               mask = 0x0000ff00;
+       else if (chan < 24)
+               mask = 0x00ff0000;
        else
-               bits = 0xff000000;
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_INPUT : COMEDI_OUTPUT;
-               return insn->n;
-       default:
-               return -EINVAL;
-       }
+               mask = 0xff000000;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        outl(s->io_bits, dev->iobase + APCI16XX_DIR_REG(s->index));
 
index dbc0678027ca79b879661d0c03501b14c4960987..cf5dd10eaf91daa71cb75ced4270c450d49d31de 100644 (file)
@@ -686,38 +686,28 @@ static int apci3xxx_dio_insn_config(struct comedi_device *dev,
                                    unsigned int *data)
 {
        unsigned int chan = CR_CHAN(insn->chanspec);
-       unsigned int mask = 1 << chan;
-       unsigned int bits;
+       unsigned int mask;
+       int ret;
 
        /*
         * Port 0 (channels 0-7) are always inputs
         * Port 1 (channels 8-15) are always outputs
         * Port 2 (channels 16-23) are programmable i/o
-        *
-        * Changing any channel in port 2 changes the entire port.
         */
-       if (mask & 0xff0000)
-               bits = 0xff0000;
-       else
-               bits = 0;
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-       default:
-               return -EINVAL;
+       if (chan < 16) {
+               if (data[0] != INSN_CONFIG_DIO_QUERY)
+                       return -EINVAL;
+       } else {
+               /* changing any channel in port 2 changes the entire port */
+               mask = 0xff0000;
        }
 
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
+
        /* update port 2 configuration */
-       if (bits)
-               outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
+       outl((s->io_bits >> 24) & 0xff, dev->iobase + 224);
 
        return insn->n;
 }
index f914fb1f571be13fd248203765a00b5a788a984f..b793d6987b843366654ac9935b0546ade9230f10 100644 (file)
@@ -180,38 +180,29 @@ static int pci1723_dio_insn_config(struct comedi_device *dev,
                                   struct comedi_subdevice *s,
                                   struct comedi_insn *insn, unsigned int *data)
 {
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int mask;
-       unsigned int bits;
-       unsigned short dio_mode;
+       unsigned short mode;
+       int ret;
 
-       mask = 1 << CR_CHAN(insn->chanspec);
-       if (mask & 0x00FF)
-               bits = 0x00FF;
+       if (chan < 8)
+               mask = 0x00ff;
        else
-               bits = 0xFF00;
+               mask = 0xff00;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        /* update hardware DIO mode */
-       dio_mode = 0x0000;      /* low byte output, high byte output */
-       if ((s->io_bits & 0x00FF) == 0)
-               dio_mode |= 0x0001;     /* low byte input */
-       if ((s->io_bits & 0xFF00) == 0)
-               dio_mode |= 0x0002;     /* high byte input */
-       outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
-       return 1;
+       mode = 0x0000;                  /* assume output */
+       if (!(s->io_bits & 0x00ff))
+               mode |= 0x0001;         /* low byte input */
+       if (!(s->io_bits & 0xff00))
+               mode |= 0x0002;         /* high byte input */
+       outw(mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
+
+       return insn->n;
 }
 
 /*
index 32c490b27b55505de50241662e4682b80ff9b021..c1f723e8614613826d9753e07ec6af5044f925a7 100644 (file)
@@ -976,34 +976,26 @@ static int dio200_subdev_8255_config(struct comedi_device *dev,
                                     struct comedi_insn *insn,
                                     unsigned int *data)
 {
+       unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int mask;
-       unsigned int bits;
-
-       mask = 1 << CR_CHAN(insn->chanspec);
-       if (mask & 0x0000ff)
-               bits = 0x0000ff;
-       else if (mask & 0x00ff00)
-               bits = 0x00ff00;
-       else if (mask & 0x0f0000)
-               bits = 0x0f0000;
+       int ret;
+
+       if (chan < 8)
+               mask = 0x0000ff;
+       else if (chan < 16)
+               mask = 0x00ff00;
+       else if (chan < 20)
+               mask = 0x0f0000;
        else
-               bits = 0xf00000;
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+               mask = 0xf00000;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
+
        dio200_subdev_8255_set_dir(dev, s);
-       return 1;
+
+       return insn->n;
 }
 
 /*
index 05e01a3b5af6aed51fb2f31e15e542cf3c5d440d..0ce93da70847c566fd328ae21ae80f258fade0f1 100644 (file)
@@ -341,33 +341,22 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev,
 
 static int das16cs_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 das16cs_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
-       int bits;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       int ret;
 
        if (chan < 4)
-               bits = 0x0f;
+               mask = 0x0f;
        else
-               bits = 0xf0;
+               mask = 0xf0;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= bits;
-               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;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        devpriv->status2 &= ~0x00c0;
        devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0;
index e0e7beab7274b255c79e079fa94a5e190b2a13f6..38918a1198aa83cfbcc717f69be05c074b9bd7aa 100644 (file)
@@ -551,32 +551,19 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev,
 
 static int dt2801_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 which = 0;
+       int ret;
 
-       if (s == &dev->subdevices[3])
-               which = 1;
+       ret = comedi_dio_insn_config(dev, s, insn, data, 0xff);
+       if (ret)
+               return ret;
 
-       /* configure */
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits = 0xff;
-               dt2801_writecmd(dev, DT_C_SET_DIGOUT);
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits = 0;
-               dt2801_writecmd(dev, DT_C_SET_DIGIN);
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = s->io_bits ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-       default:
-               return -EINVAL;
-       }
-       dt2801_writedata(dev, which);
+       dt2801_writecmd(dev, s->io_bits ? DT_C_SET_DIGOUT : DT_C_SET_DIGIN);
+       dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);
 
-       return 1;
+       return insn->n;
 }
 
 /*
index e4748da1993b8dc13cab8176616f4583c6491a31..64ef87598b607deffe7b9a11999c753defbce126 100644 (file)
@@ -642,32 +642,23 @@ static void dt3k_dio_config(struct comedi_device *dev, int bits)
 
 static int dt3k_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 mask;
-
-       mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
-
-       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 & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
-                   COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
-       mask = (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3);
-       dt3k_dio_config(dev, mask);
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       int ret;
+
+       if (chan < 4)
+               mask = 0x0f;
+       else
+               mask = 0xf0;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
+
+       dt3k_dio_config(dev, (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3));
 
        return insn->n;
 }
index cdcc8f42e20935bd477b7385badf977ac7761a4f..559bf5583530c2e2796ece8ad712dcec22514fa1 100644 (file)
@@ -224,37 +224,26 @@ struct hpdi_private {
        volatile uint32_t bits[24];
        /* number of bytes at which to generate COMEDI_CB_BLOCK events */
        volatile unsigned int block_size;
-       unsigned dio_config_output:1;
 };
 
 static int dio_config_insn(struct comedi_device *dev,
-                          struct comedi_subdevice *s, struct comedi_insn *insn,
+                          struct comedi_subdevice *s,
+                          struct comedi_insn *insn,
                           unsigned int *data)
 {
-       struct hpdi_private *devpriv = dev->private;
+       int ret;
 
        switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               devpriv->dio_config_output = 1;
-               return insn->n;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               devpriv->dio_config_output = 0;
-               return insn->n;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   devpriv->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
        case INSN_CONFIG_BLOCK_SIZE:
                return dio_config_block_size(dev, data);
-               break;
        default:
+               ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
+               if (ret)
+                       return ret;
                break;
        }
 
-       return -EINVAL;
+       return insn->n;
 }
 
 static void disable_plx_interrupts(struct comedi_device *dev)
@@ -673,9 +662,7 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
                         struct comedi_cmd *cmd)
 {
-       struct hpdi_private *devpriv = dev->private;
-
-       if (devpriv->dio_config_output)
+       if (s->io_bits)
                return -EINVAL;
        else
                return di_cmd_test(dev, s, cmd);
@@ -746,9 +733,7 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 
 static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-       struct hpdi_private *devpriv = dev->private;
-
-       if (devpriv->dio_config_output)
+       if (s->io_bits)
                return -EINVAL;
        else
                return di_cmd(dev, s);
index 954c5397f33c84630b3726c8f3ab45f584ae8d76..5c3a318b464012bff1f5a44c2788e20008399ed7 100644 (file)
@@ -350,31 +350,22 @@ static int ii20k_dio_insn_config(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = 1 << CR_CHAN(insn->chanspec);
-       unsigned int bits;
-
-       if (mask & 0x000000ff)
-               bits = 0x000000ff;
-       else if (mask & 0x0000ff00)
-               bits = 0x0000ff00;
-       else if (mask & 0x00ff0000)
-               bits = 0x00ff0000;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       int ret;
+
+       if (chan < 8)
+               mask = 0x000000ff;
+       else if (chan < 16)
+               mask = 0x0000ff00;
+       else if (chan < 24)
+               mask = 0x00ff0000;
        else
-               bits = 0xff000000;
+               mask = 0xff000000;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        ii20k_dio_config(dev, s);
 
index 1eda40a9332ee04ba801e86670f310c333bdccb4..8f4afadab76a617a526da821d3ac029562eadf3c 100644 (file)
@@ -1358,98 +1358,57 @@ static int me4000_dio_insn_bits(struct comedi_device *dev,
 
 static int me4000_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 long tmp;
-       int chan = CR_CHAN(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       unsigned int tmp;
+       int ret;
 
-       switch (data[0]) {
-       default:
-               return -EINVAL;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-       case INSN_CONFIG_DIO_INPUT:
-       case INSN_CONFIG_DIO_OUTPUT:
-               break;
-       }
+       if (chan < 8)
+               mask = 0x000000ff;
+       else if (chan < 16)
+               mask = 0x0000ff00;
+       else if (chan < 24)
+               mask = 0x00ff0000;
+       else
+               mask = 0xff000000;
 
-       /*
-        * 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 INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_OUTPUT.
-        * On the ME-4000 it is only possible to switch port wise (8 bit)
-        */
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG);
+       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 | ME4000_DIO_CTRL_BIT_MODE_1 |
+                ME4000_DIO_CTRL_BIT_MODE_2 | ME4000_DIO_CTRL_BIT_MODE_3 |
+                ME4000_DIO_CTRL_BIT_MODE_4 | ME4000_DIO_CTRL_BIT_MODE_5 |
+                ME4000_DIO_CTRL_BIT_MODE_6 | ME4000_DIO_CTRL_BIT_MODE_7);
+       if (s->io_bits & 0x000000ff)
+               tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
+       if (s->io_bits & 0x0000ff00)
+               tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
+       if (s->io_bits & 0x00ff0000)
+               tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
+       if (s->io_bits & 0xff000000)
+               tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
 
-       if (data[0] == INSN_CONFIG_DIO_OUTPUT) {
-               if (chan < 8) {
-                       s->io_bits |= 0xFF;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-                                ME4000_DIO_CTRL_BIT_MODE_1);
-                       tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
-               } else if (chan < 16) {
-                       /*
-                        * Chech for optoisolated ME-4000 version.
-                        * If one the first port is a fixed output
-                        * port and the second is a fixed input port.
-                        */
-                       if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
-                               return -ENODEV;
-
-                       s->io_bits |= 0xFF00;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-                                ME4000_DIO_CTRL_BIT_MODE_3);
-                       tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
-               } else if (chan < 24) {
-                       s->io_bits |= 0xFF0000;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-                                ME4000_DIO_CTRL_BIT_MODE_5);
-                       tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
-               } else if (chan < 32) {
-                       s->io_bits |= 0xFF000000;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-                                ME4000_DIO_CTRL_BIT_MODE_7);
-                       tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
-               } else {
-                       return -EINVAL;
-               }
-       } else {
-               if (chan < 8) {
-                       /*
-                        * Chech for optoisolated ME-4000 version.
-                        * If one the first port is a fixed output
-                        * port and the second is a fixed input port.
-                        */
-                       if (!inl(dev->iobase + ME4000_DIO_DIR_REG))
-                               return -ENODEV;
-
-                       s->io_bits &= ~0xFF;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_0 |
-                                ME4000_DIO_CTRL_BIT_MODE_1);
-               } else if (chan < 16) {
-                       s->io_bits &= ~0xFF00;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
-                                ME4000_DIO_CTRL_BIT_MODE_3);
-               } else if (chan < 24) {
-                       s->io_bits &= ~0xFF0000;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_4 |
-                                ME4000_DIO_CTRL_BIT_MODE_5);
-               } else if (chan < 32) {
-                       s->io_bits &= ~0xFF000000;
-                       tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_6 |
-                                ME4000_DIO_CTRL_BIT_MODE_7);
-               } else {
-                       return -EINVAL;
-               }
+       /*
+        * Check for optoisolated ME-4000 version.
+        * If one the first port is a fixed output
+        * port and the second is a fixed input port.
+        */
+       if (inl(dev->iobase + ME4000_DIO_DIR_REG)) {
+               s->io_bits |= 0x000000ff;
+               s->io_bits &= ~0x0000ff00;
+               tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
+               tmp &= ~(ME4000_DIO_CTRL_BIT_MODE_2 |
+                        ME4000_DIO_CTRL_BIT_MODE_3);
        }
 
        outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG);
 
-       return 1;
+       return insn->n;
 }
 
 /*=============================================================================
index e8a743c2f9a166a160ab50f09f9b8f0870a96f60..a6f6d4a46587f06d1b84ba53a45df3ebcf150821 100644 (file)
@@ -186,38 +186,30 @@ static int me_dio_insn_config(struct comedi_device *dev,
                              struct comedi_insn *insn,
                              unsigned int *data)
 {
-       struct me_private_data *dev_private = dev->private;
-       unsigned int mask = 1 << CR_CHAN(insn->chanspec);
-       unsigned int bits;
-       unsigned int port;
+       struct me_private_data *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       int ret;
 
-       if (mask & 0x0000ffff) {
-               bits = 0x0000ffff;
-               port = ENABLE_PORT_A;
-       } else {
-               bits = 0xffff0000;
-               port = ENABLE_PORT_B;
-       }
+       if (chan < 16)
+               mask = 0x0000ffff;
+       else
+               mask = 0xffff0000;
 
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               dev_private->control_2 &= ~port;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               dev_private->control_2 |= port;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
-       /* Update the port configuration */
-       writew(dev_private->control_2, dev_private->me_regbase + ME_CONTROL_2);
+       if (s->io_bits & 0x0000ffff)
+               devpriv->control_2 |= ENABLE_PORT_A;
+       else
+               devpriv->control_2 &= ~ENABLE_PORT_A;
+       if (s->io_bits & 0xffff0000)
+               devpriv->control_2 |= ENABLE_PORT_B;
+       else
+               devpriv->control_2 &= ~ENABLE_PORT_B;
+
+       writew(devpriv->control_2, devpriv->me_regbase + ME_CONTROL_2);
 
        return insn->n;
 }
index 0025496bc643caf04b2c74374f65c4e642de3592..b9122fd835e1e714cec811c43d2c6c1a51675e9e 100644 (file)
@@ -248,42 +248,35 @@ static int atao_dio_insn_bits(struct comedi_device *dev,
 
 static int atao_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 atao_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec);
-       unsigned int mask, bit;
-
-       /* 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. */
-
-       mask = (chan < 4) ? 0x0f : 0xf0;
-       bit = (chan < 4) ? DOUTEN1 : DOUTEN2;
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= mask;
-               devpriv->cfg3 |= bit;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~mask;
-               devpriv->cfg3 &= ~bit;
-               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;
-       }
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int mask;
+       int ret;
+
+       if (chan < 4)
+               mask = 0x0f;
+       else
+               mask = 0xf0;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
+
+       if (s->io_bits & 0x0f)
+               devpriv->cfg3 |= DOUTEN1;
+       else
+               devpriv->cfg3 &= ~DOUTEN1;
+       if (s->io_bits & 0xf0)
+               devpriv->cfg3 |= DOUTEN2;
+       else
+               devpriv->cfg3 &= ~DOUTEN2;
 
        outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
 
-       return 1;
+       return insn->n;
 }
 
 /*
index cca972ebd010edb604a07986113a48b4af02ffd7..cc1dc7f66e5b5868d4c717b352a9e54e8785c149 100644 (file)
@@ -184,39 +184,30 @@ static void enable_chan(struct comedi_device *dev, struct comedi_subdevice *s,
 /* overriding the 8255 insn config */
 static int subdev_3724_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 bits;
-
-       mask = 1 << CR_CHAN(insn->chanspec);
-       if (mask & 0x0000ff)
-               bits = 0x0000ff;
-       else if (mask & 0x00ff00)
-               bits = 0x00ff00;
-       else if (mask & 0x0f0000)
-               bits = 0x0f0000;
+       int ret;
+
+       if (chan < 8)
+               mask = 0x0000ff;
+       else if (chan < 16)
+               mask = 0x00ff00;
+       else if (chan < 20)
+               mask = 0x0f0000;
        else
-               bits = 0xf00000;
-
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_INPUT:
-               s->io_bits &= ~bits;
-               break;
-       case INSN_CONFIG_DIO_OUTPUT:
-               s->io_bits |= bits;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-               break;
-       default:
-               return -EINVAL;
-       }
+               mask = 0xf00000;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
 
        do_3724_config(dev, s, insn->chanspec);
        enable_chan(dev, s, insn->chanspec);
-       return 1;
+
+       return insn->n;
 }
 
 static int pcm3724_attach(struct comedi_device *dev,
index 6670b865256b3aa4ba6652fae636532d00053b63..d629463b85a2ae38ba7c97d8329633ce606b7c1c 100644 (file)
@@ -515,32 +515,35 @@ static int s526_dio_insn_bits(struct comedi_device *dev,
 
 static int s526_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);
-       int group, mask;
+       unsigned int mask;
+       int ret;
+
+       if (chan < 4)
+               mask = 0x0f;
+       else
+               mask = 0xf0;
+
+       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
+       if (ret)
+               return ret;
+
+       /* bit 10/11 set the group 1/2's mode */
+       if (s->io_bits & 0x0f)
+               s->state |= (1 << 10);
+       else
+               s->state &= ~(1 << 10);
+       if (s->io_bits & 0xf0)
+               s->state |= (1 << 11);
+       else
+               s->state &= ~(1 << 11);
 
-       group = chan >> 2;
-       mask = 0xF << (group << 2);
-       switch (data[0]) {
-       case INSN_CONFIG_DIO_OUTPUT:
-               /* bit 10/11 set the group 1/2's mode */
-               s->state |= 1 << (group + 10);
-               s->io_bits |= mask;
-               break;
-       case INSN_CONFIG_DIO_INPUT:
-               s->state &= ~(1 << (group + 10)); /* 1 is output, 0 is input. */
-               s->io_bits &= ~mask;
-               break;
-       case INSN_CONFIG_DIO_QUERY:
-               data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
-       default:
-               return -EINVAL;
-       }
        outw(s->state, dev->iobase + REG_DIO);
 
-       return 1;
+       return insn->n;
 }
 
 static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)