Commit 800453dc authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: ni_65xx: use the subdevice 'io_bits' to handle the 'invert_outputs'

Some of the boards supported by this driver have output ports that are
inverted from the comedi view of the output state. For these boards the
read values from the output ports needs to be inverted before being
modified and inverted again before being written back in the (*insn_bits)
operation.

Currently the subdevice type and the boardinfo is checked in the (*insn_bits)
to determine if the inverted outputs need to be handled.

Since thise driver does not use the subdevice 'io_bits', simplify the driver
a bit by initializing the 'io_bits' during the attach to handle the inversion.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5c70b536
...@@ -362,19 +362,13 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, ...@@ -362,19 +362,13 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
const struct ni_65xx_board *board = comedi_board(dev);
struct ni_65xx_private *devpriv = dev->private; struct ni_65xx_private *devpriv = dev->private;
unsigned long base_port = (unsigned long)s->private; unsigned long base_port = (unsigned long)s->private;
unsigned int base_chan = CR_CHAN(insn->chanspec); unsigned int base_chan = CR_CHAN(insn->chanspec);
int last_port_offset = NI_65XX_CHAN_TO_PORT(s->n_chan - 1); int last_port_offset = NI_65XX_CHAN_TO_PORT(s->n_chan - 1);
unsigned invert = 0x00;
unsigned read_bits = 0; unsigned read_bits = 0;
int port_offset; 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); for (port_offset = NI_65XX_CHAN_TO_PORT(base_chan);
port_offset <= last_port_offset; port_offset++) { port_offset <= last_port_offset; port_offset++) {
unsigned port = base_port + port_offset; unsigned port = base_port + port_offset;
...@@ -399,16 +393,16 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, ...@@ -399,16 +393,16 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
/* update the outputs */ /* update the outputs */
if (port_mask) { if (port_mask) {
bits = readb(devpriv->mmio + NI_65XX_IO_DATA_REG(port)); bits = readb(devpriv->mmio + NI_65XX_IO_DATA_REG(port));
bits ^= invert; bits ^= s->io_bits; /* invert if necessary */
bits &= ~port_mask; bits &= ~port_mask;
bits |= (port_data & port_mask); bits |= (port_data & port_mask);
bits ^= invert; bits ^= s->io_bits; /* invert back */
writeb(bits, devpriv->mmio + NI_65XX_IO_DATA_REG(port)); writeb(bits, devpriv->mmio + NI_65XX_IO_DATA_REG(port));
} }
/* read back the actual state */ /* read back the actual state */
bits = readb(devpriv->mmio + NI_65XX_IO_DATA_REG(port)); bits = readb(devpriv->mmio + NI_65XX_IO_DATA_REG(port));
bits ^= invert; bits ^= s->io_bits; /* invert if necessary */
if (bitshift > 0) if (bitshift > 0)
bits <<= bitshift; bits <<= bitshift;
else else
...@@ -662,6 +656,9 @@ static int ni_65xx_auto_attach(struct comedi_device *dev, ...@@ -662,6 +656,9 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
/* the output ports always start after the input ports */ /* the output ports always start after the input ports */
s->private = (void *)(unsigned long)board->num_di_ports; s->private = (void *)(unsigned long)board->num_di_ports;
/* use the io_bits to handle the inverted outputs */
s->io_bits = (board->invert_outputs) ? 0xff : 0x00;
} else { } else {
s->type = COMEDI_SUBD_UNUSED; s->type = COMEDI_SUBD_UNUSED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment