Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 364199
b: refs/heads/master
c: 7f34085
h: refs/heads/master
i:
  364197: 43337e0
  364195: 263872c
  364191: 2b8827c
v: v3
  • Loading branch information
H Hartley Sweeten authored and Greg Kroah-Hartman committed Apr 23, 2013
1 parent 1833380 commit 1b2b42d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b4780a3afb944765f4b94d79463e570e4472ccb6
refs/heads/master: 7f340859f26e6de7069d0c4f234d948820c4fd47
85 changes: 37 additions & 48 deletions trunk/drivers/staging/comedi/drivers/das800.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ cmd triggers supported:
#define STATUS2_INTE 0X20
#define DAS800_ID 7

#define DAS802_16_HALF_FIFO_SZ 128

struct das800_board {
const char *name;
int ai_speed;
Expand Down Expand Up @@ -483,92 +485,79 @@ static unsigned int das800_ai_get_sample(struct comedi_device *dev)

static irqreturn_t das800_interrupt(int irq, void *d)
{
short i; /* loop index */
short dataPoint = 0;
struct comedi_device *dev = d;
const struct das800_board *thisboard = comedi_board(dev);
struct das800_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
struct comedi_async *async;
int status;
struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async = s ? s->async : NULL;
unsigned long irq_flags;
static const int max_loops = 128; /* half-fifo size for cio-das802/16 */
/* flags */
int fifo_empty = 0;
int fifo_overflow = 0;
unsigned int status;
unsigned int val;
bool fifo_empty;
bool fifo_overflow;
int i;

status = inb(dev->iobase + DAS800_STATUS);
/* if interrupt was not generated by board or driver not attached, quit */
if (!(status & IRQ))
return IRQ_NONE;
if (!(dev->attached))
if (!dev->attached)
return IRQ_HANDLED;

/* wait until here to initialize async, since we will get null dereference
* if interrupt occurs before driver is fully attached!
*/
async = s->async;

/* if hardware conversions are not enabled, then quit */
spin_lock_irqsave(&dev->spinlock, irq_flags);
status = das800_ind_read(dev, CONTROL1) & STATUS2_HCEN;
/* don't release spinlock yet since we want to make sure no one else disables hardware conversions */
/*
* Don't release spinlock yet since we want to make sure
* no one else disables hardware conversions.
*/

/* if hardware conversions are not enabled, then quit */
if (status == 0) {
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
return IRQ_HANDLED;
}

/* loop while card's fifo is not empty (and limit to half fifo for cio-das802/16) */
for (i = 0; i < max_loops; i++) {
/* read 16 bits from dev->iobase and dev->iobase + 1 */
dataPoint = inb(dev->iobase + DAS800_LSB);
dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
if (thisboard->resolution == 12) {
fifo_empty = dataPoint & FIFO_EMPTY;
fifo_overflow = dataPoint & FIFO_OVF;
if (fifo_overflow)
break;
for (i = 0; i < DAS802_16_HALF_FIFO_SZ; i++) {
val = das800_ai_get_sample(dev);
if (s->maxdata == 0x0fff) {
fifo_empty = !!(val & FIFO_EMPTY);
fifo_overflow = !!(val & FIFO_OVF);
} else {
fifo_empty = 0; /* cio-das802/16 has no fifo empty status bit */
/* cio-das802/16 has no fifo empty status bit */
fifo_empty = false;
fifo_overflow = !!(inb(dev->iobase + DAS800_GAIN) &
CIO_FFOV);
}
if (fifo_empty)
if (fifo_empty || fifo_overflow)
break;
/* strip off extraneous bits for 12 bit cards */
if (thisboard->resolution == 12)
dataPoint = (dataPoint >> 4) & 0xfff;

if (s->maxdata == 0x0fff)
val >>= 4; /* 12-bit sample */

/* if there are more data points to collect */
if (devpriv->count > 0 || devpriv->forever == 1) {
if (devpriv->count > 0 || devpriv->forever) {
/* write data point to buffer */
cfc_write_to_buffer(s, dataPoint);
if (devpriv->count > 0)
devpriv->count--;
cfc_write_to_buffer(s, val & s->maxdata);
devpriv->count--;
}
}
async->events |= COMEDI_CB_BLOCK;
/* check for fifo overflow */
if (thisboard->resolution == 12) {
fifo_overflow = dataPoint & FIFO_OVF;
/* else cio-das802/16 */
} else {
fifo_overflow = inb(dev->iobase + DAS800_GAIN) & CIO_FFOV;
}

if (fifo_overflow) {
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
comedi_error(dev, "DAS800 FIFO overflow");
das800_cancel(dev, s);
async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
comedi_event(dev, s);
async->events = 0;
return IRQ_HANDLED;
}
if (devpriv->count > 0 || devpriv->forever == 1) {

if (devpriv->count > 0 || devpriv->forever) {
/* Re-enable card's interrupt.
* We already have spinlock, so indirect addressing is safe */
das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits,
CONTROL1);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
/* otherwise, stop taking data */
} else {
/* otherwise, stop taking data */
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
das800_disable(dev);
async->events |= COMEDI_CB_EOA;
Expand Down

0 comments on commit 1b2b42d

Please sign in to comment.