[U-Boot] [PATCH 01/10] Use common function to set GPIOs for MX3 and MX5

Stefano Babic sbabic at denx.de
Thu Sep 30 14:47:51 CEST 2010


The patch adds support for setting gpios to the
MX51 processor and change name to the corresponding
functions for MX31. In this way, it is possible to get rid
of nasty #ifdef switches related to the processor type.

Signed-off-by: Stefano Babic <sbabic at denx.de>
---
 arch/arm/include/asm/arch-mx31/mx31-regs.h |   14 +++-
 arch/arm/include/asm/arch-mx31/mx31.h      |   25 -------
 arch/arm/include/asm/arch-mx51/imx-regs.h  |    6 ++
 board/davedenx/qong/qong.c                 |   29 ++++----
 drivers/gpio/Makefile                      |    2 +-
 drivers/gpio/mx31_gpio.c                   |   88 -----------------------
 drivers/gpio/mxc_gpio.c                    |  107 ++++++++++++++++++++++++++++
 drivers/spi/mxc_spi.c                      |   15 ++--
 include/configs/imx31_phycore.h            |    2 +-
 include/configs/qong.h                     |    2 +-
 include/mxc_gpio.h                         |   52 +++++++++++++
 11 files changed, 201 insertions(+), 141 deletions(-)
 delete mode 100644 drivers/gpio/mx31_gpio.c
 create mode 100644 drivers/gpio/mxc_gpio.c
 create mode 100644 include/mxc_gpio.h

diff --git a/arch/arm/include/asm/arch-mx31/mx31-regs.h b/arch/arm/include/asm/arch-mx31/mx31-regs.h
index d72585c..f05e743 100644
--- a/arch/arm/include/asm/arch-mx31/mx31-regs.h
+++ b/arch/arm/include/asm/arch-mx31/mx31-regs.h
@@ -57,6 +57,14 @@ struct clock_control_regs {
 	u32 pdr2;
 };
 
+/* GPIO Registers */
+struct gpio_regs {
+	u32	gpio_dr;
+	u32	gpio_dir;
+	u32	gpio_psr;
+};
+
+
 /* Bit definitions for RCSR register in CCM */
 #define CCM_RCSR_NF16B	(1 << 31)
 #define CCM_RCSR_NFMS	(1 << 30)
