staging: comedi: s626: simplify dio register access
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Fri, 22 Mar 2013 22:54:20 +0000 (15:54 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 25 Mar 2013 18:44:43 +0000 (11:44 -0700)
This driver has three dio subdevices, each with 16 channels. These
subdevices use hardware registers that are spaced 0x10 bytes apart
for each "group" of 16 channels.

Create new macros to get the correct addresses for each register
based on the dio "group". Use the s->private (void *) to hold the
"group" number to use in the subdevice functions.

This allows removing struct dio_private and all its uses. It also
removes the ugly casts used to get the register address.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/s626.c
drivers/staging/comedi/drivers/s626.h

index 7d009463b92d3d17cba320a3fbf7be50acdf99fd..104594bca25462fbfd97aa34f7b50d31bd95cf35 100644 (file)
@@ -106,64 +106,6 @@ struct s626_private {
        unsigned int ao_readback[S626_DAC_CHANNELS];
 };
 
-struct dio_private {
-       uint16_t RDDIn;
-       uint16_t WRDOut;
-       uint16_t RDEdgSel;
-       uint16_t WREdgSel;
-       uint16_t RDCapSel;
-       uint16_t WRCapSel;
-       uint16_t RDCapFlg;
-       uint16_t RDIntSel;
-       uint16_t WRIntSel;
-};
-
-static struct dio_private dio_private_A = {
-       .RDDIn = LP_RDDINA,
-       .WRDOut = LP_WRDOUTA,
-       .RDEdgSel = LP_RDEDGSELA,
-       .WREdgSel = LP_WREDGSELA,
-       .RDCapSel = LP_RDCAPSELA,
-       .WRCapSel = LP_WRCAPSELA,
-       .RDCapFlg = LP_RDCAPFLGA,
-       .RDIntSel = LP_RDINTSELA,
-       .WRIntSel = LP_WRINTSELA,
-};
-
-static struct dio_private dio_private_B = {
-       .RDDIn = LP_RDDINB,
-       .WRDOut = LP_WRDOUTB,
-       .RDEdgSel = LP_RDEDGSELB,
-       .WREdgSel = LP_WREDGSELB,
-       .RDCapSel = LP_RDCAPSELB,
-       .WRCapSel = LP_WRCAPSELB,
-       .RDCapFlg = LP_RDCAPFLGB,
-       .RDIntSel = LP_RDINTSELB,
-       .WRIntSel = LP_WRINTSELB,
-};
-
-static struct dio_private dio_private_C = {
-       .RDDIn = LP_RDDINC,
-       .WRDOut = LP_WRDOUTC,
-       .RDEdgSel = LP_RDEDGSELC,
-       .WREdgSel = LP_WREDGSELC,
-       .RDCapSel = LP_RDCAPSELC,
-       .WRCapSel = LP_WRCAPSELC,
-       .RDCapFlg = LP_RDCAPFLGC,
-       .RDIntSel = LP_RDINTSELC,
-       .WRIntSel = LP_WRINTSELC,
-};
-
-/* to group dio devices (48 bits mask and data are not allowed ???)
-static struct dio_private *dio_private_word[]={
-  &dio_private_A,
-  &dio_private_B,
-  &dio_private_C,
-};
-*/
-
-#define diopriv ((struct dio_private *)s->private)
-
 /*  COUNTER OBJECT ------------------------------------------------ */
 struct enc_private {
        /*  Pointers to functions that differ for A and B counters: */
@@ -670,43 +612,24 @@ static unsigned int s626_ai_reg_to_uint(int data)
 
 static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
 {
-       unsigned int group;
-       unsigned int bitmask;
+       unsigned int group = chan / 16;
+       unsigned int mask = 1 << (chan - (16 * group));
        unsigned int status;
 
-       /* select dio bank */
-       group = chan / 16;
-       bitmask = 1 << (chan - (16 * group));
-
        /* set channel to capture positive edge */
-       status = DEBIread(dev,
-                         ((struct dio_private *)(dev->subdevices + 2 +
-                                                 group)->private)->RDEdgSel);
-       DEBIwrite(dev,
-                 ((struct dio_private *)(dev->subdevices + 2 +
-                                         group)->private)->WREdgSel,
-                 bitmask | status);
+       status = DEBIread(dev, LP_RDEDGSEL(group));
+       DEBIwrite(dev, LP_WREDGSEL(group), mask | status);
 
        /* enable interrupt on selected channel */
-       status = DEBIread(dev,
-                         ((struct dio_private *)(dev->subdevices + 2 +
-                                                 group)->private)->RDIntSel);
-       DEBIwrite(dev,
-                 ((struct dio_private *)(dev->subdevices + 2 +
-                                         group)->private)->WRIntSel,
-                 bitmask | status);
+       status = DEBIread(dev, LP_RDINTSEL(group));
+       DEBIwrite(dev, LP_WRINTSEL(group), mask | status);
 
        /* enable edge capture write command */
        DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
 
        /* enable edge capture on selected channel */
-       status = DEBIread(dev,
-                         ((struct dio_private *)(dev->subdevices + 2 +
-                                                 group)->private)->RDCapSel);
-       DEBIwrite(dev,
-                 ((struct dio_private *)(dev->subdevices + 2 +
-                                         group)->private)->WRCapSel,
-                 bitmask | status);
+       status = DEBIread(dev, LP_RDCAPSEL(group));
+       DEBIwrite(dev, LP_WRCAPSEL(group), mask | status);
 
        return 0;
 }
@@ -718,9 +641,7 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
        DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
        /* enable edge capture on selected channel */
-       DEBIwrite(dev,
-                 ((struct dio_private *)(dev->subdevices + 2 +
-                                         group)->private)->WRCapSel, mask);
+       DEBIwrite(dev, LP_WRCAPSEL(group), mask);
 
        return 0;
 }
@@ -732,13 +653,9 @@ static int s626_dio_clear_irq(struct comedi_device *dev)
        /* disable edge capture write command */
        DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
-       for (group = 0; group < S626_DIO_BANKS; group++) {
-               /* clear pending events and interrupt */
-               DEBIwrite(dev,
-                         ((struct dio_private *)(dev->subdevices + 2 +
-                                                 group)->private)->WRCapSel,
-                         0xffff);
-       }
+       /* clear all dio pending events and interrupt */
+       for (group = 0; group < S626_DIO_BANKS; group++)
+               DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
 
        return 0;
 }
