mirror of https://gitee.com/openkylin/linux.git
staging: comedi: rtd520: use comedi_timeout()
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>
This commit is contained in:
parent
a9f9d83145
commit
051448c525
|
@ -237,20 +237,6 @@
|
|||
/* 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 */
|
||||
|
|
Loading…
Reference in New Issue