staging: comedi: rtd520: use comedi_timeout()
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Mon, 10 Feb 2014 18:49:36 +0000 (11:49 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 14 Feb 2014 17:28:46 +0000 (09:28 -0800)
Use comedi_timeout() to wait for the analog input and output end-of-
conversions.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/rtd520.c

index 0e83e7e..cd3fdf9 100644 (file)
 /* The board support a channel list up to the FIFO length (1K or 8K) */
 #define RTD_MAX_CHANLIST       128     /* max channel list that we allow */
 
-/* tuning for ai/ao instruction done polling */
-#ifdef FAST_SPIN
-#define WAIT_QUIETLY           /* as nothing, spin on done bit */
-#define RTD_ADC_TIMEOUT        66000   /* 2 msec at 33mhz bus rate */
-#define RTD_DAC_TIMEOUT        66000
-#define RTD_DMA_TIMEOUT        33000   /* 1 msec */
-#else
-/* by delaying, power and electrical noise are reduced somewhat */
-#define WAIT_QUIETLY   udelay(1)
-#define RTD_ADC_TIMEOUT        2000    /* in usec */
-#define RTD_DAC_TIMEOUT        2000    /* in usec */
-#define RTD_DMA_TIMEOUT        1000    /* in usec */
-#endif
-
 /*======================================================================
   Board specific stuff
 ======================================================================*/
@@ -562,21 +548,27 @@ static int rtd520_probe_fifo_depth(struct comedi_device *dev)
        return fifo_size;
 }
 
-/*
-  "instructions" read/write data in "one-shot" or "software-triggered"
-  mode (simplest case).
-  This doesn't use interrupts.
+static int rtd_ai_eoc(struct comedi_device *dev,
+                     struct comedi_subdevice *s,
+                     struct comedi_insn *insn,
+                     unsigned long context)
+{
+       struct rtd_private *devpriv = dev->private;
+       unsigned int status;
+
+       status = readl(devpriv->las0 + LAS0_ADC);
+       if (status & FS_ADC_NOT_EMPTY)
+               return 0;
+       return -EBUSY;
+}
 
-  Note, we don't do any settling delays.  Use a instruction list to
-  select, delay, then read.
- */
 static int rtd_ai_rinsn(struct comedi_device *dev,
                        struct comedi_subdevice *s, struct comedi_insn *insn,
                        unsigned int *data)
 {
        struct rtd_private *devpriv = dev->private;
-       int n, ii;
-       int stat;
+       int ret;
+       int n;
 
        /* clear any old fifo data */
        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
@@ -593,14 +585,9 @@ static int rtd_ai_rinsn(struct comedi_device *dev,
                /* trigger conversion */
                writew(0, devpriv->las0 + LAS0_ADC);
 
-               for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
-                       stat = readl(devpriv->las0 + LAS0_ADC);
-                       if (stat & FS_ADC_NOT_EMPTY)    /* 1 -> not empty */
-                               break;
-                       WAIT_QUIETLY;
-               }
-               if (ii >= RTD_ADC_TIMEOUT)
-                       return -ETIMEDOUT;
+               ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
+               if (ret)
+                       return ret;
 
                /* read data */
                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
@@ -1116,9 +1103,22 @@ static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
        return 0;
 }
 
-/*
-  Output one (or more) analog values to a single port as fast as possible.
-*/
+static int rtd_ao_eoc(struct comedi_device *dev,
+                     struct comedi_subdevice *s,
+                     struct comedi_insn *insn,
+                     unsigned long context)
+{
+       struct rtd_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
+       unsigned int status;
+
+       status = readl(devpriv->las0 + LAS0_ADC);
+       if (status & bit)
+               return 0;
+       return -EBUSY;
+}
+
 static int rtd_ao_winsn(struct comedi_device *dev,
                        struct comedi_subdevice *s, struct comedi_insn *insn,
                        unsigned int *data)
@@ -1127,6 +1127,7 @@ static int rtd_ao_winsn(struct comedi_device *dev,
        int i;
        int chan = CR_CHAN(insn->chanspec);
        int range = CR_RANGE(insn->chanspec);
+       int ret;
 
        /* Configure the output range (table index matches the range values) */
        writew(range & 7, devpriv->las0 +
@@ -1136,8 +1137,6 @@ static int rtd_ao_winsn(struct comedi_device *dev,
         * very useful, but that's how the interface is defined. */
        for (i = 0; i < insn->n; ++i) {
                int val = data[i] << 3;
-               int stat = 0;   /* initialize to avoid bogus warning */
-               int ii;
 
                /* VERIFY: comedi range and offset conversions */
 
@@ -1157,16 +1156,9 @@ static int rtd_ao_winsn(struct comedi_device *dev,
 
                devpriv->ao_readback[chan] = data[i];
 
-               for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
-                       stat = readl(devpriv->las0 + LAS0_ADC);
-                       /* 1 -> not empty */
-                       if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
-                                   FS_DAC2_NOT_EMPTY))
-                               break;
-                       WAIT_QUIETLY;
-               }
-               if (ii >= RTD_DAC_TIMEOUT)
-                       return -ETIMEDOUT;
+               ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
+               if (ret)
+                       return ret;
        }
 
        /* return the number of samples read/written */