@@ -834,12 +751,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d)
                for (group = 0; group < S626_DIO_BANKS; group++) {
                        irqbit = 0;
                        /* read interrupt type */
-                       irqbit = DEBIread(dev,
-                                         ((struct dio_private *)(dev->
-                                                                 subdevices +
-                                                                 2 +
-                                                                 group)->
-                                          private)->RDCapFlg);
+                       irqbit = DEBIread(dev, LP_RDCAPFLG(group));
 
                        /* check if interrupt is generated from dio channels */
                        if (irqbit) {
@@ -1679,22 +1591,20 @@ static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
 static void s626_dio_init(struct comedi_device *dev)
 {
        uint16_t group;
-       struct comedi_subdevice *s;
 
        /*  Prepare to treat writes to WRCapSel as capture disables. */
        DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
 
        /*  For each group of sixteen channels ... */
        for (group = 0; group < S626_DIO_BANKS; group++) {
-               s = dev->subdevices + 2 + group;
-               DEBIwrite(dev, diopriv->WRIntSel, 0);   /*  Disable all interrupts. */
-               DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF);      /*  Disable all event */
-               /*  captures. */
-               DEBIwrite(dev, diopriv->WREdgSel, 0);   /*  Init all DIOs to */
-               /*  default edge */
-               /*  polarity. */
-               DEBIwrite(dev, diopriv->WRDOut, 0);     /*  Program all outputs */
-               /*  to inactive state. */
+               /* Disable all interrupts */
+               DEBIwrite(dev, LP_WRINTSEL(group), 0);
+               /* Disable all event captures */
+               DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff);
+               /* Init all DIOs to default edge polarity */
+               DEBIwrite(dev, LP_WREDGSEL(group), 0);
+               /* Program all outputs to inactive state */
+               DEBIwrite(dev, LP_WRDOUT(group), 0);
        }
 }
 
@@ -1708,6 +1618,8 @@ static int s626_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
                              struct comedi_insn *insn, unsigned int *data)
 {
+       unsigned long group = (unsigned long)s->private;
+
        /*
         * The insn data consists of a mask in data[0] and the new data in
         * data[1]. The mask defines which bits we are concerning about.
@@ -1724,9 +1636,9 @@ static int s626_dio_insn_bits(struct comedi_device *dev,
 
                /* Write out the new digital output lines */
 
-               DEBIwrite(dev, diopriv->WRDOut, s->state);
+               DEBIwrite(dev, LP_WRDOUT(group), s->state);
        }
-       data[1] = DEBIread(dev, diopriv->RDDIn);
+       data[1] = DEBIread(dev, LP_RDDIN(group));
 
        return insn->n;
 }
