summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-06-18 13:25:15 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-24 15:51:04 -0700
commit89aaa92adffa5c57d9c2a545c7cb9809ddd3b615 (patch)
treeb66314598c1cb10a2c31ca388477fc69fe5ab948
parent1699d80aef8ba7992d5f4176aed3504db8cffaf9 (diff)
staging: comedi: pcmuio: introduce pcmuio_read()
Introduce a helper function to handle reading a 24-bit value from the three 8-bit registers associated with a "port" or "page". Simplify the for() loop in pcmuio_handle_asic_interrupt() that finds which channels have triggered the interrupt. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
index 8f745127ea6f..e52f6aeee453 100644
--- a/drivers/staging/comedi/drivers/pcmuio.c
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -110,7 +110,6 @@
#define CHANS_PER_PORT 8
#define PORTS_PER_ASIC 6
-#define INTR_PORTS_PER_ASIC 3
/* number of channels per comedi subdevice */
#define MAX_CHANS_PER_SUBDEV 24
#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV / CHANS_PER_PORT)
@@ -183,6 +182,27 @@ static void pcmuio_write(struct comedi_device *dev, unsigned int val,
}
}
+static unsigned int pcmuio_read(struct comedi_device *dev,
+ int asic, int page, int port)
+{
+ unsigned long iobase = dev->iobase + (asic * ASIC_IOSIZE);
+ unsigned int val;
+
+ if (page == 0) {
+ /* Port registers are valid for any page */
+ val = inb(iobase + PCMUIO_PORT_REG(port + 0));
+ val |= (inb(iobase + PCMUIO_PORT_REG(port + 1)) << 8);
+ val |= (inb(iobase + PCMUIO_PORT_REG(port + 2)) << 16);
+ } else {
+ outb(PCMUIO_PAGE(page), iobase + PCMUIO_PAGE_LOCK_REG);
+ val = inb(iobase + PCMUIO_PAGE_REG(0));
+ val |= (inb(iobase + PCMUIO_PAGE_REG(1)) << 8);
+ val |= (inb(iobase + PCMUIO_PAGE_REG(2)) << 16);
+ }
+
+ return val;
+}
+
static int pcmuio_dio_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
@@ -296,12 +316,6 @@ static int pcmuio_dio_insn_config(struct comedi_device *dev,
return insn->n;
}
-static void switch_page(struct comedi_device *dev, int asic, int page)
-{
- outb(PCMUIO_PAGE(page),
- dev->iobase + ASIC_IOSIZE * asic + PCMUIO_PAGE_LOCK_REG);
-}
-
static void init_asics(struct comedi_device *dev)
{
const struct pcmuio_board *board = comedi_board(dev);
@@ -401,7 +415,7 @@ static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic)
struct pcmuio_private *devpriv = dev->private;
struct pcmuio_subdev_private *subpriv;
unsigned long iobase = dev->iobase + (asic * ASIC_IOSIZE);
- unsigned triggered = 0;
+ unsigned int triggered = 0;
int got1 = 0;
unsigned long flags;
unsigned char int_pend;
@@ -411,19 +425,8 @@ static int pcmuio_handle_asic_interrupt(struct comedi_device *dev, int asic)
int_pend = inb(iobase + PCMUIO_INT_PENDING_REG) & 0x07;
if (int_pend) {
- for (i = 0; i < INTR_PORTS_PER_ASIC; ++i) {
- if (int_pend & (0x1 << i)) {
- unsigned char val;
-
- switch_page(dev, asic, PCMUIO_PAGE_INT_ID);
- val = inb(iobase + PCMUIO_PAGE_REG(i));
- if (val)
- /* clear pending interrupt */
- outb(0, iobase + PCMUIO_PAGE_REG(i));
-
- triggered |= (val << (i * 8));
- }
- }
+ triggered = pcmuio_read(dev, asic, PCMUIO_PAGE_INT_ID, 0);
+ pcmuio_write(dev, 0, asic, PCMUIO_PAGE_INT_ID, 0);
++got1;
}