[PATCH 15/15] staging: comedi: amplc_dio200_common: use 8255 module

H Hartley Sweeten hsweeten at visionengravers.com
Fri Aug 1 21:18:26 UTC 2014


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 <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at 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



More information about the devel mailing list