@@ -153,9 +161,9 @@ struct clock_control_regs {
 /*
  * GPIO
  */
-#define GPIO1_BASE	0x53FCC000
-#define GPIO2_BASE	0x53FD0000
-#define GPIO3_BASE	0x53FA4000
+#define GPIO1_BASE_ADDR	0x53FCC000
+#define GPIO2_BASE_ADDR	0x53FD0000
+#define GPIO3_BASE_ADDR	0x53FA4000
 #define GPIO_DR		0x00000000	/* data register */
 #define GPIO_GDIR	0x00000004	/* direction register */
 #define GPIO_PSR	0x00000008	/* pad status register */
diff --git a/arch/arm/include/asm/arch-mx31/mx31.h b/arch/arm/include/asm/arch-mx31/mx31.h
index f702d26..5a5aa11 100644
--- a/arch/arm/include/asm/arch-mx31/mx31.h
+++ b/arch/arm/include/asm/arch-mx31/mx31.h
@@ -28,31 +28,6 @@ extern u32 mx31_get_ipg_clk(void);
 #define imx_get_uartclk mx31_get_ipg_clk
 extern void mx31_gpio_mux(unsigned long mode);
 
-enum mx31_gpio_direction {
-	MX31_GPIO_DIRECTION_IN,
-	MX31_GPIO_DIRECTION_OUT,
-};
-
-#ifdef CONFIG_MX31_GPIO
-extern int mx31_gpio_direction(unsigned int gpio,
-			       enum mx31_gpio_direction direction);
-extern void mx31_gpio_set(unsigned int gpio, unsigned int value);
-extern int mx31_gpio_get(unsigned int gpio);
-#else
-static inline int mx31_gpio_direction(unsigned int gpio,
-				      enum mx31_gpio_direction direction)
-{
-	return 1;
-}
-static inline int mx31_gpio_get(unsigned int gpio)
-{
-	return 1;
-}
-static inline void mx31_gpio_set(unsigned int gpio, unsigned int value)
-{
-}
-#endif
-
 void mx31_uart1_hw_init(void);
 void mx31_spi2_hw_init(void);
 
diff --git a/arch/arm/include/asm/arch-mx51/imx-regs.h b/arch/arm/include/asm/arch-mx51/imx-regs.h
index 3887d3c..0e3bc2a 100644
--- a/arch/arm/include/asm/arch-mx51/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx51/imx-regs.h
@@ -256,6 +256,12 @@ struct weim {
 	u32	cswcr2;
 };
 
+/* GPIO Registers */
+struct gpio_regs {
+	u32	gpio_dr;
+	u32	gpio_dir;
+	u32	gpio_psr;
+};
 #endif /* __ASSEMBLER__*/
 
 #endif				/*  __ASM_ARCH_MXC_MX51_H__ */
diff --git a/board/davedenx/qong/qong.c b/board/davedenx/qong/qong.c
index e509383..9abc29c 100644
--- a/board/davedenx/qong/qong.c
+++ b/board/davedenx/qong/qong.c
@@ -27,6 +27,7 @@
 #include <asm/arch/mx31-regs.h>
 #include <nand.h>
 #include <fsl_pmic.h>
+#include <mxc_gpio.h>
 #include "qong_fpga.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -41,9 +42,9 @@ int dram_init (void)
 
 static void qong_fpga_reset(void)
 {
-	mx31_gpio_set(QONG_FPGA_RST_PIN, 0);
+	mxc_gpio_set(QONG_FPGA_RST_PIN, 0);
 	udelay(30);
-	mx31_gpio_set(QONG_FPGA_RST_PIN, 1);
+	mxc_gpio_set(QONG_FPGA_RST_PIN, 1);
 
 	udelay(300);
 }
@@ -66,11 +67,11 @@ int board_early_init_f (void)
 
 	/* FPGA reset  Pin */
 	/* rstn = 0 */
-	mx31_gpio_set(QONG_FPGA_RST_PIN, 0);
-	mx31_gpio_direction(QONG_FPGA_RST_PIN, MX31_GPIO_DIRECTION_OUT);
+	mxc_gpio_set(QONG_FPGA_RST_PIN, 0);
+	mxc_gpio_direction(QONG_FPGA_RST_PIN, MXC_GPIO_DIRECTION_OUT);
 
 	/* set interrupt pin as input */
-	mx31_gpio_direction(QONG_FPGA_IRQ_PIN, MX31_GPIO_DIRECTION_IN);
+	mxc_gpio_direction(QONG_FPGA_IRQ_PIN, MXC_GPIO_DIRECTION_IN);
 
 #endif
 
@@ -206,27 +207,27 @@ static void board_nand_setup(void)
 	qong_fpga_reset();
 
 	/* Enable NAND flash */
-	mx31_gpio_set(15, 1);
-	mx31_gpio_set(14, 1);
-	mx31_gpio_direction(15, MX31_GPIO_DIRECTION_OUT);
-	mx31_gpio_direction(16, MX31_GPIO_DIRECTION_IN);
-	mx31_gpio_direction(14, MX31_GPIO_DIRECTION_IN);
-	mx31_gpio_set(15, 0);
+	mxc_gpio_set(15, 1);
+	mxc_gpio_set(14, 1);
+	mxc_gpio_direction(15, MXC_GPIO_DIRECTION_OUT);
+	mxc_gpio_direction(16, MXC_GPIO_DIRECTION_IN);
+	mxc_gpio_direction(14, MXC_GPIO_DIRECTION_IN);
+	mxc_gpio_set(15, 0);
 
 }
 
 int qong_nand_rdy(void *chip)
 {
 	udelay(1);
-	return mx31_gpio_get(16);
+	return mxc_gpio_get(16);
 }
 
 void qong_nand_select_chip(struct mtd_info *mtd, int chip)
 {
 	if (chip >= 0)
-		mx31_gpio_set(15, 0);
+		mxc_gpio_set(15, 0);
 	else
-		mx31_gpio_set(15, 1);
+		mxc_gpio_set(15, 1);
 
 }
 
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 07d395d..a0f4552 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -27,7 +27,7 @@ LIB 	:= $(obj)libgpio.a
 
 COBJS-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
 COBJS-$(CONFIG_KIRKWOOD_GPIO)	+= kw_gpio.o
-COBJS-$(CONFIG_MX31_GPIO)	+= mx31_gpio.o
+COBJS-$(CONFIG_MXC_GPIO)	+= mxc_gpio.o
 COBJS-$(CONFIG_PCA953X)		+= pca953x.o
 COBJS-$(CONFIG_S5P)		+= s5p_gpio.o
 
