Commit 36c973d0 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: dt9812: convert digital out subdevice to (*insn_bits)

Currently the (*insn_write) function for the digital output subdevice
only sets the state for a single channel. It's more efficent to use
the (*insn_bits) function and allow setting the state for all the
channels.

The comedi core can use the (*insn_bits) to emulate the (*insn_write)
if needed.

Also, use the subdevice 'state' variable to hold the current state
of the channels instead of 'do_shadow' in the private data.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e81eaba6
...@@ -265,7 +265,6 @@ struct dt9812_private { ...@@ -265,7 +265,6 @@ struct dt9812_private {
} cmd_wr, cmd_rd; } cmd_wr, cmd_rd;
u16 device; u16 device;
u16 ao_shadow[2]; u16 ao_shadow[2];
u8 do_shadow;
}; };
static int dt9812_read_info(struct comedi_device *dev, static int dt9812_read_info(struct comedi_device *dev,
...@@ -390,23 +389,11 @@ static int dt9812_digital_out(struct comedi_device *dev, u8 bits) ...@@ -390,23 +389,11 @@ static int dt9812_digital_out(struct comedi_device *dev, u8 bits)
down(&devpriv->sem); down(&devpriv->sem);
ret = dt9812_write_multiple_registers(dev, 1, reg, value); ret = dt9812_write_multiple_registers(dev, 1, reg, value);
devpriv->do_shadow = bits;
up(&devpriv->sem); up(&devpriv->sem);
return ret; return ret;
} }
static int dt9812_digital_out_shadow(struct comedi_device *dev, u8 *bits)
{
struct dt9812_private *devpriv = dev->private;
down(&devpriv->sem);
*bits = devpriv->do_shadow;
up(&devpriv->sem);
return 0;
}
static void dt9812_configure_mux(struct comedi_device *dev, static void dt9812_configure_mux(struct comedi_device *dev,
struct dt9812_rmw_byte *rmw, int channel) struct dt9812_rmw_byte *rmw, int channel)
{ {
...@@ -624,24 +611,24 @@ static int dt9812_di_insn_bits(struct comedi_device *dev, ...@@ -624,24 +611,24 @@ static int dt9812_di_insn_bits(struct comedi_device *dev,
return insn->n; return insn->n;
} }
static int dt9812_do_winsn(struct comedi_device *dev, static int dt9812_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn, struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
unsigned int channel = CR_CHAN(insn->chanspec); unsigned int mask = data[0];
int n; unsigned int bits = data[1];
u8 bits = 0;
dt9812_digital_out_shadow(dev, &bits); if (mask) {
for (n = 0; n < insn->n; n++) { s->state &= ~mask;
u8 mask = 1 << channel; s->state |= (bits & mask);
bits &= ~mask; dt9812_digital_out(dev, s->state);
if (data[n])
bits |= mask;
} }
dt9812_digital_out(dev, bits);
return n; data[1] = s->state;
return insn->n;
} }
static int dt9812_ai_rinsn(struct comedi_device *dev, static int dt9812_ai_rinsn(struct comedi_device *dev,
...@@ -849,9 +836,7 @@ static int dt9812_auto_attach(struct comedi_device *dev, ...@@ -849,9 +836,7 @@ static int dt9812_auto_attach(struct comedi_device *dev,
s->n_chan = 8; s->n_chan = 8;
s->maxdata = 1; s->maxdata = 1;
s->range_table = &range_digital; s->range_table = &range_digital;
s->insn_write = dt9812_do_winsn; s->insn_bits = dt9812_do_insn_bits;
devpriv->do_shadow = 0;
/* Analog Input subdevice */ /* Analog Input subdevice */
s = &dev->subdevices[2]; s = &dev->subdevices[2];
......
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