]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
twl4030 gpio cleanups
authorDavid Brownell <dbrownell@users.sourceforge.net>
Tue, 30 Sep 2008 19:49:06 +0000 (12:49 -0700)
committerTony Lindgren <tony@atomide.com>
Wed, 1 Oct 2008 10:38:27 +0000 (13:38 +0300)
Clean up the twl4030-gpio code a bit ... mostly by shrinkage.

Remove a bunch of macros that are just obfuscating what the
TWL4030 GPIO code is doing.  Some duplicated standard macros
like BIT(); others hid trivial math (mask/shift); others were
completely unused.

Use BIT() in several places to highlight the bitmasking and
make the code more compact.

Remove pointless locking calls, sanity checks, and parenthesis.
And needless irq_chip.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Tony Lindgren <tony@atomide.com>
drivers/gpio/twl4030-gpio.c

index 47dc6e2510407d6ab9a004feb09a3e85c41ef56f..d9303f76f7c779122d15bb38d930d9631b342801 100644 (file)
 #include <linux/i2c/twl4030-gpio.h>
 
 
+/*
+ * The GPIO "subchip" supports 18 GPIOs which can be configured as
+ * inputs or outputs, with pullups or pulldowns on each pin.  Each
+ * GPIO can trigger interrupts on either or both edges.
+ *
+ * GPIO interrupts can be fed to either of two IRQ lines; this is
+ * intended to support multiple hosts.
+ *
+ * There are also two LED pins used sometimes as output-only GPIOs.
+ *
+ * FIXME code currently only handles the first IRQ line.
+ */
+
+
 static inline void activate_irq(int irq)
 {
 #ifdef CONFIG_ARM
@@ -65,83 +79,15 @@ static int twl4030_gpio_irq_end;
 #define is_module()    false
 #endif
 
-/* BitField Definitions */
-
-/* Data banks : 3 banks for 8 gpios each */
-#define DATA_BANK_MAX                          8
-#define GET_GPIO_DATA_BANK(x)                  ((x)/DATA_BANK_MAX)
-#define GET_GPIO_DATA_OFF(x)                   ((x)%DATA_BANK_MAX)
-
-/* GPIODATADIR Fields each block 0-7 */
-#define BIT_GPIODATADIR_GPIOxDIR(x)            (x)
-#define MASK_GPIODATADIR_GPIOxDIR(x)           (0x01 << (x))
-
-/* GPIODATAIN Fields each block 0-7 */
-#define BIT_GPIODATAIN_GPIOxIN(x)              (x)
-#define MASK_GPIODATAIN_GPIOxIN(x)             (0x01 << (x))
-
-/* GPIODATAOUT Fields each block 0-7 */
-#define BIT_GPIODATAOUT_GPIOxOUT(x)            (x)
-#define MASK_GPIODATAOUT_GPIOxOUT(x)           (0x01 << (x))
-
-/* CLEARGPIODATAOUT Fields */
-#define BIT_CLEARGPIODATAOUT_GPIOxOUT(x)       (x)
-#define MASK_CLEARGPIODATAOUT_GPIOxOUT(x)      (0x01 << (x))
-
-/* SETGPIODATAOUT Fields */
-#define BIT_SETGPIODATAOUT_GPIOxOUT(x)         (x)
-#define MASK_SETGPIODATAOUT_GPIOxOUT(x)                (0x01 << (x))
-
-/* GPIO_DEBEN Fields */
-#define BIT_GPIO_DEBEN_GPIOxDEB(x)             (x)
-#define MASK_GPIO_DEBEN_GPIOxDEB(x)            (0x01 << (x))
-
-/* GPIO_ISR1A Fields */
-#define BIT_GPIO_ISR_GPIOxISR(x)               (x)
-#define MASK_GPIO_ISR_GPIOxISR(x)              (0x01 << (x))
-
-/* GPIO_IMR1A Fields */
-#define BIT_GPIO_IMR1A_GPIOxIMR(x)             (x)
-#define MASK_GPIO_IMR1A_GPIOxIMR(x)            (0x01 << (x))
-
-/* GPIO_SIR1 Fields */
-#define BIT_GPIO_SIR1_GPIOxSIR(x)              (x)
-#define MASK_GPIO_SIR1_GPIO0SIR                        (0x01 << (x))
-
-
-/* Control banks : 5 banks for 4 gpios each */
-#define DATA_CTL_MAX                   4
-#define GET_GPIO_CTL_BANK(x)           ((x)/DATA_CTL_MAX)
-#define GET_GPIO_CTL_OFF(x)            ((x)%DATA_CTL_MAX)
-#define GPIO_BANK_MAX                  GET_GPIO_CTL_BANK(TWL4030_GPIO_MAX)
-
-/* GPIOPUPDCTRx Fields 5 banks of 4 gpios each */
-#define BIT_GPIOPUPDCTR1_GPIOxPD(x)    (2 * (x))
-#define MASK_GPIOPUPDCTR1_GPIOxPD(x)   (0x01 << (2 * (x)))
-#define BIT_GPIOPUPDCTR1_GPIOxPU(x)    ((x) + 1)
-#define MASK_GPIOPUPDCTR1_GPIOxPU(x)   (0x01 << (((2 * (x)) + 1)))
-
-/* GPIO_EDR1 Fields */
-#define BIT_GPIO_EDR1_GPIOxFALLING(x)  (2 * (x))
-#define MASK_GPIO_EDR1_GPIOxFALLING(x) (0x01 << (2 * (x)))
-#define BIT_GPIO_EDR1_GPIOxRISING(x)   ((x) + 1)
-#define MASK_GPIO_EDR1_GPIOxRISING(x)  (0x01 << (((2 * (x)) + 1)))
-
 /* GPIO_SIH_CTRL Fields */
-#define BIT_GPIO_SIH_CTRL_EXCLEN       (0x000)
-#define MASK_GPIO_SIH_CTRL_EXCLEN      (0x00000001)
-#define BIT_GPIO_SIH_CTRL_PENDDIS      (0x001)
-#define MASK_GPIO_SIH_CTRL_PENDDIS     (0x00000002)
-#define BIT_GPIO_SIH_CTRL_COR          (0x002)
-#define MASK_GPIO_SIH_CTRL_COR         (0x00000004)
+#define MASK_GPIO_SIH_CTRL_EXCLEN      BIT(0)
+#define MASK_GPIO_SIH_CTRL_PENDDIS     BIT(1)
+#define MASK_GPIO_SIH_CTRL_COR         BIT(2)
 
 /* GPIO_CTRL Fields */
-#define BIT_GPIO_CTRL_GPIO0CD1         (0x000)
-#define MASK_GPIO_CTRL_GPIO0CD1                (0x00000001)
-#define BIT_GPIO_CTRL_GPIO1CD2         (0x001)
-#define MASK_GPIO_CTRL_GPIO1CD2                (0x00000002)
-#define BIT_GPIO_CTRL_GPIO_ON          (0x002)
-#define MASK_GPIO_CTRL_GPIO_ON         (0x00000004)
+#define MASK_GPIO_CTRL_GPIO0CD1                BIT(0)
+#define MASK_GPIO_CTRL_GPIO1CD2                BIT(1)
+#define MASK_GPIO_CTRL_GPIO_ON         BIT(2)
 
 /* Mask for GPIO registers when aggregated into a 32-bit integer */
 #define GPIO_32_MASK                   0x0003ffff
@@ -298,29 +244,13 @@ static struct irq_chip twl4030_gpio_irq_chip = {
        .set_type       = twl4030_gpio_irq_set_type,
 };
 
-/*
- * These are the irqchip methods for the TWL4030 PIH GPIO module interrupt.
- * The PIH module doesn't have interrupt masking capability, so these
- * methods are NULL.
- */
-static void twl4030_gpio_module_ack(unsigned int irq) {}
-static void twl4030_gpio_module_mask(unsigned int irq) {}
-static void twl4030_gpio_module_unmask(unsigned int irq) {}
-static struct irq_chip twl4030_gpio_module_irq_chip = {
-       .ack    = twl4030_gpio_module_ack,
-       .mask   = twl4030_gpio_module_mask,
-       .unmask = twl4030_gpio_module_unmask,
-};
 
 /*
  * To configure TWL4030 GPIO module registers
  */
 static inline int gpio_twl4030_write(u8 address, u8 data)
 {
-       int ret = 0;
-
-       ret = twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
-       return ret;
+       return twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, data, address);
 }
 
 /*
@@ -332,9 +262,7 @@ static inline int gpio_twl4030_read(u8 address)
        int ret = 0;
 
        ret = twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &data, address);
-       if (ret >= 0)
-               ret = data;
-       return ret;
+       return (ret < 0) ? ret : data;
 }
 
 /*
@@ -352,7 +280,7 @@ int twl4030_request_gpio(int gpio)
                return ret;
 
        mutex_lock(&gpio_lock);
-       if (gpio_usage_count & (0x1 << gpio)) {
+       if (gpio_usage_count & BIT(gpio)) {
                ret = -EBUSY;
        } else {
                /* First time usage? - switch on GPIO module */
