[PATCH v2 15/18] staging: comedi: ni_65xx: remove 'output_bits' from private data

H Hartley Sweeten hsweeten at visionengravers.com
Mon Jul 14 19:07:05 UTC 2014


Remove the need for the 'output_bits' in the private data by just
reading the current state of the data port when updating the output
channels in the (*insn_bits) function.

Add a local variable to handle the inverting of the hardware values
when the boardinfo indicates that the outputs are inverted.

Rename the local variable 'port_read_bits' to 'bits' so that we can
use it for updating the output channels and reading back the actual
state to return to the user.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Reviewed-by: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregk at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/ni_65xx.c | 41 ++++++++++++++++----------------
 1 file changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index 46d4ebc..a6d5fde 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -129,7 +129,6 @@
 #define NI_65XX_WDOG_HI_LO_REG(x)	(0x48 + NI_65XX_PORT(x))
 #define NI_65XX_RTSI_ENA(x)		(0x49 + NI_65XX_PORT(x))
 
-#define NI_65XX_MAX_NUM_PORTS		12
 #define NI_65XX_PORT_TO_CHAN(x)		((x) * 8)
 #define NI_65XX_CHAN_TO_PORT(x)		((x) / 8)
 #define NI_65XX_CHAN_TO_MASK(x)		(1 << ((x) % 8))
@@ -287,7 +286,6 @@ static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board
 
 struct ni_65xx_private {
 	void __iomem *mmio;
-	unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
 };
 
 static int ni_65xx_dio_insn_config(struct comedi_device *dev,
@@ -369,14 +367,19 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
 	unsigned long base_port = (unsigned long)s->private;
 	unsigned int base_chan = CR_CHAN(insn->chanspec);
 	int last_port_offset = NI_65XX_CHAN_TO_PORT(s->n_chan - 1);
+	unsigned invert = 0x00;
 	unsigned read_bits = 0;
 	int port_offset;
 
+	/* handle inverted outputs if necessary */
+	if (s->type == COMEDI_SUBD_DO && board->invert_outputs)
+		invert = 0xff;
+
 	for (port_offset = NI_65XX_CHAN_TO_PORT(base_chan);
 	     port_offset <= last_port_offset; port_offset++) {
 		unsigned port = base_port + port_offset;
 		int base_port_channel = NI_65XX_PORT_TO_CHAN(port_offset);
-		unsigned port_mask, port_data, port_read_bits;
+		unsigned port_mask, port_data, bits;
 		int bitshift = base_port_channel - base_chan;
 
 		if (bitshift >= 32)
@@ -392,30 +395,26 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
 		}
 		port_mask &= 0xff;
 		port_data &= 0xff;
+
+		/* update the outputs */
 		if (port_mask) {
-			unsigned bits;
-			devpriv->output_bits[port] &= ~port_mask;
-			devpriv->output_bits[port] |=
-			    port_data & port_mask;
-			bits = devpriv->output_bits[port];
-			if (board->invert_outputs)
-				bits = ~bits;
+			bits = readb(devpriv->mmio + NI_65XX_IO_DATA_REG(port));
+			bits ^= invert;
+			bits &= ~port_mask;
+			bits |= (port_data & port_mask);
+			bits ^= invert;
 			writeb(bits, devpriv->mmio + NI_65XX_IO_DATA_REG(port));
 		}
-		port_read_bits = readb(devpriv->mmio +
-				       NI_65XX_IO_DATA_REG(port));
-		if (s->type == COMEDI_SUBD_DO && board->invert_outputs) {
-			/* Outputs inverted, so invert value read back from
-			 * DO subdevice.  (Does not apply to boards with DIO
-			 * subdevice.) */
-			port_read_bits ^= 0xFF;
-		}
+
+		/* read back the actual state */
+		bits = readb(devpriv->mmio + NI_65XX_IO_DATA_REG(port));
+		bits ^= invert;
 		if (bitshift > 0)
-			port_read_bits <<= bitshift;
+			bits <<= bitshift;
 		else
-			port_read_bits >>= -bitshift;
+			bits >>= -bitshift;
 
-		read_bits |= port_read_bits;
+		read_bits |= bits;
 	}
 	data[1] = read_bits;
 	return insn->n;
-- 
1.9.3



More information about the devel mailing list