diff options
author | Ian Abbott <abbotti@mev.co.uk> | 2018-10-30 14:17:11 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-11-07 13:05:38 +0100 |
commit | 130151991dcb14e5c383c730b3ef37a6fdc32c95 (patch) | |
tree | a747ccb05b2fe50ae8df0520d6bfe33a414c346c /drivers/staging/comedi | |
parent | fafb85b45f68e95e784d025696512ea062c00bd4 (diff) |
staging: comedi: cb_pcidas64: Use insn->n in AO insn_write handler
The `insn_write` handler for the AO subdevice (`ao_winsn()` currently
ignores `insn->n` (the number of samples to write) and assumes a single
sample is to be written. But `insn->n` could be 0, meaning no samples
should be written, in which case `data[0]` is invalid.
Follow the usual Comedi guidelines and change `ao_winsn()` to write the
specified number of samples. This fixes the assumption that `data[0]`
is valid.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/comedi')
-rw-r--r-- | drivers/staging/comedi/drivers/cb_pcidas64.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 631a703b345d..44e5aaf8bae5 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3097,8 +3097,10 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, { const struct pcidas64_board *board = dev->board_ptr; struct pcidas64_private *devpriv = dev->private; - int chan = CR_CHAN(insn->chanspec); - int range = CR_RANGE(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int range = CR_RANGE(insn->chanspec); + unsigned int val = s->readback[chan]; + unsigned int i; /* do some initializing */ writew(0, devpriv->main_iobase + DAC_CONTROL0_REG); @@ -3108,20 +3110,24 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, writew(devpriv->dac_control1_bits, devpriv->main_iobase + DAC_CONTROL1_REG); - /* write to channel */ - if (board->layout == LAYOUT_4020) { - writew(data[0] & 0xff, - devpriv->main_iobase + dac_lsb_4020_reg(chan)); - writew((data[0] >> 8) & 0xf, - devpriv->main_iobase + dac_msb_4020_reg(chan)); - } else { - writew(data[0], devpriv->main_iobase + dac_convert_reg(chan)); + for (i = 0; i < insn->n; i++) { + /* write to channel */ + val = data[i]; + if (board->layout == LAYOUT_4020) { + writew(val & 0xff, + devpriv->main_iobase + dac_lsb_4020_reg(chan)); + writew((val >> 8) & 0xf, + devpriv->main_iobase + dac_msb_4020_reg(chan)); + } else { + writew(val, + devpriv->main_iobase + dac_convert_reg(chan)); + } } - /* remember output value */ - s->readback[chan] = data[0]; + /* remember last output value */ + s->readback[chan] = val; - return 1; + return insn->n; } static void set_dac_control0_reg(struct comedi_device *dev, |