@@ -362,7 +290,7 @@ int twl4030_request_gpio(int gpio)
                        ret = gpio_twl4030_write(REG_GPIO_SIH_CTRL, 0x00);
                }
                if (!ret)
-                       gpio_usage_count |= (0x1 << gpio);
+                       gpio_usage_count |= BIT(gpio);
                else
                        gpio_free(twl_gpiochip.base + gpio);
        }
@@ -383,10 +311,10 @@ int twl4030_free_gpio(int gpio)
 
        mutex_lock(&gpio_lock);
 
-       if ((gpio_usage_count & (0x1 << gpio)) == 0) {
+       if ((gpio_usage_count & BIT(gpio)) == 0) {
                ret = -EPERM;
        } else {
-               gpio_usage_count &= ~(0x1 << gpio);
+               gpio_usage_count &= ~BIT(gpio);
                gpio_free(twl_gpiochip.base + gpio);
        }
 
@@ -399,27 +327,21 @@ int twl4030_free_gpio(int gpio)
 }
 EXPORT_SYMBOL(twl4030_free_gpio);
 
-/*
- * Set direction for TWL4030 GPIO
- */
 static int twl4030_set_gpio_direction(int gpio, int is_input)
 {
-       u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-       u8 d_msk = MASK_GPIODATADIR_GPIOxDIR(GET_GPIO_DATA_OFF(gpio));
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
        u8 reg = 0;
        u8 base = REG_GPIODATADIR1 + d_bnk;
        int ret = 0;
 
-       if (unlikely(!(gpio_usage_count & (0x1 << gpio))))
-               return -EPERM;
-
        mutex_lock(&gpio_lock);
        ret = gpio_twl4030_read(base);
        if (ret >= 0) {
                if (is_input)
-                       reg = (u8) ((ret) & ~(d_msk));
+                       reg = ret & ~d_msk;
                else
-                       reg = (u8) ((ret) | (d_msk));
+                       reg = ret | d_msk;
 
                ret = gpio_twl4030_write(base, reg);
        }
@@ -427,48 +349,33 @@ static int twl4030_set_gpio_direction(int gpio, int is_input)
        return ret;
 }
 
