It's possible for the user to write more than one value to an analog
output channel with the (*insn_write) operation. Use comedi_timeout()
to check the interrupt status register to ensure that each data
conversion is complete before writing the next value.

Signed-off-by: H Hartley Sweeten <hswee...@visionengravers.com>
Cc: Ian Abbott <abbo...@mev.co.uk>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/staging/comedi/drivers/s526.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/comedi/drivers/s526.c 
b/drivers/staging/comedi/drivers/s526.c
index 242db7d..152be95 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -418,16 +418,19 @@ static int s526_ai_insn_config(struct comedi_device *dev,
        return result;
 }
 
-static int s526_ai_eoc(struct comedi_device *dev,
-                      struct comedi_subdevice *s,
-                      struct comedi_insn *insn,
-                      unsigned long context)
+static int s526_eoc(struct comedi_device *dev,
+                   struct comedi_subdevice *s,
+                   struct comedi_insn *insn,
+                   unsigned long context)
 {
        unsigned int status;
 
        status = inw(dev->iobase + S526_INT_STATUS_REG);
-       if (status & S526_INT_AI)
+       if (status & context) {
+               /* we got our eoc event, clear it */
+               outw(context, dev->iobase + S526_INT_STATUS_REG);
                return 0;
+       }
        return -EBUSY;
 }
 
@@ -455,12 +458,10 @@ static int s526_ai_rinsn(struct comedi_device *dev, 
struct comedi_subdevice *s,
                outw(ctrl, dev->iobase + S526_AI_CTRL_REG);
 
                /* wait for conversion to end */
-               ret = comedi_timeout(dev, s, insn, s526_ai_eoc, 0);
+               ret = comedi_timeout(dev, s, insn, s526_eoc, S526_INT_AI);
                if (ret)
                        return ret;
 
-               outw(S526_INT_AI, dev->iobase + S526_INT_STATUS_REG);
-
                d = inw(dev->iobase + S526_AI_REG);
 
                /* munge data */
@@ -479,6 +480,7 @@ static int s526_ao_insn_write(struct comedi_device *dev,
        unsigned int chan = CR_CHAN(insn->chanspec);
        unsigned int ctrl = S526_AO_CTRL_CHAN(chan);
        unsigned int val = s->readback[chan];
+       int ret;
        int i;
 
        outw(ctrl, dev->iobase + S526_AO_CTRL_REG);
@@ -488,6 +490,11 @@ static int s526_ao_insn_write(struct comedi_device *dev,
                val = data[i];
                outw(val, dev->iobase + S526_AO_REG);
                outw(ctrl, dev->iobase + S526_AO_CTRL_REG);
+
+               /* wait for conversion to end */
+               ret = comedi_timeout(dev, s, insn, s526_eoc, S526_INT_AO);
+               if (ret)
+                       return ret;
        }
        s->readback[chan] = val;
 
-- 
2.4.3

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to