Commit 7d783469 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: cb_pcidas: split ai code out of interrupt handler

Clarify the interrupt handler by splitting the analog input handling
into a new function.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent abfe2196
...@@ -97,6 +97,11 @@ ...@@ -97,6 +97,11 @@
#define PCIDAS_CTRL_LADFUL BIT(13) /* fifo overflow / clear */ #define PCIDAS_CTRL_LADFUL BIT(13) /* fifo overflow / clear */
#define PCIDAS_CTRL_DAEMI BIT(14) /* dac fifo empty int status / clear */ #define PCIDAS_CTRL_DAEMI BIT(14) /* dac fifo empty int status / clear */
#define PCIDAS_CTRL_AI_INT (PCIDAS_CTRL_EOAI | PCIDAS_CTRL_EOBI | \
PCIDAS_CTRL_ADHFI | PCIDAS_CTRL_ADNEI | \
PCIDAS_CTRL_LADFUL)
#define PCIDAS_CTRL_AO_INT (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI)
#define PCIDAS_AI_REG 0x02 /* ADC CHANNEL MUX AND CONTROL reg */ #define PCIDAS_AI_REG 0x02 /* ADC CHANNEL MUX AND CONTROL reg */
#define PCIDAS_AI_FIRST(x) ((x) & 0xf) #define PCIDAS_AI_FIRST(x) ((x) & 0xf)
#define PCIDAS_AI_LAST(x) (((x) & 0xf) << 4) #define PCIDAS_AI_LAST(x) (((x) & 0xf) << 4)
...@@ -1144,47 +1149,22 @@ static void cb_pcidas_ao_interrupt(struct comedi_device *dev, ...@@ -1144,47 +1149,22 @@ static void cb_pcidas_ao_interrupt(struct comedi_device *dev,
comedi_handle_events(dev, s); comedi_handle_events(dev, s);
} }
static irqreturn_t cb_pcidas_interrupt(int irq, void *d) static void cb_pcidas_ai_interrupt(struct comedi_device *dev,
unsigned int status)
{ {
struct comedi_device *dev = d;
const struct cb_pcidas_board *board = dev->board_ptr; const struct cb_pcidas_board *board = dev->board_ptr;
struct cb_pcidas_private *devpriv = dev->private; struct cb_pcidas_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_async *async; struct comedi_async *async = s->async;
struct comedi_cmd *cmd; struct comedi_cmd *cmd = &async->cmd;
int status, s5933_status;
int half_fifo = board->fifo_size / 2;
unsigned int num_samples, i;
static const int timeout = 10000;
unsigned long flags; unsigned long flags;
if (!dev->attached)
return IRQ_NONE;
async = s->async;
cmd = &async->cmd;
s5933_status = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
return IRQ_NONE;
/* make sure mailbox 4 is empty */
inl_p(devpriv->amcc + AMCC_OP_REG_IMB4);
/* clear interrupt on amcc s5933 */
outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS,
devpriv->amcc + AMCC_OP_REG_INTCSR);
status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG);
/* check for analog output interrupt */
if (status & (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI))
cb_pcidas_ao_interrupt(dev, status);
/* check for analog input interrupts */
/* if fifo half-full */ /* if fifo half-full */
if (status & PCIDAS_CTRL_ADHFI) { if (status & PCIDAS_CTRL_ADHFI) {
unsigned int num_samples;
/* read data */ /* read data */
num_samples = comedi_nsamples_left(s, half_fifo); num_samples = comedi_nsamples_left(s, board->fifo_size / 2);
insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG, insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG,
devpriv->ai_buffer, num_samples); devpriv->ai_buffer, num_samples);
comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
...@@ -1200,7 +1180,9 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) ...@@ -1200,7 +1180,9 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
spin_unlock_irqrestore(&dev->spinlock, flags); spin_unlock_irqrestore(&dev->spinlock, flags);
/* else if fifo not empty */ /* else if fifo not empty */
} else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) { } else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) {
for (i = 0; i < timeout; i++) { unsigned int i;
for (i = 0; i < 10000; i++) {
unsigned short val; unsigned short val;
/* break if fifo is empty */ /* break if fifo is empty */
...@@ -1242,6 +1224,38 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d) ...@@ -1242,6 +1224,38 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
} }
comedi_handle_events(dev, s); comedi_handle_events(dev, s);
}
static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
{
struct comedi_device *dev = d;
struct cb_pcidas_private *devpriv = dev->private;
unsigned int amcc_status;
unsigned int status;
if (!dev->attached)
return IRQ_NONE;
amcc_status = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
if ((INTCSR_INTR_ASSERTED & amcc_status) == 0)
return IRQ_NONE;
/* make sure mailbox 4 is empty */
inl_p(devpriv->amcc + AMCC_OP_REG_IMB4);
/* clear interrupt on amcc s5933 */
outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS,
devpriv->amcc + AMCC_OP_REG_INTCSR);
status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG);
/* handle analog output interrupts */
if (status & PCIDAS_CTRL_AO_INT)
cb_pcidas_ao_interrupt(dev, status);
/* handle analog input interrupts */
if (status & PCIDAS_CTRL_AI_INT)
cb_pcidas_ai_interrupt(dev, status);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment