[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