diff --git a/drivers/gpio/mx31_gpio.c b/drivers/gpio/mx31_gpio.c
deleted file mode 100644
index b07f038..0000000
--- a/drivers/gpio/mx31_gpio.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2009
- * Guennadi Liakhovetski, DENX Software Engineering, <lg at denx.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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 <asm/arch/mx31.h>
-#include <asm/arch/mx31-regs.h>
-
-/* GPIO port description */
-static unsigned long gpio_ports[] = {
-	[0] = GPIO1_BASE,
-	[1] = GPIO2_BASE,
-	[2] = GPIO3_BASE,
-};
-
-int mx31_gpio_direction(unsigned int gpio, enum mx31_gpio_direction direction)
-{
-	unsigned int port = gpio >> 5;
-	u32 l;
-
-	if (port >= ARRAY_SIZE(gpio_ports))
-		return 1;
-
-	gpio &= 0x1f;
-
-	l = __REG(gpio_ports[port] + GPIO_GDIR);
-	switch (direction) {
-	case MX31_GPIO_DIRECTION_OUT:
-		l |= 1 << gpio;
-		break;
-	case MX31_GPIO_DIRECTION_IN:
-		l &= ~(1 << gpio);
-	}
-	__REG(gpio_ports[port] + GPIO_GDIR) = l;
-
-	return 0;
-}
-
-void mx31_gpio_set(unsigned int gpio, unsigned int value)
-{
-	unsigned int port = gpio >> 5;
-	u32 l;
-
-	if (port >= ARRAY_SIZE(gpio_ports))
-		return;
-
-	gpio &= 0x1f;
-
-	l = __REG(gpio_ports[port] + GPIO_DR);
-	if (value)
-		l |= 1 << gpio;
-	else
-		l &= ~(1 << gpio);
-	__REG(gpio_ports[port] + GPIO_DR) = l;
-}
-
-int mx31_gpio_get(unsigned int gpio)
-{
-	unsigned int port = gpio >> 5;
-	u32 l;
-
-	if (port >= ARRAY_SIZE(gpio_ports))
-		return -1;
-
-	gpio &= 0x1f;
-
-	l = (__REG(gpio_ports[port] + GPIO_DR) >> gpio) & 0x01;
-
-	return l;
-}
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
new file mode 100644
index 0000000..663141f
--- /dev/null
+++ b/drivers/gpio/mxc_gpio.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2009
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg at denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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>
+#ifdef CONFIG_MX31
+#include <asm/arch/mx31-regs.h>
+#endif
+#ifdef CONFIG_MX51
+#include <asm/arch/imx-regs.h>
+#endif
+#include <asm/io.h>
+#include <mxc_gpio.h>
+
+/* GPIO port description */
+static unsigned long gpio_ports[] = {
+	[0] = GPIO1_BASE_ADDR,
+	[1] = GPIO2_BASE_ADDR,
+	[2] = GPIO3_BASE_ADDR,
+#ifdef CONFIG_MX51
+	[3] = GPIO4_BASE_ADDR,
+#endif
+};
+
+int mxc_gpio_direction(unsigned int gpio, enum mxc_gpio_direction direction)
+{
+	unsigned int port = gpio >> 5;
+	struct gpio_regs *regs;
+	u32 l;
+
+	if (port >= ARRAY_SIZE(gpio_ports))
+		return 1;
+
+	gpio &= 0x1f;
+
+	regs = (struct gpio_regs *)gpio_ports[port];
+
+	l = readl(&regs->gpio_dir);
+
+	switch (direction) {
+	case MXC_GPIO_DIRECTION_OUT:
+		l |= 1 << gpio;
+		break;
+	case MXC_GPIO_DIRECTION_IN:
+		l &= ~(1 << gpio);
+	}
+	writel(l, &regs->gpio_dir);
+
+	return 0;
+}
+
+void mxc_gpio_set(unsigned int gpio, unsigned int value)
+{
+	unsigned int port = gpio >> 5;
+	struct gpio_regs *regs;
+	u32 l;
+
+	if (port >= ARRAY_SIZE(gpio_ports))
+		return;
+
+	gpio &= 0x1f;
+
+	regs = (struct gpio_regs *)gpio_ports[port];
+
+	l = readl(&regs->gpio_dr);
+	if (value)
+		l |= 1 << gpio;
+	else
+		l &= ~(1 << gpio);
+	writel(l, &regs->gpio_dr);
+}
+
+int mxc_gpio_get(unsigned int gpio)
+{
+	unsigned int port = gpio >> 5;
+	struct gpio_regs *regs;
+	u32 l;
+
+	if (port >= ARRAY_SIZE(gpio_ports))
+		return -1;
+
+	gpio &= 0x1f;
+
+	regs = (struct gpio_regs *)gpio_ports[port];
+
+	l = (readl(&regs->gpio_dr) >> gpio) & 0x01;
+
+	return l;
+}
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
index e15a63c..802cd2e 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/mxc_spi.c
@@ -23,6 +23,7 @@
 #include <spi.h>
 #include <asm/errno.h>
 #include <asm/io.h>