-/*
- * To enable/disable GPIO pin on TWL4030
- */
 static int twl4030_set_gpio_dataout(int gpio, int enable)
 {
-       u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-       u8 d_msk = MASK_GPIODATAOUT_GPIOxOUT(GET_GPIO_DATA_OFF(gpio));
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
        u8 base = 0;
-       int ret = 0;
-
-       if (unlikely(!(gpio_usage_count & (0x1 << gpio))))
-               return -EPERM;
 
        if (enable)
                base = REG_SETGPIODATAOUT1 + d_bnk;
        else
                base = REG_CLEARGPIODATAOUT1 + d_bnk;
 
-       mutex_lock(&gpio_lock);
-       ret = gpio_twl4030_write(base, d_msk);
-       mutex_unlock(&gpio_lock);
-       return ret;
+       return gpio_twl4030_write(base, d_msk);
 }
 
-/*
- * To get the status of a GPIO pin on TWL4030
- */
 int twl4030_get_gpio_datain(int gpio)
 {
-       u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-       u8 d_off = BIT_GPIODATAIN_GPIOxIN(GET_GPIO_DATA_OFF(gpio));
+       u8 d_bnk = gpio >> 3;
+       u8 d_off = gpio & 0x7;
        u8 base = 0;
        int ret = 0;
 
        if (unlikely((gpio >= TWL4030_GPIO_MAX)
-               || !(gpio_usage_count & (0x1 << gpio))))
+               || !(gpio_usage_count & BIT(gpio))))
                return -EPERM;
 
        base = REG_GPIODATAIN1 + d_bnk;
