[PATCH 1/7] pinctrl: enable pxa3xx pinmux
Haojian Zhuang
haojian.zhuang at marvell.com
Fri Nov 25 18:08:58 EST 2011
Support PXA300/PXA310/PXA320/PXA910 pinmux.
Signed-off-by: Haojian Zhuang <haojian.zhuang at marvell.com>
---
drivers/pinctrl/Kconfig | 5 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinmux-pxa3xx.c | 931 +++++++++++++++++++++++++++++++++++++++
3 files changed, 937 insertions(+), 0 deletions(-)
create mode 100644 drivers/pinctrl/pinmux-pxa3xx.c
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e17e2f8..582f72d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -20,6 +20,11 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+config PINMUX_PXA3xx
+ bool "PXA pinmux driver"
+ default y if ARCH_PXA || ARCH_MMP
+ select PINMUX
+
config PINMUX_SIRF
bool "CSR SiRFprimaII pinmux driver"
depends on ARCH_PRIMA2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index bdc548a..a364787 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -4,5 +4,6 @@ ccflags-$(CONFIG_DEBUG_PINMUX) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.o
+obj-$(CONFIG_PINMUX_PXA3xx) += pinmux-pxa3xx.o
obj-$(CONFIG_PINMUX_SIRF) += pinmux-sirf.o
obj-$(CONFIG_PINMUX_U300) += pinmux-u300.o
diff --git a/drivers/pinctrl/pinmux-pxa3xx.c b/drivers/pinctrl/pinmux-pxa3xx.c
new file mode 100644
index 0000000..e4386fa
--- /dev/null
+++ b/drivers/pinctrl/pinmux-pxa3xx.c
@@ -0,0 +1,931 @@
+/*
+ * linux/drivers/pinctrl/pinmux-pxa3xx.c
+ *
+ * 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
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang at marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+#define MFPR_FUNC 7
+#define MFPR_FUNC_MASK (~MFPR_FUNC)
+
+
+enum {
+ PINMUX_PXA300 = 0,
+ PINMUX_PXA310,
+ PINMUX_PXA320,
+ PINMUX_PXA910,
+ PINMUX_MAX,
+};
+
+struct pxa3xx_pin_group {
+ const char *name;
+ const unsigned int *func;
+ const unsigned int *pins;
+ const unsigned int num_pins;
+};
+
+struct pxa3xx_pmx_func {
+ const char *name;
+ const char * const * groups;
+ const unsigned num_groups;
+};
+
+struct pxa3xx_pinmux_info {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ unsigned int phy_base;
+ unsigned int phy_size;
+ void __iomem *virt_base;
+ unsigned int cpuid;
+ struct pxa3xx_pin_group *grp;
+ unsigned int num_grps;
+ struct pxa3xx_pmx_func *func;
+ unsigned int num_funcs;
+};
+
+/* These 135 pins exists in PXA300, PXA310 & PXA320 */
+#define PXA3XX_COMMON_PINS() \
+ PINCTRL_PIN(0, "GPIO0"), PINCTRL_PIN(1, "GPIO1"), \
+ PINCTRL_PIN(2, "GPIO2"), PINCTRL_PIN(3, "GPIO3"), \
+ PINCTRL_PIN(4, "GPIO4"), PINCTRL_PIN(5, "GPIO5"), \
+ PINCTRL_PIN(6, "GPIO6"), PINCTRL_PIN(7, "GPIO7"), \
+ PINCTRL_PIN(8, "GPIO8"), PINCTRL_PIN(9, "GPIO9"), \
+ PINCTRL_PIN(10, "GPIO10"), PINCTRL_PIN(11, "GPIO11"), \
+ PINCTRL_PIN(12, "GPIO12"), PINCTRL_PIN(13, "GPIO13"), \
+ PINCTRL_PIN(14, "GPIO14"), PINCTRL_PIN(15, "GPIO15"), \
+ PINCTRL_PIN(16, "GPIO16"), PINCTRL_PIN(17, "GPIO17"), \
+ PINCTRL_PIN(18, "GPIO18"), PINCTRL_PIN(19, "GPIO19"), \
+ PINCTRL_PIN(20, "GPIO20"), PINCTRL_PIN(21, "GPIO21"), \
+ PINCTRL_PIN(22, "GPIO22"), PINCTRL_PIN(23, "GPIO23"), \
+ PINCTRL_PIN(24, "GPIO24"), PINCTRL_PIN(25, "GPIO25"), \
+ PINCTRL_PIN(26, "GPIO26"), PINCTRL_PIN(27, "GPIO27"), \
+ PINCTRL_PIN(28, "GPIO28"), PINCTRL_PIN(29, "GPIO29"), \
+ PINCTRL_PIN(30, "GPIO30"), PINCTRL_PIN(31, "GPIO31"), \
+ PINCTRL_PIN(32, "GPIO32"), PINCTRL_PIN(33, "GPIO33"), \
+ PINCTRL_PIN(34, "GPIO34"), PINCTRL_PIN(35, "GPIO35"), \
+ PINCTRL_PIN(36, "GPIO36"), PINCTRL_PIN(37, "GPIO37"), \
+ PINCTRL_PIN(38, "GPIO38"), PINCTRL_PIN(39, "GPIO39"), \
+ PINCTRL_PIN(40, "GPIO40"), PINCTRL_PIN(41, "GPIO41"), \
+ PINCTRL_PIN(42, "GPIO42"), PINCTRL_PIN(43, "GPIO43"), \
+ PINCTRL_PIN(44, "GPIO44"), PINCTRL_PIN(45, "GPIO45"), \
+ PINCTRL_PIN(46, "GPIO46"), PINCTRL_PIN(47, "GPIO47"), \
+ PINCTRL_PIN(48, "GPIO48"), PINCTRL_PIN(49, "GPIO49"), \
+ PINCTRL_PIN(50, "GPIO50"), PINCTRL_PIN(51, "GPIO51"), \
+ PINCTRL_PIN(52, "GPIO52"), PINCTRL_PIN(53, "GPIO53"), \
+ PINCTRL_PIN(54, "GPIO54"), PINCTRL_PIN(55, "GPIO55"), \
+ PINCTRL_PIN(56, "GPIO56"), PINCTRL_PIN(57, "GPIO57"), \
+ PINCTRL_PIN(58, "GPIO58"), PINCTRL_PIN(59, "GPIO59"), \
+ PINCTRL_PIN(60, "GPIO60"), PINCTRL_PIN(61, "GPIO61"), \
+ PINCTRL_PIN(62, "GPIO62"), PINCTRL_PIN(63, "GPIO63"), \
+ PINCTRL_PIN(64, "GPIO64"), PINCTRL_PIN(65, "GPIO65"), \
+ PINCTRL_PIN(66, "GPIO66"), PINCTRL_PIN(67, "GPIO67"), \
+ PINCTRL_PIN(68, "GPIO68"), PINCTRL_PIN(69, "GPIO69"), \
+ PINCTRL_PIN(70, "GPIO70"), PINCTRL_PIN(71, "GPIO71"), \
+ PINCTRL_PIN(72, "GPIO72"), PINCTRL_PIN(73, "GPIO73"), \
+ PINCTRL_PIN(74, "GPIO74"), PINCTRL_PIN(75, "GPIO75"), \
+ PINCTRL_PIN(76, "GPIO76"), PINCTRL_PIN(77, "GPIO77"), \
+ PINCTRL_PIN(78, "GPIO78"), PINCTRL_PIN(79, "GPIO79"), \
+ PINCTRL_PIN(80, "GPIO80"), PINCTRL_PIN(81, "GPIO81"), \
+ PINCTRL_PIN(82, "GPIO82"), PINCTRL_PIN(83, "GPIO83"), \
+ PINCTRL_PIN(84, "GPIO84"), PINCTRL_PIN(85, "GPIO85"), \
+ PINCTRL_PIN(86, "GPIO86"), PINCTRL_PIN(87, "GPIO87"), \
+ PINCTRL_PIN(88, "GPIO88"), PINCTRL_PIN(89, "GPIO89"), \
+ PINCTRL_PIN(90, "GPIO90"), PINCTRL_PIN(91, "GPIO91"), \
+ PINCTRL_PIN(92, "GPIO92"), PINCTRL_PIN(93, "GPIO93"), \
+ PINCTRL_PIN(94, "GPIO94"), PINCTRL_PIN(95, "GPIO95"), \
+ PINCTRL_PIN(96, "GPIO96"), PINCTRL_PIN(97, "GPIO97"), \
+ PINCTRL_PIN(98, "GPIO98"), PINCTRL_PIN(99, "GPIO99"), \
+ PINCTRL_PIN(100, "GPIO100"), PINCTRL_PIN(101, "GPIO101"), \
+ PINCTRL_PIN(102, "GPIO102"), PINCTRL_PIN(103, "GPIO103"), \
+ PINCTRL_PIN(104, "GPIO104"), PINCTRL_PIN(105, "GPIO105"), \
+ PINCTRL_PIN(106, "GPIO106"), PINCTRL_PIN(107, "GPIO107"), \
+ PINCTRL_PIN(108, "GPIO108"), PINCTRL_PIN(109, "GPIO109"), \
+ PINCTRL_PIN(110, "GPIO110"), PINCTRL_PIN(111, "GPIO111"), \
+ PINCTRL_PIN(112, "GPIO112"), PINCTRL_PIN(113, "GPIO113"), \
+ PINCTRL_PIN(114, "GPIO114"), PINCTRL_PIN(115, "GPIO115"), \
+ PINCTRL_PIN(116, "GPIO116"), PINCTRL_PIN(117, "GPIO117"), \
+ PINCTRL_PIN(118, "GPIO118"), PINCTRL_PIN(119, "GPIO119"), \
+ PINCTRL_PIN(120, "GPIO120"), PINCTRL_PIN(121, "GPIO121"), \
+ PINCTRL_PIN(122, "GPIO122"), PINCTRL_PIN(123, "GPIO123"), \
+ PINCTRL_PIN(124, "GPIO124"), PINCTRL_PIN(125, "GPIO125"), \
+ PINCTRL_PIN(126, "GPIO126"), PINCTRL_PIN(127, "GPIO127")
+
+#ifdef CONFIG_ARCH_PXA
+static struct pinctrl_pin_desc pxa300_pads[] = {
+ PXA3XX_COMMON_PINS(),
+ PINCTRL_PIN(128, "GPIO0_2"), PINCTRL_PIN(129, "GPIO1_2"),
+ PINCTRL_PIN(130, "GPIO2_2"), PINCTRL_PIN(131, "GPIO3_2"),
+ PINCTRL_PIN(132, "GPIO4_2"), PINCTRL_PIN(133, "GPIO5_2"),
+ PINCTRL_PIN(134, "GPIO6_2"),
+};
+
+static struct pinctrl_pin_desc pxa310_pads[] = {
+ PXA3XX_COMMON_PINS(),
+ PINCTRL_PIN(128, "GPIO0_2"), PINCTRL_PIN(129, "GPIO1_2"),
+ PINCTRL_PIN(130, "GPIO2_2"), PINCTRL_PIN(131, "GPIO3_2"),
+ PINCTRL_PIN(132, "GPIO4_2"), PINCTRL_PIN(133, "GPIO5_2"),
+ PINCTRL_PIN(134, "GPIO6_2"), PINCTRL_PIN(135, "GPIO7_2"),
+ PINCTRL_PIN(136, "GPIO8_2"), PINCTRL_PIN(137, "GPIO9_2"),
+ PINCTRL_PIN(138, "GPIO10_2"),
+};
+
+static struct pinctrl_pin_desc pxa320_pads[] = {
+ PXA3XX_COMMON_PINS(),
+ PINCTRL_PIN(128, "GPIO0_2"), PINCTRL_PIN(129, "GPIO1_2"),
+ PINCTRL_PIN(130, "GPIO2_2"), PINCTRL_PIN(131, "GPIO3_2"),
+ PINCTRL_PIN(132, "GPIO4_2"), PINCTRL_PIN(133, "GPIO5_2"),
+ PINCTRL_PIN(134, "GPIO6_2"), PINCTRL_PIN(135, "GPIO7_2"),
+ PINCTRL_PIN(136, "GPIO8_2"), PINCTRL_PIN(137, "GPIO9_2"),
+ PINCTRL_PIN(138, "GPIO10_2"), PINCTRL_PIN(139, "GPIO11_2"),
+ PINCTRL_PIN(140, "GPIO12_2"), PINCTRL_PIN(141, "GPIO13_2"),
+ PINCTRL_PIN(142, "GPIO14_2"), PINCTRL_PIN(143, "GPIO15_2"),
+ PINCTRL_PIN(144, "GPIO16_2"), PINCTRL_PIN(145, "GPIO17_2"),
+};
+
+/* the sequence follows pxa300_pads[] */
+const static unsigned pxa300_mfpr[] = {
+ 0x0B4, 0x0B8, 0x0BC, 0x27C, 0x280, 0x284, 0x288, 0x28C, 0x290, 0x294,
+ 0x298, 0x29C, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x2B4, 0x2B8, 0x2BC,
+ 0x2C0, 0x2C4, 0x2C8, 0x2CC, 0x2D0, 0x2D4, 0x2D8, 0x400, 0x404, 0x408,
+ 0x40C, 0x410, 0x414, 0x418, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430,
+ 0x434, 0x438, 0x43C, 0x440, 0x444, 0x448, 0x44C, 0x450, 0x454, 0x458,
+ 0x45C, 0x460, 0x464, 0x468, 0x46C, 0x470, 0x474, 0x478, 0x47C, 0x480,
+ 0x484, 0x488, 0x48C, 0x490, 0x494, 0x498, 0x49C, 0x4A0, 0x4A4, 0x4A8,
+ 0x4AC, 0x4B0, 0x4B4, 0x4B8, 0x4BC, 0x4C0, 0x4C4, 0x4C8, 0x4CC, 0x4D0,
+ 0x4D4, 0x4D8, 0x4DC, 0x4E0, 0x4E4, 0x4E8, 0x4EC, 0x4F0, 0x4F4, 0x4F8,
+ 0x4FC, 0x500, 0x504, 0x508, 0x50C, 0x510, 0x514, 0x518, 0x51C, 0x600,
+ 0x604, 0x608, 0x60C, 0x610, 0x614, 0x618, 0x61C, 0x620, 0x624, 0x628,
+ 0x62C, 0x630, 0x634, 0x638, 0x63C, 0x640, 0x644, 0x648, 0x64C, 0x650,
+ 0x654, 0x658, 0x65C, 0x660, 0x664, 0x668, 0x66C, 0x670,
+ /* the below pins can also be configured as GPIO[6:0] */
+ 0x674, 0x678, 0x2DC, 0x2E0, 0x2E4, 0x2E8, 0x2EC,
+};
+
+/* the sequence follows pxa310_pads[] */
+const static unsigned pxa310_mfpr[] = {
+ 0x0B4, 0x0B8, 0x0BC, 0x27C, 0x280, 0x284, 0x288, 0x28C, 0x290, 0x294,
+ 0x298, 0x29C, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x2B4, 0x2B8, 0x2BC,
+ 0x2C0, 0x2C4, 0x2C8, 0x2CC, 0x2D0, 0x2D4, 0x2D8, 0x400, 0x404, 0x408,
+ 0x418, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430, 0x434, 0x438, 0x43C,
+ 0x440, 0x444, 0x448, 0x44C, 0x450, 0x454, 0x458, 0x45C, 0x460, 0x464,
+ 0x468, 0x46C, 0x470, 0x474, 0x478, 0x47C, 0x480, 0x484, 0x488, 0x48C,
+ 0x490, 0x494, 0x498, 0x49C, 0x4A0, 0x4A4, 0x4A8, 0x4AC, 0x4B0, 0x4B4,
+ 0x4B8, 0x4BC, 0x4C0, 0x4C4, 0x4C8, 0x4CC, 0x4D0, 0x4D4, 0x4D8, 0x4DC,
+ 0x4E0, 0x4E4, 0x4E8, 0x4EC, 0x4F0, 0x4F4, 0x4F8, 0x4FC, 0x500, 0x504,
+ 0x508, 0x50C, 0x510, 0x514, 0x518, 0x51C, 0x520, 0x524, 0x528, 0x600,
+ 0x604, 0x608, 0x60C, 0x610, 0x614, 0x618, 0x61C, 0x620, 0x624, 0x628,
+ 0x62C, 0x630, 0x634, 0x638, 0x63C, 0x640, 0x644, 0x648, 0x64C, 0x650,
+ 0x654, 0x658, 0x65C, 0x660, 0x664, 0x668, 0x66C, 0x670,
+ /* the below pins can also be configured as GPIO[10:0] */
+ 0x674, 0x678, 0x2DC, 0x2E0, 0x2E4, 0x2E8, 0x2EC, 0x52C, 0x530, 0x534,
+ 0x538,
+};
+
+/* the sequence follows pxa320_pads[] */
+const static unsigned pxa320_mfpr[] = {
+ 0x124, 0x128, 0x12C, 0x130, 0x134, 0x28C, 0x290, 0x294, 0x298, 0x29C,
+ 0x458, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x2B4, 0x2B8, 0x2BC, 0x2C0,
+ 0x2C4, 0x2C8, 0x2CC, 0x2D0, 0x2D4, 0x2D8, 0x2DC, 0x400, 0x404, 0x408,
+ 0x40C, 0x410, 0x414, 0x418, 0x41C, 0x420, 0x424, 0x428, 0x42C, 0x430,
+ 0x434, 0x438, 0x43C, 0x440, 0x444, 0x448, 0x44C, 0x450, 0x454, 0x45C,
+ 0x460, 0x464, 0x468, 0x46C, 0x470, 0x474, 0x478, 0x47C, 0x480, 0x484,
+ 0x488, 0x48C, 0x490, 0x4B4, 0x4B8, 0x4BC, 0x4C0, 0x4C4, 0x4C8, 0x4CC,
+ 0x4D0, 0x4D4, 0x4D8, 0x4DC, 0x4F0, 0x4F4, 0x4F8, 0x4FC, 0x500, 0x504,
+ 0x508, 0x50C, 0x510, 0x514, 0x518, 0x51C, 0x520, 0x524, 0x528, 0x52C,
+ 0x530, 0x534, 0x538, 0x53C, 0x540, 0x544, 0x548, 0x54C, 0x550, 0x600,
+ 0x604, 0x608, 0x60C, 0x610, 0x614, 0x618, 0x61C, 0x620, 0x624, 0x628,
+ 0x62C, 0x630, 0x634, 0x638, 0x63C, 0x640, 0x644, 0x648, 0x64C, 0x650,
+ 0x654, 0x658, 0x65C, 0x660, 0x664, 0x668, 0x66C, 0x670,
+ /* the below pins can also be configured as GPIO[17:0] */
+ 0x674, 0x678, 0x67C, 0x680, 0x684, 0x688, 0x494, 0x498, 0x49C, 0x4A0,
+ 0x4A4, 0x4A8, 0x4AC, 0x4B0, 0x4E0, 0x4E4, 0x4E8, 0x4EC,
+};
+
+/*
+ * pxa300_xxx_pins and pxa300_xxx_func are pairs.
+ * One is pin number, the other is function number.
+ */
+static const unsigned pxa300_uart1_0_pins[] = {30, 31, 32, 33, 34, 35, 36, 37};
+static const unsigned pxa300_uart1_0_func[] = {2, 2, 2, 2, 2, 2, 2, 2};
+static const unsigned pxa300_uart1_1_pins[] = {77, 78, 79, 81, 83, 84};
+static const unsigned pxa300_uart1_1_func[] = {1, 1, 1, 1, 1, 1};
+static const unsigned pxa300_uart2_pins[] = {111, 112, 113, 114};
+static const unsigned pxa300_uart2_func[] = {1, 1, 1, 1};
+static const unsigned pxa300_uart3_0_pins[] = {107, 108, 109, 110};
+static const unsigned pxa300_uart3_0_func[] = {1, 1, 1, 1};
+static const unsigned pxa300_uart3_1_pins[] = {109, 110};
+static const unsigned pxa300_uart3_1_func[] = {1, 1};
+static const unsigned pxa300_lcd0_pins[] = {54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 127};
+static const unsigned pxa300_lcd0_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1};
+/* not include LCD_CS */
+static const unsigned pxa300_lcd1_pins[] = {54, 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76};
+static const unsigned pxa300_lcd1_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
+/* pxa300_ac97[] not include SDATA_IN_1 pin */
+static const unsigned pxa300_ac97_pins[] = {23, 24, 25, 27, 28, 29};
+static const unsigned pxa300_ac97_func[] = {1, 1, 1, 1, 1, 1};
+static const unsigned pxa300_ssp1_pins[] = {85, 56, 87, 88, 89, 90};
+static const unsigned pxa300_ssp1_func[] = {1, 1, 1, 1, 1, 1};
+/* SSPSCLK2 & SSPTXD2 */
+static const unsigned pxa300_ssp2_0_pins[] = {25, 27};
+static const unsigned pxa300_ssp2_0_func[] = {2, 2};
+/* SSPSCLK2, SSPSFRM2, SSPTXD2 & SSPEXTCLK2 */
+static const unsigned pxa300_ssp2_1_pins[] = {25, 26, 27, 29};
+static const unsigned pxa300_ssp2_1_func[] = {2, 2, 2, 2};
+static const unsigned pxa300_ssp3_pins[] = {91, 92, 93, 94};
+static const unsigned pxa300_ssp3_func[] = {1, 1, 1, 1};
+/* DKIN[1:0], MKIN[7:0] & MKOUT[7:0] */
+static const unsigned pxa300_key0_pins[] = {107, 108, 115, 116, 117, 118,
+ 119, 120, 130, 131, 121, 122, 123, 124, 125, 132, 133, 134};
+static const unsigned pxa300_key0_func[] = {2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1};
+/* DKIN[1:0], MKIN[5:0] & MKOUT[4:0] */
+static const unsigned pxa300_key1_pins[] = {107, 108, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125};
+static const unsigned pxa300_key1_func[] = {2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1};
+/* MKIN[7:0] & MKOUT[5:0] */
+static const unsigned pxa300_key2_pins[] = {115, 116, 117, 118, 119, 120, 130,
+ 131, 121, 122, 123, 124, 125, 132};
+static const unsigned pxa300_key2_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1};
+static const unsigned pxa300_mmc1_0_pins[] = {3, 4, 5, 6, 7, 8};
+static const unsigned pxa300_mmc1_0_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa300_mmc1_1_pins[] = {3, 4, 5, 6, 7, 14};
+static const unsigned pxa300_mmc1_1_func[] = {4, 4, 4, 4, 4, 5};
+static const unsigned pxa300_mmc2_pins[] = {9, 10, 11, 12, 13, 14};
+static const unsigned pxa300_mmc2_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa300_usbh_pins[] = {128, 129};
+static const unsigned pxa300_usbh_func[] = {1, 1};
+static const unsigned pxa300_usbp3_pins[] = {77, 78, 79, 80, 81, 82};
+static const unsigned pxa300_usbp3_func[] = {2, 2, 2, 2, 2, 2};
+static const unsigned pxa300_i2c_pins[] = {21, 22};
+static const unsigned pxa300_i2c_func[] = {1, 1};
+static const unsigned pxa300_smc_pins[] = {2};
+static const unsigned pxa300_smc_func[] = {1};
+static const unsigned pxa300_pwm3_pins[] = {20};
+static const unsigned pxa300_pwm3_func[] = {1};
+
+static struct pxa3xx_pin_group pxa300_pin_groups[] = {
+ {"ffuart0", pxa300_uart1_0_func, ARRAY_AND_SIZE(pxa300_uart1_0_pins)},
+ {"ffuart1", pxa300_uart1_0_func, ARRAY_AND_SIZE(pxa300_uart1_1_pins)},
+ {"btuart", pxa300_uart2_func, ARRAY_AND_SIZE(pxa300_uart2_pins)},
+ {"stuart0", pxa300_uart3_0_func, ARRAY_AND_SIZE(pxa300_uart3_0_pins)},
+ {"stuart1", pxa300_uart3_1_func, ARRAY_AND_SIZE(pxa300_uart3_1_pins)},
+ {"lcd0", pxa300_lcd0_func, ARRAY_AND_SIZE(pxa300_lcd0_pins)},
+ {"lcd1", pxa300_lcd1_func, ARRAY_AND_SIZE(pxa300_lcd1_pins)},
+ {"ac97", pxa300_ac97_func, ARRAY_AND_SIZE(pxa300_ac97_pins)},
+ {"ssp2_0", pxa300_ssp2_0_func, ARRAY_AND_SIZE(pxa300_ssp2_0_pins)},
+ {"ssp2_1", pxa300_ssp2_1_func, ARRAY_AND_SIZE(pxa300_ssp2_1_pins)},
+ {"ssp3", pxa300_ssp3_func, ARRAY_AND_SIZE(pxa300_ssp3_pins)},
+ {"key0", pxa300_key0_func, ARRAY_AND_SIZE(pxa300_key0_pins)},
+ {"key1", pxa300_key1_func, ARRAY_AND_SIZE(pxa300_key1_pins)},
+ {"key2", pxa300_key2_func, ARRAY_AND_SIZE(pxa300_key2_pins)},
+ {"mmc1_0", pxa300_mmc1_0_func, ARRAY_AND_SIZE(pxa300_mmc1_0_pins)},
+ {"mmc1_1", pxa300_mmc1_1_func, ARRAY_AND_SIZE(pxa300_mmc1_1_pins)},
+ {"mmc2", pxa300_mmc2_func, ARRAY_AND_SIZE(pxa300_mmc2_pins)},
+ {"usbh", pxa300_usbh_func, ARRAY_AND_SIZE(pxa300_usbh_pins)},
+ {"usbp3", pxa300_usbp3_func, ARRAY_AND_SIZE(pxa300_usbp3_pins)},
+ {"i2c", pxa300_i2c_func, ARRAY_AND_SIZE(pxa300_i2c_pins)},
+ {"smc", pxa300_smc_func, ARRAY_AND_SIZE(pxa300_smc_pins)},
+ {"pwm3", pxa300_pwm3_func, ARRAY_AND_SIZE(pxa300_pwm3_pins)},
+};
+
+static const char * const pxa300_uart0_grps[] = {"ffuart0", "ffuart1"};
+static const char * const pxa300_uart1_grps[] = {"btuart"};
+static const char * const pxa300_uart2_grps[] = {"stuart0", "stuart1"};
+static const char * const pxa300_lcd_grps[] = {"lcd0", "lcd1"};
+static const char * const pxa300_ac97_grps[] = {"ac97"};
+static const char * const pxa300_ssp2_grps[] = {"ssp2_0", "ssp2_1"};
+static const char * const pxa300_ssp3_grps[] = {"ssp3"};
+static const char * const pxa300_key_grps[] = {"key0", "key1", "key2"};
+static const char * const pxa300_mmc1_grps[] = {"mmc1_0", "mmc1_1"};
+static const char * const pxa300_mmc2_grps[] = {"mmc2"};
+static const char * const pxa300_usbh_grps[] = {"usbh"};
+static const char * const pxa300_usbp3_grps[] = {"usbp3"};
+static const char * const pxa300_i2c_grps[] = {"i2c"};
+static const char * const pxa300_smc_grps[] = {"smc"};
+static const char * const pxa300_pwm3_grps[] = {"pwm3"};
+
+static struct pxa3xx_pmx_func pxa300_pmx_functions[] = {
+ {"uart0", ARRAY_AND_SIZE(pxa300_uart0_grps)},
+ {"uart1", ARRAY_AND_SIZE(pxa300_uart1_grps)},
+ {"uart2", ARRAY_AND_SIZE(pxa300_uart2_grps)},
+ {"lcd", ARRAY_AND_SIZE(pxa300_lcd_grps)},
+ {"ac97", ARRAY_AND_SIZE(pxa300_ac97_grps)},
+ {"ssp2", ARRAY_AND_SIZE(pxa300_ssp2_grps)},
+ {"ssp3", ARRAY_AND_SIZE(pxa300_ssp3_grps)},
+ {"key", ARRAY_AND_SIZE(pxa300_key_grps)},
+ {"mmc1", ARRAY_AND_SIZE(pxa300_mmc1_grps)},
+ {"mmc2", ARRAY_AND_SIZE(pxa300_mmc2_grps)},
+ {"usbh", ARRAY_AND_SIZE(pxa300_usbh_grps)},
+ {"usbp3", ARRAY_AND_SIZE(pxa300_usbp3_grps)},
+ {"i2c", ARRAY_AND_SIZE(pxa300_i2c_grps)},
+ {"smc", ARRAY_AND_SIZE(pxa300_smc_grps)},
+ {"pwm3", ARRAY_AND_SIZE(pxa300_pwm3_grps)},
+};
+
+/* RxD, TxD, CTS, RTS of UART1 */
+static const unsigned pxa310_uart1_2_pins[] = {99, 100, 101, 106};
+static const unsigned pxa310_uart1_2_func[] = {1, 1, 1, 1};
+static const unsigned pxa310_mmc3_pins[] = {135, 136, 137, 138, 103, 105};
+static const unsigned pxa310_mmc3_func[] = {1, 1, 1, 1, 2, 2};
+static const unsigned pxa310_ulpi_pins[] = {30, 31, 32, 33, 34, 35, 36,
+ 37, 38};
+static const unsigned pxa310_ulpi_func[] = {3, 3, 3, 3, 3, 3, 3, 3, 1};
+
+static struct pxa3xx_pin_group pxa310_pin_groups[] = {
+ {"ffuart2", pxa310_uart1_2_func, ARRAY_AND_SIZE(pxa310_uart1_2_pins)},
+ {"btuart", pxa300_uart2_func, ARRAY_AND_SIZE(pxa300_uart2_pins)},
+ {"stuart0", pxa300_uart3_0_func, ARRAY_AND_SIZE(pxa300_uart3_0_pins)},
+ {"stuart1", pxa300_uart3_1_func, ARRAY_AND_SIZE(pxa300_uart3_1_pins)},
+ {"lcd0", pxa300_lcd0_func, ARRAY_AND_SIZE(pxa300_lcd0_pins)},
+ {"lcd1", pxa300_lcd1_func, ARRAY_AND_SIZE(pxa300_lcd1_pins)},
+ {"ac97", pxa300_ac97_func, ARRAY_AND_SIZE(pxa300_ac97_pins)},
+ {"ssp2", pxa300_ssp2_0_func, ARRAY_AND_SIZE(pxa300_ssp2_0_pins)},
+ {"ssp3", pxa300_ssp3_func, ARRAY_AND_SIZE(pxa300_ssp3_pins)},
+ {"key0", pxa300_key0_func, ARRAY_AND_SIZE(pxa300_key0_pins)},
+ {"key1", pxa300_key1_func, ARRAY_AND_SIZE(pxa300_key1_pins)},
+ {"key2", pxa300_key2_func, ARRAY_AND_SIZE(pxa300_key2_pins)},
+ {"mmc1_0", pxa300_mmc1_0_func, ARRAY_AND_SIZE(pxa300_mmc1_0_pins)},
+ {"mmc1_1", pxa300_mmc1_1_func, ARRAY_AND_SIZE(pxa300_mmc1_1_pins)},
+ {"mmc2", pxa300_mmc2_func, ARRAY_AND_SIZE(pxa300_mmc2_pins)},
+ {"mmc3", pxa310_mmc3_func, ARRAY_AND_SIZE(pxa310_mmc3_pins)},
+ {"usbh", pxa300_usbh_func, ARRAY_AND_SIZE(pxa300_usbh_pins)},
+ {"ulpi", pxa310_ulpi_func, ARRAY_AND_SIZE(pxa310_ulpi_pins)},
+ {"usbp3", pxa300_usbp3_func, ARRAY_AND_SIZE(pxa300_usbp3_pins)},
+ {"i2c", pxa300_i2c_func, ARRAY_AND_SIZE(pxa300_i2c_pins)},
+ {"smc", pxa300_smc_func, ARRAY_AND_SIZE(pxa300_smc_pins)},
+ {"pwm3", pxa300_pwm3_func, ARRAY_AND_SIZE(pxa300_pwm3_pins)},
+};
+
+static const char * const pxa310_uart0_grps[] = {"ffuart2"};
+static const char * const pxa310_mmc3_grps[] = {"mmc3"};
+static const char * const pxa310_ulpi_grps[] = {"ulpi"};
+
+static struct pxa3xx_pmx_func pxa310_pmx_functions[] = {
+ {"uart1", ARRAY_AND_SIZE(pxa300_uart1_grps)},
+ {"uart2", ARRAY_AND_SIZE(pxa300_uart2_grps)},
+ {"lcd", ARRAY_AND_SIZE(pxa300_lcd_grps)},
+ {"ac97", ARRAY_AND_SIZE(pxa300_ac97_grps)},
+ {"ssp3", ARRAY_AND_SIZE(pxa300_ssp3_grps)},
+ {"key", ARRAY_AND_SIZE(pxa300_key_grps)},
+ {"mmc1", ARRAY_AND_SIZE(pxa300_mmc1_grps)},
+ {"mmc2", ARRAY_AND_SIZE(pxa300_mmc2_grps)},
+ {"usbh", ARRAY_AND_SIZE(pxa300_usbh_grps)},
+ {"usbp3", ARRAY_AND_SIZE(pxa300_usbp3_grps)},
+ {"i2c", ARRAY_AND_SIZE(pxa300_i2c_grps)},
+ {"smc", ARRAY_AND_SIZE(pxa300_smc_grps)},
+ {"pwm3", ARRAY_AND_SIZE(pxa300_pwm3_grps)},
+ /* new in PXA310 */
+ {"uart0", ARRAY_AND_SIZE(pxa310_uart0_grps)},
+ {"mmc3", ARRAY_AND_SIZE(pxa310_mmc3_grps)},
+ {"ulpi", ARRAY_AND_SIZE(pxa310_ulpi_grps)},
+};
+
+static const unsigned pxa320_lcd_pins[] = {134, 135, 136, 137, 138, 139,
+ 140, 141, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 142, 143, 144, 145};
+static const unsigned pxa320_lcd_func[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1};
+static const unsigned pxa320_uart0_pins[] = {41, 42, 43, 44, 45, 46, 47, 48};
+static const unsigned pxa320_uart0_func[] = {2, 2, 2, 2, 2, 2, 2, 2};
+/* not include SDATA_IN_1 */
+static const unsigned pxa320_ac97_pins[] = {34, 35, 37, 38, 39, 40};
+static const unsigned pxa320_ac97_func[] = {1, 1, 1, 1, 1, 1};
+static const unsigned pxa320_ssp3_pins[] = {89, 90, 91, 92};
+static const unsigned pxa320_ssp3_func[] = {1, 1, 1, 1};
+static const unsigned pxa320_i2c_pins[] = {32, 33};
+static const unsigned pxa320_i2c_func[] = {1, 1};
+/* DKIN[1:0], MKIN[7:0] & MKOUT[7:0] */
+static const unsigned pxa320_key_pins[] = {105, 106, 113, 114, 115, 116, 117,
+ 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 133};
+static const unsigned pxa320_key_func[] = {2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1};
+static const unsigned pxa320_smc_pins[] = {4};
+static const unsigned pxa320_smc_func[] = {1};
+static const unsigned pxa320_mmc1_pins[] = {18, 19, 20, 21, 22, 23};
+static const unsigned pxa320_mmc1_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa320_mmc2_pins[] = {24, 25, 26, 27, 28, 29};
+static const unsigned pxa320_mmc2_func[] = {4, 4, 4, 4, 4, 4};
+static const unsigned pxa320_usbh_pins[] = {130, 131};
+static const unsigned pxa320_usbh_func[] = {1, 1};
+static const unsigned pxa320_pwm3_pins[] = {14};
+static const unsigned pxa320_pwm3_func[] = {1};
+static const unsigned pxa320_usim_pins[] = {15, 17};
+static const unsigned pxa320_usim_func[] = {1};
+
+static struct pxa3xx_pin_group pxa320_pin_groups[] = {
+ {"lcd", pxa320_lcd_func, ARRAY_AND_SIZE(pxa320_lcd_pins)},
+ {"ffuart", pxa320_uart0_func, ARRAY_AND_SIZE(pxa320_uart0_pins)},
+ {"ac97", pxa320_ac97_func, ARRAY_AND_SIZE(pxa320_ac97_pins)},
+ {"ssp3", pxa320_ssp3_func, ARRAY_AND_SIZE(pxa320_ssp3_pins)},
+ {"i2c", pxa320_i2c_func, ARRAY_AND_SIZE(pxa320_i2c_pins)},
+ {"key", pxa320_key_func, ARRAY_AND_SIZE(pxa320_key_pins)},
+ {"smc", pxa320_smc_func, ARRAY_AND_SIZE(pxa320_smc_pins)},
+ {"mmc1", pxa320_mmc1_func, ARRAY_AND_SIZE(pxa320_mmc1_pins)},
+ {"mmc2", pxa320_mmc2_func, ARRAY_AND_SIZE(pxa320_mmc2_pins)},
+ {"usbh", pxa320_usbh_func, ARRAY_AND_SIZE(pxa320_usbh_pins)},
+ {"pwm3", pxa320_pwm3_func, ARRAY_AND_SIZE(pxa320_pwm3_pins)},
+ {"usim", pxa320_usim_func, ARRAY_AND_SIZE(pxa320_usim_pins)},
+};
+
+static const char * const pxa320_lcd_grps[] = {"lcd"};
+static const char * const pxa320_uart0_grps[] = {"ffuart"};
+static const char * const pxa320_ac97_grps[] = {"ac97"};
+static const char * const pxa320_ssp3_grps[] = {"ssp3"};
+static const char * const pxa320_i2c_grps[] = {"i2c"};
+static const char * const pxa320_key_grps[] = {"key"};
+static const char * const pxa320_smc_grps[] = {"smc"};
+static const char * const pxa320_mmc1_grps[] = {"mmc1"};
+static const char * const pxa320_mmc2_grps[] = {"mmc2"};
+static const char * const pxa320_usbh_grps[] = {"usbh"};
+static const char * const pxa320_pwm3_grps[] = {"pwm3"};
+static const char * const pxa320_usim_grps[] = {"usim"};
+
+static struct pxa3xx_pmx_func pxa320_pmx_functions[] = {
+ {"lcd", ARRAY_AND_SIZE(pxa320_lcd_grps)},
+ {"uart0", ARRAY_AND_SIZE(pxa320_uart0_grps)},
+ {"ac97", ARRAY_AND_SIZE(pxa320_ac97_grps)},
+ {"ssp3", ARRAY_AND_SIZE(pxa320_ssp3_grps)},
+ {"i2c", ARRAY_AND_SIZE(pxa320_i2c_grps)},
+ {"key", ARRAY_AND_SIZE(pxa320_key_grps)},
+ {"smc", ARRAY_AND_SIZE(pxa320_smc_grps)},
+ {"mmc1", ARRAY_AND_SIZE(pxa320_mmc1_grps)},
+ {"mmc2", ARRAY_AND_SIZE(pxa320_mmc2_grps)},
+ {"usbh", ARRAY_AND_SIZE(pxa320_usbh_grps)},
+ {"pwm3", ARRAY_AND_SIZE(pxa320_pwm3_grps)},
+ {"usim", ARRAY_AND_SIZE(pxa320_usim_grps)},
+};
+#endif
+
+#ifdef CONFIG_ARCH_MMP
+static struct pinctrl_pin_desc pxa910_pads[] = {
+ PXA3XX_COMMON_PINS(),
+};
+
+const static unsigned pxa910_mfpr[] = {
+ 0x0DC, 0x0E0, 0x0E4, 0x0E8, 0x0EC, 0x0F0, 0x0F4, 0x0F8, 0x0FC, 0x100,
+ 0x104, 0x108, 0x10C, 0x110, 0x114, 0x118, 0x11C, 0x120, 0x124, 0x128,
+ 0x12C, 0x130, 0x134, 0x138, 0x13C, 0x140, 0x144, 0x148, 0x14C, 0x150,
+ 0x154, 0x158, 0x15C, 0x160, 0x164, 0x168, 0x16C, 0x170, 0x174, 0x178,
+ 0x17C, 0x180, 0x184, 0x188, 0x18C, 0x190, 0x194, 0x198, 0x19C, 0x1A0,
+ 0x1A4, 0x1A8, 0x1AC, 0x1B0, 0x1B4, 0x2F0, 0x2F4, 0x2F8, 0x2FC, 0x300,
+ 0x304, 0x308, 0x30C, 0x310, 0x314, 0x318, 0x31C, 0x1B8, 0x1BC, 0x1C0,
+ 0x1C4, 0x1C8, 0x1CC, 0x1D0, 0x1D4, 0x1D8, 0x1DC, 0x1E0, 0x1E4, 0x1E8,
+ 0x1EC, 0x1F0, 0x1F4, 0x1F8, 0x1FC, 0x200, 0x204, 0x208, 0x20C, 0x210,
+ 0x214, 0x218, 0x21C, 0x220, 0x224, 0x228, 0x22C, 0x230, 0x234, 0x0B0,
+ 0x238, 0x23C, 0x240, 0x244, 0x248, 0x24C, 0x250, 0x254, 0x258, 0x25C,
+ 0x298, 0x29C, 0x2A0, 0x2A4, 0x2A8, 0x2AC, 0x2B0, 0x0B4, 0x0B8, 0x0BC,
+ 0x0C0, 0x32C, 0x0C8, 0x0CC, 0x0D0, 0x0D4, 0x06C, 0x070,
+};
+
+static const unsigned pxa910_uart2_pins[] = {47, 48};
+static const unsigned pxa910_uart2_func[] = {6, 6};
+
+static struct pxa3xx_pin_group pxa910_pin_groups[] = {
+ {"uart2", pxa910_uart2_func, ARRAY_AND_SIZE(pxa910_uart2_pins)},
+};
+
+static const char * const pxa910_uart2_grps[] = {"uart2"};
+
+static struct pxa3xx_pmx_func pxa910_pmx_functions[] = {
+ {"uart2", ARRAY_AND_SIZE(pxa910_uart2_grps)},
+};
+#endif
+
+static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector > info->num_grps)
+ return -EINVAL;
+ return 0;
+}
+
+static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
+ unsigned selector)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector >= info->num_grps)
+ return NULL;
+ return info->grp[selector].name;
+}
+
+static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
+ unsigned selector,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector > info->num_grps)
+ return -EINVAL;
+ *pins = info->grp[selector].pins;
+ *num_pins = info->grp[selector].num_pins;
+ return 0;
+}
+
+static struct pinctrl_ops pxa3xx_pctrl_ops = {
+ .list_groups = pxa3xx_list_groups,
+ .get_group_name = pxa3xx_get_group_name,
+ .get_group_pins = pxa3xx_get_group_pins,
+};
+
+static int pxa3xx_get_gpio_func(unsigned int cpuid, unsigned int gpio)
+{
+ int ret = 0;
+
+ switch (cpuid) {
+#ifdef CONFIG_ARCH_PXA
+ case PINMUX_PXA300:
+ case PINMUX_PXA310:
+ if (gpio == 50)
+ ret = 2;
+ else if (gpio == 49 || gpio == 51 || gpio == 53)
+ ret = 3;
+ break;
+ case PINMUX_PXA320:
+ if (gpio == 56 || (gpio > 58 && gpio < 63))
+ goto out;
+ break;
+#endif
+#ifdef CONFIG_ARCH_MMP
+ case PINMUX_PXA910:
+ if ((gpio > 116 && gpio < 121) || gpio == 122 || gpio == 123 ||
+ gpio == 125 || gpio == 99 || gpio == 58 || gpio == 59)
+ ret = 1;
+ break;
+#endif
+ default:
+ goto out;
+ }
+ return ret & MFPR_FUNC;
+out:
+ return -1;
+}
+
+static int pxa3xx_get_mfpr(unsigned int cpuid, unsigned int pin)
+{
+ int ret;
+ switch (cpuid) {
+#ifdef CONFIG_ARCH_PXA
+ case PINMUX_PXA300:
+ if (pin > ARRAY_SIZE(pxa300_mfpr))
+ goto out;
+ ret = pxa300_mfpr[pin];
+ break;
+ case PINMUX_PXA310:
+ if (pin > ARRAY_SIZE(pxa310_mfpr))
+ goto out;
+ ret = pxa310_mfpr[pin];
+ break;
+ case PINMUX_PXA320:
+ if (pin > ARRAY_SIZE(pxa320_mfpr))
+ goto out;
+ ret = pxa320_mfpr[pin];
+ break;
+#endif
+#ifdef CONFIG_ARCH_MMP
+ case PINMUX_PXA910:
+ if (pin > ARRAY_SIZE(pxa910_mfpr))
+ goto out;
+ ret = pxa910_mfpr[pin];
+#endif
+ default:
+ goto out;
+ }
+ return ret;
+out:
+ return -EINVAL;
+}
+
+static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ unsigned int data;
+ int mfpr, pin_func, gpio;
+
+ /* convert pin to gpio */
+ gpio = pin - range->pin_base + range->base;
+ pin_func = pxa3xx_get_gpio_func(info->cpuid, gpio);
+ if (pin_func < 0)
+ goto out;
+ mfpr = pxa3xx_get_mfpr(info->cpuid, pin);
+ if (mfpr < 0)
+ goto out;
+
+ /* write gpio function into mfpr register */
+ data = readl_relaxed(info->virt_base + mfpr) & MFPR_FUNC_MASK;
+ data |= pin_func;
+ writel_relaxed(data, info->virt_base + mfpr);
+ return 0;
+out:
+ return -EINVAL;
+}
+
+static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
+ unsigned group)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ struct pxa3xx_pin_group *pin_grp = &info->grp[group];
+ unsigned int data, pin_func;
+ int i, mfpr;
+
+ for (i = 0; i < pin_grp->num_pins; i++) {
+ mfpr = pxa3xx_get_mfpr(info->cpuid, pin_grp->pins[i]);
+ if (mfpr < 0) {
+ dev_err(info->dev, "error pin:%d mfpr offset:%x\n",
+ pin_grp->pins[i], mfpr);
+ goto out;
+ }
+ pin_func = pin_grp->func[i];
+ data = readl_relaxed(info->virt_base + mfpr);
+ data &= MFPR_FUNC_MASK;
+ data |= pin_func;
+ writel_relaxed(data, info->virt_base + mfpr);
+ }
+ return 0;
+out:
+ return -EINVAL;
+}
+
+static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
+ unsigned group)
+{
+}
+
+static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (func > info->num_funcs)
+ return -EINVAL;
+ return 0;
+}
+
+static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
+ unsigned func)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ return info->func[func].name;
+}
+
+static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ *groups = info->func[func].groups;
+ *num_groups = info->func[func].num_groups;
+ return 0;
+}
+
+static struct pinmux_ops pxa3xx_pmx_ops = {
+ .list_functions = pxa3xx_pmx_list_func,
+ .get_function_name = pxa3xx_pmx_get_func_name,
+ .get_function_groups = pxa3xx_pmx_get_groups,
+ .enable = pxa3xx_pmx_enable,
+ .disable = pxa3xx_pmx_disable,
+ .gpio_request_enable = pxa3xx_pmx_request_gpio,
+};
+
+#ifdef CONFIG_ARCH_PXA
+static struct pinctrl_desc pxa300_pctrl_desc = {
+ .name = "pxa300-pinctrl",
+ .pins = pxa300_pads,
+ .npins = ARRAY_SIZE(pxa300_pads),
+ .maxpin = 260,
+ .pctlops = &pxa3xx_pctrl_ops,
+ .pmxops = &pxa3xx_pmx_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_desc pxa310_pctrl_desc = {
+ .name = "pxa310-pinctrl",
+ .pins = pxa310_pads,
+ .npins = ARRAY_SIZE(pxa310_pads),
+ .maxpin = 260,
+ .pctlops = &pxa3xx_pctrl_ops,
+ .pmxops = &pxa3xx_pmx_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_desc pxa320_pctrl_desc = {
+ .name = "pxa320-pinctrl",
+ .pins = pxa320_pads,
+ .npins = ARRAY_SIZE(pxa320_pads),
+ .maxpin = 260,
+ .pctlops = &pxa3xx_pctrl_ops,
+ .pmxops = &pxa3xx_pmx_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_gpio_range pxa300_gpio_ranges[] = {
+ {
+ .name = "gpio",
+ .id = 0,
+ .base = 0,
+ .pin_base = 0,
+ .npins = 128,
+ }, {
+ .name = "gpio",
+ .id = 1,
+ .base = 0,
+ .pin_base = 128,
+ .npins = 7,
+ },
+};
+
+static struct pinctrl_gpio_range pxa310_gpio_ranges[] = {
+ {
+ .name = "gpio",
+ .id = 0,
+ .base = 0,
+ .pin_base = 0,
+ .npins = 128,
+ }, {
+ .name = "gpio",
+ .id = 1,
+ .base = 0,
+ .pin_base = 128,
+ .npins = 11,
+ },
+};
+
+static struct pinctrl_gpio_range pxa320_gpio_ranges[] = {
+ {
+ .name = "gpio",
+ .id = 0,
+ .base = 0,
+ .pin_base = 0,
+ .npins = 128,
+ }, {
+ .name = "gpio",
+ .id = 1,
+ .base = 0,
+ .pin_base = 128,
+ .npins = 18,
+ },
+};
+#endif
+
+#ifdef CONFIG_ARCH_MMP
+static struct pinctrl_desc pxa910_pctrl_desc = {
+ .name = "pxa910-pinctrl",
+ .pins = pxa910_pads,
+ .npins = ARRAY_SIZE(pxa910_pads),
+ .maxpin = 260,
+ .pctlops = &pxa3xx_pctrl_ops,
+ .pmxops = &pxa3xx_pmx_ops,
+ .owner = THIS_MODULE,
+};
+
+static struct pinctrl_gpio_range pxa910_gpio_ranges[] = {
+ {
+ .name = "gpio",
+ .id = 0,
+ .base = 0,
+ .pin_base = 0,
+ .npins = 128,
+ },
+};
+#endif
+
+static int __devinit pxa3xx_pinmux_probe(struct platform_device *pdev)
+{
+ struct pxa3xx_pinmux_info *info;
+ struct pinctrl_gpio_range *range = NULL;
+ struct resource *res;
+ int ret, i, range_num;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ return -ENOENT;
+ }
+ info = devm_kzalloc(&pdev->dev, sizeof(struct pxa3xx_pinmux_info),
+ GFP_KERNEL);
+ if (!info) {
+ return -ENOMEM;
+ }
+ info->phy_base = res->start;
+ info->phy_size = resource_size(res);
+ info->virt_base = ioremap(info->phy_base, info->phy_size);
+ if (!info->virt_base) {
+ ret = -ENOMEM;
+ goto out_remap;
+ }
+#ifdef CONFIG_ARCH_PXA
+ if (cpu_is_pxa300()) {
+ info->cpuid = PINMUX_PXA300;
+ info->grp = pxa300_pin_groups;
+ info->func = pxa300_pmx_functions;
+ info->num_grps = ARRAY_SIZE(pxa300_pin_groups);
+ info->num_funcs = ARRAY_SIZE(pxa300_pmx_functions);
+ info->pctl = pinctrl_register(&pxa300_pctrl_desc, &pdev->dev,
+ info);
+ range = pxa300_gpio_ranges;
+ range_num = ARRAY_SIZE(pxa300_gpio_ranges);
+ } else if (cpu_is_pxa310()) {
+ info->cpuid = PINMUX_PXA310;
+ info->grp = pxa310_pin_groups;
+ info->func = pxa310_pmx_functions;
+ info->num_grps = ARRAY_SIZE(pxa310_pin_groups);
+ info->num_funcs = ARRAY_SIZE(pxa310_pmx_functions);
+ info->pctl = pinctrl_register(&pxa310_pctrl_desc, &pdev->dev,
+ info);
+ range = pxa310_gpio_ranges;
+ range_num = ARRAY_SIZE(pxa310_gpio_ranges);
+ } else if (cpu_is_pxa320()) {
+ info->cpuid = PINMUX_PXA320;
+ info->grp = pxa320_pin_groups;
+ info->func = pxa320_pmx_functions;
+ info->num_grps = ARRAY_SIZE(pxa320_pin_groups);
+ info->num_funcs = ARRAY_SIZE(pxa320_pmx_functions);
+ info->pctl = pinctrl_register(&pxa320_pctrl_desc, &pdev->dev,
+ info);
+ range = pxa320_gpio_ranges;
+ range_num = ARRAY_SIZE(pxa320_gpio_ranges);
+ }
+#endif
+#ifdef CONFIG_ARCH_MMP
+ if (cpu_is_pxa910()) {
+ info->cpuid = PINMUX_PXA910;
+ info->grp = pxa910_pin_groups;
+ info->func = pxa910_pmx_functions;
+ info->num_grps = ARRAY_SIZE(pxa910_pin_groups);
+ info->num_funcs = ARRAY_SIZE(pxa910_pmx_functions);
+ info->pctl = pinctrl_register(&pxa910_pctrl_desc, &pdev->dev,
+ info);
+ range = pxa910_gpio_ranges;
+ range_num = ARRAY_SIZE(pxa910_gpio_ranges);
+ }
+#endif
+ if (!info->pctl) {
+ dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
+ ret = -EINVAL;
+ goto out_pctrl;
+ }
+ for (i = 0; i < range_num; i++)
+ pinctrl_add_gpio_range(info->pctl, &range[0]);
+ platform_set_drvdata(pdev, info);
+ return 0;
+out_pctrl:
+ release_mem_region(info->phy_base, info->phy_size);
+out_remap:
+ devm_kfree(&pdev->dev, info);
+ return ret;
+}
+
+static int __devexit pxa3xx_pinmux_remove(struct platform_device *pdev)
+{
+ struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
+
+ pinctrl_unregister(info->pctl);
+ iounmap(info->virt_base);
+ platform_set_drvdata(pdev, NULL);
+ devm_kfree(&pdev->dev, info);
+ return 0;
+}
+
+static struct platform_driver pxa3xx_pinmux_driver = {
+ .driver = {
+ .name = "pxa3xx-pinmux",
+ .owner = THIS_MODULE,
+ },
+ .probe = pxa3xx_pinmux_probe,
+ .remove = __devexit_p(pxa3xx_pinmux_remove),
+};
+
+static int __init pxa3xx_pinmux_init(void)
+{
+ return platform_driver_register(&pxa3xx_pinmux_driver);
+}
+postcore_initcall(pxa3xx_pinmux_init);
+
+static void __exit pxa3xx_pinmux_exit(void)
+{
+ platform_driver_unregister(&pxa3xx_pinmux_driver);
+}
+module_exit(pxa3xx_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang at marvell.com>");
+MODULE_DESCRIPTION("PXA pin control driver");
+MODULE_LICENSE("GPL");
--
1.7.0.4
More information about the linux-arm-kernel
mailing list