[PATCH v2 05/24] staging: comedi: addi_apci_3xxx: fix digital output 'insn_bits' function

H Hartley Sweeten hartleys at visionengravers.com
Tue Nov 6 17:02:16 UTC 2012


This driver does not follow the comedi API. The digital output 'insn_bits'
function is passed a mask value in data[0] indicating which output bits in
data[1] are changing. The function is then supposed to update the outputs
accordingly and then return the current state of the outputs in data[1].

Fix the 'insn_bits' function so it works like the comedi core expects. The
core can then use the function to emulate the 'insn_read' and 'insn_write'
functions for individual channels.

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>
---
 .../comedi/drivers/addi-data/hwdrv_apci3xxx.c      | 257 ++-------------------
 drivers/staging/comedi/drivers/addi_apci_3xxx.c    |  56 ++---
 2 files changed, 27 insertions(+), 286 deletions(-)

diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
index 5d3570c..a45a2a2 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -1288,257 +1288,26 @@ static int apci3xxx_di_insn_bits(struct comedi_device *dev,
 	return insn->n;
 }
 
-/*
-+----------------------------------------------------------------------------+
-|                           DIGITAL OUTPUT SUBDEVICE                         |
-+----------------------------------------------------------------------------+
-
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function name     :int i_APCI3XXX_InsnBitsDigitalOutput                    |
-|                                          (struct comedi_device *dev,              |
-|                                           struct comedi_subdevice *s,             |
-|                                           struct comedi_insn *insn,               |
-|                                           unsigned int *data)                  |
-+----------------------------------------------------------------------------+
-| Task              : Write the selected output mask and read the status from|
-|                     all digital output channles                            |
-+----------------------------------------------------------------------------+
-| Input Parameters  : dw_ChannelMask = data [0];                             |
-|                     dw_BitMask     = data [1];                             |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[1] : All digital output channles states           |
-+----------------------------------------------------------------------------+
-| Return Value      : >0  : No error                                         |
-|                    -4   : Channel mask error                               |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device *dev,
-					    struct comedi_subdevice *s,
-					    struct comedi_insn *insn,
-					    unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_ChannelCpt = 0;
-	unsigned int dw_ChannelMask = 0;
-	unsigned int dw_BitMask = 0;
-	unsigned int dw_Status = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 2) {
-	   /*******************************/
-		/* Get the channe and bit mask */
-	   /*******************************/
-
-		dw_ChannelMask = data[0];
-		dw_BitMask = data[1];
-
-	   /*************************/
-		/* Test the channel mask */
-	   /*************************/
-
-		if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
-	      /*********************************/
-			/* Test if set/reset any channel */
-	      /*********************************/
-
-			if (dw_ChannelMask & 0xF) {
-		 /********************************/
-				/* Read the digital output port */
-		 /********************************/
-
-				dw_Status = inl(devpriv->iobase + 48);
-
-				for (b_ChannelCpt = 0; b_ChannelCpt < 4;
-					b_ChannelCpt++) {
-					if ((dw_ChannelMask >> b_ChannelCpt) &
-						1) {
-						dw_Status =
-							(dw_Status & (0xF -
-								(1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
-					}
-				}
-
-				outl(dw_Status, devpriv->iobase + 48);
-			}
-
-	      /********************************/
-			/* Read the digital output port */
-	      /********************************/
-
-			data[1] = inl(devpriv->iobase + 48);
-		} else {
-	      /************************/
-			/* Config command error */
-	      /************************/
-
-			printk("Channel mask error\n");
-			i_ReturnValue = -4;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name     :int i_APCI3XXX_InsnWriteDigitalOutput                   |
-|                                          (struct comedi_device *dev,              |
-|                                           struct comedi_subdevice *s,             |
-|                                           struct comedi_insn *insn,               |
-|                                           unsigned int *data)                  |
-+----------------------------------------------------------------------------+
-| Task              : Set the state from digital output channel              |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
-|                     b_State   = data [0]                                   |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : >0  : No error                                         |
-|                    -3   : Channel selection error                          |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device *dev,
-					     struct comedi_subdevice *s,
-					     struct comedi_insn *insn,
-					     unsigned int *data)
+static int apci3xxx_do_insn_bits(struct comedi_device *dev,
+				 struct comedi_subdevice *s,
+				 struct comedi_insn *insn,
+				 unsigned int *data)
 {
 	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_Channel = CR_CHAN(insn->chanspec);
-	unsigned char b_State = 0;
-	unsigned int dw_Status = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
+	unsigned int mask = data[0];
+	unsigned int bits = data[1];
 
-	if (insn->n >= 1) {
-	   /***************************/
-		/* Test the channel number */
-	   /***************************/
-
-		if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
-	      /*******************/
-			/* Get the command */
-	      /*******************/
-
-			b_State = (unsigned char) data[0];
+	s->state = inl(devpriv->iobase + 48) & 0xf;
+	if (mask) {
+		s->state &= ~mask;
+		s->state |= (bits & mask);
 
-	      /********************************/
-			/* Read the digital output port */
-	      /********************************/
-
-			dw_Status = inl(devpriv->iobase + 48);
-
-			dw_Status =
-				(dw_Status & (0xF -
-					(1 << b_Channel))) | ((b_State & 1) <<
-				b_Channel);
-			outl(dw_Status, devpriv->iobase + 48);
-		} else {
-	      /***************************/
-			/* Channel selection error */
-	      /***************************/
-
-			printk("Channel selection error\n");
-			i_ReturnValue = -3;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
+		outl(s->state, devpriv->iobase + 48);
 	}
 
-	return i_ReturnValue;
-}
+	data[1] = s->state;
 
-/*
-+----------------------------------------------------------------------------+
-| Function name     :int i_APCI3XXX_InsnReadDigitalOutput                    |
-|                                          (struct comedi_device *dev,              |
-|                                           struct comedi_subdevice *s,             |
-|                                           struct comedi_insn *insn,               |
-|                                           unsigned int *data)                  |
-+----------------------------------------------------------------------------+
-| Task              : Read the state from digital output channel             |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
-+----------------------------------------------------------------------------+
-| Output Parameters : b_State   = data [0]                                   |
-+----------------------------------------------------------------------------+
-| Return Value      : >0  : No error                                         |
-|                    -3   : Channel selection error                          |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-
-static int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device *dev,
-					    struct comedi_subdevice *s,
-					    struct comedi_insn *insn,
-					    unsigned int *data)
-{
-	struct addi_private *devpriv = dev->private;
-	int i_ReturnValue = insn->n;
-	unsigned char b_Channel = CR_CHAN(insn->chanspec);
-	unsigned int dw_Status = 0;
-
-	/************************/
-	/* Test the buffer size */
-	/************************/
-
-	if (insn->n >= 1) {
-	   /***************************/
-		/* Test the channel number */
-	   /***************************/
-
-		if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
-	      /********************************/
-			/* Read the digital output port */
-	      /********************************/
-
-			dw_Status = inl(devpriv->iobase + 48);
-
-			dw_Status = (dw_Status >> b_Channel) & 1;
-			*data = dw_Status;
-		} else {
-	      /***************************/
-			/* Channel selection error */
-	      /***************************/
-
-			printk("Channel selection error\n");
-			i_ReturnValue = -3;
-		}
-	} else {
-	   /*******************/
-		/* Data size error */
-	   /*******************/
-
-		printk("Buffer size error\n");
-		i_ReturnValue = -101;
-	}
-
-	return i_ReturnValue;
+	return insn->n;
 }
 
 /*
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index d0cd2e8..ae2967a 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -191,9 +191,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -224,9 +222,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -257,9 +253,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -290,9 +284,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -323,9 +315,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -356,9 +346,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -513,9 +501,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -550,9 +536,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -587,9 +571,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -624,9 +606,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.ao_write		= i_APCI3XXX_InsnWriteAnalogOutput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 		.ttl_config		= i_APCI3XXX_InsnConfigInitTTLIO,
 		.ttl_bits		= i_APCI3XXX_InsnBitsTTLIO,
 		.ttl_read		= i_APCI3XXX_InsnReadTTLIO,
@@ -655,9 +635,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 	}, {
 		.pc_DriverName		= "apci3002-16",
 		.i_VendorId		= PCI_VENDOR_ID_ADDIDATA,
@@ -682,9 +660,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 	}, {
 		.pc_DriverName		= "apci3002-8",
 		.i_VendorId		= PCI_VENDOR_ID_ADDIDATA,
@@ -709,9 +685,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 	}, {
 		.pc_DriverName		= "apci3002-4",
 		.i_VendorId		= PCI_VENDOR_ID_ADDIDATA,
@@ -736,9 +710,7 @@ static const struct addi_board apci3xxx_boardtypes[] = {
 		.ai_config		= i_APCI3XXX_InsnConfigAnalogInput,
 		.ai_read		= i_APCI3XXX_InsnReadAnalogInput,
 		.di_bits		= apci3xxx_di_insn_bits,
-		.do_write		= i_APCI3XXX_InsnWriteDigitalOutput,
-		.do_bits		= i_APCI3XXX_InsnBitsDigitalOutput,
-		.do_read		= i_APCI3XXX_InsnReadDigitalOutput,
+		.do_bits		= apci3xxx_do_insn_bits,
 	}, {
 		.pc_DriverName		= "apci3500",
 		.i_VendorId		= PCI_VENDOR_ID_ADDIDATA,
-- 
1.7.11




More information about the devel mailing list