-       mutex_lock(&gpio_lock);
        ret = gpio_twl4030_read(base);
-       mutex_unlock(&gpio_lock);
        if (ret > 0)
                ret = (ret >> d_off) & 0x1;
 
@@ -478,8 +385,8 @@ EXPORT_SYMBOL(twl4030_get_gpio_datain);
 
 static int twl4030_set_gpio_edge_ctrl(int gpio, int edge)
 {
-       u8 c_bnk = GET_GPIO_CTL_BANK(gpio);
-       u8 c_off = GET_GPIO_CTL_OFF(gpio);
+       u8 c_bnk = gpio >> 2;
+       u8 c_off = (gpio & 0x3) * 2;
        u8 c_msk = 0;
        u8 reg = 0;
        u8 base = 0;
@@ -488,17 +395,16 @@ static int twl4030_set_gpio_edge_ctrl(int gpio, int edge)
        base = REG_GPIO_EDR1 + c_bnk;
 
        if (edge & IRQ_TYPE_EDGE_RISING)
-               c_msk |= MASK_GPIO_EDR1_GPIOxRISING(c_off);
+               c_msk |= BIT(c_off + 1);
        if (edge & IRQ_TYPE_EDGE_FALLING)
-               c_msk |= MASK_GPIO_EDR1_GPIOxFALLING(c_off);
+               c_msk |= BIT(c_off);
 
        mutex_lock(&gpio_lock);
        ret = gpio_twl4030_read(base);
        if (ret >= 0) {
                /* clear the previous rising/falling values */
                reg = (u8) ret;
-               reg &= ~(MASK_GPIO_EDR1_GPIOxFALLING(c_off)
-                       | MASK_GPIO_EDR1_GPIOxRISING(c_off));
+               reg &= ~(0x3 << c_off);
                reg |= c_msk;
                ret = gpio_twl4030_write(base, reg);
        }
@@ -511,14 +417,14 @@ static int twl4030_set_gpio_edge_ctrl(int gpio, int edge)
  */
 int twl4030_set_gpio_debounce(int gpio, int enable)
 {
-       u8 d_bnk = GET_GPIO_DATA_BANK(gpio);
-       u8 d_msk = MASK_GPIO_DEBEN_GPIOxDEB(GET_GPIO_DATA_OFF(gpio));
+       u8 d_bnk = gpio >> 3;
+       u8 d_msk = BIT(gpio & 0x7);
        u8 reg = 0;
        u8 base = 0;
        int ret = 0;
 
        if (unlikely((gpio >= TWL4030_GPIO_MAX)
-               || !(gpio_usage_count & (0x1 << gpio))))
+               || !(gpio_usage_count & BIT(gpio))))
                return -EPERM;
 
        base = REG_GPIO_DEBEN1 + d_bnk;
@@ -526,9 +432,9 @@ int twl4030_set_gpio_debounce(int gpio, int enable)
        ret = gpio_twl4030_read(base);
        if (ret >= 0) {
                if (enable)
-                       reg = (u8) ((ret) | (d_msk));
+                       reg = ret | d_msk;
                else
-                       reg = (u8) ((ret) & ~(d_msk));
+                       reg = ret & ~d_msk;
 
                ret = gpio_twl4030_write(base, reg);
        }
@@ -552,7 +458,7 @@ int twl4030_set_gpio_card_detect(int gpio, int enable)
 
        /* Only GPIO 0 or 1 can be used for CD feature.. */
        if (unlikely((gpio >= TWL4030_GPIO_MAX)
-               || !(gpio_usage_count & (0x1 << gpio))
+               || !(gpio_usage_count & BIT(gpio))
                || (gpio >= TWL4030_GPIO_MAX_CD))) {
                return -EPERM;
        }
@@ -855,7 +761,6 @@ static int __devinit gpio_twl4030_probe(struct platform_device *pdev)
                 * Install an irq handler to demultiplex the gpio module
                 * interrupt.
                 */
-               set_irq_chip(irq, &twl4030_gpio_module_irq_chip);
                set_irq_chained_handler(irq, do_twl4030_gpio_module_irq);
                wake_up_process(gpio_unmask_thread);