]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-davinci/include/mach/gpio.h
ARM: DaVinci: SOC GPIOs use gpiolib
[linux-2.6-omap-h63xx.git] / arch / arm / mach-davinci / include / mach / gpio.h
index ec151ccf1e8f3a951cbd8933810d80d602c0e1b9..b3a2961f0f46f7780c21a2f78eceaabc3133dffd 100644 (file)
@@ -14,6 +14,7 @@
 #define        __DAVINCI_GPIO_H
 
 #include <linux/io.h>
+#include <asm-generic/gpio.h>
 #include <mach/hardware.h>
 
 /*
  * need to pay attention to PINMUX0 and PINMUX1 to be sure those pins are
  * used as gpios, not with other peripherals.
  *
- * GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation, and maybe
- * for later updates, code should write GPIO(N) or:
+ * On-chip GPIOs are numbered 0..(DAVINCI_N_GPIO-1).  For documentation,
+ * and maybe for later updates, code should write GPIO(N) or:
  *  - GPIOV18(N) for 1.8V pins, N in 0..53; same as GPIO(0)..GPIO(53)
  *  - GPIOV33(N) for 3.3V pins, N in 0..17; same as GPIO(54)..GPIO(70)
  *
  * For GPIO IRQs use gpio_to_irq(GPIO(N)) or gpio_to_irq(GPIOV33(N)) etc
  * for now, that's != GPIO(N)
+ *
+ * GPIOs can also be on external chips, numbered after the ones built-in
+ * to the DaVinci chip.  For now, they won't be usable as IRQ sources.
  */
 #define        GPIO(X)         (X)             /* 0 <= X <= 70 */
 #define        GPIOV18(X)      (X)             /* 1.8V i/o; 0 <= X <= 53 */
@@ -67,11 +71,11 @@ __gpio_to_controller(unsigned gpio)
        void *__iomem ptr;
 
        if (gpio < 32)
-               ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
+               ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
        else if (gpio < 64)
-               ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
+               ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
        else if (gpio < DAVINCI_N_GPIO)
-               ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
+               ptr = IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
        else
                ptr = NULL;
        return ptr;
@@ -83,25 +87,17 @@ static inline u32 __gpio_mask(unsigned gpio)
 }
 
 /* The get/set/clear functions will inline when called with constant
- * parameters, for low-overhead bitbanging.  Illegal constant parameters
- * cause link-time errors.
+ * parameters referencing built-in GPIOs, for low-overhead bitbanging.
  *
- * Otherwise, calls with variable parameters use outlined functions.
+ * Otherwise, calls with variable parameters or referencing external
+ * GPIOs (e.g. on GPIO expander chips) use outlined functions.
  */
-extern int __error_inval_gpio(void);
-
-extern void __gpio_set(unsigned gpio, int value);
-extern int __gpio_get(unsigned gpio);
-
 static inline void gpio_set_value(unsigned gpio, int value)
 {
-       if (__builtin_constant_p(value)) {
+       if (__builtin_constant_p(value) && gpio < DAVINCI_N_GPIO) {
                struct gpio_controller  *__iomem g;
                u32                     mask;
 
-               if (gpio >= DAVINCI_N_GPIO)
-                       __error_inval_gpio();
-
                g = __gpio_to_controller(gpio);
                mask = __gpio_mask(gpio);
                if (value)
@@ -111,48 +107,47 @@ static inline void gpio_set_value(unsigned gpio, int value)
                return;
        }
 
-       __gpio_set(gpio, value);
+       __gpio_set_value(gpio, value);
 }
 
 /* Returns zero or nonzero; works for gpios configured as inputs OR
- * as outputs.
+ * as outputs, at least for built-in GPIOs.
  *
- * NOTE: changes in reported values are synchronized to the GPIO clock.
- * This is most easily seen after calling gpio_set_value() and then immediatly
- * gpio_get_value(), where the gpio_get_value() would return the old value
- * until the GPIO clock ticks and the new value gets latched.
+ * NOTE: for built-in GPIOs, changes in reported values are synchronized
+ * to the GPIO clock.  This is easily seen after calling gpio_set_value()
+ * and then immediately gpio_get_value(), where the gpio_get_value() will
+ * return the old value until the GPIO clock ticks and the new value gets
+ * latched.
  */
-
 static inline int gpio_get_value(unsigned gpio)
 {
-       struct gpio_controller *__iomem g;
-
-       if (!__builtin_constant_p(gpio))
-               return __gpio_get(gpio);
+       struct gpio_controller  *__iomem g;
 
-       if (gpio >= DAVINCI_N_GPIO)
-               return __error_inval_gpio();
+       if (!__builtin_constant_p(gpio) || gpio >= DAVINCI_N_GPIO)
+               return __gpio_get_value(gpio);
 
        g = __gpio_to_controller(gpio);
-       return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
+       return __gpio_mask(gpio) & __raw_readl(&g->in_data);
 }
 
-/* powerup default direction is IN */
-extern int gpio_direction_input(unsigned gpio);
-extern int gpio_direction_output(unsigned gpio, int value);
-
-#include <asm-generic/gpio.h>  /* cansleep wrappers */
-
-extern int gpio_request(unsigned gpio, const char *tag);
-extern void gpio_free(unsigned gpio);
+static inline int gpio_cansleep(unsigned gpio)
+{
+       if (__builtin_constant_p(gpio) && gpio < DAVINCI_N_GPIO)
+               return 0;
+       else
+               return __gpio_cansleep(gpio);
+}
 
 static inline int gpio_to_irq(unsigned gpio)
 {
+       if (gpio >= DAVINCI_N_GPIO)
+               return -EINVAL;
        return DAVINCI_N_AINTC_IRQ + gpio;
 }
 
 static inline int irq_to_gpio(unsigned irq)
 {
+       /* caller guarantees gpio_to_irq() succeeded */
        return irq - DAVINCI_N_AINTC_IRQ;
 }