This driver currently duplicates the functionality of the 8255 module.
The only difference is in how the i/o access is handled.

Provide a private (*io) callback for the 8255 module to handle the
differences. We can then use that module and initialize the subdevice
with subdev_8255_init().

Update the Kconfig to select the COMEDI_8255 module.

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/Kconfig                     |   1 +
 .../staging/comedi/drivers/amplc_dio200_common.c   | 120 +++------------------
 2 files changed, 14 insertions(+), 107 deletions(-)

diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 36f2c71..d5509d1 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1266,6 +1266,7 @@ config COMEDI_FC
 
 config COMEDI_AMPLC_DIO200
        tristate
+       select COMEDI_8255
 
 config COMEDI_AMPLC_PC236
        tristate
diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c 
b/drivers/staging/comedi/drivers/amplc_dio200_common.c
index 6cadf7e..4eb883c 100644
--- a/drivers/staging/comedi/drivers/amplc_dio200_common.c
+++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c
@@ -27,7 +27,7 @@
 #include "amplc_dio200.h"
 #include "comedi_fc.h"
 #include "8253.h"
-#include "8255.h"              /* only for register defines */
+#include "8255.h"
 
 /* 200 series registers */
 #define DIO200_IO_SIZE         0x20
@@ -111,10 +111,6 @@ struct dio200_subdev_8254 {
        spinlock_t spinlock;
 };
 
-struct dio200_subdev_8255 {
-       unsigned int ofs;               /* DIO base offset */
-};
-
 struct dio200_subdev_intr {
        spinlock_t spinlock;
        unsigned int ofs;
@@ -178,6 +174,16 @@ static void dio200_write32(struct comedi_device *dev,
                outl(val, dev->iobase + offset);
 }
 
+static int dio200_8255_io(struct comedi_device *dev,
+                         int dir, int port, int data, unsigned long regbase)
+{
+       if (dir) {
+               dio200_write8(dev, regbase + port, data);
+               return 0;
+       }
+       return dio200_read8(dev, regbase + port);
+}
+
 static int dio200_subdev_intr_insn_bits(struct comedi_device *dev,
                                        struct comedi_subdevice *s,
                                        struct comedi_insn *insn,
@@ -801,106 +807,6 @@ static int dio200_subdev_8254_init(struct comedi_device 
*dev,
        return 0;
 }
 
-static void dio200_subdev_8255_set_dir(struct comedi_device *dev,
-                                      struct comedi_subdevice *s)
-{
-       struct dio200_subdev_8255 *subpriv = s->private;
-       int config;
-
-       config = I8255_CTRL_CW;
-       /* 1 in io_bits indicates output, 1 in config indicates input */
-       if (!(s->io_bits & 0x0000ff))
-               config |= I8255_CTRL_A_IO;
-       if (!(s->io_bits & 0x00ff00))
-               config |= I8255_CTRL_B_IO;
-       if (!(s->io_bits & 0x0f0000))
-               config |= I8255_CTRL_C_LO_IO;
-       if (!(s->io_bits & 0xf00000))
-               config |= I8255_CTRL_C_HI_IO;
-       dio200_write8(dev, subpriv->ofs + I8255_CTRL_REG, config);
-}
-
-static int dio200_subdev_8255_bits(struct comedi_device *dev,
-                                  struct comedi_subdevice *s,
-                                  struct comedi_insn *insn,
-                                  unsigned int *data)
-{
-       struct dio200_subdev_8255 *subpriv = s->private;
-       unsigned int mask;
-       unsigned int val;
-
-       mask = comedi_dio_update_state(s, data);
-       if (mask) {
-               if (mask & 0xff)
-                       dio200_write8(dev, subpriv->ofs + I8255_DATA_A_REG,
-                                     s->state & 0xff);
-               if (mask & 0xff00)
-                       dio200_write8(dev, subpriv->ofs + I8255_DATA_B_REG,
-                                     (s->state >> 8) & 0xff);
-               if (mask & 0xff0000)
-                       dio200_write8(dev, subpriv->ofs + I8255_DATA_C_REG,
-                                     (s->state >> 16) & 0xff);
-       }
-
-       val = dio200_read8(dev, subpriv->ofs + I8255_DATA_A_REG);
-       val |= dio200_read8(dev, subpriv->ofs + I8255_DATA_B_REG) << 8;
-       val |= dio200_read8(dev, subpriv->ofs + I8255_DATA_C_REG) << 16;
-
-       data[1] = val;
-
-       return insn->n;
-}
-
-static int dio200_subdev_8255_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;
-       int ret;
-
-       if (chan < 8)
-               mask = 0x0000ff;
-       else if (chan < 16)
-               mask = 0x00ff00;
-       else if (chan < 20)
-               mask = 0x0f0000;
-       else
-               mask = 0xf00000;
-
-       ret = comedi_dio_insn_config(dev, s, insn, data, mask);
-       if (ret)
-               return ret;
-
-       dio200_subdev_8255_set_dir(dev, s);
-
-       return insn->n;
-}
-
-static int dio200_subdev_8255_init(struct comedi_device *dev,
-                                  struct comedi_subdevice *s,
-                                  unsigned int offset)
-{
-       struct dio200_subdev_8255 *subpriv;
-
-       subpriv = comedi_alloc_spriv(s, sizeof(*subpriv));
-       if (!subpriv)
-               return -ENOMEM;
-
-       subpriv->ofs = offset;
-
-       s->type = COMEDI_SUBD_DIO;
-       s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
-       s->n_chan = 24;
-       s->range_table = &range_digital;
-       s->maxdata = 1;
-       s->insn_bits = dio200_subdev_8255_bits;
-       s->insn_config = dio200_subdev_8255_config;
-       dio200_subdev_8255_set_dir(dev, s);
-       return 0;
-}
-
 static int dio200_subdev_timer_read(struct comedi_device *dev,
                                    struct comedi_subdevice *s,
                                    struct comedi_insn *insn,
@@ -1002,8 +908,8 @@ int amplc_dio200_common_attach(struct comedi_device *dev, 
unsigned int irq,
                        break;
                case sd_8255:
                        /* digital i/o subdevice (8255) */
-                       ret = dio200_subdev_8255_init(dev, s,
-                                                     board->sdinfo[n]);
+                       ret = subdev_8255_init(dev, s, dio200_8255_io,
+                                              board->sdinfo[n]);
                        if (ret < 0)
                                return ret;
                        break;
-- 
2.0.3

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

Reply via email to