staging: comedi: das1800: add analog output readback

Use the core provided readback support to allow reading back the last
value written to the analog output channels.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
H Hartley Sweeten 2016-04-08 12:41:47 -07:00 committed by Greg Kroah-Hartman
parent a5405cfa1b
commit 750bca653d
1 changed files with 9 additions and 8 deletions

View File

@ -91,7 +91,6 @@ Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
TODO: TODO:
Make it automatically allocate irq and dma channels if they are not specified Make it automatically allocate irq and dma channels if they are not specified
Add support for analog out on 'ao' cards Add support for analog out on 'ao' cards
read insn for analog out
*/ */
#include <linux/module.h> #include <linux/module.h>
@ -341,8 +340,6 @@ struct das1800_private {
int dma_bits; int dma_bits;
uint16_t *fifo_buf; /* bounce buffer for analog input FIFO */ uint16_t *fifo_buf; /* bounce buffer for analog input FIFO */
unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
unsigned short ao_update_bits; /* remembers the last write to the
* 'update' dac */
bool ai_is_unipolar; bool ai_is_unipolar;
}; };
@ -1017,7 +1014,6 @@ static int das1800_ao_insn_write(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
struct das1800_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec); unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int update_chan = s->n_chan - 1; unsigned int update_chan = s->n_chan - 1;
unsigned long flags; unsigned long flags;
@ -1029,9 +1025,9 @@ static int das1800_ao_insn_write(struct comedi_device *dev,
for (i = 0; i < insn->n; i++) { for (i = 0; i < insn->n; i++) {
unsigned int val = data[i]; unsigned int val = data[i];
s->readback[chan] = val;
val = comedi_offset_munge(s, val); val = comedi_offset_munge(s, val);
if (chan == update_chan)
devpriv->ao_update_bits = val;
/* load this channel (and update if it's the last channel) */ /* load this channel (and update if it's the last channel) */
outb(DAC(chan), dev->iobase + DAS1800_SELECT); outb(DAC(chan), dev->iobase + DAS1800_SELECT);
@ -1039,9 +1035,10 @@ static int das1800_ao_insn_write(struct comedi_device *dev,
/* update all channels */ /* update all channels */
if (chan != update_chan) { if (chan != update_chan) {
val = comedi_offset_munge(s, s->readback[update_chan]);
outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);
outw(devpriv->ao_update_bits, outw(val, dev->iobase + DAS1800_DAC);
dev->iobase + DAS1800_DAC);
} }
} }
spin_unlock_irqrestore(&dev->spinlock, flags); spin_unlock_irqrestore(&dev->spinlock, flags);
@ -1318,6 +1315,10 @@ static int das1800_attach(struct comedi_device *dev,
s->range_table = &range_bipolar10; s->range_table = &range_bipolar10;
s->insn_write = das1800_ao_insn_write; s->insn_write = das1800_ao_insn_write;
ret = comedi_alloc_subdev_readback(s);
if (ret)
return ret;
/* initialize all channels to 0V */ /* initialize all channels to 0V */
for (i = 0; i < s->n_chan; i++) { for (i = 0; i < s->n_chan; i++) {
outb(DAC(i), dev->iobase + DAS1800_SELECT); outb(DAC(i), dev->iobase + DAS1800_SELECT);