]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/gpio/mxc_gpio.c
dm: Add GPIO support and tests
[karo-tx-uboot.git] / drivers / gpio / mxc_gpio.c
index 6efbb02c161931d970d415aaeb223a9e53dd8255..6a572d5454b39e4905da9094edd01f47cf451035 100644 (file)
@@ -2,53 +2,51 @@
  * Copyright (C) 2009
  * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
  *
- * See file CREDITS for list of people who contributed to this
- * project.
+ * Copyright (C) 2011
+ * Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <common.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
-#include <mxc_gpio.h>
 #include <errno.h>
 
+enum mxc_gpio_direction {
+       MXC_GPIO_DIRECTION_IN,
+       MXC_GPIO_DIRECTION_OUT,
+};
+
+#define GPIO_TO_PORT(n)                (n / 32)
+
 /* GPIO port description */
 static unsigned long gpio_ports[] = {
        [0] = GPIO1_BASE_ADDR,
        [1] = GPIO2_BASE_ADDR,
        [2] = GPIO3_BASE_ADDR,
-#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
+#if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX51) || \
+               defined(CONFIG_MX53) || defined(CONFIG_MX6)
        [3] = GPIO4_BASE_ADDR,
 #endif
-#if defined(CONFIG_MX53)
+#if defined(CONFIG_MX27) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
        [4] = GPIO5_BASE_ADDR,
        [5] = GPIO6_BASE_ADDR,
+#endif
+#if defined(CONFIG_MX53) || defined(CONFIG_MX6)
        [6] = GPIO7_BASE_ADDR,
 #endif
 };
 
-int mxc_gpio_direction(unsigned int gpio, enum mxc_gpio_direction direction)
+static int mxc_gpio_direction(unsigned int gpio,
+       enum mxc_gpio_direction direction)
 {
-       unsigned int port = gpio >> 5;
+       unsigned int port = GPIO_TO_PORT(gpio);
        struct gpio_regs *regs;
        u32 l;
 
        if (port >= ARRAY_SIZE(gpio_ports))
-               return -EINVAL;
+               return -1;
 
        gpio &= 0x1f;
 
@@ -68,14 +66,14 @@ int mxc_gpio_direction(unsigned int gpio, enum mxc_gpio_direction direction)
        return 0;
 }
 
-void mxc_gpio_set(unsigned int gpio, unsigned int value)
+int gpio_set_value(unsigned gpio, int value)
 {
-       unsigned int port = gpio >> 5;
+       unsigned int port = GPIO_TO_PORT(gpio);
        struct gpio_regs *regs;
        u32 l;
 
        if (port >= ARRAY_SIZE(gpio_ports))
-               return;
+               return -1;
 
        gpio &= 0x1f;
 
@@ -87,22 +85,52 @@ void mxc_gpio_set(unsigned int gpio, unsigned int value)
        else
                l &= ~(1 << gpio);
        writel(l, &regs->gpio_dr);
+
+       return 0;
 }
 
-int mxc_gpio_get(unsigned int gpio)
+int gpio_get_value(unsigned gpio)
 {
-       unsigned int port = gpio >> 5;
+       unsigned int port = GPIO_TO_PORT(gpio);
        struct gpio_regs *regs;
-       u32 l;
+       u32 val;
 
        if (port >= ARRAY_SIZE(gpio_ports))
-               return -EINVAL;
+               return -1;
 
        gpio &= 0x1f;
 
        regs = (struct gpio_regs *)gpio_ports[port];
 
-       l = (readl(&regs->gpio_dr) >> gpio) & 0x01;
+       val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
+
+       return val;
+}
+
+int gpio_request(unsigned gpio, const char *label)
+{
+       unsigned int port = GPIO_TO_PORT(gpio);
+       if (port >= ARRAY_SIZE(gpio_ports))
+               return -1;
+       return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+       return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+       return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_IN);
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+       int ret = gpio_set_value(gpio, value);
+
+       if (ret < 0)
+               return ret;
 
-       return l;
+       return mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT);
 }