@@ -1735,6 +1647,7 @@ static int s626_dio_insn_config(struct comedi_device *dev,
                                struct comedi_subdevice *s,
                                struct comedi_insn *insn, unsigned int *data)
 {
+       unsigned long group = (unsigned long)s->private;
 
        switch (data[0]) {
        case INSN_CONFIG_DIO_QUERY:
@@ -1754,7 +1667,7 @@ static int s626_dio_insn_config(struct comedi_device *dev,
                return -EINVAL;
                break;
        }
-       DEBIwrite(dev, diopriv->WRDOut, s->io_bits);
+       DEBIwrite(dev, LP_WRDOUT(group), s->io_bits);
 
        return 1;
 }
@@ -2739,7 +2652,7 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->n_chan = 16;
        s->maxdata = 1;
        s->io_bits = 0xffff;
-       s->private = &dio_private_A;
+       s->private = (void *)0;         /* DIO group 0 */
        s->range_table = &range_digital;
        s->insn_config = s626_dio_insn_config;
        s->insn_bits = s626_dio_insn_bits;
@@ -2751,7 +2664,7 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->n_chan = 16;
        s->maxdata = 1;
        s->io_bits = 0xffff;
-       s->private = &dio_private_B;
+       s->private = (void *)1;         /* DIO group 1 */
        s->range_table = &range_digital;
        s->insn_config = s626_dio_insn_config;
        s->insn_bits = s626_dio_insn_bits;
@@ -2763,7 +2676,7 @@ static int s626_auto_attach(struct comedi_device *dev,
        s->n_chan = 16;
        s->maxdata = 1;
        s->io_bits = 0xffff;
-       s->private = &dio_private_C;
+       s->private = (void *)2;         /* DIO group 2 */
        s->range_table = &range_digital;
        s->insn_config = s626_dio_insn_config;
        s->insn_bits = s626_dio_insn_bits;
index ff4b3a5e4e5f2096d1a4c889f591e77f9a73b440..938dcd9f86f6a6e76d6e68b31764ad91e59a414f 100644 (file)
 #define LP_DACPOL              0x0082  /*   Write DAC polarity. */
 #define LP_GSEL                        0x0084  /*   Write ADC gain. */
 #define LP_ISEL                        0x0086  /*   Write ADC channel select. */
-/*  Digital I/O (write only): */
-#define LP_WRINTSELA           0x0042  /*   Write A interrupt enable. */
-#define LP_WREDGSELA           0x0044  /*   Write A edge selection. */
-#define LP_WRCAPSELA           0x0046  /*   Write A capture enable. */
-#define LP_WRDOUTA             0x0048  /*   Write A digital output. */
-#define LP_WRINTSELB           0x0052  /*   Write B interrupt enable. */
-#define LP_WREDGSELB           0x0054  /*   Write B edge selection. */
-#define LP_WRCAPSELB           0x0056  /*   Write B capture enable. */
-#define LP_WRDOUTB             0x0058  /*   Write B digital output. */
-#define LP_WRINTSELC           0x0062  /*   Write C interrupt enable. */
-#define LP_WREDGSELC           0x0064  /*   Write C edge selection. */
-#define LP_WRCAPSELC           0x0066  /*   Write C capture enable. */
-#define LP_WRDOUTC             0x0068  /*   Write C digital output. */
-
-/*  Digital I/O (read only): */
-#define LP_RDDINA              0x0040  /*   Read digital input. */
-#define LP_RDCAPFLGA           0x0048  /*   Read edges captured. */
-#define LP_RDINTSELA           0x004A  /*   Read interrupt enable register. */
-#define LP_RDEDGSELA           0x004C  /*   Read edge selection register. */
-#define LP_RDCAPSELA           0x004E  /*   Read capture enable register. */
-#define LP_RDDINB              0x0050  /*   Read digital input. */
-#define LP_RDCAPFLGB           0x0058  /*   Read edges captured. */
-#define LP_RDINTSELB           0x005A  /*   Read interrupt enable register. */
-#define LP_RDEDGSELB           0x005C  /*   Read edge selection register. */
-#define LP_RDCAPSELB           0x005E  /*   Read capture enable register. */
-#define LP_RDDINC              0x0060  /*   Read digital input. */
-#define LP_RDCAPFLGC           0x0068  /*   Read edges captured. */
-#define LP_RDINTSELC           0x006A  /*   Read interrupt enable register. */
-#define LP_RDEDGSELC           0x006C  /*   Read edge selection register. */
-#define LP_RDCAPSELC           0x006E  /*   Read capture enable register. */
+
+/* Digital I/O registers */
+#define LP_RDDIN(x)            (0x0040 + (x) * 0x10)   /* R: digital input */
+#define LP_WRINTSEL(x)         (0x0042 + (x) * 0x10)   /* W: int enable */
+#define LP_WREDGSEL(x)         (0x0044 + (x) * 0x10)   /* W: edge selection */
+#define LP_WRCAPSEL(x)         (0x0046 + (x) * 0x10)   /* W: capture enable */
+#define LP_RDCAPFLG(x)         (0x0048 + (x) * 0x10)   /* R: edges captured */
+#define LP_WRDOUT(x)           (0x0048 + (x) * 0x10)   /* W: digital output */
+#define LP_RDINTSEL(x)         (0x004a + (x) * 0x10)   /* R: int enable */
+#define LP_RDEDGSEL(x)         (0x004c + (x) * 0x10)   /* R: edge selection */
+#define LP_RDCAPSEL(x)         (0x004e + (x) * 0x10)   /* R: capture enable */
 
 /*  Counter Registers (read/write): */
 #define LP_CR0A                        0x0000  /*   0A setup register. */