+#include <mxc_gpio.h>
 
 #ifdef CONFIG_MX27
 /* i.MX27 has a completely wrong register layout and register definitions in the
@@ -68,9 +69,6 @@ static unsigned long spi_bases[] = {
 	0x53f84000,
 };
 
-#define OUT	MX31_GPIO_DIRECTION_OUT
-#define mxc_gpio_direction	mx31_gpio_direction
-#define mxc_gpio_set		mx31_gpio_set
 #elif defined(CONFIG_MX51)
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
@@ -111,13 +109,12 @@ static unsigned long spi_bases[] = {
 	CSPI2_BASE_ADDR,
 	CSPI3_BASE_ADDR,
 };
-#define mxc_gpio_direction(gpio, dir)	(0)
-#define mxc_gpio_set(gpio, value)	{}
-#define OUT	1
 #else
 #error "Unsupported architecture"
 #endif
 
+#define OUT	MXC_GPIO_DIRECTION_OUT
+
 struct mxc_spi_slave {
 	struct spi_slave slave;
 	unsigned long	base;
@@ -126,6 +123,7 @@ struct mxc_spi_slave {
 	u32		cfg_reg;
 #endif
 	int		gpio;
+	int		ss_pol;
 };
 
 static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave)
@@ -147,7 +145,7 @@ void spi_cs_activate(struct spi_slave *slave)
 {
 	struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
 	if (mxcs->gpio > 0)
-		mxc_gpio_set(mxcs->gpio, mxcs->ctrl_reg & MXC_CSPICTRL_SSPOL);
+		mxc_gpio_set(mxcs->gpio, mxcs->ss_pol);
 }
 
 void spi_cs_deactivate(struct spi_slave *slave)
@@ -155,7 +153,7 @@ void spi_cs_deactivate(struct spi_slave *slave)
 	struct mxc_spi_slave *mxcs = to_mxc_spi_slave(slave);
 	if (mxcs->gpio > 0)
 		mxc_gpio_set(mxcs->gpio,
-			      !(mxcs->ctrl_reg & MXC_CSPICTRL_SSPOL));
+			      !(mxcs->ss_pol));
 }
 
 #ifdef CONFIG_MX51
@@ -394,6 +392,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 	mxcs->slave.bus = bus;
 	mxcs->slave.cs = cs;
 	mxcs->base = spi_bases[bus];
+	mxcs->ss_pol = (mode & SPI_CS_HIGH) ? 1 : 0;
 
 #ifdef CONFIG_MX51
 	/* Can be used for i.MX31 too ? */
diff --git a/include/configs/imx31_phycore.h b/include/configs/imx31_phycore.h
index 1dbafa0..62944a9 100644
--- a/include/configs/imx31_phycore.h
+++ b/include/configs/imx31_phycore.h
@@ -183,7 +183,7 @@
 #ifdef CONFIG_IMX31_PHYCORE_EET
 #define BOARD_LATE_INIT
 
-#define CONFIG_MX31_GPIO			1
+#define CONFIG_MXC_GPIO
 
 #define CONFIG_HARD_SPI				1
 #define CONFIG_MXC_SPI				1
diff --git a/include/configs/qong.h b/include/configs/qong.h
index 7a68b7b..7cd9558 100644
--- a/include/configs/qong.h
+++ b/include/configs/qong.h
@@ -52,7 +52,7 @@
 #define CONFIG_MXC_UART	1
 #define CONFIG_SYS_MX31_UART1	1
 
-#define CONFIG_MX31_GPIO
+#define CONFIG_MXC_GPIO
 
 #define CONFIG_MXC_SPI
 #define CONFIG_DEFAULT_SPI_BUS	1
diff --git a/include/mxc_gpio.h b/include/mxc_gpio.h
new file mode 100644
index 0000000..002ba61
--- /dev/null
+++ b/include/mxc_gpio.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer at pengutronix.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __MXC_GPIO_H
+#define __MXC_GPIO_H
+
+enum mxc_gpio_direction {
+	MXC_GPIO_DIRECTION_IN,
+	MXC_GPIO_DIRECTION_OUT,
+};
+
+#ifdef CONFIG_MXC_GPIO
+extern int mxc_gpio_direction(unsigned int gpio,
+			       enum mxc_gpio_direction direction);
+extern void mxc_gpio_set(unsigned int gpio, unsigned int value);
+extern int mxc_gpio_get(unsigned int gpio);
+#else
+static inline int mxc_gpio_direction(unsigned int gpio,
+				      enum mxc_gpio_direction direction)
+{
+	return 1;
+}
+static inline int mxc_gpio_get(unsigned int gpio)
+{
+	return 1;
+}
+static inline void mxc_gpio_set(unsigned int gpio, unsigned int value)
+{
+}
+#endif
+
+#endif
-- 
1.6.3.3



More information about the U-Boot mailing list