]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/gpio/am33xx_gpio.c
gpio: am33xx: add missing gpio_get_value() function
[karo-tx-uboot.git] / drivers / gpio / am33xx_gpio.c
index 71cd50e34df2ac919d00e165d57efa8bdd17dcbb..de0bc475ca8cbc65f36ebed21f3f4e9719d4a0d6 100644 (file)
 
 #include <common.h>
 #include <errno.h>
-#include <asm-generic/gpio.h>
 #include <asm/io.h>
 #include <asm/bitops.h>
 #include <asm/sizes.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
 
 struct gpio_regs {
        unsigned int res1[0x134 / 4];
@@ -32,21 +32,24 @@ struct gpio_regs {
        unsigned int setdataout;        /* 0x194 */
 };
 
-struct gpio_regs *gpio_base[] = {
-       (struct gpio_regs *)GPIO0_BASE,
-       (struct gpio_regs *)GPIO1_BASE,
-       (struct gpio_regs *)GPIO2_BASE,
-       (struct gpio_regs *)GPIO3_BASE,
+static const struct gpio_regs *gpio_base[] = {
+       (struct gpio_regs *)AM33XX_GPIO0_BASE,
+       (struct gpio_regs *)AM33XX_GPIO1_BASE,
+       (struct gpio_regs *)AM33XX_GPIO2_BASE,
+       (struct gpio_regs *)AM33XX_GPIO3_BASE,
 };
 
-static unsigned long gpio_map[ARRAY_SIZE(gpio_base)];
+static unsigned long gpio_map[ARRAY_SIZE(gpio_base)] __attribute__((section("data")));
 
 #define MAX_GPIO       (ARRAY_SIZE(gpio_base) * 32)
 
 int gpio_request(unsigned gpio, const char *name)
 {
-       if (gpio >= MAX_GPIO)
+       if (gpio >= MAX_GPIO) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
                return -EINVAL;
+       }
        if (test_and_set_bit(gpio, gpio_map))
                return -EBUSY;
        return 0;
@@ -54,9 +57,11 @@ int gpio_request(unsigned gpio, const char *name)
 
 int gpio_free(unsigned gpio)
 {
-       if (gpio >= MAX_GPIO)
+       if (gpio >= MAX_GPIO) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
                return -EINVAL;
-
+       }
        if (test_bit(gpio, gpio_map))
                __clear_bit(gpio, gpio_map);
        else
@@ -70,9 +75,11 @@ int gpio_set_value(unsigned gpio, int val)
        int bank = gpio / 32;
        int mask = 1 << (gpio % 32);
 
-       if (bank >= ARRAY_SIZE(gpio_base))
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
                return -EINVAL;
-
+       }
        if (val)
                writel(mask, &gpio_base[bank]->setdataout);
        else
@@ -80,14 +87,29 @@ int gpio_set_value(unsigned gpio, int val)
        return 0;
 }
 
-int gpio_direction_input(unsigned gpio)
+int gpio_get_value(unsigned gpio)
 {
        int bank = gpio / 32;
        int mask = 1 << (gpio % 32);
 
-       if (bank >= ARRAY_SIZE(gpio_base))
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
                return -EINVAL;
+       }
+       return (readl(&gpio_base[bank]->datain) & mask) != 0;
+}
 
+int gpio_direction_input(unsigned gpio)
+{
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
        writel(readl(&gpio_base[bank]->oe) | mask, &gpio_base[bank]->oe);
        return 0;
 }
@@ -97,9 +119,11 @@ int gpio_direction_output(unsigned gpio, int val)
        int bank = gpio / 32;
        int mask = 1 << (gpio % 32);
 
-       if (bank >= ARRAY_SIZE(gpio_base))
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
                return -EINVAL;
-
+       }
        gpio_set_value(gpio, val);
        writel(readl(&gpio_base[bank]->oe) & ~mask, &gpio_base[bank]->oe);
        return 0;