[PATCH 6/9] lpc2k: multifunction pin configuration

Ithamar R. Adema ithamar.adema at team-embedded.nl
Thu Mar 17 11:54:21 EDT 2011


Inspired by the mfp support in PXA. Includes definition of pins
for NXP LPC2468/78.

Signed-off-by: Ithamar R. Adema <ithamar.adema at team-embedded.nl>
---
 arch/arm/mach-lpc2k/Makefile                   |    2 +-
 arch/arm/mach-lpc2k/include/mach/hardware.h    |    1 +
 arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h |   98 +++++++++++
 arch/arm/mach-lpc2k/include/mach/mfp.h         |  209 ++++++++++++++++++++++++
 arch/arm/mach-lpc2k/mfp.c                      |   99 +++++++++++
 5 files changed, 408 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
 create mode 100644 arch/arm/mach-lpc2k/include/mach/mfp.h
 create mode 100644 arch/arm/mach-lpc2k/mfp.c

diff --git a/arch/arm/mach-lpc2k/Makefile b/arch/arm/mach-lpc2k/Makefile
index 89596a7..2c50bb9 100644
--- a/arch/arm/mach-lpc2k/Makefile
+++ b/arch/arm/mach-lpc2k/Makefile
@@ -1 +1 @@
-obj-y	:= clock.o irq.o gpio.o time.o
+obj-y	:= clock.o irq.o gpio.o mfp.o time.o
diff --git a/arch/arm/mach-lpc2k/include/mach/hardware.h b/arch/arm/mach-lpc2k/include/mach/hardware.h
index 0d7c10c..29c561a 100644
--- a/arch/arm/mach-lpc2k/include/mach/hardware.h
+++ b/arch/arm/mach-lpc2k/include/mach/hardware.h
@@ -20,6 +20,7 @@
 #define APB_TIMER1_BASE		0xe0008000
 #define APB_UART0_BASE		0xe000c000
 #define APB_GPIO_BASE		0xe0028000
+#define APB_PINSEL_BASE		0xe002c000
 #define APB_SCB_BASE		0xe01fc000
 #define APH_VIC_BASE		0xfffff000
 
diff --git a/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h b/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
new file mode 100644
index 0000000..9b6bec4
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/mfp-lpc24xx.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema at team-embedded.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MACH_LPC2K_MFP_LPC24XX_H
+#define MACH_LPC2K_MFP_LPC24XX_H
+
+#include <mach/mfp.h>
+
+#define GPIO0_RD1		MFP_CFG(GPIO0, AF1)
+#define GPIO0_TXD3		MFP_CFG(GPIO0, AF2)
+#define GPIO0_SDA1		MFP_CFG(GPIO0, AF3)
+#define GPIO1_TD1		MFP_CFG(GPIO1, AF1)
+#define GPIO1_RXD3		MFP_CFG(GPIO1, AF2)
+#define GPIO1_SCL1		MFP_CFG(GPIO1, AF3)
+#define GPIO2_TXD0		MFP_CFG(GPIO2, AF1)
+#define GPIO3_RXD0		MFP_CFG(GPIO3, AF1)
+#define GPIO4_LCDVD0		MFP_CFG(GPIO4, AF1)
+#define GPIO5_LCDVD1		MFP_CFG(GPIO5, AF1)
+#define GPIO6_LCDVD8		MFP_CFG(GPIO6, AF1)
+#define GPIO7_LCDVD9		MFP_CFG(GPIO7, AF1)
+#define GPIO8_LCDVD16		MFP_CFG(GPIO8, AF1)
+#define GPIO9_LCDVD17		MFP_CFG(GPIO9, AF1)
+#define GPIO10_TXD2		MFP_CFG(GPIO10, AF1)
+#define GPIO11_RXD2		MFP_CFG(GPIO11, AF1)
+#define GPIO12_USB_PPWR2	MFP_CFG(GPIO12, AF1)
+#define GPIO13_USB_UP_LED2	MFP_CFG(GPIO13, AF1)
+#define GPIO15_SCK		MFP_CFG(GPIO15, AF3)
+#define GPIO17_MISO		MFP_CFG(GPIO17, AF3)
+#define GPIO18_MOSI		MFP_CFG(GPIO18, AF3)
+#define GPIO27_SDA0		MFP_CFG(GPIO27, AF1)
+#define GPIO28_SCL0		MFP_CFG(GPIO28, AF1)
+#define GPIO29_USB_Dp1		MFP_CFG(GPIO29, AF1)
+#define GPIO30_USB_Dn1		MFP_CFG(GPIO30, AF1)
+#define GPIO31_USB_Dp2		MFP_CFG(GPIO31, AF1)
+#define GPIO32_ENET_TXD0	MFP_CFG(GPIO32, AF1)
+#define GPIO33_ENET_TXD1	MFP_CFG(GPIO33, AF1)
+#define GPIO34_MCICLK		MFP_CFG(GPIO34, AF2)
+#define GPIO35_MCICMD		MFP_CFG(GPIO35, AF2)
+#define GPIO36_ENET_TX_EN	MFP_CFG(GPIO36, AF1)
+#define GPIO37_MCIPWR		MFP_CFG(GPIO37, AF2)
+#define GPIO38_ENET_TX_CLK	MFP_CFG(GPIO38, AF1)
+#define GPIO38_MCIDAT0		MFP_CFG(GPIO38, AF2)
+#define GPIO39_MCIDAT1		MFP_CFG(GPIO39, AF2)
+#define GPIO40_ENET_CRS		MFP_CFG(GPIO40, AF1)
+#define GPIO41_ENET_RXD0	MFP_CFG(GPIO41, AF1)
+#define GPIO42_ENET_RXD1	MFP_CFG(GPIO42, AF1)
+#define GPIO43_MCIDAT2		MFP_CFG(GPIO43, AF2)
+#define GPIO44_MCIDAT3		MFP_CFG(GPIO44, AF2)
+#define GPIO46_ENET_RX_ERR	MFP_CFG(GPIO46, AF1)
+#define GPIO47_ENET_REF_CLK	MFP_CFG(GPIO47, AF1)
+#define GPIO48_ENET_MDC		MFP_CFG(GPIO48, AF1)
+#define GPIO49_ENET_MDIO	MFP_CFG(GPIO49, AF1)
+#define GPIO50_PWM1		MFP_CFG(GPIO50, AF2)
+#define GPIO52_LCDVD10		MFP_CFG(GPIO52, AF1)
+#define GPIO53_LCDVD11		MFP_CFG(GPIO53, AF1)
+#define GPIO54_LCDVD12		MFP_CFG(GPIO54, AF1)
+#define GPIO55_LCDVD13		MFP_CFG(GPIO55, AF1)
+#define GPIO56_LCDVD14		MFP_CFG(GPIO56, AF1)
+#define GPIO57_LCDVD15		MFP_CFG(GPIO57, AF1)
+#define GPIO58_LCDVD20		MFP_CFG(GPIO58, AF1)
+#define GPIO59_LCDVD21		MFP_CFG(GPIO59, AF1)
+#define GPIO60_LCDVD22		MFP_CFG(GPIO60, AF1)
+#define GPIO61_LCDVD23		MFP_CFG(GPIO61, AF1)
+#define GPIO62_VBUS		MFP_CFG(GPIO62, AF2)
+#define GPIO63_USB_OVRCR2	MFP_CFG(GPIO63, AF1)
+#define GPIO64_LCDPWR		MFP_CFG(GPIO64, AF3)
+#define GPIO65_LCDLE		MFP_CFG(GPIO65, AF3)
+#define GPIO66_LCDDCLK		MFP_CFG(GPIO66, AF3)
+#define GPIO67_LCDFP		MFP_CFG(GPIO67, AF3)
+#define GPIO68_LCDM		MFP_CFG(GPIO68, AF3)
+#define GPIO69_LCDLP		MFP_CFG(GPIO69, AF3)
+#define GPIO70_LCDVP4		MFP_CFG(GPIO70, AF3)
+#define GPIO71_LCDVP5		MFP_CFG(GPIO71, AF3)
+#define GPIO72_LCDVP6		MFP_CFG(GPIO72, AF3)
+#define GPIO73_LCDVP7		MFP_CFG(GPIO73, AF3)
+#define GPIO75_LCDCLKIN		MFP_CFG(GPIO75, AF1)
+#define GPIO76_LCDVP18		MFP_CFG(GPIO76, AF1)
+#define GPIO77_LCDVP19		MFP_CFG(GPIO77, AF1)
+#define GPIO112_TXD1		MFP_CFG(GPIO112, AF3)
+#define GPIO113_RXD1		MFP_CFG(GPIO113, AF3)
+#define GPIO114_CTS1		MFP_CFG(GPIO114, AF3)
+#define GPIO115_DCD1		MFP_CFG(GPIO115, AF3)
+#define GPIO116_DSR1		MFP_CFG(GPIO116, AF3)
+#define GPIO117_DR1		MFP_CFG(GPIO117, AF3)
+#define GPIO118_RI1		MFP_CFG(GPIO118, AF3)
+#define GPIO126_RTS1		MFP_CFG(GPIO126, AF3)
+#define GPIO156_TXD3		MFP_CFG(GPIO156, AF3)
+#define GPIO156_LCDVP2		MFP_CFG(GPIO156, AF2)
+#define GPIO157_RXD3		MFP_CFG(GPIO157, AF3)
+#define GPIO157_LCDVP3		MFP_CFG(GPIO157, AF2)
+
+#endif /* MACH_LPC2K_MFP_LPC24XX_H */
diff --git a/arch/arm/mach-lpc2k/include/mach/mfp.h b/arch/arm/mach-lpc2k/include/mach/mfp.h
new file mode 100644
index 0000000..3c919c8
--- /dev/null
+++ b/arch/arm/mach-lpc2k/include/mach/mfp.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2011 Team Embedded VOF
+ *     Ithamar R. Adema <ihamar.adema at team-embedded.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef ARCH_LPC2K_MFP_H
+#define ARCH_LPC2K_MFP_H
+
+#define mfp_to_gpio(m)	((m) % 160)
+
+/* list of all the configurable MFP pins */
+enum {
+	MFP_PIN_INVALID = -1,
+
+	MFP_PIN_GPIO0 = 0,
+	MFP_PIN_GPIO1,
+	MFP_PIN_GPIO2,
+	MFP_PIN_GPIO3,
+	MFP_PIN_GPIO4,
+	MFP_PIN_GPIO5,
+	MFP_PIN_GPIO6,
+	MFP_PIN_GPIO7,
+	MFP_PIN_GPIO8,
+	MFP_PIN_GPIO9,
+	MFP_PIN_GPIO10,
+	MFP_PIN_GPIO11,
+	MFP_PIN_GPIO12,
+	MFP_PIN_GPIO13,
+	MFP_PIN_GPIO14,
+	MFP_PIN_GPIO15,
+	MFP_PIN_GPIO16,
+	MFP_PIN_GPIO17,
+	MFP_PIN_GPIO18,
+	MFP_PIN_GPIO19,
+	MFP_PIN_GPIO20,
+	MFP_PIN_GPIO21,
+	MFP_PIN_GPIO22,
+	MFP_PIN_GPIO23,
+	MFP_PIN_GPIO24,
+	MFP_PIN_GPIO25,
+	MFP_PIN_GPIO26,
+	MFP_PIN_GPIO27,
+	MFP_PIN_GPIO28,
+	MFP_PIN_GPIO29,
+	MFP_PIN_GPIO30,
+	MFP_PIN_GPIO31,
+	MFP_PIN_GPIO32,
+	MFP_PIN_GPIO33,
+	MFP_PIN_GPIO34,
+	MFP_PIN_GPIO35,
+	MFP_PIN_GPIO36,
+	MFP_PIN_GPIO37,
+	MFP_PIN_GPIO38,
+	MFP_PIN_GPIO39,
+	MFP_PIN_GPIO40,
+	MFP_PIN_GPIO41,
+	MFP_PIN_GPIO42,
+	MFP_PIN_GPIO43,
+	MFP_PIN_GPIO44,
+	MFP_PIN_GPIO45,
+	MFP_PIN_GPIO46,
+	MFP_PIN_GPIO47,
+	MFP_PIN_GPIO48,
+	MFP_PIN_GPIO49,
+	MFP_PIN_GPIO50,
+	MFP_PIN_GPIO51,
+	MFP_PIN_GPIO52,
+	MFP_PIN_GPIO53,
+	MFP_PIN_GPIO54,
+	MFP_PIN_GPIO55,
+	MFP_PIN_GPIO56,
+	MFP_PIN_GPIO57,
+	MFP_PIN_GPIO58,
+	MFP_PIN_GPIO59,
+	MFP_PIN_GPIO60,
+	MFP_PIN_GPIO61,
+	MFP_PIN_GPIO62,
+	MFP_PIN_GPIO63,
+	MFP_PIN_GPIO64,
+	MFP_PIN_GPIO65,
+	MFP_PIN_GPIO66,
+	MFP_PIN_GPIO67,
+	MFP_PIN_GPIO68,
+	MFP_PIN_GPIO69,
+	MFP_PIN_GPIO70,
+	MFP_PIN_GPIO71,
+	MFP_PIN_GPIO72,
+	MFP_PIN_GPIO73,
+	MFP_PIN_GPIO74,
+	MFP_PIN_GPIO75,
+	MFP_PIN_GPIO76,
+	MFP_PIN_GPIO77,
+	MFP_PIN_GPIO78,
+	MFP_PIN_GPIO79,
+	MFP_PIN_GPIO80,
+	MFP_PIN_GPIO81,
+	MFP_PIN_GPIO82,
+	MFP_PIN_GPIO83,
+	MFP_PIN_GPIO84,
+	MFP_PIN_GPIO85,
+	MFP_PIN_GPIO86,
+	MFP_PIN_GPIO87,
+	MFP_PIN_GPIO88,
+	MFP_PIN_GPIO89,
+	MFP_PIN_GPIO90,
+	MFP_PIN_GPIO91,
+	MFP_PIN_GPIO92,
+	MFP_PIN_GPIO93,
+	MFP_PIN_GPIO94,
+	MFP_PIN_GPIO95,
+	MFP_PIN_GPIO96,
+	MFP_PIN_GPIO97,
+	MFP_PIN_GPIO98,
+	MFP_PIN_GPIO99,
+	MFP_PIN_GPIO100,
+	MFP_PIN_GPIO101,
+	MFP_PIN_GPIO102,
+	MFP_PIN_GPIO103,
+	MFP_PIN_GPIO104,
+	MFP_PIN_GPIO105,
+	MFP_PIN_GPIO106,
+	MFP_PIN_GPIO107,
+	MFP_PIN_GPIO108,
+	MFP_PIN_GPIO109,
+	MFP_PIN_GPIO110,
+	MFP_PIN_GPIO111,
+	MFP_PIN_GPIO112,
+	MFP_PIN_GPIO113,
+	MFP_PIN_GPIO114,
+	MFP_PIN_GPIO115,
+	MFP_PIN_GPIO116,
+	MFP_PIN_GPIO117,
+	MFP_PIN_GPIO118,
+	MFP_PIN_GPIO119,
+	MFP_PIN_GPIO120,
+	MFP_PIN_GPIO121,
+	MFP_PIN_GPIO122,
+	MFP_PIN_GPIO123,
+	MFP_PIN_GPIO124,
+	MFP_PIN_GPIO125,
+	MFP_PIN_GPIO126,
+	MFP_PIN_GPIO127,
+	MFP_PIN_GPIO128,
+	MFP_PIN_GPIO129,
+	MFP_PIN_GPIO130,
+	MFP_PIN_GPIO131,
+	MFP_PIN_GPIO132,
+	MFP_PIN_GPIO133,
+	MFP_PIN_GPIO134,
+	MFP_PIN_GPIO135,
+	MFP_PIN_GPIO136,
+	MFP_PIN_GPIO137,
+	MFP_PIN_GPIO138,
+	MFP_PIN_GPIO139,
+	MFP_PIN_GPIO140,
+	MFP_PIN_GPIO141,
+	MFP_PIN_GPIO142,
+	MFP_PIN_GPIO143,
+	MFP_PIN_GPIO144,
+	MFP_PIN_GPIO145,
+	MFP_PIN_GPIO146,
+	MFP_PIN_GPIO147,
+	MFP_PIN_GPIO148,
+	MFP_PIN_GPIO149,
+	MFP_PIN_GPIO150,
+	MFP_PIN_GPIO151,
+	MFP_PIN_GPIO152,
+	MFP_PIN_GPIO153,
+	MFP_PIN_GPIO154,
+	MFP_PIN_GPIO155,
+	MFP_PIN_GPIO156,
+	MFP_PIN_GPIO157,
+	MFP_PIN_GPIO158,
+	MFP_PIN_GPIO159,
+};
+
+/* pin number; currently only 0-159 are used */
+#define MFP_PIN(x)	((x) & 0x3ff)
+
+/* Alternate functions, currently only 0-3 are used */
+#define MFP_AF0		(0x0 << 10)
+#define MFP_AF1		(0x1 << 10)
+#define MFP_AF2		(0x2 << 10)
+#define MFP_AF3		(0x3 << 10)
+#define MFP_AF_MASK	(0x3 << 10)
+#define MFP_AF(x)	(((x) >> 10) & 0x3)
+
+/* Pullup/down configuration, currently only none/high/low are used */
+#define MFP_PULL_NONE	(0x2 << 21)
+#define MFP_PULL_LOW	(0x3 << 21)
+#define MFP_PULL_HIGH	(0x0 << 21)
+#define MFP_PULL_MASK	(0x3 << 21)
+#define MFP_PULL(x)	(((x) >> 21) & 0x3)
+
+#define MFP_CFG_DEFAULT	(MFP_PULL_HIGH | MFP_AF0)
+
+#define MFP_CFG(pin, af)		\
+	((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
+
+#define MFP_CFG_PULL(pin, af, pull)	\
+	((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_PULL_MASK)) |\
+	 (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##pull))
+
+#endif /* ARCH_LPC2K_MFP_H */
diff --git a/arch/arm/mach-lpc2k/mfp.c b/arch/arm/mach-lpc2k/mfp.c
new file mode 100644
index 0000000..6e4779d
--- /dev/null
+++ b/arch/arm/mach-lpc2k/mfp.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Team Embeded VOF
+ *     Ithamar R. Adema <ihamar.adema at team-embedded.nl>
+ *
+ * Based on MFP code from mach-pxa.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mfp.h>
+
+#define PINSEL(bank)	(0x00 + (bank)*4)
+#define PINMODE(bank)	(0x40 + (bank)*4)
+
+struct gpio_desc {
+	unsigned valid:1;
+	unsigned long config;
+};
+
+static struct gpio_desc gpio_desc[MFP_PIN_GPIO159 + 1];
+
+static int __mfp_config_gpio(unsigned gpio, unsigned long c)
+{
+	unsigned bank = gpio >> 4;
+	unsigned shift = (gpio & 0xf) * 2;
+	unsigned val;
+
+	/* Configure alternate function */
+	val = __raw_readl(APB_PINSEL_BASE + PINSEL(bank));
+	if ((val & (3 << shift)) &&
+	    (val & (3 << shift)) != (MFP_AF(c) << shift))
+		pr_warning
+		    ("GPIO%d is already configured (%x), not reconfigured!\n",
+		     gpio, (val & (3 << shift)) >> shift);
+	else {
+		val &= ~(0x3 << shift);
+		val |= MFP_AF(c) << shift;
+		__raw_writel(val, APB_PINSEL_BASE + PINSEL(bank));
+	}
+
+	/* Configuration pullup/dn */
+	val = __raw_readl(APB_PINSEL_BASE + PINMODE(bank));
+	val &= ~(0x3 << shift);
+	val |= MFP_PULL(c) << shift;
+	__raw_writel(val, APB_PINSEL_BASE + PINMODE(bank));
+
+	return 0;
+}
+
+static inline int __mfp_validate(int mfp)
+{
+	int gpio = mfp_to_gpio(mfp);
+
+	if (!gpio_desc[gpio].valid) {
+		pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
+		return -1;
+	}
+
+	return gpio;
+}
+
+void lpc2k_mfp_config(unsigned long *mfp_cfgs, int num)
+{
+	unsigned long flags;
+	unsigned long *c;
+	int i, gpio;
+
+	for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
+
+		gpio = __mfp_validate(MFP_PIN(*c));
+		if (gpio < 0)
+			continue;
+
+		local_irq_save(flags);
+
+		gpio_desc[gpio].config = *c;
+		__mfp_config_gpio(gpio, *c);
+
+		local_irq_restore(flags);
+	}
+}
+
+static int __init lpc2k_mfp_init(void)
+{
+	int i;
+
+	for (i = MFP_PIN_GPIO0; i <= MFP_PIN_GPIO159; i++)
+		gpio_desc[i].valid = 1;
+
+	return 0;
+}
+
+postcore_initcall(lpc2k_mfp_init);
-- 
1.7.1




More information about the linux-arm-kernel mailing list