summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/gpio.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-12-03 14:16:33 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2009-12-10 12:15:01 +0100
commitf601b74d015b6b428eba82544b11661c72dc25d8 (patch)
treeb9d0f2af657481bde9f490be58147baee57445dc /arch/arm/mach-imx/gpio.c
parent6bd5caf6c662b7e91bc94070e085fa96e6dd994a (diff)
downloadbarebox-f601b74d015b6b428eba82544b11661c72dc25d8.tar.gz
barebox-f601b74d015b6b428eba82544b11661c72dc25d8.tar.xz
complete i.MX GPIO support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-imx/gpio.c')
-rw-r--r--arch/arm/mach-imx/gpio.c87
1 files changed, 82 insertions, 5 deletions
diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index eb095ec93c..6157bd11cd 100644
--- a/arch/arm/mach-imx/gpio.c
+++ b/arch/arm/mach-imx/gpio.c
@@ -24,28 +24,105 @@
*/
#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
#include <mach/imx-regs.h>
+#if defined CONFIG_ARCH_IMX1 || defined CONFIG_ARCH_IMX21 || defined CONFIG_ARCH_IMX27
+#define GPIO_DR 0x1c
+#define GPIO_GDIR 0x00
+#define GPIO_PSR 0x24
+#define GPIO_ICR1 0x28
+#define GPIO_ICR2 0x2C
+#define GPIO_IMR 0x30
+#define GPIO_ISR 0x34
+#else
+#define GPIO_DR 0x00
+#define GPIO_GDIR 0x04
+#define GPIO_PSR 0x08
+#define GPIO_ICR1 0x0C
+#define GPIO_ICR2 0x10
+#define GPIO_IMR 0x14
+#define GPIO_ISR 0x18
+#define GPIO_ISR 0x18
+#endif
+
+extern void *imx_gpio_base[];
+extern int imx_gpio_count;
+
+static void *gpio_get_base(unsigned gpio)
+{
+ if (gpio >= imx_gpio_count)
+ return 0;
+
+ return imx_gpio_base[gpio / 32];
+}
+
void gpio_set_value(unsigned gpio, int value)
{
- if(value)
- DR(gpio >> GPIO_PORT_SHIFT) |= (1 << (gpio & GPIO_PIN_MASK));
+ void *base = gpio_get_base(gpio);
+ int shift = gpio % 32;
+ u32 val;
+
+ if (!base)
+ return;
+
+ val = readl(base + GPIO_DR);
+
+ if (value)
+ val |= 1 << shift;
else
- DR(gpio >> GPIO_PORT_SHIFT) &= ~(1 << (gpio & GPIO_PIN_MASK));
+ val &= ~(1 << shift);
+
+ writel(val, base + GPIO_DR);
}
int gpio_direction_input(unsigned gpio)
{
- imx_gpio_mode(gpio | GPIO_IN | GPIO_GIUS | GPIO_GPIO);
+ void *base = gpio_get_base(gpio);
+ int shift = gpio % 32;
+ u32 val;
+
+ if (!base)
+ return -EINVAL;
+
+ val = readl(base + GPIO_GDIR);
+ val &= ~(1 << shift);
+ writel(val, base + GPIO_GDIR);
+
return 0;
}
int gpio_direction_output(unsigned gpio, int value)
{
+ void *base = gpio_get_base(gpio);
+ int shift = gpio % 32;
+ u32 val;
+
+ if (!base)
+ return -EINVAL;
+
gpio_set_value(gpio, value);
- imx_gpio_mode(gpio | GPIO_OUT | GPIO_GIUS | GPIO_GPIO);
+
+ val = readl(base + GPIO_GDIR);
+ val |= 1 << shift;
+ writel(val, base + GPIO_GDIR);
+
return 0;
}
+int gpio_get_value(unsigned gpio)
+{
+ void *base = gpio_get_base(gpio);
+ int shift = gpio % 32;
+ u32 val;
+
+ if (!base)
+ return -EINVAL;
+
+ val = readl(base + GPIO_DR);
+
+ return val & (1 << shift) ? 1 : 0;
+}