*data = devpriv->do_int_type;
return insn->n;
}
-
-/*
- * Interrupt handler for the interruptible digital inputs
- */
-static void apci1564_interrupt(int irq, void *d)
-{
- struct comedi_device *dev = d;
- struct apci1564_private *devpriv = dev->private;
- unsigned int ui_DO, ui_DI;
- unsigned int ui_Timer;
- unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
- unsigned int ul_Command2 = 0;
-
- ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG) & 0x01;
- ui_DO = inl(devpriv->amcc_iobase + APCI1564_DO_IRQ_REG) & 0x01;
- ui_Timer = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG) & 0x01;
- ui_C1 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
- ui_C2 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
- ui_C3 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
- ui_C4 =
- inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
- if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
- && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
- dev_err(dev->class_dev, "Interrupt from unknown source.\n");
- }
-
- if (ui_DI == 1) {
- ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
- outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
- /* send signal to the sample */
- send_sig(SIGIO, devpriv->tsk_current, 0);
- /* enable the interrupt */
- outl(ui_DI, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
- return;
- }
-
- if (ui_DO == 1) {
- /* Check for Digital Output interrupt Type */
- /* 1: VCC interrupt */
- /* 2: CC interrupt */
- devpriv->do_int_type = inl(devpriv->amcc_iobase +
- APCI1564_DO_INT_STATUS_REG) & 0x3;
- /* Disable the Interrupt */
- outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
-
- /* Sends signal to user space */
- send_sig(SIGIO, devpriv->tsk_current, 0);
- }
-
- if (ui_Timer == 1) {
- devpriv->timer_select_mode = ADDIDATA_TIMER;
- if (devpriv->timer_select_mode) {
-
- /* Disable Timer Interrupt */
- ul_Command2 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
- outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_current, 0);
-
- /* Enable Timer Interrupt */
-
- outl(ul_Command2, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
- }
- }
-
- if (ui_C1 == 1) {
- devpriv->timer_select_mode = ADDIDATA_COUNTER;
- if (devpriv->timer_select_mode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
- }
- }
-
- if (ui_C2 == 1) {
- devpriv->timer_select_mode = ADDIDATA_COUNTER;
- if (devpriv->timer_select_mode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
- }
- }
-
- if (ui_C3 == 1) {
- devpriv->timer_select_mode = ADDIDATA_COUNTER;
- if (devpriv->timer_select_mode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
- }
- }
-
- if (ui_C4 == 1) {
- devpriv->timer_select_mode = ADDIDATA_COUNTER;
- if (devpriv->timer_select_mode) {
-
- /* Disable Counter Interrupt */
- ul_Command2 =
- inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- outl(0x0,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
-
- /* Send a signal to from kernel to user space */
- send_sig(SIGIO, devpriv->tsk_current, 0);
-
- /* Enable Counter Interrupt */
- outl(ul_Command2,
- dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
- }
- }
- return;
-}
#include "../comedidev.h"
#include "comedi_fc.h"
+#include "amcc_s5933.h"
#include "addi-data/addi_common.h"
return 0;
}
-static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
+static irqreturn_t apci1564_interrupt(int irq, void *d)
{
- apci1564_interrupt(irq, d);
- return IRQ_RETVAL(1);
+ struct comedi_device *dev = d;
+ struct apci1564_private *devpriv = dev->private;
+ struct comedi_subdevice *s = dev->read_subdev;
+ unsigned int ui_DO, ui_DI;
+ unsigned int ui_Timer;
+ unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
+ unsigned int ul_Command2 = 0;
+
+ /* check interrupt is from this device */
+ if ((inl(devpriv->amcc_iobase + AMCC_OP_REG_INTCSR) &
+ INTCSR_INTR_ASSERTED) == 0)
+ return IRQ_NONE;
+
+ /* check which interrupt was triggered */
+ ui_DI = inl(devpriv->amcc_iobase + APCI1564_DI_IRQ_REG) &
+ APCI1564_DI_INT_ENABLE;
+ ui_DO = inl(devpriv->amcc_iobase + APCI1564_DO_IRQ_REG) & 0x01;
+ ui_Timer = inl(devpriv->amcc_iobase + APCI1564_TIMER_IRQ_REG) & 0x01;
+ ui_C1 =
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)) & 0x1;
+ ui_C2 =
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)) & 0x1;
+ ui_C3 =
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)) & 0x1;
+ ui_C4 =
+ inl(dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)) & 0x1;
+ if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
+ && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
+ return IRQ_HANDLED;
+ }
+
+ if (ui_DI) {
+ /* disable the interrupt */
+ outl(ui_DI & APCI1564_DI_INT_DISABLE, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+
+ s->state = inl(dev->iobase + APCI1564_DI_INT_STATUS_REG) & 0xffff;
+ comedi_buf_put(s, s->state);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+
+ /* enable the interrupt */
+ outl(ui_DI, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG);
+ }
+
+ if (ui_DO == 1) {
+ /* Check for Digital Output interrupt Type */
+ /* 1: VCC interrupt */
+ /* 2: CC interrupt */
+ devpriv->do_int_type = inl(devpriv->amcc_iobase +
+ APCI1564_DO_INT_STATUS_REG) & 0x3;
+ /* Disable the Interrupt */
+ outl(0x0, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG);
+
+ /* Sends signal to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+ }
+
+ if (ui_Timer == 1) {
+ devpriv->timer_select_mode = ADDIDATA_TIMER;
+ if (devpriv->timer_select_mode) {
+
+ /* Disable Timer Interrupt */
+ ul_Command2 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Timer Interrupt */
+
+ outl(ul_Command2, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG);
+ }
+ }
+
+ if (ui_C1 == 1) {
+ devpriv->timer_select_mode = ADDIDATA_COUNTER;
+ if (devpriv->timer_select_mode) {
+
+ /* Disable Counter Interrupt */
+ ul_Command2 =
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ outl(0x0,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Counter Interrupt */
+ outl(ul_Command2,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER1));
+ }
+ }
+
+ if (ui_C2 == 1) {
+ devpriv->timer_select_mode = ADDIDATA_COUNTER;
+ if (devpriv->timer_select_mode) {
+
+ /* Disable Counter Interrupt */
+ ul_Command2 =
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ outl(0x0,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Counter Interrupt */
+ outl(ul_Command2,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2));
+ }
+ }
+
+ if (ui_C3 == 1) {
+ devpriv->timer_select_mode = ADDIDATA_COUNTER;
+ if (devpriv->timer_select_mode) {
+
+ /* Disable Counter Interrupt */
+ ul_Command2 =
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ outl(0x0,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Counter Interrupt */
+ outl(ul_Command2,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3));
+ }
+ }
+
+ if (ui_C4 == 1) {
+ devpriv->timer_select_mode = ADDIDATA_COUNTER;
+ if (devpriv->timer_select_mode) {
+
+ /* Disable Counter Interrupt */
+ ul_Command2 =
+ inl(dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+ outl(0x0,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+
+ /* Send a signal to from kernel to user space */
+ send_sig(SIGIO, devpriv->tsk_current, 0);
+
+ /* Enable Counter Interrupt */
+ outl(ul_Command2,
+ dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4));
+ }
+ }
+ return IRQ_HANDLED;
}
static int apci1564_di_insn_bits(struct comedi_device *dev,
apci1564_reset(dev);
if (pcidev->irq > 0) {
- ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
+ ret = request_irq(pcidev->irq, apci1564_interrupt, IRQF_SHARED,
dev->board_name, dev);
if (ret == 0)
dev->irq = pcidev->irq;