]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/plat-omap/gpio.c
ARM: OMAP: Add 24xx GPIO debounce support
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / gpio.c
index 7dd50a43fbcfaebffc948d514f157b0c180a22df..56f4d1394d562bdfc652a2d7f13ee436042ed88c 100644 (file)
 #define OMAP24XX_GPIO_LEVELDETECT1     0x0044
 #define OMAP24XX_GPIO_RISINGDETECT     0x0048
 #define OMAP24XX_GPIO_FALLINGDETECT    0x004c
+#define OMAP24XX_GPIO_DEBOUNCE_EN      0x0050
+#define OMAP24XX_GPIO_DEBOUNCE_VAL     0x0054
 #define OMAP24XX_GPIO_CLEARIRQENABLE1  0x0060
 #define OMAP24XX_GPIO_SETIRQENABLE1    0x0064
 #define OMAP24XX_GPIO_CLEARWKUENA      0x0080
@@ -221,51 +223,35 @@ static int gpio_bank_count;
 
 static inline struct gpio_bank *get_gpio_bank(int gpio)
 {
-#ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap15xx()) {
                if (OMAP_GPIO_IS_MPUIO(gpio))
                        return &gpio_bank[0];
                return &gpio_bank[1];
        }
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
        if (cpu_is_omap16xx()) {
                if (OMAP_GPIO_IS_MPUIO(gpio))
                        return &gpio_bank[0];
                return &gpio_bank[1 + (gpio >> 4)];
        }
-#endif
-#ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730()) {
                if (OMAP_GPIO_IS_MPUIO(gpio))
                        return &gpio_bank[0];
                return &gpio_bank[1 + (gpio >> 5)];
        }
-#endif
-#ifdef CONFIG_ARCH_OMAP24XX
        if (cpu_is_omap24xx())
                return &gpio_bank[gpio >> 5];
-#endif
-#ifdef CONFIG_ARCH_OMAP34XX
        if (cpu_is_omap34xx())
                return &gpio_bank[gpio >> 5];
-#endif
 }
 
 static inline int get_gpio_index(int gpio)
 {
-#ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730())
                return gpio & 0x1f;
-#endif
-#ifdef CONFIG_ARCH_OMAP24XX
        if (cpu_is_omap24xx())
                return gpio & 0x1f;
-#endif
-#ifdef CONFIG_ARCH_OMAP34XX
        if (cpu_is_omap34xx())
                return gpio & 0x1f;
-#endif
        return gpio & 0x0f;
 }
 
@@ -273,33 +259,21 @@ static inline int gpio_valid(int gpio)
 {
        if (gpio < 0)
                return -1;
-#ifndef CONFIG_ARCH_OMAP24XX
-       if (OMAP_GPIO_IS_MPUIO(gpio)) {
+       if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
                if (gpio >= OMAP_MAX_GPIO_LINES + 16)
                        return -1;
                return 0;
        }
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
        if (cpu_is_omap15xx() && gpio < 16)
                return 0;
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
        if ((cpu_is_omap16xx()) && gpio < 64)
                return 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP730
        if (cpu_is_omap730() && gpio < 192)
                return 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP24XX
        if (cpu_is_omap24xx() && gpio < 128)
                return 0;
-#endif
-#ifdef CONFIG_ARCH_OMAP34XX
        if (cpu_is_omap34xx() && gpio < 160)
                return 0;
-#endif
        return -1;
 }
 
@@ -491,8 +465,50 @@ do {       \
        __raw_writel(l, base + reg); \
 } while(0)
 
+void omap_set_gpio_debounce(int gpio, int enable)
+{
+       struct gpio_bank *bank;
+       void __iomem *reg;
+       u32 val, l = 1 << get_gpio_index(gpio);
+
+       if (cpu_class_is_omap1())
+               return;
+
+       bank = get_gpio_bank(gpio);
+       reg = bank->base;
+
+       reg += OMAP24XX_GPIO_DEBOUNCE_EN;
+       val = __raw_readl(reg);
+
+       if (enable)
+               val |= l;
+       else
+               val &= ~l;
+
+       __raw_writel(val, reg);
+}
+EXPORT_SYMBOL(omap_set_gpio_debounce);
+
+void omap_set_gpio_debounce_time(int gpio, int enc_time)
+{
+       struct gpio_bank *bank;
+       void __iomem *reg;
+
+       if (cpu_class_is_omap1())
+               return;
+
+       bank = get_gpio_bank(gpio);
+       reg = bank->base;
+
+       enc_time &= 0xff;
+       reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
+       __raw_writel(enc_time, reg);
+}
+EXPORT_SYMBOL(omap_set_gpio_debounce_time);
+
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
-static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
+static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
+                                               int trigger)
 {
        void __iomem *base = bank->base;
        u32 gpio_bit = 1 << gpio;
@@ -505,19 +521,25 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, in
                trigger & __IRQT_RISEDGE);
        MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
                trigger & __IRQT_FALEDGE);
+
        if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
                if (trigger != 0)
-                       __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA);
+                       __raw_writel(1 << gpio, bank->base
+                                       + OMAP24XX_GPIO_SETWKUENA);
                else
-                       __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA);
+                       __raw_writel(1 << gpio, bank->base
+                                       + OMAP24XX_GPIO_CLEARWKUENA);
        } else {
                if (trigger != 0)
                        bank->enabled_non_wakeup_gpios |= gpio_bit;
                else
                        bank->enabled_non_wakeup_gpios &= ~gpio_bit;
        }
-       /* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level
-        * triggering requested. */
+
+       /*
+        * FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only
+        * level triggering requested.
+        */
 }
 #endif
 
@@ -1393,27 +1415,22 @@ static int __init _omap_gpio_init(void)
                spin_lock_init(&bank->lock);
                if (bank_is_mpuio(bank))
                        omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
-#ifdef CONFIG_ARCH_OMAP15XX
-               if (bank->method == METHOD_GPIO_1510) {
+               if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
                        __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
                        __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
                }
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-               if (bank->method == METHOD_GPIO_1610) {
+               if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
                        __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
                        __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
                        __raw_writew(0x0014, bank->base + OMAP1610_GPIO_SYSCONFIG);
                }
-#endif
-#ifdef CONFIG_ARCH_OMAP730
-               if (bank->method == METHOD_GPIO_730) {
+               if (cpu_is_omap730() && bank->method == METHOD_GPIO_730) {
                        __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
                        __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
 
                        gpio_count = 32; /* 730 has 32-bit GPIOs */
                }
-#endif
+
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
                if (bank->method == METHOD_GPIO_24XX) {
                        static const u32 non_wakeup_gpios[] = {
@@ -1450,14 +1467,12 @@ static int __init _omap_gpio_init(void)
        if (cpu_is_omap16xx())
                omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
 
-#if defined(CONFIG_ARCH_OMAP24XX)
        /* Enable autoidle for the OCP interface */
        if (cpu_is_omap24xx())
                omap_writel(1 << 0, 0x48019010);
-#elif defined(CONFIG_ARCH_OMAP34XX)
        if (cpu_is_omap34xx())
                omap_writel(1 << 0, 0x48306814);
-#endif
+
        return 0;
 }