[PATCH 06/16] complete i.MX GPIO support
Sascha Hauer
s.hauer at pengutronix.de
Wed Dec 9 04:03:31 EST 2009
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
arch/arm/mach-imx/Makefile | 14 ++--
arch/arm/mach-imx/gpio.c | 87 +++++++++++++++++++++++++++--
arch/arm/mach-imx/gpio.h | 4 +
arch/arm/mach-imx/imx1.c | 31 ++++++++++
arch/arm/mach-imx/imx21.c | 14 +++++
arch/arm/mach-imx/imx25.c | 30 ++++++++++
arch/arm/mach-imx/imx27.c | 15 +++++-
arch/arm/mach-imx/imx31.c | 29 ++++++++++
arch/arm/mach-imx/imx35.c | 29 ++++++++++
arch/arm/mach-imx/imx51.c | 30 ++++++++++
arch/arm/mach-imx/include/mach/gpio.h | 1 +
arch/arm/mach-imx/include/mach/imx-regs.h | 25 --------
12 files changed, 271 insertions(+), 38 deletions(-)
create mode 100644 arch/arm/mach-imx/gpio.h
create mode 100644 arch/arm/mach-imx/imx1.c
create mode 100644 arch/arm/mach-imx/imx25.c
create mode 100644 arch/arm/mach-imx/imx31.c
create mode 100644 arch/arm/mach-imx/imx35.c
create mode 100644 arch/arm/mach-imx/imx51.c
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 767cd30..445a879 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -1,10 +1,10 @@
-obj-y += clocksource.o
-obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o gpio.o iomux-v1.o
-obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o iomux-v3.o
-obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o gpio.o imx21.o iomux-v1.o
-obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o gpio.o imx27.o iomux-v1.o
-obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o iomux-v2.o
-obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o iomux-v3.o
+obj-y += clocksource.o gpio.o
+obj-$(CONFIG_ARCH_IMX1) += speed-imx1.o imx1.o iomux-v1.o
+obj-$(CONFIG_ARCH_IMX25) += speed-imx25.o imx25.o iomux-v3.o
+obj-$(CONFIG_ARCH_IMX21) += speed-imx21.o imx21.o iomux-v1.o
+obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o imx27.o iomux-v1.o
+obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o imx31.o iomux-v2.o
+obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o imx35.o iomux-v3.o
obj-$(CONFIG_IMX_CLKO) += clko.o
obj-$(CONFIG_NAND_IMX) += nand.o
obj-y += speed.o
diff --git a/arch/arm/mach-imx/gpio.c b/arch/arm/mach-imx/gpio.c
index eb095ec..6157bd1 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;
+}
diff --git a/arch/arm/mach-imx/gpio.h b/arch/arm/mach-imx/gpio.h
new file mode 100644
index 0000000..545cebe
--- /dev/null
+++ b/arch/arm/mach-imx/gpio.h
@@ -0,0 +1,4 @@
+
+extern void *imx_gpio_base[];
+extern int imx_gpio_count;
+
diff --git a/arch/arm/mach-imx/imx1.c b/arch/arm/mach-imx/imx1.c
new file mode 100644
index 0000000..742a260
--- /dev/null
+++ b/arch/arm/mach-imx/imx1.c
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+#include <common.h>
+
+#include "gpio.h"
+
+void *imx_gpio_base[] = {
+ (void *)0x0021c000,
+ (void *)0x0021c100,
+ (void *)0x0021c200,
+ (void *)0x0021c300,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
+
diff --git a/arch/arm/mach-imx/imx21.c b/arch/arm/mach-imx/imx21.c
index 0741f11..bbef33d 100644
--- a/arch/arm/mach-imx/imx21.c
+++ b/arch/arm/mach-imx/imx21.c
@@ -18,6 +18,8 @@
#include <common.h>
#include <mach/imx-regs.h>
+#include "gpio.h"
+
int imx_silicon_revision(void)
{
// Known values:
@@ -25,3 +27,15 @@ int imx_silicon_revision(void)
// 0x201D101D : mask set ID 1M55B or M55B
return CID;
}
+
+void *imx_gpio_base[] = {
+ (void *)0x10015000,
+ (void *)0x10015100,
+ (void *)0x10015200,
+ (void *)0x10015300,
+ (void *)0x10015400,
+ (void *)0x10015500,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
new file mode 100644
index 0000000..00a1e4e
--- /dev/null
+++ b/arch/arm/mach-imx/imx25.c
@@ -0,0 +1,30 @@
+/*
+ * 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
+ */
+
+#include <common.h>
+
+#include "gpio.h"
+
+void *imx_gpio_base[] = {
+ (void *)0x53fcc000,
+ (void *)0x53fd0000,
+ (void *)0x53fa4000,
+ (void *)0x53f9c000,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
diff --git a/arch/arm/mach-imx/imx27.c b/arch/arm/mach-imx/imx27.c
index c33346a..04bdd5f 100644
--- a/arch/arm/mach-imx/imx27.c
+++ b/arch/arm/mach-imx/imx27.c
@@ -18,8 +18,21 @@
#include <common.h>
#include <mach/imx-regs.h>
+#include "gpio.h"
+
int imx_silicon_revision(void)
{
- return CID >> 28;
+ return CID >> 28;
}
+void *imx_gpio_base[] = {
+ (void *)0x10015000,
+ (void *)0x10015100,
+ (void *)0x10015200,
+ (void *)0x10015300,
+ (void *)0x10015400,
+ (void *)0x10015500,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
diff --git a/arch/arm/mach-imx/imx31.c b/arch/arm/mach-imx/imx31.c
new file mode 100644
index 0000000..f2fea4c
--- /dev/null
+++ b/arch/arm/mach-imx/imx31.c
@@ -0,0 +1,29 @@
+/*
+ * 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
+ */
+
+#include <common.h>
+
+#include "gpio.h"
+
+void *imx_gpio_base[] = {
+ (void *)0x53fcc000,
+ (void *)0x53fd0000,
+ (void *)0x53fa4000,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
diff --git a/arch/arm/mach-imx/imx35.c b/arch/arm/mach-imx/imx35.c
new file mode 100644
index 0000000..f2fea4c
--- /dev/null
+++ b/arch/arm/mach-imx/imx35.c
@@ -0,0 +1,29 @@
+/*
+ * 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
+ */
+
+#include <common.h>
+
+#include "gpio.h"
+
+void *imx_gpio_base[] = {
+ (void *)0x53fcc000,
+ (void *)0x53fd0000,
+ (void *)0x53fa4000,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
new file mode 100644
index 0000000..8c4fc11
--- /dev/null
+++ b/arch/arm/mach-imx/imx51.c
@@ -0,0 +1,30 @@
+/*
+ * 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
+ */
+
+#include <common.h>
+
+#include "gpio.h"
+
+void *imx_gpio_base[] = {
+ (void *)0x87f84000,
+ (void *)0x73f88000,
+ (void *)0x73f8c000,
+ (void *)0x73f90000,
+};
+
+int imx_gpio_count = ARRAY_SIZE(imx_gpio_base) * 32;
+
diff --git a/arch/arm/mach-imx/include/mach/gpio.h b/arch/arm/mach-imx/include/mach/gpio.h
index 71298f4..0ebc3f9 100644
--- a/arch/arm/mach-imx/include/mach/gpio.h
+++ b/arch/arm/mach-imx/include/mach/gpio.h
@@ -3,6 +3,7 @@
void imx_gpio_mode(int gpio_mode);
void gpio_set_value(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int gpio_direction_input(unsigned gpio);
diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h
index 459714e..2cc49dd 100644
--- a/arch/arm/mach-imx/include/mach/imx-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx-regs.h
@@ -55,31 +55,6 @@
# error "unknown i.MX soc type"
#endif
-/*
- * GPIO Module and I/O Multiplexer
- * x = 0..3 for reg_A, reg_B, reg_C, reg_D
- *
- * i.MX1 and i.MXL: 0 <= x <= 3
- * i.MX27 : 0 <= x <= 5
- */
-#define DDIR(x) __REG2(IMX_GPIO_BASE + 0x00, ((x) & 7) << 8)
-#define OCR1(x) __REG2(IMX_GPIO_BASE + 0x04, ((x) & 7) << 8)
-#define OCR2(x) __REG2(IMX_GPIO_BASE + 0x08, ((x) & 7) << 8)
-#define ICONFA1(x) __REG2(IMX_GPIO_BASE + 0x0c, ((x) & 7) << 8)
-#define ICONFA2(x) __REG2(IMX_GPIO_BASE + 0x10, ((x) & 7) << 8)
-#define ICONFB1(x) __REG2(IMX_GPIO_BASE + 0x14, ((x) & 7) << 8)
-#define ICONFB2(x) __REG2(IMX_GPIO_BASE + 0x18, ((x) & 7) << 8)
-#define DR(x) __REG2(IMX_GPIO_BASE + 0x1c, ((x) & 7) << 8)
-#define GIUS(x) __REG2(IMX_GPIO_BASE + 0x20, ((x) & 7) << 8)
-#define SSR(x) __REG2(IMX_GPIO_BASE + 0x24, ((x) & 7) << 8)
-#define ICR1(x) __REG2(IMX_GPIO_BASE + 0x28, ((x) & 7) << 8)
-#define ICR2(x) __REG2(IMX_GPIO_BASE + 0x2c, ((x) & 7) << 8)
-#define IMR(x) __REG2(IMX_GPIO_BASE + 0x30, ((x) & 7) << 8)
-#define ISR(x) __REG2(IMX_GPIO_BASE + 0x34, ((x) & 7) << 8)
-#define GPR(x) __REG2(IMX_GPIO_BASE + 0x38, ((x) & 7) << 8)
-#define SWR(x) __REG2(IMX_GPIO_BASE + 0x3c, ((x) & 7) << 8)
-#define PUEN(x) __REG2(IMX_GPIO_BASE + 0x40, ((x) & 7) << 8)
-
#define GPIO_PIN_MASK 0x1f
#define GPIO_PORT_SHIFT 5
--
1.6.5.2
More information about the u-boot-v2
mailing list