staging: comedi: pcmuio: introduce pcmuio_read()
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Tue, 18 Jun 2013 20:25:15 +0000 (13:25 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Jun 2013 22:51:04 +0000 (15:51 -0700)
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>
drivers/staging/comedi/drivers/pcmuio.c

index 8f745127ea6fd33aff210245b762aaf7b368a9d2..e52f6aeee45376f457b93b6f80aa7f219606e20c 100644 (file)
 
 #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;
        }