staging: comedi: das08: Support read-back of AO subdevice
authorIan Abbott <abbotti@mev.co.uk>
Fri, 31 Aug 2012 19:41:44 +0000 (20:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 4 Sep 2012 19:00:42 +0000 (12:00 -0700)
Stash the last value written to each AO channel in private data and
support the INSN_READ instruction to read it back.  Don't bother setting
the SDF_READABLE subdevice flag though as the hardware isn't really
readable - we're just faking it.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/das08.c
drivers/staging/comedi/drivers/das08.h

index 0457b9b7ef2d618c2818b51e47cd047767335599..623e77ef2d280de5cbdbacf31cd8a2387b015486 100644 (file)
@@ -373,6 +373,7 @@ static void das08_ao_set_data(struct comedi_device *dev,
                              unsigned int chan, unsigned int data)
 {
        const struct das08_board_struct *thisboard = comedi_board(dev);
+       struct das08_private_struct *devpriv = dev->private;
        unsigned char lsb;
        unsigned char msb;
 
@@ -389,6 +390,7 @@ static void das08_ao_set_data(struct comedi_device *dev,
                /* load DACs */
                inb(dev->iobase + DAS08AO_AO_UPDATE);
        }
+       devpriv->ao_readback[chan] = data;
 }
 
 static void das08_ao_initialize(struct comedi_device *dev,
@@ -417,6 +419,22 @@ static int das08_ao_winsn(struct comedi_device *dev,
        return n;
 }
 
+static int das08_ao_rinsn(struct comedi_device *dev,
+                         struct comedi_subdevice *s,
+                         struct comedi_insn *insn, unsigned int *data)
+{
+       struct das08_private_struct *devpriv = dev->private;
+       unsigned int n;
+       unsigned int chan;
+
+       chan = CR_CHAN(insn->chanspec);
+
+       for (n = 0; n < insn->n; n++)
+               data[n] = devpriv->ao_readback[chan];
+
+       return n;
+}
+
 static void i8254_initialize(struct comedi_device *dev)
 {
        const struct das08_board_struct *thisboard = comedi_board(dev);
@@ -670,12 +688,12 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
        /* ao */
        if (thisboard->ao_nbits) {
                s->type = COMEDI_SUBD_AO;
-/* XXX lacks read-back insn */
                s->subdev_flags = SDF_WRITABLE;
                s->n_chan = 2;
                s->maxdata = (1 << thisboard->ao_nbits) - 1;
                s->range_table = &range_bipolar5;
                s->insn_write = das08_ao_winsn;
+               s->insn_read = das08_ao_rinsn;
                das08_ao_initialize(dev, s);
        } else {
                s->type = COMEDI_SUBD_UNUSED;
index 5a339934f1ba4b47450108e0f840caebcf19e4b7..4231be553c0d5110605d4500db47345b797d88e0 100644 (file)
@@ -52,6 +52,7 @@ struct das08_private_struct {
        unsigned int do_bits;   /*  bits for do register on boards with register dedicated to digital out only */
        const unsigned int *pg_gainlist;
        struct pci_dev *pdev;   /*  struct for pci-das08 */
+       unsigned int ao_readback[2];    /* assume 2 AO channels */
 };
 
 int das08_common_attach(struct comedi_device *dev, unsigned long iobase);