summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/Kconfig12
-rw-r--r--drivers/pinctrl/Makefile4
-rw-r--r--drivers/pinctrl/pinctrl-nomadik-db8500.c857
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.c1780
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.h77
-rw-r--r--drivers/pinctrl/pinctrl-tegra.c236
-rw-r--r--drivers/pinctrl/pinctrl-tegra.h23
-rw-r--r--drivers/pinctrl/pinctrl-tegra20.c40
-rw-r--r--drivers/pinctrl/pinctrl-tegra30.c40
-rw-r--r--drivers/pinctrl/spear/Kconfig44
-rw-r--r--drivers/pinctrl/spear/Makefile9
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c354
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.h393
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1310.c2198
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1340.c1989
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear300.c708
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear310.c431
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear320.c3468
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.c487
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear3xx.h92
20 files changed, 13116 insertions, 126 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 91c1f64102f0..c6e6ae0aa3b1 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -80,6 +80,16 @@ config PINCTRL_IMX28
select PINCONF
select PINCTRL_MXS
+config PINCTRL_NOMADIK
+ bool "Nomadik pin controller driver"
+ depends on ARCH_U8500 || ARCH_NOMADIK
+ select PINMUX
+ select PINCONF
+
+config PINCTRL_DB8500
+ bool "DB8500 pin controller driver"
+ depends on PINCTRL_NOMADIK && ARCH_U8500
+
config PINCTRL_PXA168
bool "PXA168 pin controller driver"
depends on ARCH_MMP
@@ -127,6 +137,8 @@ config PINCTRL_COH901
COH 901 335 and COH 901 571/3. They contain 3, 5 or 7
ports of 8 GPIO pins each.
+source "drivers/pinctrl/spear/Kconfig"
+
endmenu
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 515e32ff1597..8c074376cdea 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -18,6 +18,8 @@ obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o
obj-$(CONFIG_PINCTRL_IMX23) += pinctrl-imx23.o
obj-$(CONFIG_PINCTRL_IMX28) += pinctrl-imx28.o
+obj-$(CONFIG_PINCTRL_NOMADIK) += pinctrl-nomadik.o
+obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
@@ -26,3 +28,5 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
+
+obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c
new file mode 100644
index 000000000000..8b2022276f71
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c
@@ -0,0 +1,857 @@
+#include <linux/kernel.h>
+#include <linux/pinctrl/pinctrl.h>
+#include "pinctrl-nomadik.h"
+
+/* All the pins that can be used for GPIO and some other functions */
+#define _GPIO(offset) (offset)
+
+#define DB8500_PIN_AJ5 _GPIO(0)
+#define DB8500_PIN_AJ3 _GPIO(1)
+#define DB8500_PIN_AH4 _GPIO(2)
+#define DB8500_PIN_AH3 _GPIO(3)
+#define DB8500_PIN_AH6 _GPIO(4)
+#define DB8500_PIN_AG6 _GPIO(5)
+#define DB8500_PIN_AF6 _GPIO(6)
+#define DB8500_PIN_AG5 _GPIO(7)
+#define DB8500_PIN_AD5 _GPIO(8)
+#define DB8500_PIN_AE4 _GPIO(9)
+#define DB8500_PIN_AF5 _GPIO(10)
+#define DB8500_PIN_AG4 _GPIO(11)
+#define DB8500_PIN_AC4 _GPIO(12)
+#define DB8500_PIN_AF3 _GPIO(13)
+#define DB8500_PIN_AE3 _GPIO(14)
+#define DB8500_PIN_AC3 _GPIO(15)
+#define DB8500_PIN_AD3 _GPIO(16)
+#define DB8500_PIN_AD4 _GPIO(17)
+#define DB8500_PIN_AC2 _GPIO(18)
+#define DB8500_PIN_AC1 _GPIO(19)
+#define DB8500_PIN_AB4 _GPIO(20)
+#define DB8500_PIN_AB3 _GPIO(21)
+#define DB8500_PIN_AA3 _GPIO(22)
+#define DB8500_PIN_AA4 _GPIO(23)
+#define DB8500_PIN_AB2 _GPIO(24)
+#define DB8500_PIN_Y4 _GPIO(25)
+#define DB8500_PIN_Y2 _GPIO(26)
+#define DB8500_PIN_AA2 _GPIO(27)
+#define DB8500_PIN_AA1 _GPIO(28)
+#define DB8500_PIN_W2 _GPIO(29)
+#define DB8500_PIN_W3 _GPIO(30)
+#define DB8500_PIN_V3 _GPIO(31)
+#define DB8500_PIN_V2 _GPIO(32)
+#define DB8500_PIN_AF2 _GPIO(33)
+#define DB8500_PIN_AE1 _GPIO(34)
+#define DB8500_PIN_AE2 _GPIO(35)
+#define DB8500_PIN_AG2 _GPIO(36)
+/* Hole */
+#define DB8500_PIN_F3 _GPIO(64)
+#define DB8500_PIN_F1 _GPIO(65)
+#define DB8500_PIN_G3 _GPIO(66)
+#define DB8500_PIN_G2 _GPIO(67)
+#define DB8500_PIN_E1 _GPIO(68)
+#define DB8500_PIN_E2 _GPIO(69)
+#define DB8500_PIN_G5 _GPIO(70)
+#define DB8500_PIN_G4 _GPIO(71)
+#define DB8500_PIN_H4 _GPIO(72)
+#define DB8500_PIN_H3 _GPIO(73)
+#define DB8500_PIN_J3 _GPIO(74)
+#define DB8500_PIN_H2 _GPIO(75)
+#define DB8500_PIN_J2 _GPIO(76)
+#define DB8500_PIN_H1 _GPIO(77)
+#define DB8500_PIN_F4 _GPIO(78)
+#define DB8500_PIN_E3 _GPIO(79)
+#define DB8500_PIN_E4 _GPIO(80)
+#define DB8500_PIN_D2 _GPIO(81)
+#define DB8500_PIN_C1 _GPIO(82)
+#define DB8500_PIN_D3 _GPIO(83)
+#define DB8500_PIN_C2 _GPIO(84)
+#define DB8500_PIN_D5 _GPIO(85)
+#define DB8500_PIN_C6 _GPIO(86)
+#define DB8500_PIN_B3 _GPIO(87)
+#define DB8500_PIN_C4 _GPIO(88)
+#define DB8500_PIN_E6 _GPIO(89)
+#define DB8500_PIN_A3 _GPIO(90)
+#define DB8500_PIN_B6 _GPIO(91)
+#define DB8500_PIN_D6 _GPIO(92)
+#define DB8500_PIN_B7 _GPIO(93)
+#define DB8500_PIN_D7 _GPIO(94)
+#define DB8500_PIN_E8 _GPIO(95)
+#define DB8500_PIN_D8 _GPIO(96)
+#define DB8500_PIN_D9 _GPIO(97)
+/* Hole */
+#define DB8500_PIN_A5 _GPIO(128)
+#define DB8500_PIN_B4 _GPIO(129)
+#define DB8500_PIN_C8 _GPIO(130)
+#define DB8500_PIN_A12 _GPIO(131)
+#define DB8500_PIN_C10 _GPIO(132)
+#define DB8500_PIN_B10 _GPIO(133)
+#define DB8500_PIN_B9 _GPIO(134)
+#define DB8500_PIN_A9 _GPIO(135)
+#define DB8500_PIN_C7 _GPIO(136)
+#define DB8500_PIN_A7 _GPIO(137)
+#define DB8500_PIN_C5 _GPIO(138)
+#define DB8500_PIN_C9 _GPIO(139)
+#define DB8500_PIN_B11 _GPIO(140)
+#define DB8500_PIN_C12 _GPIO(141)
+#define DB8500_PIN_C11 _GPIO(142)
+#define DB8500_PIN_D12 _GPIO(143)
+#define DB8500_PIN_B13 _GPIO(144)
+#define DB8500_PIN_C13 _GPIO(145)
+#define DB8500_PIN_D13 _GPIO(146)
+#define DB8500_PIN_C15 _GPIO(147)
+#define DB8500_PIN_B16 _GPIO(148)
+#define DB8500_PIN_B14 _GPIO(149)
+#define DB8500_PIN_C14 _GPIO(150)
+#define DB8500_PIN_D17 _GPIO(151)
+#define DB8500_PIN_D16 _GPIO(152)
+#define DB8500_PIN_B17 _GPIO(153)
+#define DB8500_PIN_C16 _GPIO(154)
+#define DB8500_PIN_C19 _GPIO(155)
+#define DB8500_PIN_C17 _GPIO(156)
+#define DB8500_PIN_A18 _GPIO(157)
+#define DB8500_PIN_C18 _GPIO(158)
+#define DB8500_PIN_B19 _GPIO(159)
+#define DB8500_PIN_B20 _GPIO(160)
+#define DB8500_PIN_D21 _GPIO(161)
+#define DB8500_PIN_D20 _GPIO(162)
+#define DB8500_PIN_C20 _GPIO(163)
+#define DB8500_PIN_B21 _GPIO(164)
+#define DB8500_PIN_C21 _GPIO(165)
+#define DB8500_PIN_A22 _GPIO(166)
+#define DB8500_PIN_B24 _GPIO(167)
+#define DB8500_PIN_C22 _GPIO(168)
+#define DB8500_PIN_D22 _GPIO(169)
+#define DB8500_PIN_C23 _GPIO(170)
+#define DB8500_PIN_D23 _GPIO(171)
+/* Hole */
+#define DB8500_PIN_AJ27 _GPIO(192)
+#define DB8500_PIN_AH27 _GPIO(193)
+#define DB8500_PIN_AF27 _GPIO(194)
+#define DB8500_PIN_AG28 _GPIO(195)
+#define DB8500_PIN_AG26 _GPIO(196)
+#define DB8500_PIN_AH24 _GPIO(197)
+#define DB8500_PIN_AG25 _GPIO(198)
+#define DB8500_PIN_AH23 _GPIO(199)
+#define DB8500_PIN_AH26 _GPIO(200)
+#define DB8500_PIN_AF24 _GPIO(201)
+#define DB8500_PIN_AF25 _GPIO(202)
+#define DB8500_PIN_AE23 _GPIO(203)
+#define DB8500_PIN_AF23 _GPIO(204)
+#define DB8500_PIN_AG23 _GPIO(205)
+#define DB8500_PIN_AG24 _GPIO(206)
+#define DB8500_PIN_AJ23 _GPIO(207)
+#define DB8500_PIN_AH16 _GPIO(208)
+#define DB8500_PIN_AG15 _GPIO(209)
+#define DB8500_PIN_AJ15 _GPIO(210)
+#define DB8500_PIN_AG14 _GPIO(211)
+#define DB8500_PIN_AF13 _GPIO(212)
+#define DB8500_PIN_AG13 _GPIO(213)
+#define DB8500_PIN_AH15 _GPIO(214)
+#define DB8500_PIN_AH13 _GPIO(215)
+#define DB8500_PIN_AG12 _GPIO(216)
+#define DB8500_PIN_AH12 _GPIO(217)
+#define DB8500_PIN_AH11 _GPIO(218)
+#define DB8500_PIN_AG10 _GPIO(219)
+#define DB8500_PIN_AH10 _GPIO(220)
+#define DB8500_PIN_AJ11 _GPIO(221)
+#define DB8500_PIN_AJ9 _GPIO(222)
+#define DB8500_PIN_AH9 _GPIO(223)
+#define DB8500_PIN_AG9 _GPIO(224)
+#define DB8500_PIN_AG8 _GPIO(225)
+#define DB8500_PIN_AF8 _GPIO(226)
+#define DB8500_PIN_AH7 _GPIO(227)
+#define DB8500_PIN_AJ6 _GPIO(228)
+#define DB8500_PIN_AG7 _GPIO(229)
+#define DB8500_PIN_AF7 _GPIO(230)
+/* Hole */
+#define DB8500_PIN_AF28 _GPIO(256)
+#define DB8500_PIN_AE29 _GPIO(257)
+#define DB8500_PIN_AD29 _GPIO(258)
+#define DB8500_PIN_AC29 _GPIO(259)
+#define DB8500_PIN_AD28 _GPIO(260)
+#define DB8500_PIN_AD26 _GPIO(261)
+#define DB8500_PIN_AE26 _GPIO(262)
+#define DB8500_PIN_AG29 _GPIO(263)
+#define DB8500_PIN_AE27 _GPIO(264)
+#define DB8500_PIN_AD27 _GPIO(265)
+#define DB8500_PIN_AC28 _GPIO(266)
+#define DB8500_PIN_AC27 _GPIO(267)
+
+/*
+ * The names of the pins are denoted by GPIO number and ball name, even
+ * though they can be used for other things than GPIO, this is the first
+ * column in the table of the data sheet and often used on schematics and
+ * such.
+ */
+static const struct pinctrl_pin_desc nmk_db8500_pins[] = {
+ PINCTRL_PIN(DB8500_PIN_AJ5, "GPIO0_AJ5"),
+ PINCTRL_PIN(DB8500_PIN_AJ3, "GPIO1_AJ3"),
+ PINCTRL_PIN(DB8500_PIN_AH4, "GPIO2_AH4"),
+ PINCTRL_PIN(DB8500_PIN_AH3, "GPIO3_AH3"),
+ PINCTRL_PIN(DB8500_PIN_AH6, "GPIO4_AH6"),
+ PINCTRL_PIN(DB8500_PIN_AG6, "GPIO5_AG6"),
+ PINCTRL_PIN(DB8500_PIN_AF6, "GPIO6_AF6"),
+ PINCTRL_PIN(DB8500_PIN_AG5, "GPIO7_AG5"),
+ PINCTRL_PIN(DB8500_PIN_AD5, "GPIO8_AD5"),
+ PINCTRL_PIN(DB8500_PIN_AE4, "GPIO9_AE4"),
+ PINCTRL_PIN(DB8500_PIN_AF5, "GPIO10_AF5"),
+ PINCTRL_PIN(DB8500_PIN_AG4, "GPIO11_AG4"),
+ PINCTRL_PIN(DB8500_PIN_AC4, "GPIO12_AC4"),
+ PINCTRL_PIN(DB8500_PIN_AF3, "GPIO13_AF3"),
+ PINCTRL_PIN(DB8500_PIN_AE3, "GPIO14_AE3"),
+ PINCTRL_PIN(DB8500_PIN_AC3, "GPIO15_AC3"),
+ PINCTRL_PIN(DB8500_PIN_AD3, "GPIO16_AD3"),
+ PINCTRL_PIN(DB8500_PIN_AD4, "GPIO17_AD4"),
+ PINCTRL_PIN(DB8500_PIN_AC2, "GPIO18_AC2"),
+ PINCTRL_PIN(DB8500_PIN_AC1, "GPIO19_AC1"),
+ PINCTRL_PIN(DB8500_PIN_AB4, "GPIO20_AB4"),
+ PINCTRL_PIN(DB8500_PIN_AB3, "GPIO21_AB3"),
+ PINCTRL_PIN(DB8500_PIN_AA3, "GPIO22_AA3"),
+ PINCTRL_PIN(DB8500_PIN_AA4, "GPIO23_AA4"),
+ PINCTRL_PIN(DB8500_PIN_AB2, "GPIO24_AB2"),
+ PINCTRL_PIN(DB8500_PIN_Y4, "GPIO25_Y4"),
+ PINCTRL_PIN(DB8500_PIN_Y2, "GPIO26_Y2"),
+ PINCTRL_PIN(DB8500_PIN_AA2, "GPIO27_AA2"),
+ PINCTRL_PIN(DB8500_PIN_AA1, "GPIO28_AA1"),
+ PINCTRL_PIN(DB8500_PIN_W2, "GPIO29_W2"),
+ PINCTRL_PIN(DB8500_PIN_W3, "GPIO30_W3"),
+ PINCTRL_PIN(DB8500_PIN_V3, "GPIO31_V3"),
+ PINCTRL_PIN(DB8500_PIN_V2, "GPIO32_V2"),
+ PINCTRL_PIN(DB8500_PIN_AF2, "GPIO33_AF2"),
+ PINCTRL_PIN(DB8500_PIN_AE1, "GPIO34_AE1"),
+ PINCTRL_PIN(DB8500_PIN_AE2, "GPIO35_AE2"),
+ PINCTRL_PIN(DB8500_PIN_AG2, "GPIO36_AG2"),
+ /* Hole */
+ PINCTRL_PIN(DB8500_PIN_F3, "GPIO64_F3"),
+ PINCTRL_PIN(DB8500_PIN_F1, "GPIO65_F1"),
+ PINCTRL_PIN(DB8500_PIN_G3, "GPIO66_G3"),
+ PINCTRL_PIN(DB8500_PIN_G2, "GPIO67_G2"),
+ PINCTRL_PIN(DB8500_PIN_E1, "GPIO68_E1"),
+ PINCTRL_PIN(DB8500_PIN_E2, "GPIO69_E2"),
+ PINCTRL_PIN(DB8500_PIN_G5, "GPIO70_G5"),
+ PINCTRL_PIN(DB8500_PIN_G4, "GPIO71_G4"),
+ PINCTRL_PIN(DB8500_PIN_H4, "GPIO72_H4"),
+ PINCTRL_PIN(DB8500_PIN_H3, "GPIO73_H3"),
+ PINCTRL_PIN(DB8500_PIN_J3, "GPIO74_J3"),
+ PINCTRL_PIN(DB8500_PIN_H2, "GPIO75_H2"),
+ PINCTRL_PIN(DB8500_PIN_J2, "GPIO76_J2"),
+ PINCTRL_PIN(DB8500_PIN_H1, "GPIO77_H1"),
+ PINCTRL_PIN(DB8500_PIN_F4, "GPIO78_F4"),
+ PINCTRL_PIN(DB8500_PIN_E3, "GPIO79_E3"),
+ PINCTRL_PIN(DB8500_PIN_E4, "GPIO80_E4"),
+ PINCTRL_PIN(DB8500_PIN_D2, "GPIO81_D2"),
+ PINCTRL_PIN(DB8500_PIN_C1, "GPIO82_C1"),
+ PINCTRL_PIN(DB8500_PIN_D3, "GPIO83_D3"),
+ PINCTRL_PIN(DB8500_PIN_C2, "GPIO84_C2"),
+ PINCTRL_PIN(DB8500_PIN_D5, "GPIO85_D5"),
+ PINCTRL_PIN(DB8500_PIN_C6, "GPIO86_C6"),
+ PINCTRL_PIN(DB8500_PIN_B3, "GPIO87_B3"),
+ PINCTRL_PIN(DB8500_PIN_C4, "GPIO88_C4"),
+ PINCTRL_PIN(DB8500_PIN_E6, "GPIO89_E6"),
+ PINCTRL_PIN(DB8500_PIN_A3, "GPIO90_A3"),
+ PINCTRL_PIN(DB8500_PIN_B6, "GPIO91_B6"),
+ PINCTRL_PIN(DB8500_PIN_D6, "GPIO92_D6"),
+ PINCTRL_PIN(DB8500_PIN_B7, "GPIO93_B7"),
+ PINCTRL_PIN(DB8500_PIN_D7, "GPIO94_D7"),
+ PINCTRL_PIN(DB8500_PIN_E8, "GPIO95_E8"),
+ PINCTRL_PIN(DB8500_PIN_D8, "GPIO96_D8"),
+ PINCTRL_PIN(DB8500_PIN_D9, "GPIO97_D9"),
+ /* Hole */
+ PINCTRL_PIN(DB8500_PIN_A5, "GPIO128_A5"),
+ PINCTRL_PIN(DB8500_PIN_B4, "GPIO129_B4"),
+ PINCTRL_PIN(DB8500_PIN_C8, "GPIO130_C8"),
+ PINCTRL_PIN(DB8500_PIN_A12, "GPIO131_A12"),
+ PINCTRL_PIN(DB8500_PIN_C10, "GPIO132_C10"),
+ PINCTRL_PIN(DB8500_PIN_B10, "GPIO133_B10"),
+ PINCTRL_PIN(DB8500_PIN_B9, "GPIO134_B9"),
+ PINCTRL_PIN(DB8500_PIN_A9, "GPIO135_A9"),
+ PINCTRL_PIN(DB8500_PIN_C7, "GPIO136_C7"),
+ PINCTRL_PIN(DB8500_PIN_A7, "GPIO137_A7"),
+ PINCTRL_PIN(DB8500_PIN_C5, "GPIO138_C5"),
+ PINCTRL_PIN(DB8500_PIN_C9, "GPIO139_C9"),
+ PINCTRL_PIN(DB8500_PIN_B11, "GPIO140_B11"),
+ PINCTRL_PIN(DB8500_PIN_C12, "GPIO141_C12"),
+ PINCTRL_PIN(DB8500_PIN_C11, "GPIO142_C11"),
+ PINCTRL_PIN(DB8500_PIN_D12, "GPIO143_D12"),
+ PINCTRL_PIN(DB8500_PIN_B13, "GPIO144_B13"),
+ PINCTRL_PIN(DB8500_PIN_C13, "GPIO145_C13"),
+ PINCTRL_PIN(DB8500_PIN_D13, "GPIO146_D13"),
+ PINCTRL_PIN(DB8500_PIN_C15, "GPIO147_C15"),
+ PINCTRL_PIN(DB8500_PIN_B16, "GPIO148_B16"),
+ PINCTRL_PIN(DB8500_PIN_B14, "GPIO149_B14"),
+ PINCTRL_PIN(DB8500_PIN_C14, "GPIO150_C14"),
+ PINCTRL_PIN(DB8500_PIN_D17, "GPIO151_D17"),
+ PINCTRL_PIN(DB8500_PIN_D16, "GPIO152_D16"),
+ PINCTRL_PIN(DB8500_PIN_B17, "GPIO153_B17"),
+ PINCTRL_PIN(DB8500_PIN_C16, "GPIO154_C16"),
+ PINCTRL_PIN(DB8500_PIN_C19, "GPIO155_C19"),
+ PINCTRL_PIN(DB8500_PIN_C17, "GPIO156_C17"),
+ PINCTRL_PIN(DB8500_PIN_A18, "GPIO157_A18"),
+ PINCTRL_PIN(DB8500_PIN_C18, "GPIO158_C18"),
+ PINCTRL_PIN(DB8500_PIN_B19, "GPIO159_B19"),
+ PINCTRL_PIN(DB8500_PIN_B20, "GPIO160_B20"),
+ PINCTRL_PIN(DB8500_PIN_D21, "GPIO161_D21"),
+ PINCTRL_PIN(DB8500_PIN_D20, "GPIO162_D20"),
+ PINCTRL_PIN(DB8500_PIN_C20, "GPIO163_C20"),
+ PINCTRL_PIN(DB8500_PIN_B21, "GPIO164_B21"),
+ PINCTRL_PIN(DB8500_PIN_C21, "GPIO165_C21"),
+ PINCTRL_PIN(DB8500_PIN_A22, "GPIO166_A22"),
+ PINCTRL_PIN(DB8500_PIN_B24, "GPIO167_B24"),
+ PINCTRL_PIN(DB8500_PIN_C22, "GPIO168_C22"),
+ PINCTRL_PIN(DB8500_PIN_D22, "GPIO169_D22"),
+ PINCTRL_PIN(DB8500_PIN_C23, "GPIO170_C23"),
+ PINCTRL_PIN(DB8500_PIN_D23, "GPIO171_D23"),
+ /* Hole */
+ PINCTRL_PIN(DB8500_PIN_AJ27, "GPIO192_AJ27"),
+ PINCTRL_PIN(DB8500_PIN_AH27, "GPIO193_AH27"),
+ PINCTRL_PIN(DB8500_PIN_AF27, "GPIO194_AF27"),
+ PINCTRL_PIN(DB8500_PIN_AG28, "GPIO195_AG28"),
+ PINCTRL_PIN(DB8500_PIN_AG26, "GPIO196_AG26"),
+ PINCTRL_PIN(DB8500_PIN_AH24, "GPIO197_AH24"),
+ PINCTRL_PIN(DB8500_PIN_AG25, "GPIO198_AG25"),
+ PINCTRL_PIN(DB8500_PIN_AH23, "GPIO199_AH23"),
+ PINCTRL_PIN(DB8500_PIN_AH26, "GPIO200_AH26"),
+ PINCTRL_PIN(DB8500_PIN_AF24, "GPIO201_AF24"),
+ PINCTRL_PIN(DB8500_PIN_AF25, "GPIO202_AF25"),
+ PINCTRL_PIN(DB8500_PIN_AE23, "GPIO203_AE23"),
+ PINCTRL_PIN(DB8500_PIN_AF23, "GPIO204_AF23"),
+ PINCTRL_PIN(DB8500_PIN_AG23, "GPIO205_AG23"),
+ PINCTRL_PIN(DB8500_PIN_AG24, "GPIO206_AG24"),
+ PINCTRL_PIN(DB8500_PIN_AJ23, "GPIO207_AJ23"),
+ PINCTRL_PIN(DB8500_PIN_AH16, "GPIO208_AH16"),
+ PINCTRL_PIN(DB8500_PIN_AG15, "GPIO209_AG15"),
+ PINCTRL_PIN(DB8500_PIN_AJ15, "GPIO210_AJ15"),
+ PINCTRL_PIN(DB8500_PIN_AG14, "GPIO211_AG14"),
+ PINCTRL_PIN(DB8500_PIN_AF13, "GPIO212_AF13"),
+ PINCTRL_PIN(DB8500_PIN_AG13, "GPIO213_AG13"),
+ PINCTRL_PIN(DB8500_PIN_AH15, "GPIO214_AH15"),
+ PINCTRL_PIN(DB8500_PIN_AH13, "GPIO215_AH13"),
+ PINCTRL_PIN(DB8500_PIN_AG12, "GPIO216_AG12"),
+ PINCTRL_PIN(DB8500_PIN_AH12, "GPIO217_AH12"),
+ PINCTRL_PIN(DB8500_PIN_AH11, "GPIO218_AH11"),
+ PINCTRL_PIN(DB8500_PIN_AG10, "GPIO219_AG10"),
+ PINCTRL_PIN(DB8500_PIN_AH10, "GPIO220_AH10"),
+ PINCTRL_PIN(DB8500_PIN_AJ11, "GPIO221_AJ11"),
+ PINCTRL_PIN(DB8500_PIN_AJ9, "GPIO222_AJ9"),
+ PINCTRL_PIN(DB8500_PIN_AH9, "GPIO223_AH9"),
+ PINCTRL_PIN(DB8500_PIN_AG9, "GPIO224_AG9"),
+ PINCTRL_PIN(DB8500_PIN_AG8, "GPIO225_AG8"),
+ PINCTRL_PIN(DB8500_PIN_AF8, "GPIO226_AF8"),
+ PINCTRL_PIN(DB8500_PIN_AH7, "GPIO227_AH7"),
+ PINCTRL_PIN(DB8500_PIN_AJ6, "GPIO228_AJ6"),
+ PINCTRL_PIN(DB8500_PIN_AG7, "GPIO229_AG7"),
+ PINCTRL_PIN(DB8500_PIN_AF7, "GPIO230_AF7"),
+ /* Hole */
+ PINCTRL_PIN(DB8500_PIN_AF28, "GPIO256_AF28"),
+ PINCTRL_PIN(DB8500_PIN_AE29, "GPIO257_AE29"),
+ PINCTRL_PIN(DB8500_PIN_AD29, "GPIO258_AD29"),
+ PINCTRL_PIN(DB8500_PIN_AC29, "GPIO259_AC29"),
+ PINCTRL_PIN(DB8500_PIN_AD28, "GPIO260_AD28"),
+ PINCTRL_PIN(DB8500_PIN_AD26, "GPIO261_AD26"),
+ PINCTRL_PIN(DB8500_PIN_AE26, "GPIO262_AE26"),
+ PINCTRL_PIN(DB8500_PIN_AG29, "GPIO263_AG29"),
+ PINCTRL_PIN(DB8500_PIN_AE27, "GPIO264_AE27"),
+ PINCTRL_PIN(DB8500_PIN_AD27, "GPIO265_AD27"),
+ PINCTRL_PIN(DB8500_PIN_AC28, "GPIO266_AC28"),
+ PINCTRL_PIN(DB8500_PIN_AC27, "GPIO267_AC27"),
+};
+
+#define DB8500_GPIO_RANGE(a, b, c) { .name = "DB8500", .id = a, .base = b, \
+ .pin_base = b, .npins = c }
+
+/*
+ * This matches the 32-pin gpio chips registered by the GPIO portion. This
+ * cannot be const since we assign the struct gpio_chip * pointer at runtime.
+ */
+static struct pinctrl_gpio_range nmk_db8500_ranges[] = {
+ DB8500_GPIO_RANGE(0, 0, 32),
+ DB8500_GPIO_RANGE(1, 32, 5),
+ DB8500_GPIO_RANGE(2, 64, 32),
+ DB8500_GPIO_RANGE(3, 96, 2),
+ DB8500_GPIO_RANGE(4, 128, 32),
+ DB8500_GPIO_RANGE(5, 160, 12),
+ DB8500_GPIO_RANGE(6, 192, 32),
+ DB8500_GPIO_RANGE(7, 224, 7),
+ DB8500_GPIO_RANGE(8, 256, 12),
+};
+
+/*
+ * Read the pin group names like this:
+ * u0_a_1 = first groups of pins for uart0 on alt function a
+ * i2c2_b_2 = second group of pins for i2c2 on alt function b
+ *
+ * The groups are arranged as sets per altfunction column, so we can
+ * mux in one group at a time by selecting the same altfunction for them
+ * all. When functions require pins on different altfunctions, you need
+ * to combine several groups.
+ */
+
+/* Altfunction A column */
+static const unsigned u0_a_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3,
+ DB8500_PIN_AH4, DB8500_PIN_AH3 };
+static const unsigned u1rxtx_a_1_pins[] = { DB8500_PIN_AH6, DB8500_PIN_AG6 };
+static const unsigned u1ctsrts_a_1_pins[] = { DB8500_PIN_AF6, DB8500_PIN_AG5 };
+/* Image processor I2C line, this is driven by image processor firmware */
+static const unsigned ipi2c_a_1_pins[] = { DB8500_PIN_AD5, DB8500_PIN_AE4 };
+static const unsigned ipi2c_a_2_pins[] = { DB8500_PIN_AF5, DB8500_PIN_AG4 };
+/* MSP0 can only be on these pins, but TXD and RXD can be flipped */
+static const unsigned msp0txrx_a_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
+static const unsigned msp0tfstck_a_1_pins[] = { DB8500_PIN_AF3, DB8500_PIN_AE3 };
+static const unsigned msp0rfsrck_a_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
+/* Basic pins of the MMC/SD card 0 interface */
+static const unsigned mc0_a_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
+ DB8500_PIN_AB4, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
+ DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+/* Often only 4 bits are used, then these are not needed (only used for MMC) */
+static const unsigned mc0_dat47_a_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
+ DB8500_PIN_V3, DB8500_PIN_V2};
+static const unsigned mc0dat31dir_a_1_pins[] = { DB8500_PIN_AB3 };
+/* MSP1 can only be on these pins, but TXD and RXD can be flipped */
+static const unsigned msp1txrx_a_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
+static const unsigned msp1_a_1_pins[] = { DB8500_PIN_AE1, DB8500_PIN_AE2 };
+/* LCD interface */
+static const unsigned lcdb_a_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
+ DB8500_PIN_G3, DB8500_PIN_G2 };
+static const unsigned lcdvsi0_a_1_pins[] = { DB8500_PIN_E1 };
+static const unsigned lcdvsi1_a_1_pins[] = { DB8500_PIN_E2 };
+static const unsigned lcd_d0_d7_a_1_pins[] = {
+ DB8500_PIN_G5, DB8500_PIN_G4, DB8500_PIN_H4, DB8500_PIN_H3,
+ DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1 };
+/* D8 thru D11 often used as TVOUT lines */
+static const unsigned lcd_d8_d11_a_1_pins[] = { DB8500_PIN_F4,
+ DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2 };
+static const unsigned lcd_d12_d23_a_1_pins[] = {
+ DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5,
+ DB8500_PIN_C6, DB8500_PIN_B3, DB8500_PIN_C4, DB8500_PIN_E6,
+ DB8500_PIN_A3, DB8500_PIN_B6, DB8500_PIN_D6, DB8500_PIN_B7 };
+static const unsigned kp_a_1_pins[] = { DB8500_PIN_D7, DB8500_PIN_E8,
+ DB8500_PIN_D8, DB8500_PIN_D9 };
+static const unsigned kpskaskb_a_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16 };
+static const unsigned kp_a_2_pins[] = {
+ DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+ DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+ DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+/* MC2 has 8 data lines and no direction control, so only for (e)MMC */
+static const unsigned mc2_a_1_pins[] = { DB8500_PIN_A5, DB8500_PIN_B4,
+ DB8500_PIN_C8, DB8500_PIN_A12, DB8500_PIN_C10, DB8500_PIN_B10,
+ DB8500_PIN_B9, DB8500_PIN_A9, DB8500_PIN_C7, DB8500_PIN_A7,
+ DB8500_PIN_C5 };
+static const unsigned ssp1_a_1_pins[] = { DB8500_PIN_C9, DB8500_PIN_B11,
+ DB8500_PIN_C12, DB8500_PIN_C11 };
+static const unsigned ssp0_a_1_pins[] = { DB8500_PIN_D12, DB8500_PIN_B13,
+ DB8500_PIN_C13, DB8500_PIN_D13 };
+static const unsigned i2c0_a_1_pins[] = { DB8500_PIN_C15, DB8500_PIN_B16 };
+/*
+ * Image processor GPIO pins are named "ipgpio" and have their own
+ * numberspace
+ */
+static const unsigned ipgpio0_a_1_pins[] = { DB8500_PIN_B14 };
+static const unsigned ipgpio1_a_1_pins[] = { DB8500_PIN_C14 };
+/* Three modem pins named RF_PURn, MODEM_STATE and MODEM_PWREN */
+static const unsigned modem_a_1_pins[] = { DB8500_PIN_D22, DB8500_PIN_C23,
+ DB8500_PIN_D23 };
+/*
+ * This MSP cannot switch RX and TX, SCK in a separate group since this
+ * seems to be optional.
+ */
+static const unsigned msp2sck_a_1_pins[] = { DB8500_PIN_AJ27 };
+static const unsigned msp2_a_1_pins[] = { DB8500_PIN_AH27, DB8500_PIN_AF27,
+ DB8500_PIN_AG28, DB8500_PIN_AG26 };
+static const unsigned mc4_a_1_pins[] = { DB8500_PIN_AH24, DB8500_PIN_AG25,
+ DB8500_PIN_AH23, DB8500_PIN_AH26, DB8500_PIN_AF24, DB8500_PIN_AF25,
+ DB8500_PIN_AE23, DB8500_PIN_AF23, DB8500_PIN_AG23, DB8500_PIN_AG24,
+ DB8500_PIN_AJ23 };
+/* MC1 has only 4 data pins, designed for SD or SDIO exclusively */
+static const unsigned mc1_a_1_pins[] = { DB8500_PIN_AH16, DB8500_PIN_AG15,
+ DB8500_PIN_AJ15, DB8500_PIN_AG14, DB8500_PIN_AF13, DB8500_PIN_AG13,
+ DB8500_PIN_AH15 };
+static const unsigned mc1dir_a_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
+ DB8500_PIN_AH12, DB8500_PIN_AH11 };
+static const unsigned hsir_a_1_pins[] = { DB8500_PIN_AG10, DB8500_PIN_AH10 };
+static const unsigned hsit_a_1_pins[] = { DB8500_PIN_AJ11, DB8500_PIN_AJ9,
+ DB8500_PIN_AH9, DB8500_PIN_AG9, DB8500_PIN_AG8, DB8500_PIN_AF8 };
+static const unsigned clkout_a_1_pins[] = { DB8500_PIN_AH7, DB8500_PIN_AJ6 };
+static const unsigned clkout_a_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 };
+static const unsigned usb_a_1_pins[] = { DB8500_PIN_AF28, DB8500_PIN_AE29,
+ DB8500_PIN_AD29, DB8500_PIN_AC29, DB8500_PIN_AD28, DB8500_PIN_AD26,
+ DB8500_PIN_AE26, DB8500_PIN_AG29, DB8500_PIN_AE27, DB8500_PIN_AD27,
+ DB8500_PIN_AC28, DB8500_PIN_AC27 };
+
+/* Altfunction B column */
+static const unsigned trig_b_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3 };
+static const unsigned i2c4_b_1_pins[] = { DB8500_PIN_AH6, DB8500_PIN_AG6 };
+static const unsigned i2c1_b_1_pins[] = { DB8500_PIN_AF6, DB8500_PIN_AG5 };
+static const unsigned i2c2_b_1_pins[] = { DB8500_PIN_AD5, DB8500_PIN_AE4 };
+static const unsigned i2c2_b_2_pins[] = { DB8500_PIN_AF5, DB8500_PIN_AG4 };
+static const unsigned msp0txrx_b_1_pins[] = { DB8500_PIN_AC4, DB8500_PIN_AC3 };
+static const unsigned i2c1_b_2_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
+/* Just RX and TX for UART2 */
+static const unsigned u2rxtx_b_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1 };
+static const unsigned uartmodtx_b_1_pins[] = { DB8500_PIN_AB4 };
+static const unsigned msp0sck_b_1_pins[] = { DB8500_PIN_AB3 };
+static const unsigned uartmodrx_b_1_pins[] = { DB8500_PIN_AA3 };
+static const unsigned stmmod_b_1_pins[] = { DB8500_PIN_AA4, DB8500_PIN_Y4,
+ DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned uartmodrx_b_2_pins[] = { DB8500_PIN_AB2 };
+static const unsigned spi3_b_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3,
+ DB8500_PIN_V3, DB8500_PIN_V2 };
+static const unsigned msp1txrx_b_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AG2 };
+static const unsigned kp_b_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1,
+ DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_E1, DB8500_PIN_E2,
+ DB8500_PIN_G5, DB8500_PIN_G4, DB8500_PIN_H4, DB8500_PIN_H3,
+ DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1,
+ DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2,
+ DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 };
+static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
+ DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
+ DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
+ DB8500_PIN_D9, DB8500_PIN_A5, DB8500_PIN_B4, DB8500_PIN_C8,
+ DB8500_PIN_A12, DB8500_PIN_C10, DB8500_PIN_B10, DB8500_PIN_B9,
+ DB8500_PIN_A9, DB8500_PIN_C7, DB8500_PIN_A7, DB8500_PIN_C5,
+ DB8500_PIN_C9, DB8500_PIN_B14 };
+/* This chip select pin can be "ps0" in alt B so have it separately */
+static const unsigned smcs0_b_1_pins[] = { DB8500_PIN_E8 };
+static const unsigned ipgpio7_b_1_pins[] = { DB8500_PIN_B11 };
+static const unsigned ipgpio2_b_1_pins[] = { DB8500_PIN_C12 };
+static const unsigned ipgpio3_b_1_pins[] = { DB8500_PIN_C11 };
+static const unsigned lcdaclk_b_1_pins[] = { DB8500_PIN_C14 };
+static const unsigned lcda_b_1_pins[] = { DB8500_PIN_D22,
+ DB8500_PIN_C23, DB8500_PIN_D23 };
+static const unsigned lcd_b_1_pins[] = { DB8500_PIN_D17, DB8500_PIN_D16,
+ DB8500_PIN_B17, DB8500_PIN_C16, DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19, DB8500_PIN_B20,
+ DB8500_PIN_D21, DB8500_PIN_D20, DB8500_PIN_C20, DB8500_PIN_B21,
+ DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24, DB8500_PIN_C22 };
+static const unsigned ddrtrig_b_1_pins[] = { DB8500_PIN_AJ27 };
+static const unsigned pwl_b_1_pins[] = { DB8500_PIN_AF25 };
+static const unsigned spi1_b_1_pins[] = { DB8500_PIN_AG15, DB8500_PIN_AF13,
+ DB8500_PIN_AG13, DB8500_PIN_AH15 };
+static const unsigned mc3_b_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
+ DB8500_PIN_AH12, DB8500_PIN_AH11, DB8500_PIN_AG10, DB8500_PIN_AH10,
+ DB8500_PIN_AJ11, DB8500_PIN_AJ9, DB8500_PIN_AH9, DB8500_PIN_AG9,
+ DB8500_PIN_AG8 };
+static const unsigned pwl_b_2_pins[] = { DB8500_PIN_AF8 };
+static const unsigned pwl_b_3_pins[] = { DB8500_PIN_AG7 };
+static const unsigned pwl_b_4_pins[] = { DB8500_PIN_AF7 };
+
+/* Altfunction C column */
+static const unsigned ipjtag_c_1_pins[] = { DB8500_PIN_AJ5, DB8500_PIN_AJ3,
+ DB8500_PIN_AH4, DB8500_PIN_AH3, DB8500_PIN_AH6 };
+static const unsigned ipgpio6_c_1_pins[] = { DB8500_PIN_AG6 };
+static const unsigned ipgpio0_c_1_pins[] = { DB8500_PIN_AF6 };
+static const unsigned ipgpio1_c_1_pins[] = { DB8500_PIN_AG5 };
+static const unsigned ipgpio3_c_1_pins[] = { DB8500_PIN_AF5 };
+static const unsigned ipgpio2_c_1_pins[] = { DB8500_PIN_AG4 };
+static const unsigned slim0_c_1_pins[] = { DB8500_PIN_AD3, DB8500_PIN_AD4 };
+/* Optional 4-bit Memory Stick interface */
+static const unsigned ms_c_1_pins[] = { DB8500_PIN_AC2, DB8500_PIN_AC1,
+ DB8500_PIN_AB3, DB8500_PIN_AA3, DB8500_PIN_AA4, DB8500_PIN_AB2,
+ DB8500_PIN_Y4, DB8500_PIN_Y2, DB8500_PIN_AA2, DB8500_PIN_AA1 };
+static const unsigned iptrigout_c_1_pins[] = { DB8500_PIN_AB4 };
+static const unsigned u2rxtx_c_1_pins[] = { DB8500_PIN_W2, DB8500_PIN_W3 };
+static const unsigned u2ctsrts_c_1_pins[] = { DB8500_PIN_V3, DB8500_PIN_V2 };
+static const unsigned u0_c_1_pins[] = { DB8500_PIN_AF2, DB8500_PIN_AE1,
+ DB8500_PIN_AE2, DB8500_PIN_AG2 };
+static const unsigned ipgpio4_c_1_pins[] = { DB8500_PIN_F3 };
+static const unsigned ipgpio5_c_1_pins[] = { DB8500_PIN_F1 };
+static const unsigned ipgpio6_c_2_pins[] = { DB8500_PIN_G3 };
+static const unsigned ipgpio7_c_1_pins[] = { DB8500_PIN_G2 };
+static const unsigned smcleale_c_1_pins[] = { DB8500_PIN_E1, DB8500_PIN_E2 };
+static const unsigned stmape_c_1_pins[] = { DB8500_PIN_G5, DB8500_PIN_G4,
+ DB8500_PIN_H4, DB8500_PIN_H3, DB8500_PIN_J3 };
+static const unsigned u2rxtx_c_2_pins[] = { DB8500_PIN_H2, DB8500_PIN_J2 };
+static const unsigned ipgpio2_c_2_pins[] = { DB8500_PIN_F4 };
+static const unsigned ipgpio3_c_2_pins[] = { DB8500_PIN_E3 };
+static const unsigned ipgpio4_c_2_pins[] = { DB8500_PIN_E4 };
+static const unsigned ipgpio5_c_2_pins[] = { DB8500_PIN_D2 };
+static const unsigned mc5_c_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
+ DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
+ DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8,
+ DB8500_PIN_D9 };
+static const unsigned mc2rstn_c_1_pins[] = { DB8500_PIN_C8 };
+static const unsigned kp_c_1_pins[] = { DB8500_PIN_C9, DB8500_PIN_B11,
+ DB8500_PIN_C12, DB8500_PIN_C11, DB8500_PIN_D17, DB8500_PIN_D16,
+ DB8500_PIN_C23, DB8500_PIN_D23 };
+static const unsigned smps1_c_1_pins[] = { DB8500_PIN_B14 };
+static const unsigned u2rxtx_c_3_pins[] = { DB8500_PIN_B17, DB8500_PIN_C16 };
+static const unsigned stmape_c_2_pins[] = { DB8500_PIN_C19, DB8500_PIN_C17,
+ DB8500_PIN_A18, DB8500_PIN_C18, DB8500_PIN_B19 };
+static const unsigned uartmodrx_c_1_pins[] = { DB8500_PIN_D21 };
+static const unsigned uartmodtx_c_1_pins[] = { DB8500_PIN_D20 };
+static const unsigned stmmod_c_1_pins[] = { DB8500_PIN_C20, DB8500_PIN_B21,
+ DB8500_PIN_C21, DB8500_PIN_A22, DB8500_PIN_B24 };
+static const unsigned usbsim_c_1_pins[] = { DB8500_PIN_D22 };
+static const unsigned mc4rstn_c_1_pins[] = { DB8500_PIN_AF25 };
+static const unsigned clkout_c_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AH12 };
+static const unsigned i2c3_c_1_pins[] = { DB8500_PIN_AG12, DB8500_PIN_AH11 };
+static const unsigned spi0_c_1_pins[] = { DB8500_PIN_AH10, DB8500_PIN_AH9,
+ DB8500_PIN_AG9, DB8500_PIN_AG8 };
+static const unsigned usbsim_c_2_pins[] = { DB8500_PIN_AF8 };
+static const unsigned i2c3_c_2_pins[] = { DB8500_PIN_AG7, DB8500_PIN_AF7 };
+
+/* Other C1 column */
+static const unsigned kp_oc1_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3,
+ DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6,
+ DB8500_PIN_D6, DB8500_PIN_B7 };
+static const unsigned spi2_oc1_1_pins[] = { DB8500_PIN_AH13, DB8500_PIN_AG12,
+ DB8500_PIN_AH12, DB8500_PIN_AH11 };
+
+#define DB8500_PIN_GROUP(a,b) { .name = #a, .pins = a##_pins, \
+ .npins = ARRAY_SIZE(a##_pins), .altsetting = b }
+
+static const struct nmk_pingroup nmk_db8500_groups[] = {
+ /* Altfunction A column */
+ DB8500_PIN_GROUP(u0_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(u1rxtx_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(u1ctsrts_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(ipi2c_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(ipi2c_a_2, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp0txrx_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp0tfstck_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp0rfsrck_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(mc0_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp1txrx_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(lcdb_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(lcdvsi0_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(lcdvsi1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(lcd_d0_d7_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(lcd_d8_d11_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(lcd_d12_d23_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(kp_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(mc2_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(ssp1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(ssp0_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(i2c0_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(ipgpio0_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(ipgpio1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp2sck_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(msp2_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(mc4_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(mc1_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(hsir_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(hsit_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(clkout_a_1, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(clkout_a_2, NMK_GPIO_ALT_A),
+ DB8500_PIN_GROUP(usb_a_1, NMK_GPIO_ALT_A),
+ /* Altfunction B column */
+ DB8500_PIN_GROUP(trig_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(i2c4_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(i2c1_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(i2c2_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(i2c2_b_2, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(msp0txrx_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(i2c1_b_2, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(u2rxtx_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(uartmodtx_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(msp0sck_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(uartmodrx_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(stmmod_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(uartmodrx_b_2, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(ipgpio7_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(ipgpio2_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(ipgpio3_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(lcdaclk_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(lcda_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(lcd_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(ddrtrig_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(pwl_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(spi1_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(mc3_b_1, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(pwl_b_2, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(pwl_b_3, NMK_GPIO_ALT_B),
+ DB8500_PIN_GROUP(pwl_b_4, NMK_GPIO_ALT_B),
+ /* Altfunction C column */
+ DB8500_PIN_GROUP(ipjtag_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio0_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio1_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio3_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio2_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(slim0_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ms_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(iptrigout_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(u2rxtx_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(u2ctsrts_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(u0_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio4_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio5_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio6_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio7_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(smcleale_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(stmape_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(u2rxtx_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio2_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio3_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio4_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(ipgpio5_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(mc5_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(mc2rstn_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(kp_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(smps1_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(u2rxtx_c_3, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(stmape_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(uartmodrx_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(uartmodtx_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(stmmod_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(usbsim_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(mc4rstn_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(clkout_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C),
+ /* Other alt C1 column, these are still configured as alt C */
+ DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C),
+ DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C),
+};
+
+/* We use this macro to define the groups applicable to a function */
+#define DB8500_FUNC_GROUPS(a, b...) \
+static const char * const a##_groups[] = { b };
+
+DB8500_FUNC_GROUPS(u0, "u0_a_1", "u0_c_1");
+DB8500_FUNC_GROUPS(u1, "u1rxtx_a_1", "u1ctsrts_a_1");
+/*
+ * UART2 can be muxed out with just RX/TX in four places, CTS+RTS is however
+ * only available on two pins in alternative function C
+ */
+DB8500_FUNC_GROUPS(u2, "u2rxtx_b_1", "u2rxtx_c_1", "u2ctsrts_c_1",
+ "u2rxtx_c_2", "u2rxtx_c_3");
+DB8500_FUNC_GROUPS(ipi2c, "ipi2c_a_1", "ipi2c_a_2");
+/*
+ * MSP0 can only be on a certain set of pins, but the TX/RX pins can be
+ * switched around by selecting the altfunction A or B. The SCK pin is
+ * only available on the altfunction B.
+ */
+DB8500_FUNC_GROUPS(msp0, "msp0txrx_a_1", "msp0tfstck_a_1", "msp0rfstck_a_1",
+ "msp0txrx_b_1", "msp0sck_b_1");
+DB8500_FUNC_GROUPS(mc0, "mc0_a_1");
+/* MSP0 can swap RX/TX like MSP0 but has no SCK pin available */
+DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1");
+DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1");
+DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1",
+ "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1");
+DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_c_1", "kp_oc1_1");
+DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1");
+DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1");
+DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1");
+DB8500_FUNC_GROUPS(i2c0, "i2c0_a_1");
+/* The image processor has 8 GPIO pins that can be muxed out */
+DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1",
+ "ipgpio2_b_1", "ipgpio3_b_1", "ipgpio6_c_1", "ipgpio0_c_1",
+ "ipgpio1_c_1", "ipgpio3_c_1", "ipgpio2_c_1", "ipgpio4_c_1",
+ "ipgpio5_c_1", "ipgpio6_c_2", "ipgpio7_c_1", "ipgpio2_c_2",
+ "ipgpio3_c_2", "ipgpio4_c_2", "ipgpio5_c_2");
+/* MSP2 can not invert the RX/TX pins but has the optional SCK pin */
+DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1");
+DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1");
+DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1");
+DB8500_FUNC_GROUPS(hsi, "hsir1_a_1", "hsit1_a_1");
+DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1");
+DB8500_FUNC_GROUPS(usb, "usb_a_1");
+DB8500_FUNC_GROUPS(trig, "trig_b_1");
+DB8500_FUNC_GROUPS(i2c4, "i2c4_b_1");
+DB8500_FUNC_GROUPS(i2c1, "i2c1_b_1", "i2c1_b_2");
+DB8500_FUNC_GROUPS(i2c2, "i2c2_b_1", "i2c2_b_2");
+/*
+ * The modem UART can output its RX and TX pins in some different places,
+ * so select one of each.
+ */
+DB8500_FUNC_GROUPS(uartmod, "uartmodtx_b_1", "uartmodrx_b_1", "uartmodrx_b_2",
+ "uartmodrx_c_1", "uartmod_tx_c_1");
+DB8500_FUNC_GROUPS(stmmod, "stmmod_b_1", "stmmod_c_1");
+DB8500_FUNC_GROUPS(spi3, "spi3_b_1");
+/* Select between CS0 on alt B or PS1 on alt C */
+DB8500_FUNC_GROUPS(sm, "sm_b_1", "smcs0_b_1", "smcleale_c_1", "smps1_c_1");
+DB8500_FUNC_GROUPS(lcda, "lcdaclk_b_1", "lcda_b_1");
+DB8500_FUNC_GROUPS(ddrtrig, "ddrtrig_b_1");
+DB8500_FUNC_GROUPS(pwl, "pwl_b_1", "pwl_b_2", "pwl_b_3", "pwl_b_4");
+DB8500_FUNC_GROUPS(spi1, "spi1_b_1");
+DB8500_FUNC_GROUPS(mc3, "mc3_b_1");
+DB8500_FUNC_GROUPS(ipjtag, "ipjtag_c_1");
+DB8500_FUNC_GROUPS(slim0, "slim0_c_1");
+DB8500_FUNC_GROUPS(ms, "ms_c_1");
+DB8500_FUNC_GROUPS(iptrigout, "iptrigout_c_1");
+DB8500_FUNC_GROUPS(stmape, "stmape_c_1", "stmape_c_2");
+DB8500_FUNC_GROUPS(mc5, "mc5_c_1");
+DB8500_FUNC_GROUPS(usbsim, "usbsim_c_1", "usbsim_c_2");
+DB8500_FUNC_GROUPS(i2c3, "i2c3_c_1", "i2c3_c_2");
+DB8500_FUNC_GROUPS(spi0, "spi0_c_1");
+DB8500_FUNC_GROUPS(spi2, "spi2_oc1_1");
+
+#define FUNCTION(fname) \
+ { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+static const struct nmk_function nmk_db8500_functions[] = {
+ FUNCTION(u0),
+ FUNCTION(u1),
+ FUNCTION(u2),
+ FUNCTION(ipi2c),
+ FUNCTION(msp0),
+ FUNCTION(mc0),
+ FUNCTION(msp1),
+ FUNCTION(lcdb),
+ FUNCTION(lcd),
+ FUNCTION(kp),
+ FUNCTION(mc2),
+ FUNCTION(ssp1),
+ FUNCTION(ssp0),
+ FUNCTION(i2c0),
+ FUNCTION(ipgpio),
+ FUNCTION(msp2),
+ FUNCTION(mc4),
+ FUNCTION(mc1),
+ FUNCTION(hsi),
+ FUNCTION(clkout),
+ FUNCTION(usb),
+ FUNCTION(trig),
+ FUNCTION(i2c4),
+ FUNCTION(i2c1),
+ FUNCTION(i2c2),
+ FUNCTION(uartmod),
+ FUNCTION(stmmod),
+ FUNCTION(spi3),
+ FUNCTION(sm),
+ FUNCTION(lcda),
+ FUNCTION(ddrtrig),
+ FUNCTION(pwl),
+ FUNCTION(spi1),
+ FUNCTION(mc3),
+ FUNCTION(ipjtag),
+ FUNCTION(slim0),
+ FUNCTION(ms),
+ FUNCTION(iptrigout),
+ FUNCTION(stmape),
+ FUNCTION(mc5),
+ FUNCTION(usbsim),
+ FUNCTION(i2c3),
+ FUNCTION(spi0),
+ FUNCTION(spi2),
+};
+
+static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
+ .gpio_ranges = nmk_db8500_ranges,
+ .gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges),
+ .pins = nmk_db8500_pins,
+ .npins = ARRAY_SIZE(nmk_db8500_pins),
+ .functions = nmk_db8500_functions,
+ .nfunctions = ARRAY_SIZE(nmk_db8500_functions),
+ .groups = nmk_db8500_groups,
+ .ngroups = ARRAY_SIZE(nmk_db8500_groups),
+};
+
+void __devinit
+nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
+{
+ *soc = &nmk_db8500_soc;
+}
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
new file mode 100644
index 000000000000..b8e01c3eaa95
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -0,0 +1,1780 @@
+/*
+ * Generic GPIO driver for logic cells found in the Nomadik SoC
+ *
+ * Copyright (C) 2008,2009 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ * Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2011 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/slab.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+/* Since we request GPIOs from ourself */
+#include <linux/pinctrl/consumer.h>
+
+#include <asm/mach/irq.h>
+
+#include <plat/pincfg.h>
+#include <plat/gpio-nomadik.h>
+
+#include "pinctrl-nomadik.h"
+
+/*
+ * The GPIO module in the Nomadik family of Systems-on-Chip is an
+ * AMBA device, managing 32 pins and alternate functions. The logic block
+ * is currently used in the Nomadik and ux500.
+ *
+ * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
+ */
+
+#define NMK_GPIO_PER_CHIP 32
+
+struct nmk_gpio_chip {
+ struct gpio_chip chip;
+ struct irq_domain *domain;
+ void __iomem *addr;
+ struct clk *clk;
+ unsigned int bank;
+ unsigned int parent_irq;
+ int secondary_parent_irq;
+ u32 (*get_secondary_status)(unsigned int bank);
+ void (*set_ioforce)(bool enable);
+ spinlock_t lock;
+ bool sleepmode;
+ /* Keep track of configured edges */
+ u32 edge_rising;
+ u32 edge_falling;
+ u32 real_wake;
+ u32 rwimsc;
+ u32 fwimsc;
+ u32 rimsc;
+ u32 fimsc;
+ u32 pull_up;
+ u32 lowemi;
+};
+
+struct nmk_pinctrl {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ const struct nmk_pinctrl_soc_data *soc;
+};
+
+static struct nmk_gpio_chip *
+nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
+
+static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
+
+#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
+
+static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int gpio_mode)
+{
+ u32 bit = 1 << offset;
+ u32 afunc, bfunc;
+
+ afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
+ bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
+ if (gpio_mode & NMK_GPIO_ALT_A)
+ afunc |= bit;
+ if (gpio_mode & NMK_GPIO_ALT_B)
+ bfunc |= bit;
+ writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
+ writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+}
+
+static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, enum nmk_gpio_slpm mode)
+{
+ u32 bit = 1 << offset;
+ u32 slpm;
+
+ slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
+ if (mode == NMK_GPIO_SLPM_NOCHANGE)
+ slpm |= bit;
+ else
+ slpm &= ~bit;
+ writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
+}
+
+static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, enum nmk_gpio_pull pull)
+{
+ u32 bit = 1 << offset;
+ u32 pdis;
+
+ pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
+ if (pull == NMK_GPIO_PULL_NONE) {
+ pdis |= bit;
+ nmk_chip->pull_up &= ~bit;
+ } else {
+ pdis &= ~bit;
+ }
+
+ writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
+
+ if (pull == NMK_GPIO_PULL_UP) {
+ nmk_chip->pull_up |= bit;
+ writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+ } else if (pull == NMK_GPIO_PULL_DOWN) {
+ nmk_chip->pull_up &= ~bit;
+ writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+ }
+}
+
+static void __nmk_gpio_set_lowemi(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, bool lowemi)
+{
+ u32 bit = BIT(offset);
+ bool enabled = nmk_chip->lowemi & bit;
+
+ if (lowemi == enabled)
+ return;
+
+ if (lowemi)
+ nmk_chip->lowemi |= bit;
+ else
+ nmk_chip->lowemi &= ~bit;
+
+ writel_relaxed(nmk_chip->lowemi,
+ nmk_chip->addr + NMK_GPIO_LOWEMI);
+}
+
+static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset)
+{
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+}
+
+static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int val)
+{
+ if (val)
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
+ else
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int val)
+{
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+ __nmk_gpio_set_output(nmk_chip, offset, val);
+}
+
+static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int gpio_mode,
+ bool glitch)
+{
+ u32 rwimsc = nmk_chip->rwimsc;
+ u32 fwimsc = nmk_chip->fwimsc;
+
+ if (glitch && nmk_chip->set_ioforce) {
+ u32 bit = BIT(offset);
+
+ /* Prevent spurious wakeups */
+ writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
+ writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
+
+ nmk_chip->set_ioforce(true);
+ }
+
+ __nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
+
+ if (glitch && nmk_chip->set_ioforce) {
+ nmk_chip->set_ioforce(false);
+
+ writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
+ writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
+ }
+}
+
+static void
+nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset)
+{
+ u32 falling = nmk_chip->fimsc & BIT(offset);
+ u32 rising = nmk_chip->rimsc & BIT(offset);
+ int gpio = nmk_chip->chip.base + offset;
+ int irq = NOMADIK_GPIO_TO_IRQ(gpio);
+ struct irq_data *d = irq_get_irq_data(irq);
+
+ if (!rising && !falling)
+ return;
+
+ if (!d || !irqd_irq_disabled(d))
+ return;
+
+ if (rising) {
+ nmk_chip->rimsc &= ~BIT(offset);
+ writel_relaxed(nmk_chip->rimsc,
+ nmk_chip->addr + NMK_GPIO_RIMSC);
+ }
+
+ if (falling) {
+ nmk_chip->fimsc &= ~BIT(offset);
+ writel_relaxed(nmk_chip->fimsc,
+ nmk_chip->addr + NMK_GPIO_FIMSC);
+ }
+
+ dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
+}
+
+static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
+ pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
+{
+ static const char *afnames[] = {
+ [NMK_GPIO_ALT_GPIO] = "GPIO",
+ [NMK_GPIO_ALT_A] = "A",
+ [NMK_GPIO_ALT_B] = "B",
+ [NMK_GPIO_ALT_C] = "C"
+ };
+ static const char *pullnames[] = {
+ [NMK_GPIO_PULL_NONE] = "none",
+ [NMK_GPIO_PULL_UP] = "up",
+ [NMK_GPIO_PULL_DOWN] = "down",
+ [3] /* illegal */ = "??"
+ };
+ static const char *slpmnames[] = {
+ [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
+ [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
+ };
+
+ int pin = PIN_NUM(cfg);
+ int pull = PIN_PULL(cfg);
+ int af = PIN_ALT(cfg);
+ int slpm = PIN_SLPM(cfg);
+ int output = PIN_DIR(cfg);
+ int val = PIN_VAL(cfg);
+ bool glitch = af == NMK_GPIO_ALT_C;
+
+ dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
+ pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
+ output ? "output " : "input",
+ output ? (val ? "high" : "low") : "");
+
+ if (sleep) {
+ int slpm_pull = PIN_SLPM_PULL(cfg);
+ int slpm_output = PIN_SLPM_DIR(cfg);
+ int slpm_val = PIN_SLPM_VAL(cfg);
+
+ af = NMK_GPIO_ALT_GPIO;
+
+ /*
+ * The SLPM_* values are normal values + 1 to allow zero to
+ * mean "same as normal".
+ */
+ if (slpm_pull)
+ pull = slpm_pull - 1;
+ if (slpm_output)
+ output = slpm_output - 1;
+ if (slpm_val)
+ val = slpm_val - 1;
+
+ dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
+ pin,
+ slpm_pull ? pullnames[pull] : "same",
+ slpm_output ? (output ? "output" : "input") : "same",
+ slpm_val ? (val ? "high" : "low") : "same");
+ }
+
+ if (output)
+ __nmk_gpio_make_output(nmk_chip, offset, val);
+ else {
+ __nmk_gpio_make_input(nmk_chip, offset);
+ __nmk_gpio_set_pull(nmk_chip, offset, pull);
+ }
+
+ __nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg));
+
+ /*
+ * If the pin is switching to altfunc, and there was an interrupt
+ * installed on it which has been lazy disabled, actually mask the
+ * interrupt to prevent spurious interrupts that would occur while the
+ * pin is under control of the peripheral. Only SKE does this.
+ */
+ if (af != NMK_GPIO_ALT_GPIO)
+ nmk_gpio_disable_lazy_irq(nmk_chip, offset);
+
+ /*
+ * If we've backed up the SLPM registers (glitch workaround), modify
+ * the backups since they will be restored.
+ */
+ if (slpmregs) {
+ if (slpm == NMK_GPIO_SLPM_NOCHANGE)
+ slpmregs[nmk_chip->bank] |= BIT(offset);
+ else
+ slpmregs[nmk_chip->bank] &= ~BIT(offset);
+ } else
+ __nmk_gpio_set_slpm(nmk_chip, offset, slpm);
+
+ __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
+}
+
+/*
+ * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
+ * - Save SLPM registers
+ * - Set SLPM=0 for the IOs you want to switch and others to 1
+ * - Configure the GPIO registers for the IOs that are being switched
+ * - Set IOFORCE=1
+ * - Modify the AFLSA/B registers for the IOs that are being switched
+ * - Set IOFORCE=0
+ * - Restore SLPM registers
+ * - Any spurious wake up event during switch sequence to be ignored and
+ * cleared
+ */
+static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
+{
+ int i;
+
+ for (i = 0; i < NUM_BANKS; i++) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+ unsigned int temp = slpm[i];
+
+ if (!chip)
+ break;
+
+ clk_enable(chip->clk);
+
+ slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
+ writel(temp, chip->addr + NMK_GPIO_SLPC);
+ }
+}
+
+static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
+{
+ int i;
+
+ for (i = 0; i < NUM_BANKS; i++) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+ if (!chip)
+ break;
+
+ writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
+
+ clk_disable(chip->clk);
+ }
+}
+
+static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
+{
+ static unsigned int slpm[NUM_BANKS];
+ unsigned long flags;
+ bool glitch = false;
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) {
+ glitch = true;
+ break;
+ }
+ }
+
+ spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+
+ if (glitch) {
+ memset(slpm, 0xff, sizeof(slpm));
+
+ for (i = 0; i < num; i++) {
+ int pin = PIN_NUM(cfgs[i]);
+ int offset = pin % NMK_GPIO_PER_CHIP;
+
+ if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C)
+ slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset);
+ }
+
+ nmk_gpio_glitch_slpm_init(slpm);
+ }
+
+ for (i = 0; i < num; i++) {
+ struct nmk_gpio_chip *nmk_chip;
+ int pin = PIN_NUM(cfgs[i]);
+
+ nmk_chip = nmk_gpio_chips[pin / NMK_GPIO_PER_CHIP];
+ if (!nmk_chip) {
+ ret = -EINVAL;
+ break;
+ }
+
+ clk_enable(nmk_chip->clk);
+ spin_lock(&nmk_chip->lock);
+ __nmk_config_pin(nmk_chip, pin % NMK_GPIO_PER_CHIP,
+ cfgs[i], sleep, glitch ? slpm : NULL);
+ spin_unlock(&nmk_chip->lock);
+ clk_disable(nmk_chip->clk);
+ }
+
+ if (glitch)
+ nmk_gpio_glitch_slpm_restore(slpm);
+
+ spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+
+ return ret;
+}
+
+/**
+ * nmk_config_pin - configure a pin's mux attributes
+ * @cfg: pin confguration
+ *
+ * Configures a pin's mode (alternate function or GPIO), its pull up status,
+ * and its sleep mode based on the specified configuration. The @cfg is
+ * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These
+ * are constructed using, and can be further enhanced with, the macros in
+ * plat/pincfg.h.
+ *
+ * If a pin's mode is set to GPIO, it is configured as an input to avoid
+ * side-effects. The gpio can be manipulated later using standard GPIO API
+ * calls.
+ */
+int nmk_config_pin(pin_cfg_t cfg, bool sleep)
+{
+ return __nmk_config_pins(&cfg, 1, sleep);
+}
+EXPORT_SYMBOL(nmk_config_pin);
+
+/**
+ * nmk_config_pins - configure several pins at once
+ * @cfgs: array of pin configurations
+ * @num: number of elments in the array
+ *
+ * Configures several pins using nmk_config_pin(). Refer to that function for
+ * further information.
+ */
+int nmk_config_pins(pin_cfg_t *cfgs, int num)
+{
+ return __nmk_config_pins(cfgs, num, false);
+}
+EXPORT_SYMBOL(nmk_config_pins);
+
+int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
+{
+ return __nmk_config_pins(cfgs, num, true);
+}
+EXPORT_SYMBOL(nmk_config_pins_sleep);
+
+/**
+ * nmk_gpio_set_slpm() - configure the sleep mode of a pin
+ * @gpio: pin number
+ * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
+ *
+ * This register is actually in the pinmux layer, not the GPIO block itself.
+ * The GPIO1B_SLPM register defines the GPIO mode when SLEEP/DEEP-SLEEP
+ * mode is entered (i.e. when signal IOFORCE is HIGH by the platform code).
+ * Each GPIO can be configured to be forced into GPIO mode when IOFORCE is
+ * HIGH, overriding the normal setting defined by GPIO_AFSELx registers.
+ * When IOFORCE returns LOW (by software, after SLEEP/DEEP-SLEEP exit),
+ * the GPIOs return to the normal setting defined by GPIO_AFSELx registers.
+ *
+ * If @mode is NMK_GPIO_SLPM_INPUT, the corresponding GPIO is switched to GPIO
+ * mode when signal IOFORCE is HIGH (i.e. when SLEEP/DEEP-SLEEP mode is
+ * entered) regardless of the altfunction selected. Also wake-up detection is
+ * ENABLED.
+ *
+ * If @mode is NMK_GPIO_SLPM_NOCHANGE, the corresponding GPIO remains
+ * controlled by NMK_GPIO_DATC, NMK_GPIO_DATS, NMK_GPIO_DIR, NMK_GPIO_PDIS
+ * (for altfunction GPIO) or respective on-chip peripherals (for other
+ * altfuncs) when IOFORCE is HIGH. Also wake-up detection DISABLED.
+ *
+ * Note that enable_irq_wake() will automatically enable wakeup detection.
+ */
+int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
+ if (!nmk_chip)
+ return -EINVAL;
+
+ clk_enable(nmk_chip->clk);
+ spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+ spin_lock(&nmk_chip->lock);
+
+ __nmk_gpio_set_slpm(nmk_chip, gpio % NMK_GPIO_PER_CHIP, mode);
+
+ spin_unlock(&nmk_chip->lock);
+ spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+/**
+ * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
+ * @gpio: pin number
+ * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
+ *
+ * Enables/disables pull up/down on a specified pin. This only takes effect if
+ * the pin is configured as an input (either explicitly or by the alternate
+ * function).
+ *
+ * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
+ * configured as an input. Otherwise, due to the way the controller registers
+ * work, this function will change the value output on the pin.
+ */
+int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
+ if (!nmk_chip)
+ return -EINVAL;
+
+ clk_enable(nmk_chip->clk);
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+ __nmk_gpio_set_pull(nmk_chip, gpio % NMK_GPIO_PER_CHIP, pull);
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+/* Mode functions */
+/**
+ * nmk_gpio_set_mode() - set the mux mode of a gpio pin
+ * @gpio: pin number
+ * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A,
+ * NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C
+ *
+ * Sets the mode of the specified pin to one of the alternate functions or
+ * plain GPIO.
+ */
+int nmk_gpio_set_mode(int gpio, int gpio_mode)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
+ if (!nmk_chip)
+ return -EINVAL;
+
+ clk_enable(nmk_chip->clk);
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+ __nmk_gpio_set_mode(nmk_chip, gpio % NMK_GPIO_PER_CHIP, gpio_mode);
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+EXPORT_SYMBOL(nmk_gpio_set_mode);
+
+int nmk_gpio_get_mode(int gpio)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ u32 afunc, bfunc, bit;
+
+ nmk_chip = nmk_gpio_chips[gpio / NMK_GPIO_PER_CHIP];
+ if (!nmk_chip)
+ return -EINVAL;
+
+ bit = 1 << (gpio % NMK_GPIO_PER_CHIP);
+
+ clk_enable(nmk_chip->clk);
+
+ afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
+ bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
+
+ clk_disable(nmk_chip->clk);
+
+ return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
+}
+EXPORT_SYMBOL(nmk_gpio_get_mode);
+
+
+/* IRQ functions */
+static inline int nmk_gpio_get_bitmask(int gpio)
+{
+ return 1 << (gpio % NMK_GPIO_PER_CHIP);
+}
+
+static void nmk_gpio_irq_ack(struct irq_data *d)
+{
+ struct nmk_gpio_chip *nmk_chip;
+
+ nmk_chip = irq_data_get_irq_chip_data(d);
+ if (!nmk_chip)
+ return;
+
+ clk_enable(nmk_chip->clk);
+ writel(nmk_gpio_get_bitmask(d->hwirq), nmk_chip->addr + NMK_GPIO_IC);
+ clk_disable(nmk_chip->clk);
+}
+
+enum nmk_gpio_irq_type {
+ NORMAL,
+ WAKE,
+};
+
+static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
+ int gpio, enum nmk_gpio_irq_type which,
+ bool enable)
+{
+ u32 bitmask = nmk_gpio_get_bitmask(gpio);
+ u32 *rimscval;
+ u32 *fimscval;
+ u32 rimscreg;
+ u32 fimscreg;
+
+ if (which == NORMAL) {
+ rimscreg = NMK_GPIO_RIMSC;
+ fimscreg = NMK_GPIO_FIMSC;
+ rimscval = &nmk_chip->rimsc;
+ fimscval = &nmk_chip->fimsc;
+ } else {
+ rimscreg = NMK_GPIO_RWIMSC;
+ fimscreg = NMK_GPIO_FWIMSC;
+ rimscval = &nmk_chip->rwimsc;
+ fimscval = &nmk_chip->fwimsc;
+ }
+
+ /* we must individually set/clear the two edges */
+ if (nmk_chip->edge_rising & bitmask) {
+ if (enable)
+ *rimscval |= bitmask;
+ else
+ *rimscval &= ~bitmask;
+ writel(*rimscval, nmk_chip->addr + rimscreg);
+ }
+ if (nmk_chip->edge_falling & bitmask) {
+ if (enable)
+ *fimscval |= bitmask;
+ else
+ *fimscval &= ~bitmask;
+ writel(*fimscval, nmk_chip->addr + fimscreg);
+ }
+}
+
+static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
+ int gpio, bool on)
+{
+ /*
+ * Ensure WAKEUP_ENABLE is on. No need to disable it if wakeup is
+ * disabled, since setting SLPM to 1 increases power consumption, and
+ * wakeup is anyhow controlled by the RIMSC and FIMSC registers.
+ */
+ if (nmk_chip->sleepmode && on) {
+ __nmk_gpio_set_slpm(nmk_chip, gpio % nmk_chip->chip.base,
+ NMK_GPIO_SLPM_WAKEUP_ENABLE);
+ }
+
+ __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
+}
+
+static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+ u32 bitmask;
+
+ nmk_chip = irq_data_get_irq_chip_data(d);
+ bitmask = nmk_gpio_get_bitmask(d->hwirq);
+ if (!nmk_chip)
+ return -EINVAL;
+
+ clk_enable(nmk_chip->clk);
+ spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+ spin_lock(&nmk_chip->lock);
+
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, enable);
+
+ if (!(nmk_chip->real_wake & bitmask))
+ __nmk_gpio_set_wake(nmk_chip, d->hwirq, enable);
+
+ spin_unlock(&nmk_chip->lock);
+ spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+static void nmk_gpio_irq_mask(struct irq_data *d)
+{
+ nmk_gpio_irq_maskunmask(d, false);
+}
+
+static void nmk_gpio_irq_unmask(struct irq_data *d)
+{
+ nmk_gpio_irq_maskunmask(d, true);
+}
+
+static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+ u32 bitmask;
+
+ nmk_chip = irq_data_get_irq_chip_data(d);
+ if (!nmk_chip)
+ return -EINVAL;
+ bitmask = nmk_gpio_get_bitmask(d->hwirq);
+
+ clk_enable(nmk_chip->clk);
+ spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+ spin_lock(&nmk_chip->lock);
+
+ if (irqd_irq_disabled(d))
+ __nmk_gpio_set_wake(nmk_chip, d->hwirq, on);
+
+ if (on)
+ nmk_chip->real_wake |= bitmask;
+ else
+ nmk_chip->real_wake &= ~bitmask;
+
+ spin_unlock(&nmk_chip->lock);
+ spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+ bool enabled = !irqd_irq_disabled(d);
+ bool wake = irqd_is_wakeup_set(d);
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+ u32 bitmask;
+
+ nmk_chip = irq_data_get_irq_chip_data(d);
+ bitmask = nmk_gpio_get_bitmask(d->hwirq);
+ if (!nmk_chip)
+ return -EINVAL;
+ if (type & IRQ_TYPE_LEVEL_HIGH)
+ return -EINVAL;
+ if (type & IRQ_TYPE_LEVEL_LOW)
+ return -EINVAL;
+
+ clk_enable(nmk_chip->clk);
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+
+ if (enabled)
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, false);
+
+ if (enabled || wake)
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, false);
+
+ nmk_chip->edge_rising &= ~bitmask;
+ if (type & IRQ_TYPE_EDGE_RISING)
+ nmk_chip->edge_rising |= bitmask;
+
+ nmk_chip->edge_falling &= ~bitmask;
+ if (type & IRQ_TYPE_EDGE_FALLING)
+ nmk_chip->edge_falling |= bitmask;
+
+ if (enabled)
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, NORMAL, true);
+
+ if (enabled || wake)
+ __nmk_gpio_irq_modify(nmk_chip, d->hwirq, WAKE, true);
+
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+static unsigned int nmk_gpio_irq_startup(struct irq_data *d)
+{
+ struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
+
+ clk_enable(nmk_chip->clk);
+ nmk_gpio_irq_unmask(d);
+ return 0;
+}
+
+static void nmk_gpio_irq_shutdown(struct irq_data *d)
+{
+ struct nmk_gpio_chip *nmk_chip = irq_data_get_irq_chip_data(d);
+
+ nmk_gpio_irq_mask(d);
+ clk_disable(nmk_chip->clk);
+}
+
+static struct irq_chip nmk_gpio_irq_chip = {
+ .name = "Nomadik-GPIO",
+ .irq_ack = nmk_gpio_irq_ack,
+ .irq_mask = nmk_gpio_irq_mask,
+ .irq_unmask = nmk_gpio_irq_unmask,
+ .irq_set_type = nmk_gpio_irq_set_type,
+ .irq_set_wake = nmk_gpio_irq_set_wake,
+ .irq_startup = nmk_gpio_irq_startup,
+ .irq_shutdown = nmk_gpio_irq_shutdown,
+};
+
+static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
+ u32 status)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ struct irq_chip *host_chip = irq_get_chip(irq);
+ unsigned int first_irq;
+
+ chained_irq_enter(host_chip, desc);
+
+ nmk_chip = irq_get_handler_data(irq);
+ first_irq = nmk_chip->domain->revmap_data.legacy.first_irq;
+ while (status) {
+ int bit = __ffs(status);
+
+ generic_handle_irq(first_irq + bit);
+ status &= ~BIT(bit);
+ }
+
+ chained_irq_exit(host_chip, desc);
+}
+
+static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
+ u32 status;
+
+ clk_enable(nmk_chip->clk);
+ status = readl(nmk_chip->addr + NMK_GPIO_IS);
+ clk_disable(nmk_chip->clk);
+
+ __nmk_gpio_irq_handler(irq, desc, status);
+}
+
+static void nmk_gpio_secondary_irq_handler(unsigned int irq,
+ struct irq_desc *desc)
+{
+ struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
+ u32 status = nmk_chip->get_secondary_status(nmk_chip->bank);
+
+ __nmk_gpio_irq_handler(irq, desc, status);
+}
+
+static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
+{
+ irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
+ irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
+
+ if (nmk_chip->secondary_parent_irq >= 0) {
+ irq_set_chained_handler(nmk_chip->secondary_parent_irq,
+ nmk_gpio_secondary_irq_handler);
+ irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip);
+ }
+
+ return 0;
+}
+
+/* I/O Functions */
+
+static int nmk_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ /*
+ * Map back to global GPIO space and request muxing, the direction
+ * parameter does not matter for this controller.
+ */
+ int gpio = chip->base + offset;
+
+ return pinctrl_request_gpio(gpio);
+}
+
+static void nmk_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ int gpio = chip->base + offset;
+
+ pinctrl_free_gpio(gpio);
+}
+
+static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+
+ clk_enable(nmk_chip->clk);
+
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+ u32 bit = 1 << offset;
+ int value;
+
+ clk_enable(nmk_chip->clk);
+
+ value = (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
+
+ clk_disable(nmk_chip->clk);
+
+ return value;
+}
+
+static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
+ int val)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+
+ clk_enable(nmk_chip->clk);
+
+ __nmk_gpio_set_output(nmk_chip, offset, val);
+
+ clk_disable(nmk_chip->clk);
+}
+
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+ int val)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+
+ clk_enable(nmk_chip->clk);
+
+ __nmk_gpio_make_output(nmk_chip, offset, val);
+
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+
+ return irq_find_mapping(nmk_chip->domain, offset);
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/seq_file.h>
+
+static void nmk_gpio_dbg_show_one(struct seq_file *s, struct gpio_chip *chip,
+ unsigned offset, unsigned gpio)
+{
+ const char *label = gpiochip_is_requested(chip, offset);
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+ int mode;
+ bool is_out;
+ bool pull;
+ u32 bit = 1 << offset;
+ const char *modes[] = {
+ [NMK_GPIO_ALT_GPIO] = "gpio",
+ [NMK_GPIO_ALT_A] = "altA",
+ [NMK_GPIO_ALT_B] = "altB",
+ [NMK_GPIO_ALT_C] = "altC",
+ };
+
+ clk_enable(nmk_chip->clk);
+ is_out = !!(readl(nmk_chip->addr + NMK_GPIO_DIR) & bit);
+ pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
+ mode = nmk_gpio_get_mode(gpio);
+
+ seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
+ gpio, label ?: "(none)",
+ is_out ? "out" : "in ",
+ chip->get
+ ? (chip->get(chip, offset) ? "hi" : "lo")
+ : "? ",
+ (mode < 0) ? "unknown" : modes[mode],
+ pull ? "pull" : "none");
+
+ if (label && !is_out) {
+ int irq = gpio_to_irq(gpio);
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ /* This races with request_irq(), set_irq_type(),
+ * and set_irq_wake() ... but those are "rare".
+ */
+ if (irq >= 0 && desc->action) {
+ char *trigger;
+ u32 bitmask = nmk_gpio_get_bitmask(gpio);
+
+ if (nmk_chip->edge_rising & bitmask)
+ trigger = "edge-rising";
+ else if (nmk_chip->edge_falling & bitmask)
+ trigger = "edge-falling";
+ else
+ trigger = "edge-undefined";
+
+ seq_printf(s, " irq-%d %s%s",
+ irq, trigger,
+ irqd_is_wakeup_set(&desc->irq_data)
+ ? " wakeup" : "");
+ }
+ }
+ clk_disable(nmk_chip->clk);
+}
+
+static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ unsigned i;
+ unsigned gpio = chip->base;
+
+ for (i = 0; i < chip->ngpio; i++, gpio++) {
+ nmk_gpio_dbg_show_one(s, chip, i, gpio);
+ seq_printf(s, "\n");
+ }
+}
+
+#else
+static inline void nmk_gpio_dbg_show_one(struct seq_file *s,
+ struct gpio_chip *chip,
+ unsigned offset, unsigned gpio)
+{
+}
+#define nmk_gpio_dbg_show NULL
+#endif
+
+/* This structure is replicated for each GPIO block allocated at probe time */
+static struct gpio_chip nmk_gpio_template = {
+ .request = nmk_gpio_request,
+ .free = nmk_gpio_free,
+ .direction_input = nmk_gpio_make_input,
+ .get = nmk_gpio_get_input,
+ .direction_output = nmk_gpio_make_output,
+ .set = nmk_gpio_set_output,
+ .to_irq = nmk_gpio_to_irq,
+ .dbg_show = nmk_gpio_dbg_show,
+ .can_sleep = 0,
+};
+
+void nmk_gpio_clocks_enable(void)
+{
+ int i;
+
+ for (i = 0; i < NUM_BANKS; i++) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+ if (!chip)
+ continue;
+
+ clk_enable(chip->clk);
+ }
+}
+
+void nmk_gpio_clocks_disable(void)
+{
+ int i;
+
+ for (i = 0; i < NUM_BANKS; i++) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+ if (!chip)
+ continue;
+
+ clk_disable(chip->clk);
+ }
+}
+
+/*
+ * Called from the suspend/resume path to only keep the real wakeup interrupts
+ * (those that have had set_irq_wake() called on them) as wakeup interrupts,
+ * and not the rest of the interrupts which we needed to have as wakeups for
+ * cpuidle.
+ *
+ * PM ops are not used since this needs to be done at the end, after all the
+ * other drivers are done with their suspend callbacks.
+ */
+void nmk_gpio_wakeups_suspend(void)
+{
+ int i;
+
+ for (i = 0; i < NUM_BANKS; i++) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+ if (!chip)
+ break;
+
+ clk_enable(chip->clk);
+
+ writel(chip->rwimsc & chip->real_wake,
+ chip->addr + NMK_GPIO_RWIMSC);
+ writel(chip->fwimsc & chip->real_wake,
+ chip->addr + NMK_GPIO_FWIMSC);
+
+ clk_disable(chip->clk);
+ }
+}
+
+void nmk_gpio_wakeups_resume(void)
+{
+ int i;
+
+ for (i = 0; i < NUM_BANKS; i++) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+ if (!chip)
+ break;
+
+ clk_enable(chip->clk);
+
+ writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
+ writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
+
+ clk_disable(chip->clk);
+ }
+}
+
+/*
+ * Read the pull up/pull down status.
+ * A bit set in 'pull_up' means that pull up
+ * is selected if pull is enabled in PDIS register.
+ * Note: only pull up/down set via this driver can
+ * be detected due to HW limitations.
+ */
+void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
+{
+ if (gpio_bank < NUM_BANKS) {
+ struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
+
+ if (!chip)
+ return;
+
+ *pull_up = chip->pull_up;
+ }
+}
+
+int nmk_gpio_irq_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct nmk_gpio_chip *nmk_chip = d->host_data;
+
+ if (!nmk_chip)
+ return -EINVAL;
+
+ irq_set_chip_and_handler(irq, &nmk_gpio_irq_chip, handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ irq_set_chip_data(irq, nmk_chip);
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING);
+
+ return 0;
+}
+
+const struct irq_domain_ops nmk_gpio_irq_simple_ops = {
+ .map = nmk_gpio_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+static int __devinit nmk_gpio_probe(struct platform_device *dev)
+{
+ struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
+ struct device_node *np = dev->dev.of_node;
+ struct nmk_gpio_chip *nmk_chip;
+ struct gpio_chip *chip;
+ struct resource *res;
+ struct clk *clk;
+ int secondary_irq;
+ void __iomem *base;
+ int irq;
+ int ret;
+
+ if (!pdata && !np) {
+ dev_err(&dev->dev, "No platform data or device tree found\n");
+ return -ENODEV;
+ }
+
+ if (np) {
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ if (of_get_property(np, "supports-sleepmode", NULL))
+ pdata->supports_sleepmode = true;
+
+ if (of_property_read_u32(np, "gpio-bank", &dev->id)) {
+ dev_err(&dev->dev, "gpio-bank property not found\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ pdata->first_gpio = dev->id * NMK_GPIO_PER_CHIP;
+ pdata->num_gpio = NMK_GPIO_PER_CHIP;
+ }
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ irq = platform_get_irq(dev, 0);
+ if (irq < 0) {
+ ret = irq;
+ goto out;
+ }
+
+ secondary_irq = platform_get_irq(dev, 1);
+ if (secondary_irq >= 0 && !pdata->get_secondary_status) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (request_mem_region(res->start, resource_size(res),
+ dev_name(&dev->dev)) == NULL) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ base = ioremap(res->start, resource_size(res));
+ if (!base) {
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
+ clk = clk_get(&dev->dev, NULL);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ goto out_unmap;
+ }
+
+ nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
+ if (!nmk_chip) {
+ ret = -ENOMEM;
+ goto out_clk;
+ }
+
+ /*
+ * The virt address in nmk_chip->addr is in the nomadik register space,
+ * so we can simply convert the resource address, without remapping
+ */
+ nmk_chip->bank = dev->id;
+ nmk_chip->clk = clk;
+ nmk_chip->addr = base;
+ nmk_chip->chip = nmk_gpio_template;
+ nmk_chip->parent_irq = irq;
+ nmk_chip->secondary_parent_irq = secondary_irq;
+ nmk_chip->get_secondary_status = pdata->get_secondary_status;
+ nmk_chip->set_ioforce = pdata->set_ioforce;
+ nmk_chip->sleepmode = pdata->supports_sleepmode;
+ spin_lock_init(&nmk_chip->lock);
+
+ chip = &nmk_chip->chip;
+ chip->base = pdata->first_gpio;
+ chip->ngpio = pdata->num_gpio;
+ chip->label = pdata->name ?: dev_name(&dev->dev);
+ chip->dev = &dev->dev;
+ chip->owner = THIS_MODULE;
+
+ clk_enable(nmk_chip->clk);
+ nmk_chip->lowemi = readl_relaxed(nmk_chip->addr + NMK_GPIO_LOWEMI);
+ clk_disable(nmk_chip->clk);
+
+#ifdef CONFIG_OF_GPIO
+ chip->of_node = np;
+#endif
+
+ ret = gpiochip_add(&nmk_chip->chip);
+ if (ret)
+ goto out_free;
+
+ BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
+
+ nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
+
+ platform_set_drvdata(dev, nmk_chip);
+
+ nmk_chip->domain = irq_domain_add_legacy(np, NMK_GPIO_PER_CHIP,
+ NOMADIK_GPIO_TO_IRQ(pdata->first_gpio),
+ 0, &nmk_gpio_irq_simple_ops, nmk_chip);
+ if (!nmk_chip->domain) {
+ pr_err("%s: Failed to create irqdomain\n", np->full_name);
+ ret = -ENOSYS;
+ goto out_free;
+ }
+
+ nmk_gpio_init_irq(nmk_chip);
+
+ dev_info(&dev->dev, "at address %p\n", nmk_chip->addr);
+
+ return 0;
+
+out_free:
+ kfree(nmk_chip);
+out_clk:
+ clk_disable(clk);
+ clk_put(clk);
+out_unmap:
+ iounmap(base);
+out_release:
+ release_mem_region(res->start, resource_size(res));
+out:
+ dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
+ pdata->first_gpio, pdata->first_gpio+31);
+ if (np)
+ kfree(pdata);
+
+ return ret;
+}
+
+static int nmk_get_groups_cnt(struct pinctrl_dev *pctldev)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ return npct->soc->ngroups;
+}
+
+static const char *nmk_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned selector)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ return npct->soc->groups[selector].name;
+}
+
+static int nmk_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = npct->soc->groups[selector].pins;
+ *num_pins = npct->soc->groups[selector].npins;
+ return 0;
+}
+
+static struct pinctrl_gpio_range *
+nmk_match_gpio_range(struct pinctrl_dev *pctldev, unsigned offset)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ int i;
+
+ for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
+ struct pinctrl_gpio_range *range;
+
+ range = &npct->soc->gpio_ranges[i];
+ if (offset >= range->pin_base &&
+ offset <= (range->pin_base + range->npins - 1))
+ return range;
+ }
+ return NULL;
+}
+
+static void nmk_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+ unsigned offset)
+{
+ struct pinctrl_gpio_range *range;
+ struct gpio_chip *chip;
+
+ range = nmk_match_gpio_range(pctldev, offset);
+ if (!range || !range->gc) {
+ seq_printf(s, "invalid pin offset");
+ return;
+ }
+ chip = range->gc;
+ nmk_gpio_dbg_show_one(s, chip, offset - chip->base, offset);
+}
+
+static struct pinctrl_ops nmk_pinctrl_ops = {
+ .get_groups_count = nmk_get_groups_cnt,
+ .get_group_name = nmk_get_group_name,
+ .get_group_pins = nmk_get_group_pins,
+ .pin_dbg_show = nmk_pin_dbg_show,
+};
+
+static int nmk_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ return npct->soc->nfunctions;
+}
+
+static const char *nmk_pmx_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned function)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ return npct->soc->functions[function].name;
+}
+
+static int nmk_pmx_get_func_groups(struct pinctrl_dev *pctldev,
+ unsigned function,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = npct->soc->functions[function].groups;
+ *num_groups = npct->soc->functions[function].ngroups;
+
+ return 0;
+}
+
+static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function,
+ unsigned group)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ const struct nmk_pingroup *g;
+ static unsigned int slpm[NUM_BANKS];
+ unsigned long flags;
+ bool glitch;
+ int ret = -EINVAL;
+ int i;
+
+ g = &npct->soc->groups[group];
+
+ if (g->altsetting < 0)
+ return -EINVAL;
+
+ dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins);
+
+ /* Handle this special glitch on altfunction C */
+ glitch = (g->altsetting == NMK_GPIO_ALT_C);
+
+ if (glitch) {
+ spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+
+ /* Initially don't put any pins to sleep when switching */
+ memset(slpm, 0xff, sizeof(slpm));
+
+ /*
+ * Then mask the pins that need to be sleeping now when we're
+ * switching to the ALT C function.
+ */
+ for (i = 0; i < g->npins; i++)
+ slpm[g->pins[i] / NMK_GPIO_PER_CHIP] &= ~BIT(g->pins[i]);
+ nmk_gpio_glitch_slpm_init(slpm);
+ }
+
+ for (i = 0; i < g->npins; i++) {
+ struct pinctrl_gpio_range *range;
+ struct nmk_gpio_chip *nmk_chip;
+ struct gpio_chip *chip;
+ unsigned bit;
+
+ range = nmk_match_gpio_range(pctldev, g->pins[i]);
+ if (!range) {
+ dev_err(npct->dev,
+ "invalid pin offset %d in group %s at index %d\n",
+ g->pins[i], g->name, i);
+ goto out_glitch;
+ }
+ if (!range->gc) {
+ dev_err(npct->dev, "GPIO chip missing in range for pin offset %d in group %s at index %d\n",
+ g->pins[i], g->name, i);
+ goto out_glitch;
+ }
+ chip = range->gc;
+ nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+ dev_dbg(npct->dev, "setting pin %d to altsetting %d\n", g->pins[i], g->altsetting);
+
+ clk_enable(nmk_chip->clk);
+ bit = g->pins[i] % NMK_GPIO_PER_CHIP;
+ /*
+ * If the pin is switching to altfunc, and there was an
+ * interrupt installed on it which has been lazy disabled,
+ * actually mask the interrupt to prevent spurious interrupts
+ * that would occur while the pin is under control of the
+ * peripheral. Only SKE does this.
+ */
+ nmk_gpio_disable_lazy_irq(nmk_chip, bit);
+
+ __nmk_gpio_set_mode_safe(nmk_chip, bit, g->altsetting, glitch);
+ clk_disable(nmk_chip->clk);
+ }
+
+ /* When all pins are successfully reconfigured we get here */
+ ret = 0;
+
+out_glitch:
+ if (glitch) {
+ nmk_gpio_glitch_slpm_restore(slpm);
+ spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+ }
+
+ return ret;
+}
+
+static void nmk_pmx_disable(struct pinctrl_dev *pctldev,
+ unsigned function, unsigned group)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ const struct nmk_pingroup *g;
+
+ g = &npct->soc->groups[group];
+
+ if (g->altsetting < 0)
+ return;
+
+ /* Poke out the mux, set the pin to some default state? */
+ dev_dbg(npct->dev, "disable group %s, %u pins\n", g->name, g->npins);
+}
+
+int nmk_gpio_request_enable(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ struct nmk_gpio_chip *nmk_chip;
+ struct gpio_chip *chip;
+ unsigned bit;
+
+ if (!range) {
+ dev_err(npct->dev, "invalid range\n");
+ return -EINVAL;
+ }
+ if (!range->gc) {
+ dev_err(npct->dev, "missing GPIO chip in range\n");
+ return -EINVAL;
+ }
+ chip = range->gc;
+ nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+
+ dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
+
+ clk_enable(nmk_chip->clk);
+ bit = offset % NMK_GPIO_PER_CHIP;
+ /* There is no glitch when converting any pin to GPIO */
+ __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
+ clk_disable(nmk_chip->clk);
+
+ return 0;
+}
+
+void nmk_gpio_disable_free(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned offset)
+{
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+
+ dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
+ /* Set the pin to some default state, GPIO is usually default */
+}
+
+static struct pinmux_ops nmk_pinmux_ops = {
+ .get_functions_count = nmk_pmx_get_funcs_cnt,
+ .get_function_name = nmk_pmx_get_func_name,
+ .get_function_groups = nmk_pmx_get_func_groups,
+ .enable = nmk_pmx_enable,
+ .disable = nmk_pmx_disable,
+ .gpio_request_enable = nmk_gpio_request_enable,
+ .gpio_disable_free = nmk_gpio_disable_free,
+};
+
+int nmk_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config)
+{
+ /* Not implemented */
+ return -EINVAL;
+}
+
+int nmk_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long config)
+{
+ static const char *pullnames[] = {
+ [NMK_GPIO_PULL_NONE] = "none",
+ [NMK_GPIO_PULL_UP] = "up",
+ [NMK_GPIO_PULL_DOWN] = "down",
+ [3] /* illegal */ = "??"
+ };
+ static const char *slpmnames[] = {
+ [NMK_GPIO_SLPM_INPUT] = "input/wakeup",
+ [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup",
+ };
+ struct nmk_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
+ struct nmk_gpio_chip *nmk_chip;
+ struct pinctrl_gpio_range *range;
+ struct gpio_chip *chip;
+ unsigned bit;
+
+ /*
+ * The pin config contains pin number and altfunction fields, here
+ * we just ignore that part. It's being handled by the framework and
+ * pinmux callback respectively.
+ */
+ pin_cfg_t cfg = (pin_cfg_t) config;
+ int pull = PIN_PULL(cfg);
+ int slpm = PIN_SLPM(cfg);
+ int output = PIN_DIR(cfg);
+ int val = PIN_VAL(cfg);
+ bool lowemi = PIN_LOWEMI(cfg);
+ bool gpiomode = PIN_GPIOMODE(cfg);
+ bool sleep = PIN_SLEEPMODE(cfg);
+
+ range = nmk_match_gpio_range(pctldev, pin);
+ if (!range) {
+ dev_err(npct->dev, "invalid pin offset %d\n", pin);
+ return -EINVAL;
+ }
+ if (!range->gc) {
+ dev_err(npct->dev, "GPIO chip missing in range for pin %d\n",
+ pin);
+ return -EINVAL;
+ }
+ chip = range->gc;
+ nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
+
+ if (sleep) {
+ int slpm_pull = PIN_SLPM_PULL(cfg);
+ int slpm_output = PIN_SLPM_DIR(cfg);
+ int slpm_val = PIN_SLPM_VAL(cfg);
+
+ /* All pins go into GPIO mode at sleep */
+ gpiomode = true;
+
+ /*
+ * The SLPM_* values are normal values + 1 to allow zero to
+ * mean "same as normal".
+ */
+ if (slpm_pull)
+ pull = slpm_pull - 1;
+ if (slpm_output)
+ output = slpm_output - 1;
+ if (slpm_val)
+ val = slpm_val - 1;
+
+ dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
+ pin,
+ slpm_pull ? pullnames[pull] : "same",
+ slpm_output ? (output ? "output" : "input") : "same",
+ slpm_val ? (val ? "high" : "low") : "same");
+ }
+
+ dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n",
+ pin, cfg, pullnames[pull], slpmnames[slpm],
+ output ? "output " : "input",
+ output ? (val ? "high" : "low") : "",
+ lowemi ? "on" : "off" );
+
+ clk_enable(nmk_chip->clk);
+ bit = pin % NMK_GPIO_PER_CHIP;
+ if (gpiomode)
+ /* No glitch when going to GPIO mode */
+ __nmk_gpio_set_mode(nmk_chip, bit, NMK_GPIO_ALT_GPIO);
+ if (output)
+ __nmk_gpio_make_output(nmk_chip, bit, val);
+ else {
+ __nmk_gpio_make_input(nmk_chip, bit);
+ __nmk_gpio_set_pull(nmk_chip, bit, pull);
+ }
+ /* TODO: isn't this only applicable on output pins? */
+ __nmk_gpio_set_lowemi(nmk_chip, bit, lowemi);
+
+ __nmk_gpio_set_slpm(nmk_chip, bit, slpm);
+ clk_disable(nmk_chip->clk);
+ return 0;
+}
+
+static struct pinconf_ops nmk_pinconf_ops = {
+ .pin_config_get = nmk_pin_config_get,
+ .pin_config_set = nmk_pin_config_set,
+};
+
+static struct pinctrl_desc nmk_pinctrl_desc = {
+ .name = "pinctrl-nomadik",
+ .pctlops = &nmk_pinctrl_ops,
+ .pmxops = &nmk_pinmux_ops,
+ .confops = &nmk_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+static int __devinit nmk_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct platform_device_id *platid = platform_get_device_id(pdev);
+ struct nmk_pinctrl *npct;
+ int i;
+
+ npct = devm_kzalloc(&pdev->dev, sizeof(*npct), GFP_KERNEL);
+ if (!npct)
+ return -ENOMEM;
+
+ /* Poke in other ASIC variants here */
+ if (platid->driver_data == PINCTRL_NMK_DB8500)
+ nmk_pinctrl_db8500_init(&npct->soc);
+
+ /*
+ * We need all the GPIO drivers to probe FIRST, or we will not be able
+ * to obtain references to the struct gpio_chip * for them, and we
+ * need this to proceed.
+ */
+ for (i = 0; i < npct->soc->gpio_num_ranges; i++) {
+ if (!nmk_gpio_chips[i]) {
+ dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i);
+ devm_kfree(&pdev->dev, npct);
+ return -EPROBE_DEFER;
+ }
+ npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip;
+ }
+
+ nmk_pinctrl_desc.pins = npct->soc->pins;
+ nmk_pinctrl_desc.npins = npct->soc->npins;
+ npct->dev = &pdev->dev;
+ npct->pctl = pinctrl_register(&nmk_pinctrl_desc, &pdev->dev, npct);
+ if (!npct->pctl) {
+ dev_err(&pdev->dev, "could not register Nomadik pinctrl driver\n");
+ return -EINVAL;
+ }
+
+ /* We will handle a range of GPIO pins */
+ for (i = 0; i < npct->soc->gpio_num_ranges; i++)
+ pinctrl_add_gpio_range(npct->pctl, &npct->soc->gpio_ranges[i]);
+
+ platform_set_drvdata(pdev, npct);
+ dev_info(&pdev->dev, "initialized Nomadik pin control driver\n");
+
+ return 0;
+}
+
+static const struct of_device_id nmk_gpio_match[] = {
+ { .compatible = "st,nomadik-gpio", },
+ {}
+};
+
+static struct platform_driver nmk_gpio_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "gpio",
+ .of_match_table = nmk_gpio_match,
+ },
+ .probe = nmk_gpio_probe,
+};
+
+static const struct platform_device_id nmk_pinctrl_id[] = {
+ { "pinctrl-stn8815", PINCTRL_NMK_STN8815 },
+ { "pinctrl-db8500", PINCTRL_NMK_DB8500 },
+};
+
+static struct platform_driver nmk_pinctrl_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "pinctrl-nomadik",
+ },
+ .probe = nmk_pinctrl_probe,
+ .id_table = nmk_pinctrl_id,
+};
+
+static int __init nmk_gpio_init(void)
+{
+ int ret;
+
+ ret = platform_driver_register(&nmk_gpio_driver);
+ if (ret)
+ return ret;
+ return platform_driver_register(&nmk_pinctrl_driver);
+}
+
+core_initcall(nmk_gpio_init);
+
+MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
+MODULE_DESCRIPTION("Nomadik GPIO Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h
new file mode 100644
index 000000000000..bc91aed7185d
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-nomadik.h
@@ -0,0 +1,77 @@
+#ifndef PINCTRL_PINCTRL_NOMADIK_H
+#define PINCTRL_PINCTRL_NOMADIK_H
+
+#include <plat/gpio-nomadik.h>
+
+/* Package definitions */
+#define PINCTRL_NMK_STN8815 0
+#define PINCTRL_NMK_DB8500 1
+
+/**
+ * struct nmk_function - Nomadik pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct nmk_function {
+ const char *name;
+ const char * const *groups;
+ unsigned ngroups;
+};
+
+/**
+ * struct nmk_pingroup - describes a Nomadik pin group
+ * @name: the name of this specific pin group
+ * @pins: an array of discrete physical pins used in this group, taken
+ * from the driver-local pin enumeration space
+ * @num_pins: the number of pins in this group array, i.e. the number of
+ * elements in .pins so we can iterate over that array
+ * @altsetting: the altsetting to apply to all pins in this group to
+ * configure them to be used by a function
+ */
+struct nmk_pingroup {
+ const char *name;
+ const unsigned int *pins;
+ const unsigned npins;
+ int altsetting;
+};
+
+/**
+ * struct nmk_pinctrl_soc_data - Nomadik pin controller per-SoC configuration
+ * @gpio_ranges: An array of GPIO ranges for this SoC
+ * @gpio_num_ranges: The number of GPIO ranges for this SoC
+ * @pins: An array describing all pins the pin controller affects.
+ * All pins which are also GPIOs must be listed first within the
+ * array, and be numbered identically to the GPIO controller's
+ * numbering.
+ * @npins: The number of entries in @pins.
+ * @functions: The functions supported on this SoC.
+ * @nfunction: The number of entries in @functions.
+ * @groups: An array describing all pin groups the pin SoC supports.
+ * @ngroups: The number of entries in @groups.
+ */
+struct nmk_pinctrl_soc_data {
+ struct pinctrl_gpio_range *gpio_ranges;
+ unsigned gpio_num_ranges;
+ const struct pinctrl_pin_desc *pins;
+ unsigned npins;
+ const struct nmk_function *functions;
+ unsigned nfunctions;
+ const struct nmk_pingroup *groups;
+ unsigned ngroups;
+};
+
+#ifdef CONFIG_PINCTRL_DB8500
+
+void nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc);
+
+#else
+
+static inline void
+nmk_pinctrl_db8500_init(const struct nmk_pinctrl_soc_data **soc)
+{
+}
+
+#endif
+
+#endif /* PINCTRL_PINCTRL_NOMADIK_H */
diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c
index 2c98fba01ca5..b6934867d8d3 100644
--- a/drivers/pinctrl/pinctrl-tegra.c
+++ b/drivers/pinctrl/pinctrl-tegra.c
@@ -1,7 +1,7 @@
/*
* Driver for the NVIDIA Tegra pinmux
*
- * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
*
* Derived from code:
* Copyright (C) 2010 Google, Inc.
@@ -22,7 +22,8 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
-#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
@@ -31,10 +32,9 @@
#include <mach/pinconf-tegra.h>
+#include "core.h"
#include "pinctrl-tegra.h"
-#define DRIVER_NAME "tegra-pinmux-disabled"
-
struct tegra_pmx {
struct device *dev;
struct pinctrl_dev *pctl;
@@ -83,15 +83,18 @@ static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
return 0;
}
+#ifdef CONFIG_DEBUG_FS
static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned offset)
{
- seq_printf(s, " " DRIVER_NAME);
+ seq_printf(s, " %s", dev_name(pctldev->dev));
}
+#endif
-static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
- unsigned *num_maps, unsigned reserve)
+static int reserve_map(struct device *dev, struct pinctrl_map **map,
+ unsigned *reserved_maps, unsigned *num_maps,
+ unsigned reserve)
{
unsigned old_num = *reserved_maps;
unsigned new_num = *num_maps + reserve;
@@ -101,8 +104,10 @@ static int reserve_map(struct pinctrl_map **map, unsigned *reserved_maps,
return 0;
new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);
- if (!new_map)
+ if (!new_map) {
+ dev_err(dev, "krealloc(map) failed\n");
return -ENOMEM;
+ }
memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
@@ -116,7 +121,7 @@ static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
unsigned *num_maps, const char *group,
const char *function)
{
- if (*num_maps == *reserved_maps)
+ if (WARN_ON(*num_maps == *reserved_maps))
return -ENOSPC;
(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
@@ -127,19 +132,22 @@ static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,
return 0;
}
-static int add_map_configs(struct pinctrl_map **map, unsigned *reserved_maps,
- unsigned *num_maps, const char *group,
- unsigned long *configs, unsigned num_configs)
+static int add_map_configs(struct device *dev, struct pinctrl_map **map,
+ unsigned *reserved_maps, unsigned *num_maps,
+ const char *group, unsigned long *configs,
+ unsigned num_configs)
{
unsigned long *dup_configs;
- if (*num_maps == *reserved_maps)
+ if (WARN_ON(*num_maps == *reserved_maps))
return -ENOSPC;
dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
GFP_KERNEL);
- if (!dup_configs)
+ if (!dup_configs) {
+ dev_err(dev, "kmemdup(configs) failed\n");
return -ENOMEM;
+ }
(*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
(*map)[*num_maps].data.configs.group_or_pin = group;
@@ -150,8 +158,8 @@ static int add_map_configs(struct pinctrl_map **map, unsigned *reserved_maps,
return 0;
}
-static int add_config(unsigned long **configs, unsigned *num_configs,
- unsigned long config)
+static int add_config(struct device *dev, unsigned long **configs,
+ unsigned *num_configs, unsigned long config)
{
unsigned old_num = *num_configs;
unsigned new_num = old_num + 1;
@@ -159,8 +167,10 @@ static int add_config(unsigned long **configs, unsigned *num_configs,
new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
GFP_KERNEL);
- if (!new_configs)
+ if (!new_configs) {
+ dev_err(dev, "krealloc(configs) failed\n");
return -ENOMEM;
+ }
new_configs[old_num] = config;
@@ -201,7 +211,8 @@ static const struct cfg_param {
{"nvidia,slew-rate-rising", TEGRA_PINCONF_PARAM_SLEW_RATE_RISING},
};
-int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
+int tegra_pinctrl_dt_subnode_to_map(struct device *dev,
+ struct device_node *np,
struct pinctrl_map **map,
unsigned *reserved_maps,
unsigned *num_maps)
@@ -217,16 +228,25 @@ int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
const char *group;
ret = of_property_read_string(np, "nvidia,function", &function);
- if (ret < 0)
+ if (ret < 0) {
+ /* EINVAL=missing, which is fine since it's optional */
+ if (ret != -EINVAL)
+ dev_err(dev,
+ "could not parse property nvidia,function\n");
function = NULL;
+ }
for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
ret = of_property_read_u32(np, cfg_params[i].property, &val);
if (!ret) {
config = TEGRA_PINCONF_PACK(cfg_params[i].param, val);
- ret = add_config(&configs, &num_configs, config);
+ ret = add_config(dev, &configs, &num_configs, config);
if (ret < 0)
goto exit;
+ /* EINVAL=missing, which is fine since it's optional */
+ } else if (ret != -EINVAL) {
+ dev_err(dev, "could not parse property %s\n",
+ cfg_params[i].property);
}
}
@@ -236,11 +256,13 @@ int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
if (num_configs)
reserve++;
ret = of_property_count_strings(np, "nvidia,pins");
- if (ret < 0)
+ if (ret < 0) {
+ dev_err(dev, "could not parse property nvidia,pins\n");
goto exit;
+ }
reserve *= ret;
- ret = reserve_map(map, reserved_maps, num_maps, reserve);
+ ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);
if (ret < 0)
goto exit;
@@ -253,8 +275,9 @@ int tegra_pinctrl_dt_subnode_to_map(struct device_node *np,
}
if (num_configs) {
- ret = add_map_configs(map, reserved_maps, num_maps,
- group, configs, num_configs);
+ ret = add_map_configs(dev, map, reserved_maps,
+ num_maps, group, configs,
+ num_configs);
if (ret < 0)
goto exit;
}
@@ -280,8 +303,8 @@ int tegra_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
*num_maps = 0;
for_each_child_of_node(np_config, np) {
- ret = tegra_pinctrl_dt_subnode_to_map(np, map, &reserved_maps,
- num_maps);
+ ret = tegra_pinctrl_dt_subnode_to_map(pctldev->dev, np, map,
+ &reserved_maps, num_maps);
if (ret < 0) {
tegra_pinctrl_dt_free_map(pctldev, *map, *num_maps);
return ret;
@@ -295,7 +318,9 @@ static struct pinctrl_ops tegra_pinctrl_ops = {
.get_groups_count = tegra_pinctrl_get_groups_count,
.get_group_name = tegra_pinctrl_get_group_name,
.get_group_pins = tegra_pinctrl_get_group_pins,
+#ifdef CONFIG_DEBUG_FS
.pin_dbg_show = tegra_pinctrl_pin_dbg_show,
+#endif
.dt_node_to_map = tegra_pinctrl_dt_node_to_map,
.dt_free_map = tegra_pinctrl_dt_free_map,
};
@@ -338,14 +363,14 @@ static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
g = &pmx->soc->groups[group];
- if (g->mux_reg < 0)
+ if (WARN_ON(g->mux_reg < 0))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
if (g->funcs[i] == function)
break;
}
- if (i == ARRAY_SIZE(g->funcs))
+ if (WARN_ON(i == ARRAY_SIZE(g->funcs)))
return -EINVAL;
val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
@@ -365,7 +390,7 @@ static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
g = &pmx->soc->groups[group];
- if (g->mux_reg < 0)
+ if (WARN_ON(g->mux_reg < 0))
return;
val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
@@ -385,6 +410,7 @@ static struct pinmux_ops tegra_pinmux_ops = {
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
const struct tegra_pingroup *g,
enum tegra_pinconf_param param,
+ bool report_err,
s8 *bank, s16 *reg, s8 *bit, s8 *width)
{
switch (param) {
@@ -472,9 +498,10 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
}
if (*reg < 0) {
- dev_err(pmx->dev,
- "Config param %04x not supported on group %s\n",
- param, g->name);
+ if (report_err)
+ dev_err(pmx->dev,
+ "Config param %04x not supported on group %s\n",
+ param, g->name);
return -ENOTSUPP;
}
@@ -484,12 +511,14 @@ static int tegra_pinconf_reg(struct tegra_pmx *pmx,
static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long *config)
{
+ dev_err(pctldev->dev, "pin_config_get op not supported\n");
return -ENOTSUPP;
}
static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config)
{
+ dev_err(pctldev->dev, "pin_config_set op not supported\n");
return -ENOTSUPP;
}
@@ -507,7 +536,8 @@ static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
g = &pmx->soc->groups[group];
- ret = tegra_pinconf_reg(pmx, g, param, &bank, &reg, &bit, &width);
+ ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
+ &width);
if (ret < 0)
return ret;
@@ -534,7 +564,8 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
g = &pmx->soc->groups[group];
- ret = tegra_pinconf_reg(pmx, g, param, &bank, &reg, &bit, &width);
+ ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
+ &width);
if (ret < 0)
return ret;
@@ -542,8 +573,10 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
/* LOCK can't be cleared */
if (param == TEGRA_PINCONF_PARAM_LOCK) {
- if ((val & BIT(bit)) && !arg)
+ if ((val & BIT(bit)) && !arg) {
+ dev_err(pctldev->dev, "LOCK bit cannot be cleared\n");
return -EINVAL;
+ }
}
/* Special-case Boolean values; allow any non-zero as true */
@@ -552,8 +585,12 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
/* Range-check user-supplied value */
mask = (1 << width) - 1;
- if (arg & ~mask)
+ if (arg & ~mask) {
+ dev_err(pctldev->dev,
+ "config %lx: %x too big for %d bit register\n",
+ config, arg, width);
return -EINVAL;
+ }
/* Update register */
val &= ~(mask << bit);
@@ -563,23 +600,78 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
return 0;
}
+#ifdef CONFIG_DEBUG_FS
static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned offset)
{
}
+static const char *strip_prefix(const char *s)
+{
+ const char *comma = strchr(s, ',');
+ if (!comma)
+ return s;
+
+ return comma + 1;
+}
+
static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s, unsigned selector)
+ struct seq_file *s, unsigned group)
+{
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ const struct tegra_pingroup *g;
+ int i, ret;
+ s8 bank, bit, width;
+ s16 reg;
+ u32 val;
+
+ g = &pmx->soc->groups[group];
+
+ for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
+ ret = tegra_pinconf_reg(pmx, g, cfg_params[i].param, false,
+ &bank, &reg, &bit, &width);
+ if (ret < 0)
+ continue;
+
+ val = pmx_readl(pmx, bank, reg);
+ val >>= bit;
+ val &= (1 << width) - 1;
+
+ seq_printf(s, "\n\t%s=%u",
+ strip_prefix(cfg_params[i].property), val);
+ }
+}
+
+static void tegra_pinconf_config_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s,
+ unsigned long config)
{
+ enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config);
+ u16 arg = TEGRA_PINCONF_UNPACK_ARG(config);
+ const char *pname = "unknown";
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {
+ if (cfg_params[i].param == param) {
+ pname = cfg_params[i].property;
+ break;
+ }
+ }
+
+ seq_printf(s, "%s=%d", strip_prefix(pname), arg);
}
+#endif
struct pinconf_ops tegra_pinconf_ops = {
.pin_config_get = tegra_pinconf_get,
.pin_config_set = tegra_pinconf_set,
.pin_config_group_get = tegra_pinconf_group_get,
.pin_config_group_set = tegra_pinconf_group_set,
+#ifdef CONFIG_DEBUG_FS
.pin_config_dbg_show = tegra_pinconf_dbg_show,
.pin_config_group_dbg_show = tegra_pinconf_group_dbg_show,
+ .pin_config_config_dbg_show = tegra_pinconf_config_dbg_show,
+#endif
};
static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
@@ -589,60 +681,29 @@ static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
};
static struct pinctrl_desc tegra_pinctrl_desc = {
- .name = DRIVER_NAME,
.pctlops = &tegra_pinctrl_ops,
.pmxops = &tegra_pinmux_ops,
.confops = &tegra_pinconf_ops,
.owner = THIS_MODULE,
};
-static struct of_device_id tegra_pinctrl_of_match[] __devinitdata = {
-#ifdef CONFIG_PINCTRL_TEGRA20
- {
- .compatible = "nvidia,tegra20-pinmux-disabled",
- .data = tegra20_pinctrl_init,
- },
-#endif
-#ifdef CONFIG_PINCTRL_TEGRA30
- {
- .compatible = "nvidia,tegra30-pinmux-disabled",
- .data = tegra30_pinctrl_init,
- },
-#endif
- {},
-};
-
-static int __devinit tegra_pinctrl_probe(struct platform_device *pdev)
+int __devinit tegra_pinctrl_probe(struct platform_device *pdev,
+ const struct tegra_pinctrl_soc_data *soc_data)
{
- const struct of_device_id *match;
- tegra_pinctrl_soc_initf initf = NULL;
struct tegra_pmx *pmx;
struct resource *res;
int i;
- match = of_match_device(tegra_pinctrl_of_match, &pdev->dev);
- if (match)
- initf = (tegra_pinctrl_soc_initf)match->data;
-#ifdef CONFIG_PINCTRL_TEGRA20
- if (!initf)
- initf = tegra20_pinctrl_init;
-#endif
- if (!initf) {
- dev_err(&pdev->dev,
- "Could not determine SoC-specific init func\n");
- return -EINVAL;
- }
-
pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
if (!pmx) {
dev_err(&pdev->dev, "Can't alloc tegra_pmx\n");
return -ENOMEM;
}
pmx->dev = &pdev->dev;
-
- (*initf)(&pmx->soc);
+ pmx->soc = soc_data;
tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
+ tegra_pinctrl_desc.name = dev_name(&pdev->dev);
tegra_pinctrl_desc.pins = pmx->soc->pins;
tegra_pinctrl_desc.npins = pmx->soc->npins;
@@ -697,8 +758,9 @@ static int __devinit tegra_pinctrl_probe(struct platform_device *pdev)
return 0;
}
+EXPORT_SYMBOL_GPL(tegra_pinctrl_probe);
-static int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
+int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
{
struct tegra_pmx *pmx = platform_get_drvdata(pdev);
@@ -707,30 +769,4 @@ static int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
return 0;
}
-
-static struct platform_driver tegra_pinctrl_driver = {
- .driver = {
- .name = DRIVER_NAME,
- .owner = THIS_MODULE,
- .of_match_table = tegra_pinctrl_of_match,
- },
- .probe = tegra_pinctrl_probe,
- .remove = __devexit_p(tegra_pinctrl_remove),
-};
-
-static int __init tegra_pinctrl_init(void)
-{
- return platform_driver_register(&tegra_pinctrl_driver);
-}
-arch_initcall(tegra_pinctrl_init);
-
-static void __exit tegra_pinctrl_exit(void)
-{
- platform_driver_unregister(&tegra_pinctrl_driver);
-}
-module_exit(tegra_pinctrl_exit);
-
-MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
-MODULE_DESCRIPTION("NVIDIA Tegra pinctrl driver");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(of, tegra_pinctrl_of_match);
+EXPORT_SYMBOL_GPL(tegra_pinctrl_remove);
diff --git a/drivers/pinctrl/pinctrl-tegra.h b/drivers/pinctrl/pinctrl-tegra.h
index 782c795326ef..705c007a38cc 100644
--- a/drivers/pinctrl/pinctrl-tegra.h
+++ b/drivers/pinctrl/pinctrl-tegra.h
@@ -139,25 +139,8 @@ struct tegra_pinctrl_soc_data {
unsigned ngroups;
};
-/**
- * tegra_pinctrl_soc_initf() - Retrieve pin controller details for a SoC.
- * @soc_data: This pointer must be updated to point at a struct containing
- * details of the SoC.
- */
-typedef void (*tegra_pinctrl_soc_initf)(
- const struct tegra_pinctrl_soc_data **soc_data);
-
-/**
- * tegra20_pinctrl_init() - Retrieve pin controller details for Tegra20
- * @soc_data: This pointer will be updated to point at a struct containing
- * details of Tegra20's pin controller.
- */
-void tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
-/**
- * tegra30_pinctrl_init() - Retrieve pin controller details for Tegra20
- * @soc_data: This pointer will be updated to point at a struct containing
- * details of Tegra30's pin controller.
- */
-void tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
+int tegra_pinctrl_probe(struct platform_device *pdev,
+ const struct tegra_pinctrl_soc_data *soc_data);
+int tegra_pinctrl_remove(struct platform_device *pdev);
#endif
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
index f69ff96aa292..a74f9a568536 100644
--- a/drivers/pinctrl/pinctrl-tegra20.c
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -1,7 +1,7 @@
/*
* Pinctrl data for the NVIDIA Tegra20 pinmux
*
- * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
*
* Derived from code:
* Copyright (C) 2010 Google, Inc.
@@ -17,6 +17,8 @@
* more details.
*/
+#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
@@ -2854,7 +2856,39 @@ static const struct tegra_pinctrl_soc_data tegra20_pinctrl = {
.ngroups = ARRAY_SIZE(tegra20_groups),
};
-void __devinit tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc)
+static int __devinit tegra20_pinctrl_probe(struct platform_device *pdev)
{
- *soc = &tegra20_pinctrl;
+ return tegra_pinctrl_probe(pdev, &tegra20_pinctrl);
}
+
+static struct of_device_id tegra20_pinctrl_of_match[] __devinitdata = {
+ { .compatible = "nvidia,tegra20-pinmux", },
+ { },
+};
+
+static struct platform_driver tegra20_pinctrl_driver = {
+ .driver = {
+ .name = "tegra20-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra20_pinctrl_of_match,
+ },
+ .probe = tegra20_pinctrl_probe,
+ .remove = __devexit_p(tegra_pinctrl_remove),
+};
+
+static int __init tegra20_pinctrl_init(void)
+{
+ return platform_driver_register(&tegra20_pinctrl_driver);
+}
+arch_initcall(tegra20_pinctrl_init);
+
+static void __exit tegra20_pinctrl_exit(void)
+{
+ platform_driver_unregister(&tegra20_pinctrl_driver);
+}
+module_exit(tegra20_pinctrl_exit);
+
+MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra20 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, tegra20_pinctrl_of_match);
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 4d7571d4a431..0386fdf0da16 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -1,7 +1,7 @@
/*
* Pinctrl data for the NVIDIA Tegra30 pinmux
*
- * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -13,6 +13,8 @@
* more details.
*/
+#include <linux/module.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
@@ -3720,7 +3722,39 @@ static const struct tegra_pinctrl_soc_data tegra30_pinctrl = {
.ngroups = ARRAY_SIZE(tegra30_groups),
};
-void __devinit tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc)
+static int __devinit tegra30_pinctrl_probe(struct platform_device *pdev)
{
- *soc = &tegra30_pinctrl;
+ return tegra_pinctrl_probe(pdev, &tegra30_pinctrl);
}
+
+static struct of_device_id tegra30_pinctrl_of_match[] __devinitdata = {
+ { .compatible = "nvidia,tegra30-pinmux", },
+ { },
+};
+
+static struct platform_driver tegra30_pinctrl_driver = {
+ .driver = {
+ .name = "tegra30-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra30_pinctrl_of_match,
+ },
+ .probe = tegra30_pinctrl_probe,
+ .remove = __devexit_p(tegra_pinctrl_remove),
+};
+
+static int __init tegra30_pinctrl_init(void)
+{
+ return platform_driver_register(&tegra30_pinctrl_driver);
+}
+arch_initcall(tegra30_pinctrl_init);
+
+static void __exit tegra30_pinctrl_exit(void)
+{
+ platform_driver_unregister(&tegra30_pinctrl_driver);
+}
+module_exit(tegra30_pinctrl_exit);
+
+MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra30 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, tegra30_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig
new file mode 100644
index 000000000000..91558791e766
--- /dev/null
+++ b/drivers/pinctrl/spear/Kconfig
@@ -0,0 +1,44 @@
+#
+# ST Microelectronics SPEAr PINCTRL drivers
+#
+
+if PLAT_SPEAR
+
+config PINCTRL_SPEAR
+ bool
+ depends on OF
+ select PINMUX
+ help
+ This enables pin control drivers for SPEAr Platform
+
+config PINCTRL_SPEAR3XX
+ bool
+ depends on ARCH_SPEAR3XX
+ select PINCTRL_SPEAR
+
+config PINCTRL_SPEAR300
+ bool "ST Microelectronics SPEAr300 SoC pin controller driver"
+ depends on MACH_SPEAR300
+ select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR310
+ bool "ST Microelectronics SPEAr310 SoC pin controller driver"
+ depends on MACH_SPEAR310
+ select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR320
+ bool "ST Microelectronics SPEAr320 SoC pin controller driver"
+ depends on MACH_SPEAR320
+ select PINCTRL_SPEAR3XX
+
+config PINCTRL_SPEAR1310
+ bool "ST Microelectronics SPEAr1310 SoC pin controller driver"
+ depends on MACH_SPEAR1310
+ select PINCTRL_SPEAR
+
+config PINCTRL_SPEAR1340
+ bool "ST Microelectronics SPEAr1340 SoC pin controller driver"
+ depends on MACH_SPEAR1340
+ select PINCTRL_SPEAR
+
+endif
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile
new file mode 100644
index 000000000000..b28a7ba22443
--- /dev/null
+++ b/drivers/pinctrl/spear/Makefile
@@ -0,0 +1,9 @@
+# SPEAr pinmux support
+
+obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o
+obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o
+obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o
+obj-$(CONFIG_PINCTRL_SPEAR310) += pinctrl-spear310.o
+obj-$(CONFIG_PINCTRL_SPEAR320) += pinctrl-spear320.o
+obj-$(CONFIG_PINCTRL_SPEAR1310) += pinctrl-spear1310.o
+obj-$(CONFIG_PINCTRL_SPEAR1340) += pinctrl-spear1340.o
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
new file mode 100644
index 000000000000..5ae50aadf885
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -0,0 +1,354 @@
+/*
+ * Driver for the ST Microelectronics SPEAr pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * Inspired from:
+ * - U300 Pinctl drivers
+ * - Tegra Pinctl drivers
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/pinctrl/machine.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "pinctrl-spear.h"
+
+#define DRIVER_NAME "spear-pinmux"
+
+static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
+{
+ return readl_relaxed(pmx->vbase + reg);
+}
+
+static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
+{
+ writel_relaxed(val, pmx->vbase + reg);
+}
+
+static int set_mode(struct spear_pmx *pmx, int mode)
+{
+ struct spear_pmx_mode *pmx_mode = NULL;
+ int i;
+ u32 val;
+
+ if (!pmx->machdata->pmx_modes || !pmx->machdata->npmx_modes)
+ return -EINVAL;
+
+ for (i = 0; i < pmx->machdata->npmx_modes; i++) {
+ if (pmx->machdata->pmx_modes[i]->mode == (1 << mode)) {
+ pmx_mode = pmx->machdata->pmx_modes[i];
+ break;
+ }
+ }
+
+ if (!pmx_mode)
+ return -EINVAL;
+
+ val = pmx_readl(pmx, pmx_mode->reg);
+ val &= ~pmx_mode->mask;
+ val |= pmx_mode->val;
+ pmx_writel(pmx, val, pmx_mode->reg);
+
+ pmx->machdata->mode = pmx_mode->mode;
+ dev_info(pmx->dev, "Configured Mode: %s with id: %x\n\n",
+ pmx_mode->name ? pmx_mode->name : "no_name",
+ pmx_mode->reg);
+
+ return 0;
+}
+
+void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg)
+{
+ struct spear_pingroup *pgroup;
+ struct spear_modemux *modemux;
+ int i, j, group;
+
+ for (group = 0; group < machdata->ngroups; group++) {
+ pgroup = machdata->groups[group];
+
+ for (i = 0; i < pgroup->nmodemuxs; i++) {
+ modemux = &pgroup->modemuxs[i];
+
+ for (j = 0; j < modemux->nmuxregs; j++)
+ if (modemux->muxregs[j].reg == 0xFFFF)
+ modemux->muxregs[j].reg = reg;
+ }
+ }
+}
+
+static int spear_pinctrl_get_groups_cnt(struct pinctrl_dev *pctldev)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ return pmx->machdata->ngroups;
+}
+
+static const char *spear_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned group)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ return pmx->machdata->groups[group]->name;
+}
+
+static int spear_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned group, const unsigned **pins, unsigned *num_pins)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = pmx->machdata->groups[group]->pins;
+ *num_pins = pmx->machdata->groups[group]->npins;
+
+ return 0;
+}
+
+static void spear_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s, unsigned offset)
+{
+ seq_printf(s, " " DRIVER_NAME);
+}
+
+int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+ struct device_node *np_config,
+ struct pinctrl_map **map, unsigned *num_maps)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ struct device_node *np;
+ struct property *prop;
+ const char *function, *group;
+ int ret, index = 0, count = 0;
+
+ /* calculate number of maps required */
+ for_each_child_of_node(np_config, np) {
+ ret = of_property_read_string(np, "st,function", &function);
+ if (ret < 0)
+ return ret;
+
+ ret = of_property_count_strings(np, "st,pins");
+ if (ret < 0)
+ return ret;
+
+ count += ret;
+ }
+
+ if (!count) {
+ dev_err(pmx->dev, "No child nodes passed via DT\n");
+ return -ENODEV;
+ }
+
+ *map = kzalloc(sizeof(**map) * count, GFP_KERNEL);
+ if (!*map)
+ return -ENOMEM;
+
+ for_each_child_of_node(np_config, np) {
+ of_property_read_string(np, "st,function", &function);
+ of_property_for_each_string(np, "st,pins", prop, group) {
+ (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP;
+ (*map)[index].data.mux.group = group;
+ (*map)[index].data.mux.function = function;
+ index++;
+ }
+ }
+
+ *num_maps = count;
+
+ return 0;
+}
+
+void spear_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps)
+{
+ kfree(map);
+}
+
+static struct pinctrl_ops spear_pinctrl_ops = {
+ .get_groups_count = spear_pinctrl_get_groups_cnt,
+ .get_group_name = spear_pinctrl_get_group_name,
+ .get_group_pins = spear_pinctrl_get_group_pins,
+ .pin_dbg_show = spear_pinctrl_pin_dbg_show,
+ .dt_node_to_map = spear_pinctrl_dt_node_to_map,
+ .dt_free_map = spear_pinctrl_dt_free_map,
+};
+
+static int spear_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ return pmx->machdata->nfunctions;
+}
+
+static const char *spear_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
+ unsigned function)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ return pmx->machdata->functions[function]->name;
+}
+
+static int spear_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
+ unsigned function, const char *const **groups,
+ unsigned * const ngroups)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pmx->machdata->functions[function]->groups;
+ *ngroups = pmx->machdata->functions[function]->ngroups;
+
+ return 0;
+}
+
+static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev,
+ unsigned function, unsigned group, bool enable)
+{
+ struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
+ const struct spear_pingroup *pgroup;
+ const struct spear_modemux *modemux;
+ struct spear_muxreg *muxreg;
+ u32 val, temp;
+ int i, j;
+ bool found = false;
+
+ pgroup = pmx->machdata->groups[group];
+
+ for (i = 0; i < pgroup->nmodemuxs; i++) {
+ modemux = &pgroup->modemuxs[i];
+
+ /* SoC have any modes */
+ if (pmx->machdata->modes_supported) {
+ if (!(pmx->machdata->mode & modemux->modes))
+ continue;
+ }
+
+ found = true;
+ for (j = 0; j < modemux->nmuxregs; j++) {
+ muxreg = &modemux->muxregs[j];
+
+ val = pmx_readl(pmx, muxreg->reg);
+ val &= ~muxreg->mask;
+
+ if (enable)
+ temp = muxreg->val;
+ else
+ temp = ~muxreg->val;
+
+ val |= temp;
+ pmx_writel(pmx, val, muxreg->reg);
+ }
+ }
+
+ if (!found) {
+ dev_err(pmx->dev, "pinmux group: %s not supported\n",
+ pgroup->name);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int spear_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
+ unsigned group)
+{
+ return spear_pinctrl_endisable(pctldev, function, group, true);
+}
+
+static void spear_pinctrl_disable(struct pinctrl_dev *pctldev,
+ unsigned function, unsigned group)
+{
+ spear_pinctrl_endisable(pctldev, function, group, false);
+}
+
+static struct pinmux_ops spear_pinmux_ops = {
+ .get_functions_count = spear_pinctrl_get_funcs_count,
+ .get_function_name = spear_pinctrl_get_func_name,
+ .get_function_groups = spear_pinctrl_get_func_groups,
+ .enable = spear_pinctrl_enable,
+ .disable = spear_pinctrl_disable,
+};
+
+static struct pinctrl_desc spear_pinctrl_desc = {
+ .name = DRIVER_NAME,
+ .pctlops = &spear_pinctrl_ops,
+ .pmxops = &spear_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+int __devinit spear_pinctrl_probe(struct platform_device *pdev,
+ struct spear_pinctrl_machdata *machdata)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct resource *res;
+ struct spear_pmx *pmx;
+
+ if (!machdata)
+ return -ENODEV;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -EINVAL;
+
+ pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
+ if (!pmx) {
+ dev_err(&pdev->dev, "Can't alloc spear_pmx\n");
+ return -ENOMEM;
+ }
+
+ pmx->vbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!pmx->vbase) {
+ dev_err(&pdev->dev, "Couldn't ioremap at index 0\n");
+ return -ENODEV;
+ }
+
+ pmx->dev = &pdev->dev;
+ pmx->machdata = machdata;
+
+ /* configure mode, if supported by SoC */
+ if (machdata->modes_supported) {
+ int mode = 0;
+
+ if (of_property_read_u32(np, "st,pinmux-mode", &mode)) {
+ dev_err(&pdev->dev, "OF: pinmux mode not passed\n");
+ return -EINVAL;
+ }
+
+ if (set_mode(pmx, mode)) {
+ dev_err(&pdev->dev, "OF: Couldn't configure mode: %x\n",
+ mode);
+ return -EINVAL;
+ }
+ }
+
+ platform_set_drvdata(pdev, pmx);
+
+ spear_pinctrl_desc.pins = machdata->pins;
+ spear_pinctrl_desc.npins = machdata->npins;
+
+ pmx->pctl = pinctrl_register(&spear_pinctrl_desc, &pdev->dev, pmx);
+ if (IS_ERR(pmx->pctl)) {
+ dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
+ return PTR_ERR(pmx->pctl);
+ }
+
+ return 0;
+}
+
+int __devexit spear_pinctrl_remove(struct platform_device *pdev)
+{
+ struct spear_pmx *pmx = platform_get_drvdata(pdev);
+
+ pinctrl_unregister(pmx->pctl);
+
+ return 0;
+}
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
new file mode 100644
index 000000000000..9155783bb47f
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear.h
@@ -0,0 +1,393 @@
+/*
+ * Driver header file for the ST Microelectronics SPEAr pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PINMUX_SPEAR_H__
+#define __PINMUX_SPEAR_H__
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/types.h>
+
+struct platform_device;
+struct device;
+
+/**
+ * struct spear_pmx_mode - SPEAr pmx mode
+ * @name: name of pmx mode
+ * @mode: mode id
+ * @reg: register for configuring this mode
+ * @mask: mask of this mode in reg
+ * @val: val to be configured at reg after doing (val & mask)
+ */
+struct spear_pmx_mode {
+ const char *const name;
+ u16 mode;
+ u16 reg;
+ u16 mask;
+ u32 val;
+};
+
+/**
+ * struct spear_muxreg - SPEAr mux reg configuration
+ * @reg: register offset
+ * @mask: mask bits
+ * @val: val to be written on mask bits
+ */
+struct spear_muxreg {
+ u16 reg;
+ u32 mask;
+ u32 val;
+};
+
+/**
+ * struct spear_modemux - SPEAr mode mux configuration
+ * @modes: mode ids supported by this group of muxregs
+ * @nmuxregs: number of muxreg configurations to be done for modes
+ * @muxregs: array of muxreg configurations to be done for modes
+ */
+struct spear_modemux {
+ u16 modes;
+ u8 nmuxregs;
+ struct spear_muxreg *muxregs;
+};
+
+/**
+ * struct spear_pingroup - SPEAr pin group configurations
+ * @name: name of pin group
+ * @pins: array containing pin numbers
+ * @npins: size of pins array
+ * @modemuxs: array of modemux configurations for this pin group
+ * @nmodemuxs: size of array modemuxs
+ *
+ * A representation of a group of pins in the SPEAr pin controller. Each group
+ * allows some parameter or parameters to be configured.
+ */
+struct spear_pingroup {
+ const char *name;
+ const unsigned *pins;
+ unsigned npins;
+ struct spear_modemux *modemuxs;
+ unsigned nmodemuxs;
+};
+
+/**
+ * struct spear_function - SPEAr pinctrl mux function
+ * @name: The name of the function, exported to pinctrl core.
+ * @groups: An array of pin groups that may select this function.
+ * @ngroups: The number of entries in @groups.
+ */
+struct spear_function {
+ const char *name;
+ const char *const *groups;
+ unsigned ngroups;
+};
+
+/**
+ * struct spear_pinctrl_machdata - SPEAr pin controller machine driver
+ * configuration
+ * @pins: An array describing all pins the pin controller affects.
+ * All pins which are also GPIOs must be listed first within the *array,
+ * and be numbered identically to the GPIO controller's *numbering.
+ * @npins: The numbmer of entries in @pins.
+ * @functions: An array describing all mux functions the SoC supports.
+ * @nfunctions: The numbmer of entries in @functions.
+ * @groups: An array describing all pin groups the pin SoC supports.
+ * @ngroups: The numbmer of entries in @groups.
+ *
+ * @modes_supported: Does SoC support modes
+ * @mode: mode configured from probe
+ * @pmx_modes: array of modes supported by SoC
+ * @npmx_modes: number of entries in pmx_modes.
+ */
+struct spear_pinctrl_machdata {
+ const struct pinctrl_pin_desc *pins;
+ unsigned npins;
+ struct spear_function **functions;
+ unsigned nfunctions;
+ struct spear_pingroup **groups;
+ unsigned ngroups;
+
+ bool modes_supported;
+ u16 mode;
+ struct spear_pmx_mode **pmx_modes;
+ unsigned npmx_modes;
+};
+
+/**
+ * struct spear_pmx - SPEAr pinctrl mux
+ * @dev: pointer to struct dev of platform_device registered
+ * @pctl: pointer to struct pinctrl_dev
+ * @machdata: pointer to SoC or machine specific structure
+ * @vbase: virtual base address of pinmux controller
+ */
+struct spear_pmx {
+ struct device *dev;
+ struct pinctrl_dev *pctl;
+ struct spear_pinctrl_machdata *machdata;
+ void __iomem *vbase;
+};
+
+/* exported routines */
+void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
+int __devinit spear_pinctrl_probe(struct platform_device *pdev,
+ struct spear_pinctrl_machdata *machdata);
+int __devexit spear_pinctrl_remove(struct platform_device *pdev);
+
+#define SPEAR_PIN_0_TO_101 \
+ PINCTRL_PIN(0, "PLGPIO0"), \
+ PINCTRL_PIN(1, "PLGPIO1"), \
+ PINCTRL_PIN(2, "PLGPIO2"), \
+ PINCTRL_PIN(3, "PLGPIO3"), \
+ PINCTRL_PIN(4, "PLGPIO4"), \
+ PINCTRL_PIN(5, "PLGPIO5"), \
+ PINCTRL_PIN(6, "PLGPIO6"), \
+ PINCTRL_PIN(7, "PLGPIO7"), \
+ PINCTRL_PIN(8, "PLGPIO8"), \
+ PINCTRL_PIN(9, "PLGPIO9"), \
+ PINCTRL_PIN(10, "PLGPIO10"), \
+ PINCTRL_PIN(11, "PLGPIO11"), \
+ PINCTRL_PIN(12, "PLGPIO12"), \
+ PINCTRL_PIN(13, "PLGPIO13"), \
+ PINCTRL_PIN(14, "PLGPIO14"), \
+ PINCTRL_PIN(15, "PLGPIO15"), \
+ PINCTRL_PIN(16, "PLGPIO16"), \
+ PINCTRL_PIN(17, "PLGPIO17"), \
+ PINCTRL_PIN(18, "PLGPIO18"), \
+ PINCTRL_PIN(19, "PLGPIO19"), \
+ PINCTRL_PIN(20, "PLGPIO20"), \
+ PINCTRL_PIN(21, "PLGPIO21"), \
+ PINCTRL_PIN(22, "PLGPIO22"), \
+ PINCTRL_PIN(23, "PLGPIO23"), \
+ PINCTRL_PIN(24, "PLGPIO24"), \
+ PINCTRL_PIN(25, "PLGPIO25"), \
+ PINCTRL_PIN(26, "PLGPIO26"), \
+ PINCTRL_PIN(27, "PLGPIO27"), \
+ PINCTRL_PIN(28, "PLGPIO28"), \
+ PINCTRL_PIN(29, "PLGPIO29"), \
+ PINCTRL_PIN(30, "PLGPIO30"), \
+ PINCTRL_PIN(31, "PLGPIO31"), \
+ PINCTRL_PIN(32, "PLGPIO32"), \
+ PINCTRL_PIN(33, "PLGPIO33"), \
+ PINCTRL_PIN(34, "PLGPIO34"), \
+ PINCTRL_PIN(35, "PLGPIO35"), \
+ PINCTRL_PIN(36, "PLGPIO36"), \
+ PINCTRL_PIN(37, "PLGPIO37"), \
+ PINCTRL_PIN(38, "PLGPIO38"), \
+ PINCTRL_PIN(39, "PLGPIO39"), \
+ PINCTRL_PIN(40, "PLGPIO40"), \
+ PINCTRL_PIN(41, "PLGPIO41"), \
+ PINCTRL_PIN(42, "PLGPIO42"), \
+ PINCTRL_PIN(43, "PLGPIO43"), \
+ PINCTRL_PIN(44, "PLGPIO44"), \
+ PINCTRL_PIN(45, "PLGPIO45"), \
+ PINCTRL_PIN(46, "PLGPIO46"), \
+ PINCTRL_PIN(47, "PLGPIO47"), \
+ PINCTRL_PIN(48, "PLGPIO48"), \
+ PINCTRL_PIN(49, "PLGPIO49"), \
+ PINCTRL_PIN(50, "PLGPIO50"), \
+ PINCTRL_PIN(51, "PLGPIO51"), \
+ PINCTRL_PIN(52, "PLGPIO52"), \
+ PINCTRL_PIN(53, "PLGPIO53"), \
+ PINCTRL_PIN(54, "PLGPIO54"), \
+ PINCTRL_PIN(55, "PLGPIO55"), \
+ PINCTRL_PIN(56, "PLGPIO56"), \
+ PINCTRL_PIN(57, "PLGPIO57"), \
+ PINCTRL_PIN(58, "PLGPIO58"), \
+ PINCTRL_PIN(59, "PLGPIO59"), \
+ PINCTRL_PIN(60, "PLGPIO60"), \
+ PINCTRL_PIN(61, "PLGPIO61"), \
+ PINCTRL_PIN(62, "PLGPIO62"), \
+ PINCTRL_PIN(63, "PLGPIO63"), \
+ PINCTRL_PIN(64, "PLGPIO64"), \
+ PINCTRL_PIN(65, "PLGPIO65"), \
+ PINCTRL_PIN(66, "PLGPIO66"), \
+ PINCTRL_PIN(67, "PLGPIO67"), \
+ PINCTRL_PIN(68, "PLGPIO68"), \
+ PINCTRL_PIN(69, "PLGPIO69"), \
+ PINCTRL_PIN(70, "PLGPIO70"), \
+ PINCTRL_PIN(71, "PLGPIO71"), \
+ PINCTRL_PIN(72, "PLGPIO72"), \
+ PINCTRL_PIN(73, "PLGPIO73"), \
+ PINCTRL_PIN(74, "PLGPIO74"), \
+ PINCTRL_PIN(75, "PLGPIO75"), \
+ PINCTRL_PIN(76, "PLGPIO76"), \
+ PINCTRL_PIN(77, "PLGPIO77"), \
+ PINCTRL_PIN(78, "PLGPIO78"), \
+ PINCTRL_PIN(79, "PLGPIO79"), \
+ PINCTRL_PIN(80, "PLGPIO80"), \
+ PINCTRL_PIN(81, "PLGPIO81"), \
+ PINCTRL_PIN(82, "PLGPIO82"), \
+ PINCTRL_PIN(83, "PLGPIO83"), \
+ PINCTRL_PIN(84, "PLGPIO84"), \
+ PINCTRL_PIN(85, "PLGPIO85"), \
+ PINCTRL_PIN(86, "PLGPIO86"), \
+ PINCTRL_PIN(87, "PLGPIO87"), \
+ PINCTRL_PIN(88, "PLGPIO88"), \
+ PINCTRL_PIN(89, "PLGPIO89"), \
+ PINCTRL_PIN(90, "PLGPIO90"), \
+ PINCTRL_PIN(91, "PLGPIO91"), \
+ PINCTRL_PIN(92, "PLGPIO92"), \
+ PINCTRL_PIN(93, "PLGPIO93"), \
+ PINCTRL_PIN(94, "PLGPIO94"), \
+ PINCTRL_PIN(95, "PLGPIO95"), \
+ PINCTRL_PIN(96, "PLGPIO96"), \
+ PINCTRL_PIN(97, "PLGPIO97"), \
+ PINCTRL_PIN(98, "PLGPIO98"), \
+ PINCTRL_PIN(99, "PLGPIO99"), \
+ PINCTRL_PIN(100, "PLGPIO100"), \
+ PINCTRL_PIN(101, "PLGPIO101")
+
+#define SPEAR_PIN_102_TO_245 \
+ PINCTRL_PIN(102, "PLGPIO102"), \
+ PINCTRL_PIN(103, "PLGPIO103"), \
+ PINCTRL_PIN(104, "PLGPIO104"), \
+ PINCTRL_PIN(105, "PLGPIO105"), \
+ PINCTRL_PIN(106, "PLGPIO106"), \
+ PINCTRL_PIN(107, "PLGPIO107"), \
+ PINCTRL_PIN(108, "PLGPIO108"), \
+ PINCTRL_PIN(109, "PLGPIO109"), \
+ PINCTRL_PIN(110, "PLGPIO110"), \
+ PINCTRL_PIN(111, "PLGPIO111"), \
+ PINCTRL_PIN(112, "PLGPIO112"), \
+ PINCTRL_PIN(113, "PLGPIO113"), \
+ PINCTRL_PIN(114, "PLGPIO114"), \
+ PINCTRL_PIN(115, "PLGPIO115"), \
+ PINCTRL_PIN(116, "PLGPIO116"), \
+ PINCTRL_PIN(117, "PLGPIO117"), \
+ PINCTRL_PIN(118, "PLGPIO118"), \
+ PINCTRL_PIN(119, "PLGPIO119"), \
+ PINCTRL_PIN(120, "PLGPIO120"), \
+ PINCTRL_PIN(121, "PLGPIO121"), \
+ PINCTRL_PIN(122, "PLGPIO122"), \
+ PINCTRL_PIN(123, "PLGPIO123"), \
+ PINCTRL_PIN(124, "PLGPIO124"), \
+ PINCTRL_PIN(125, "PLGPIO125"), \
+ PINCTRL_PIN(126, "PLGPIO126"), \
+ PINCTRL_PIN(127, "PLGPIO127"), \
+ PINCTRL_PIN(128, "PLGPIO128"), \
+ PINCTRL_PIN(129, "PLGPIO129"), \
+ PINCTRL_PIN(130, "PLGPIO130"), \
+ PINCTRL_PIN(131, "PLGPIO131"), \
+ PINCTRL_PIN(132, "PLGPIO132"), \
+ PINCTRL_PIN(133, "PLGPIO133"), \
+ PINCTRL_PIN(134, "PLGPIO134"), \
+ PINCTRL_PIN(135, "PLGPIO135"), \
+ PINCTRL_PIN(136, "PLGPIO136"), \
+ PINCTRL_PIN(137, "PLGPIO137"), \
+ PINCTRL_PIN(138, "PLGPIO138"), \
+ PINCTRL_PIN(139, "PLGPIO139"), \
+ PINCTRL_PIN(140, "PLGPIO140"), \
+ PINCTRL_PIN(141, "PLGPIO141"), \
+ PINCTRL_PIN(142, "PLGPIO142"), \
+ PINCTRL_PIN(143, "PLGPIO143"), \
+ PINCTRL_PIN(144, "PLGPIO144"), \
+ PINCTRL_PIN(145, "PLGPIO145"), \
+ PINCTRL_PIN(146, "PLGPIO146"), \
+ PINCTRL_PIN(147, "PLGPIO147"), \
+ PINCTRL_PIN(148, "PLGPIO148"), \
+ PINCTRL_PIN(149, "PLGPIO149"), \
+ PINCTRL_PIN(150, "PLGPIO150"), \
+ PINCTRL_PIN(151, "PLGPIO151"), \
+ PINCTRL_PIN(152, "PLGPIO152"), \
+ PINCTRL_PIN(153, "PLGPIO153"), \
+ PINCTRL_PIN(154, "PLGPIO154"), \
+ PINCTRL_PIN(155, "PLGPIO155"), \
+ PINCTRL_PIN(156, "PLGPIO156"), \
+ PINCTRL_PIN(157, "PLGPIO157"), \
+ PINCTRL_PIN(158, "PLGPIO158"), \
+ PINCTRL_PIN(159, "PLGPIO159"), \
+ PINCTRL_PIN(160, "PLGPIO160"), \
+ PINCTRL_PIN(161, "PLGPIO161"), \
+ PINCTRL_PIN(162, "PLGPIO162"), \
+ PINCTRL_PIN(163, "PLGPIO163"), \
+ PINCTRL_PIN(164, "PLGPIO164"), \
+ PINCTRL_PIN(165, "PLGPIO165"), \
+ PINCTRL_PIN(166, "PLGPIO166"), \
+ PINCTRL_PIN(167, "PLGPIO167"), \
+ PINCTRL_PIN(168, "PLGPIO168"), \
+ PINCTRL_PIN(169, "PLGPIO169"), \
+ PINCTRL_PIN(170, "PLGPIO170"), \
+ PINCTRL_PIN(171, "PLGPIO171"), \
+ PINCTRL_PIN(172, "PLGPIO172"), \
+ PINCTRL_PIN(173, "PLGPIO173"), \
+ PINCTRL_PIN(174, "PLGPIO174"), \
+ PINCTRL_PIN(175, "PLGPIO175"), \
+ PINCTRL_PIN(176, "PLGPIO176"), \
+ PINCTRL_PIN(177, "PLGPIO177"), \
+ PINCTRL_PIN(178, "PLGPIO178"), \
+ PINCTRL_PIN(179, "PLGPIO179"), \
+ PINCTRL_PIN(180, "PLGPIO180"), \
+ PINCTRL_PIN(181, "PLGPIO181"), \
+ PINCTRL_PIN(182, "PLGPIO182"), \
+ PINCTRL_PIN(183, "PLGPIO183"), \
+ PINCTRL_PIN(184, "PLGPIO184"), \
+ PINCTRL_PIN(185, "PLGPIO185"), \
+ PINCTRL_PIN(186, "PLGPIO186"), \
+ PINCTRL_PIN(187, "PLGPIO187"), \
+ PINCTRL_PIN(188, "PLGPIO188"), \
+ PINCTRL_PIN(189, "PLGPIO189"), \
+ PINCTRL_PIN(190, "PLGPIO190"), \
+ PINCTRL_PIN(191, "PLGPIO191"), \
+ PINCTRL_PIN(192, "PLGPIO192"), \
+ PINCTRL_PIN(193, "PLGPIO193"), \
+ PINCTRL_PIN(194, "PLGPIO194"), \
+ PINCTRL_PIN(195, "PLGPIO195"), \
+ PINCTRL_PIN(196, "PLGPIO196"), \
+ PINCTRL_PIN(197, "PLGPIO197"), \
+ PINCTRL_PIN(198, "PLGPIO198"), \
+ PINCTRL_PIN(199, "PLGPIO199"), \
+ PINCTRL_PIN(200, "PLGPIO200"), \
+ PINCTRL_PIN(201, "PLGPIO201"), \
+ PINCTRL_PIN(202, "PLGPIO202"), \
+ PINCTRL_PIN(203, "PLGPIO203"), \
+ PINCTRL_PIN(204, "PLGPIO204"), \
+ PINCTRL_PIN(205, "PLGPIO205"), \
+ PINCTRL_PIN(206, "PLGPIO206"), \
+ PINCTRL_PIN(207, "PLGPIO207"), \
+ PINCTRL_PIN(208, "PLGPIO208"), \
+ PINCTRL_PIN(209, "PLGPIO209"), \
+ PINCTRL_PIN(210, "PLGPIO210"), \
+ PINCTRL_PIN(211, "PLGPIO211"), \
+ PINCTRL_PIN(212, "PLGPIO212"), \
+ PINCTRL_PIN(213, "PLGPIO213"), \
+ PINCTRL_PIN(214, "PLGPIO214"), \
+ PINCTRL_PIN(215, "PLGPIO215"), \
+ PINCTRL_PIN(216, "PLGPIO216"), \
+ PINCTRL_PIN(217, "PLGPIO217"), \
+ PINCTRL_PIN(218, "PLGPIO218"), \
+ PINCTRL_PIN(219, "PLGPIO219"), \
+ PINCTRL_PIN(220, "PLGPIO220"), \
+ PINCTRL_PIN(221, "PLGPIO221"), \
+ PINCTRL_PIN(222, "PLGPIO222"), \
+ PINCTRL_PIN(223, "PLGPIO223"), \
+ PINCTRL_PIN(224, "PLGPIO224"), \
+ PINCTRL_PIN(225, "PLGPIO225"), \
+ PINCTRL_PIN(226, "PLGPIO226"), \
+ PINCTRL_PIN(227, "PLGPIO227"), \
+ PINCTRL_PIN(228, "PLGPIO228"), \
+ PINCTRL_PIN(229, "PLGPIO229"), \
+ PINCTRL_PIN(230, "PLGPIO230"), \
+ PINCTRL_PIN(231, "PLGPIO231"), \
+ PINCTRL_PIN(232, "PLGPIO232"), \
+ PINCTRL_PIN(233, "PLGPIO233"), \
+ PINCTRL_PIN(234, "PLGPIO234"), \
+ PINCTRL_PIN(235, "PLGPIO235"), \
+ PINCTRL_PIN(236, "PLGPIO236"), \
+ PINCTRL_PIN(237, "PLGPIO237"), \
+ PINCTRL_PIN(238, "PLGPIO238"), \
+ PINCTRL_PIN(239, "PLGPIO239"), \
+ PINCTRL_PIN(240, "PLGPIO240"), \
+ PINCTRL_PIN(241, "PLGPIO241"), \
+ PINCTRL_PIN(242, "PLGPIO242"), \
+ PINCTRL_PIN(243, "PLGPIO243"), \
+ PINCTRL_PIN(244, "PLGPIO244"), \
+ PINCTRL_PIN(245, "PLGPIO245")
+
+#endif /* __PINMUX_SPEAR_H__ */
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c
new file mode 100644
index 000000000000..fff168be7f00
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear1310.c
@@ -0,0 +1,2198 @@
+/*
+ * Driver for the ST Microelectronics SPEAr1310 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear.h"
+
+#define DRIVER_NAME "spear1310-pinmux"
+
+/* pins */
+static const struct pinctrl_pin_desc spear1310_pins[] = {
+ SPEAR_PIN_0_TO_101,
+ SPEAR_PIN_102_TO_245,
+};
+
+/* registers */
+#define PERIP_CFG 0x32C
+ #define MCIF_SEL_SHIFT 3
+ #define MCIF_SEL_SD (0x1 << MCIF_SEL_SHIFT)
+ #define MCIF_SEL_CF (0x2 << MCIF_SEL_SHIFT)
+ #define MCIF_SEL_XD (0x3 << MCIF_SEL_SHIFT)
+ #define MCIF_SEL_MASK (0x3 << MCIF_SEL_SHIFT)
+
+#define PCIE_SATA_CFG 0x3A4
+ #define PCIE_SATA2_SEL_PCIE (0 << 31)
+ #define PCIE_SATA1_SEL_PCIE (0 << 30)
+ #define PCIE_SATA0_SEL_PCIE (0 << 29)
+ #define PCIE_SATA2_SEL_SATA (1 << 31)
+ #define PCIE_SATA1_SEL_SATA (1 << 30)
+ #define PCIE_SATA0_SEL_SATA (1 << 29)
+ #define SATA2_CFG_TX_CLK_EN (1 << 27)
+ #define SATA2_CFG_RX_CLK_EN (1 << 26)
+ #define SATA2_CFG_POWERUP_RESET (1 << 25)
+ #define SATA2_CFG_PM_CLK_EN (1 << 24)
+ #define SATA1_CFG_TX_CLK_EN (1 << 23)
+ #define SATA1_CFG_RX_CLK_EN (1 << 22)
+ #define SATA1_CFG_POWERUP_RESET (1 << 21)
+ #define SATA1_CFG_PM_CLK_EN (1 << 20)
+ #define SATA0_CFG_TX_CLK_EN (1 << 19)
+ #define SATA0_CFG_RX_CLK_EN (1 << 18)
+ #define SATA0_CFG_POWERUP_RESET (1 << 17)
+ #define SATA0_CFG_PM_CLK_EN (1 << 16)
+ #define PCIE2_CFG_DEVICE_PRESENT (1 << 11)
+ #define PCIE2_CFG_POWERUP_RESET (1 << 10)
+ #define PCIE2_CFG_CORE_CLK_EN (1 << 9)
+ #define PCIE2_CFG_AUX_CLK_EN (1 << 8)
+ #define PCIE1_CFG_DEVICE_PRESENT (1 << 7)
+ #define PCIE1_CFG_POWERUP_RESET (1 << 6)
+ #define PCIE1_CFG_CORE_CLK_EN (1 << 5)
+ #define PCIE1_CFG_AUX_CLK_EN (1 << 4)
+ #define PCIE0_CFG_DEVICE_PRESENT (1 << 3)
+ #define PCIE0_CFG_POWERUP_RESET (1 << 2)
+ #define PCIE0_CFG_CORE_CLK_EN (1 << 1)
+ #define PCIE0_CFG_AUX_CLK_EN (1 << 0)
+
+#define PAD_FUNCTION_EN_0 0x650
+ #define PMX_UART0_MASK (1 << 1)
+ #define PMX_I2C0_MASK (1 << 2)
+ #define PMX_I2S0_MASK (1 << 3)
+ #define PMX_SSP0_MASK (1 << 4)
+ #define PMX_CLCD1_MASK (1 << 5)
+ #define PMX_EGPIO00_MASK (1 << 6)
+ #define PMX_EGPIO01_MASK (1 << 7)
+ #define PMX_EGPIO02_MASK (1 << 8)
+ #define PMX_EGPIO03_MASK (1 << 9)
+ #define PMX_EGPIO04_MASK (1 << 10)
+ #define PMX_EGPIO05_MASK (1 << 11)
+ #define PMX_EGPIO06_MASK (1 << 12)
+ #define PMX_EGPIO07_MASK (1 << 13)
+ #define PMX_EGPIO08_MASK (1 << 14)
+ #define PMX_EGPIO09_MASK (1 << 15)
+ #define PMX_SMI_MASK (1 << 16)
+ #define PMX_NAND8_MASK (1 << 17)
+ #define PMX_GMIICLK_MASK (1 << 18)
+ #define PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK (1 << 19)
+ #define PMX_RXCLK_RDV_TXEN_D03_MASK (1 << 20)
+ #define PMX_GMIID47_MASK (1 << 21)
+ #define PMX_MDC_MDIO_MASK (1 << 22)
+ #define PMX_MCI_DATA8_15_MASK (1 << 23)
+ #define PMX_NFAD23_MASK (1 << 24)
+ #define PMX_NFAD24_MASK (1 << 25)
+ #define PMX_NFAD25_MASK (1 << 26)
+ #define PMX_NFCE3_MASK (1 << 27)
+ #define PMX_NFWPRT3_MASK (1 << 28)
+ #define PMX_NFRSTPWDWN0_MASK (1 << 29)
+ #define PMX_NFRSTPWDWN1_MASK (1 << 30)
+ #define PMX_NFRSTPWDWN2_MASK (1 << 31)
+
+#define PAD_FUNCTION_EN_1 0x654
+ #define PMX_NFRSTPWDWN3_MASK (1 << 0)
+ #define PMX_SMINCS2_MASK (1 << 1)
+ #define PMX_SMINCS3_MASK (1 << 2)
+ #define PMX_CLCD2_MASK (1 << 3)
+ #define PMX_KBD_ROWCOL68_MASK (1 << 4)
+ #define PMX_EGPIO10_MASK (1 << 5)
+ #define PMX_EGPIO11_MASK (1 << 6)
+ #define PMX_EGPIO12_MASK (1 << 7)
+ #define PMX_EGPIO13_MASK (1 << 8)
+ #define PMX_EGPIO14_MASK (1 << 9)
+ #define PMX_EGPIO15_MASK (1 << 10)
+ #define PMX_UART0_MODEM_MASK (1 << 11)
+ #define PMX_GPT0_TMR0_MASK (1 << 12)
+ #define PMX_GPT0_TMR1_MASK (1 << 13)
+ #define PMX_GPT1_TMR0_MASK (1 << 14)
+ #define PMX_GPT1_TMR1_MASK (1 << 15)
+ #define PMX_I2S1_MASK (1 << 16)
+ #define PMX_KBD_ROWCOL25_MASK (1 << 17)
+ #define PMX_NFIO8_15_MASK (1 << 18)
+ #define PMX_KBD_COL1_MASK (1 << 19)
+ #define PMX_NFCE1_MASK (1 << 20)
+ #define PMX_KBD_COL0_MASK (1 << 21)
+ #define PMX_NFCE2_MASK (1 << 22)
+ #define PMX_KBD_ROW1_MASK (1 << 23)
+ #define PMX_NFWPRT1_MASK (1 << 24)
+ #define PMX_KBD_ROW0_MASK (1 << 25)
+ #define PMX_NFWPRT2_MASK (1 << 26)
+ #define PMX_MCIDATA0_MASK (1 << 27)
+ #define PMX_MCIDATA1_MASK (1 << 28)
+ #define PMX_MCIDATA2_MASK (1 << 29)
+ #define PMX_MCIDATA3_MASK (1 << 30)
+ #define PMX_MCIDATA4_MASK (1 << 31)
+
+#define PAD_FUNCTION_EN_2 0x658
+ #define PMX_MCIDATA5_MASK (1 << 0)
+ #define PMX_MCIDATA6_MASK (1 << 1)
+ #define PMX_MCIDATA7_MASK (1 << 2)
+ #define PMX_MCIDATA1SD_MASK (1 << 3)
+ #define PMX_MCIDATA2SD_MASK (1 << 4)
+ #define PMX_MCIDATA3SD_MASK (1 << 5)
+ #define PMX_MCIADDR0ALE_MASK (1 << 6)
+ #define PMX_MCIADDR1CLECLK_MASK (1 << 7)
+ #define PMX_MCIADDR2_MASK (1 << 8)
+ #define PMX_MCICECF_MASK (1 << 9)
+ #define PMX_MCICEXD_MASK (1 << 10)
+ #define PMX_MCICESDMMC_MASK (1 << 11)
+ #define PMX_MCICDCF1_MASK (1 << 12)
+ #define PMX_MCICDCF2_MASK (1 << 13)
+ #define PMX_MCICDXD_MASK (1 << 14)
+ #define PMX_MCICDSDMMC_MASK (1 << 15)
+ #define PMX_MCIDATADIR_MASK (1 << 16)
+ #define PMX_MCIDMARQWP_MASK (1 << 17)
+ #define PMX_MCIIORDRE_MASK (1 << 18)
+ #define PMX_MCIIOWRWE_MASK (1 << 19)
+ #define PMX_MCIRESETCF_MASK (1 << 20)
+ #define PMX_MCICS0CE_MASK (1 << 21)
+ #define PMX_MCICFINTR_MASK (1 << 22)
+ #define PMX_MCIIORDY_MASK (1 << 23)
+ #define PMX_MCICS1_MASK (1 << 24)
+ #define PMX_MCIDMAACK_MASK (1 << 25)
+ #define PMX_MCISDCMD_MASK (1 << 26)
+ #define PMX_MCILEDS_MASK (1 << 27)
+ #define PMX_TOUCH_XY_MASK (1 << 28)
+ #define PMX_SSP0_CS0_MASK (1 << 29)
+ #define PMX_SSP0_CS1_2_MASK (1 << 30)
+
+/* combined macros */
+#define PMX_GMII_MASK (PMX_GMIICLK_MASK | \
+ PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \
+ PMX_RXCLK_RDV_TXEN_D03_MASK | \
+ PMX_GMIID47_MASK | PMX_MDC_MDIO_MASK)
+
+#define PMX_EGPIO_0_GRP_MASK (PMX_EGPIO00_MASK | PMX_EGPIO01_MASK | \
+ PMX_EGPIO02_MASK | \
+ PMX_EGPIO03_MASK | PMX_EGPIO04_MASK | \
+ PMX_EGPIO05_MASK | PMX_EGPIO06_MASK | \
+ PMX_EGPIO07_MASK | PMX_EGPIO08_MASK | \
+ PMX_EGPIO09_MASK)
+#define PMX_EGPIO_1_GRP_MASK (PMX_EGPIO10_MASK | PMX_EGPIO11_MASK | \
+ PMX_EGPIO12_MASK | PMX_EGPIO13_MASK | \
+ PMX_EGPIO14_MASK | PMX_EGPIO15_MASK)
+
+#define PMX_KEYBOARD_6X6_MASK (PMX_KBD_ROW0_MASK | PMX_KBD_ROW1_MASK | \
+ PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL0_MASK | \
+ PMX_KBD_COL1_MASK)
+
+#define PMX_NAND8BIT_0_MASK (PMX_NAND8_MASK | PMX_NFAD23_MASK | \
+ PMX_NFAD24_MASK | PMX_NFAD25_MASK | \
+ PMX_NFWPRT3_MASK | PMX_NFRSTPWDWN0_MASK | \
+ PMX_NFRSTPWDWN1_MASK | PMX_NFRSTPWDWN2_MASK | \
+ PMX_NFCE3_MASK)
+#define PMX_NAND8BIT_1_MASK PMX_NFRSTPWDWN3_MASK
+
+#define PMX_NAND16BIT_1_MASK (PMX_KBD_ROWCOL25_MASK | PMX_NFIO8_15_MASK)
+#define PMX_NAND_4CHIPS_MASK (PMX_NFCE1_MASK | PMX_NFCE2_MASK | \
+ PMX_NFWPRT1_MASK | PMX_NFWPRT2_MASK | \
+ PMX_KBD_ROW0_MASK | PMX_KBD_ROW1_MASK | \
+ PMX_KBD_COL0_MASK | PMX_KBD_COL1_MASK)
+
+#define PMX_MCIFALL_1_MASK 0xF8000000
+#define PMX_MCIFALL_2_MASK 0x0FFFFFFF
+
+#define PMX_PCI_REG1_MASK (PMX_SMINCS2_MASK | PMX_SMINCS3_MASK | \
+ PMX_CLCD2_MASK | PMX_KBD_ROWCOL68_MASK | \
+ PMX_EGPIO_1_GRP_MASK | PMX_GPT0_TMR0_MASK | \
+ PMX_GPT0_TMR1_MASK | PMX_GPT1_TMR0_MASK | \
+ PMX_GPT1_TMR1_MASK | PMX_I2S1_MASK | \
+ PMX_NFCE2_MASK)
+#define PMX_PCI_REG2_MASK (PMX_TOUCH_XY_MASK | PMX_SSP0_CS0_MASK | \
+ PMX_SSP0_CS1_2_MASK)
+
+#define PMX_SMII_0_1_2_MASK (PMX_CLCD2_MASK | PMX_KBD_ROWCOL68_MASK)
+#define PMX_RGMII_REG0_MASK (PMX_MCI_DATA8_15_MASK | \
+ PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK | \
+ PMX_GMIID47_MASK)
+#define PMX_RGMII_REG1_MASK (PMX_KBD_ROWCOL68_MASK | PMX_EGPIO_1_GRP_MASK |\
+ PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK | \
+ PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK)
+#define PMX_RGMII_REG2_MASK (PMX_TOUCH_XY_MASK | PMX_SSP0_CS0_MASK | \
+ PMX_SSP0_CS1_2_MASK)
+
+#define PCIE_CFG_VAL(x) (PCIE_SATA##x##_SEL_PCIE | \
+ PCIE##x##_CFG_AUX_CLK_EN | \
+ PCIE##x##_CFG_CORE_CLK_EN | \
+ PCIE##x##_CFG_POWERUP_RESET | \
+ PCIE##x##_CFG_DEVICE_PRESENT)
+#define SATA_CFG_VAL(x) (PCIE_SATA##x##_SEL_SATA | \
+ SATA##x##_CFG_PM_CLK_EN | \
+ SATA##x##_CFG_POWERUP_RESET | \
+ SATA##x##_CFG_RX_CLK_EN | \
+ SATA##x##_CFG_TX_CLK_EN)
+
+/* Pad multiplexing for i2c0 device */
+static const unsigned i2c0_pins[] = { 102, 103 };
+static struct spear_muxreg i2c0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_I2C0_MASK,
+ .val = PMX_I2C0_MASK,
+ },
+};
+
+static struct spear_modemux i2c0_modemux[] = {
+ {
+ .muxregs = i2c0_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c0_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c0_pingroup = {
+ .name = "i2c0_grp",
+ .pins = i2c0_pins,
+ .npins = ARRAY_SIZE(i2c0_pins),
+ .modemuxs = i2c0_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c0_modemux),
+};
+
+static const char *const i2c0_grps[] = { "i2c0_grp" };
+static struct spear_function i2c0_function = {
+ .name = "i2c0",
+ .groups = i2c0_grps,
+ .ngroups = ARRAY_SIZE(i2c0_grps),
+};
+
+/* Pad multiplexing for ssp0 device */
+static const unsigned ssp0_pins[] = { 109, 110, 111, 112 };
+static struct spear_muxreg ssp0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_SSP0_MASK,
+ .val = PMX_SSP0_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_modemux[] = {
+ {
+ .muxregs = ssp0_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_pingroup = {
+ .name = "ssp0_grp",
+ .pins = ssp0_pins,
+ .npins = ARRAY_SIZE(ssp0_pins),
+ .modemuxs = ssp0_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_modemux),
+};
+
+/* Pad multiplexing for ssp0_cs0 device */
+static const unsigned ssp0_cs0_pins[] = { 96 };
+static struct spear_muxreg ssp0_cs0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_SSP0_CS0_MASK,
+ .val = PMX_SSP0_CS0_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_cs0_modemux[] = {
+ {
+ .muxregs = ssp0_cs0_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_cs0_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_cs0_pingroup = {
+ .name = "ssp0_cs0_grp",
+ .pins = ssp0_cs0_pins,
+ .npins = ARRAY_SIZE(ssp0_cs0_pins),
+ .modemuxs = ssp0_cs0_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_cs0_modemux),
+};
+
+/* ssp0_cs1_2 device */
+static const unsigned ssp0_cs1_2_pins[] = { 94, 95 };
+static struct spear_muxreg ssp0_cs1_2_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_SSP0_CS1_2_MASK,
+ .val = PMX_SSP0_CS1_2_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_cs1_2_modemux[] = {
+ {
+ .muxregs = ssp0_cs1_2_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_cs1_2_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_cs1_2_pingroup = {
+ .name = "ssp0_cs1_2_grp",
+ .pins = ssp0_cs1_2_pins,
+ .npins = ARRAY_SIZE(ssp0_cs1_2_pins),
+ .modemuxs = ssp0_cs1_2_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_cs1_2_modemux),
+};
+
+static const char *const ssp0_grps[] = { "ssp0_grp", "ssp0_cs0_grp",
+ "ssp0_cs1_2_grp" };
+static struct spear_function ssp0_function = {
+ .name = "ssp0",
+ .groups = ssp0_grps,
+ .ngroups = ARRAY_SIZE(ssp0_grps),
+};
+
+/* Pad multiplexing for i2s0 device */
+static const unsigned i2s0_pins[] = { 104, 105, 106, 107, 108 };
+static struct spear_muxreg i2s0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_I2S0_MASK,
+ .val = PMX_I2S0_MASK,
+ },
+};
+
+static struct spear_modemux i2s0_modemux[] = {
+ {
+ .muxregs = i2s0_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s0_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s0_pingroup = {
+ .name = "i2s0_grp",
+ .pins = i2s0_pins,
+ .npins = ARRAY_SIZE(i2s0_pins),
+ .modemuxs = i2s0_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s0_modemux),
+};
+
+static const char *const i2s0_grps[] = { "i2s0_grp" };
+static struct spear_function i2s0_function = {
+ .name = "i2s0",
+ .groups = i2s0_grps,
+ .ngroups = ARRAY_SIZE(i2s0_grps),
+};
+
+/* Pad multiplexing for i2s1 device */
+static const unsigned i2s1_pins[] = { 0, 1, 2, 3 };
+static struct spear_muxreg i2s1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_I2S1_MASK,
+ .val = PMX_I2S1_MASK,
+ },
+};
+
+static struct spear_modemux i2s1_modemux[] = {
+ {
+ .muxregs = i2s1_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s1_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s1_pingroup = {
+ .name = "i2s1_grp",
+ .pins = i2s1_pins,
+ .npins = ARRAY_SIZE(i2s1_pins),
+ .modemuxs = i2s1_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s1_modemux),
+};
+
+static const char *const i2s1_grps[] = { "i2s1_grp" };
+static struct spear_function i2s1_function = {
+ .name = "i2s1",
+ .groups = i2s1_grps,
+ .ngroups = ARRAY_SIZE(i2s1_grps),
+};
+
+/* Pad multiplexing for clcd device */
+static const unsigned clcd_pins[] = { 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142 };
+static struct spear_muxreg clcd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = PMX_CLCD1_MASK,
+ },
+};
+
+static struct spear_modemux clcd_modemux[] = {
+ {
+ .muxregs = clcd_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_pingroup = {
+ .name = "clcd_grp",
+ .pins = clcd_pins,
+ .npins = ARRAY_SIZE(clcd_pins),
+ .modemuxs = clcd_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_modemux),
+};
+
+static const unsigned clcd_high_res_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 };
+static struct spear_muxreg clcd_high_res_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_CLCD2_MASK,
+ .val = PMX_CLCD2_MASK,
+ },
+};
+
+static struct spear_modemux clcd_high_res_modemux[] = {
+ {
+ .muxregs = clcd_high_res_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_high_res_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_high_res_pingroup = {
+ .name = "clcd_high_res_grp",
+ .pins = clcd_high_res_pins,
+ .npins = ARRAY_SIZE(clcd_high_res_pins),
+ .modemuxs = clcd_high_res_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_high_res_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp", "clcd_high_res" };
+static struct spear_function clcd_function = {
+ .name = "clcd",
+ .groups = clcd_grps,
+ .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+static const unsigned arm_gpio_pins[] = { 18, 19, 20, 21, 22, 23, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152 };
+static struct spear_muxreg arm_gpio_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_EGPIO_0_GRP_MASK,
+ .val = PMX_EGPIO_0_GRP_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_EGPIO_1_GRP_MASK,
+ .val = PMX_EGPIO_1_GRP_MASK,
+ },
+};
+
+static struct spear_modemux arm_gpio_modemux[] = {
+ {
+ .muxregs = arm_gpio_muxreg,
+ .nmuxregs = ARRAY_SIZE(arm_gpio_muxreg),
+ },
+};
+
+static struct spear_pingroup arm_gpio_pingroup = {
+ .name = "arm_gpio_grp",
+ .pins = arm_gpio_pins,
+ .npins = ARRAY_SIZE(arm_gpio_pins),
+ .modemuxs = arm_gpio_modemux,
+ .nmodemuxs = ARRAY_SIZE(arm_gpio_modemux),
+};
+
+static const char *const arm_gpio_grps[] = { "arm_gpio_grp" };
+static struct spear_function arm_gpio_function = {
+ .name = "arm_gpio",
+ .groups = arm_gpio_grps,
+ .ngroups = ARRAY_SIZE(arm_gpio_grps),
+};
+
+/* Pad multiplexing for smi 2 chips device */
+static const unsigned smi_2_chips_pins[] = { 153, 154, 155, 156, 157 };
+static struct spear_muxreg smi_2_chips_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
+ },
+};
+
+static struct spear_modemux smi_2_chips_modemux[] = {
+ {
+ .muxregs = smi_2_chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(smi_2_chips_muxreg),
+ },
+};
+
+static struct spear_pingroup smi_2_chips_pingroup = {
+ .name = "smi_2_chips_grp",
+ .pins = smi_2_chips_pins,
+ .npins = ARRAY_SIZE(smi_2_chips_pins),
+ .modemuxs = smi_2_chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(smi_2_chips_modemux),
+};
+
+static const unsigned smi_4_chips_pins[] = { 54, 55 };
+static struct spear_muxreg smi_4_chips_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_SMI_MASK,
+ .val = PMX_SMI_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+ .val = PMX_SMINCS2_MASK | PMX_SMINCS3_MASK,
+ },
+};
+
+static struct spear_modemux smi_4_chips_modemux[] = {
+ {
+ .muxregs = smi_4_chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(smi_4_chips_muxreg),
+ },
+};
+
+static struct spear_pingroup smi_4_chips_pingroup = {
+ .name = "smi_4_chips_grp",
+ .pins = smi_4_chips_pins,
+ .npins = ARRAY_SIZE(smi_4_chips_pins),
+ .modemuxs = smi_4_chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(smi_4_chips_modemux),
+};
+
+static const char *const smi_grps[] = { "smi_2_chips_grp", "smi_4_chips_grp" };
+static struct spear_function smi_function = {
+ .name = "smi",
+ .groups = smi_grps,
+ .ngroups = ARRAY_SIZE(smi_grps),
+};
+
+/* Pad multiplexing for gmii device */
+static const unsigned gmii_pins[] = { 173, 174, 175, 176, 177, 178, 179, 180,
+ 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194,
+ 195, 196, 197, 198, 199, 200 };
+static struct spear_muxreg gmii_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_GMII_MASK,
+ .val = PMX_GMII_MASK,
+ },
+};
+
+static struct spear_modemux gmii_modemux[] = {
+ {
+ .muxregs = gmii_muxreg,
+ .nmuxregs = ARRAY_SIZE(gmii_muxreg),
+ },
+};
+
+static struct spear_pingroup gmii_pingroup = {
+ .name = "gmii_grp",
+ .pins = gmii_pins,
+ .npins = ARRAY_SIZE(gmii_pins),
+ .modemuxs = gmii_modemux,
+ .nmodemuxs = ARRAY_SIZE(gmii_modemux),
+};
+
+static const char *const gmii_grps[] = { "gmii_grp" };
+static struct spear_function gmii_function = {
+ .name = "gmii",
+ .groups = gmii_grps,
+ .ngroups = ARRAY_SIZE(gmii_grps),
+};
+
+/* Pad multiplexing for rgmii device */
+static const unsigned rgmii_pins[] = { 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 175,
+ 180, 181, 182, 183, 185, 188, 193, 194, 195, 196, 197, 198, 211, 212 };
+static struct spear_muxreg rgmii_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_RGMII_REG0_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_RGMII_REG1_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_RGMII_REG2_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux rgmii_modemux[] = {
+ {
+ .muxregs = rgmii_muxreg,
+ .nmuxregs = ARRAY_SIZE(rgmii_muxreg),
+ },
+};
+
+static struct spear_pingroup rgmii_pingroup = {
+ .name = "rgmii_grp",
+ .pins = rgmii_pins,
+ .npins = ARRAY_SIZE(rgmii_pins),
+ .modemuxs = rgmii_modemux,
+ .nmodemuxs = ARRAY_SIZE(rgmii_modemux),
+};
+
+static const char *const rgmii_grps[] = { "rgmii_grp" };
+static struct spear_function rgmii_function = {
+ .name = "rgmii",
+ .groups = rgmii_grps,
+ .ngroups = ARRAY_SIZE(rgmii_grps),
+};
+
+/* Pad multiplexing for smii_0_1_2 device */
+static const unsigned smii_0_1_2_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55 };
+static struct spear_muxreg smii_0_1_2_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_SMII_0_1_2_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux smii_0_1_2_modemux[] = {
+ {
+ .muxregs = smii_0_1_2_muxreg,
+ .nmuxregs = ARRAY_SIZE(smii_0_1_2_muxreg),
+ },
+};
+
+static struct spear_pingroup smii_0_1_2_pingroup = {
+ .name = "smii_0_1_2_grp",
+ .pins = smii_0_1_2_pins,
+ .npins = ARRAY_SIZE(smii_0_1_2_pins),
+ .modemuxs = smii_0_1_2_modemux,
+ .nmodemuxs = ARRAY_SIZE(smii_0_1_2_modemux),
+};
+
+static const char *const smii_0_1_2_grps[] = { "smii_0_1_2_grp" };
+static struct spear_function smii_0_1_2_function = {
+ .name = "smii_0_1_2",
+ .groups = smii_0_1_2_grps,
+ .ngroups = ARRAY_SIZE(smii_0_1_2_grps),
+};
+
+/* Pad multiplexing for ras_mii_txclk device */
+static const unsigned ras_mii_txclk_pins[] = { 98, 99 };
+static struct spear_muxreg ras_mii_txclk_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_NFCE2_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux ras_mii_txclk_modemux[] = {
+ {
+ .muxregs = ras_mii_txclk_muxreg,
+ .nmuxregs = ARRAY_SIZE(ras_mii_txclk_muxreg),
+ },
+};
+
+static struct spear_pingroup ras_mii_txclk_pingroup = {
+ .name = "ras_mii_txclk_grp",
+ .pins = ras_mii_txclk_pins,
+ .npins = ARRAY_SIZE(ras_mii_txclk_pins),
+ .modemuxs = ras_mii_txclk_modemux,
+ .nmodemuxs = ARRAY_SIZE(ras_mii_txclk_modemux),
+};
+
+static const char *const ras_mii_txclk_grps[] = { "ras_mii_txclk_grp" };
+static struct spear_function ras_mii_txclk_function = {
+ .name = "ras_mii_txclk",
+ .groups = ras_mii_txclk_grps,
+ .ngroups = ARRAY_SIZE(ras_mii_txclk_grps),
+};
+
+/* Pad multiplexing for nand 8bit device (cs0 only) */
+static const unsigned nand_8bit_pins[] = { 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
+ 170, 171, 172, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211,
+ 212 };
+static struct spear_muxreg nand_8bit_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_NAND8BIT_0_MASK,
+ .val = PMX_NAND8BIT_0_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_NAND8BIT_1_MASK,
+ .val = PMX_NAND8BIT_1_MASK,
+ },
+};
+
+static struct spear_modemux nand_8bit_modemux[] = {
+ {
+ .muxregs = nand_8bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(nand_8bit_muxreg),
+ },
+};
+
+static struct spear_pingroup nand_8bit_pingroup = {
+ .name = "nand_8bit_grp",
+ .pins = nand_8bit_pins,
+ .npins = ARRAY_SIZE(nand_8bit_pins),
+ .modemuxs = nand_8bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(nand_8bit_modemux),
+};
+
+/* Pad multiplexing for nand 16bit device */
+static const unsigned nand_16bit_pins[] = { 201, 202, 203, 204, 207, 208, 209,
+ 210 };
+static struct spear_muxreg nand_16bit_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_NAND16BIT_1_MASK,
+ .val = PMX_NAND16BIT_1_MASK,
+ },
+};
+
+static struct spear_modemux nand_16bit_modemux[] = {
+ {
+ .muxregs = nand_16bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(nand_16bit_muxreg),
+ },
+};
+
+static struct spear_pingroup nand_16bit_pingroup = {
+ .name = "nand_16bit_grp",
+ .pins = nand_16bit_pins,
+ .npins = ARRAY_SIZE(nand_16bit_pins),
+ .modemuxs = nand_16bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(nand_16bit_modemux),
+};
+
+/* Pad multiplexing for nand 4 chips */
+static const unsigned nand_4_chips_pins[] = { 205, 206, 211, 212 };
+static struct spear_muxreg nand_4_chips_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_NAND_4CHIPS_MASK,
+ .val = PMX_NAND_4CHIPS_MASK,
+ },
+};
+
+static struct spear_modemux nand_4_chips_modemux[] = {
+ {
+ .muxregs = nand_4_chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(nand_4_chips_muxreg),
+ },
+};
+
+static struct spear_pingroup nand_4_chips_pingroup = {
+ .name = "nand_4_chips_grp",
+ .pins = nand_4_chips_pins,
+ .npins = ARRAY_SIZE(nand_4_chips_pins),
+ .modemuxs = nand_4_chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(nand_4_chips_modemux),
+};
+
+static const char *const nand_grps[] = { "nand_8bit_grp", "nand_16bit_grp",
+ "nand_4_chips_grp" };
+static struct spear_function nand_function = {
+ .name = "nand",
+ .groups = nand_grps,
+ .ngroups = ARRAY_SIZE(nand_grps),
+};
+
+/* Pad multiplexing for keyboard_6x6 device */
+static const unsigned keyboard_6x6_pins[] = { 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212 };
+static struct spear_muxreg keyboard_6x6_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_KEYBOARD_6X6_MASK | PMX_NFIO8_15_MASK |
+ PMX_NFCE1_MASK | PMX_NFCE2_MASK | PMX_NFWPRT1_MASK |
+ PMX_NFWPRT2_MASK,
+ .val = PMX_KEYBOARD_6X6_MASK,
+ },
+};
+
+static struct spear_modemux keyboard_6x6_modemux[] = {
+ {
+ .muxregs = keyboard_6x6_muxreg,
+ .nmuxregs = ARRAY_SIZE(keyboard_6x6_muxreg),
+ },
+};
+
+static struct spear_pingroup keyboard_6x6_pingroup = {
+ .name = "keyboard_6x6_grp",
+ .pins = keyboard_6x6_pins,
+ .npins = ARRAY_SIZE(keyboard_6x6_pins),
+ .modemuxs = keyboard_6x6_modemux,
+ .nmodemuxs = ARRAY_SIZE(keyboard_6x6_modemux),
+};
+
+/* Pad multiplexing for keyboard_rowcol6_8 device */
+static const unsigned keyboard_rowcol6_8_pins[] = { 24, 25, 26, 27, 28, 29 };
+static struct spear_muxreg keyboard_rowcol6_8_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_KBD_ROWCOL68_MASK,
+ .val = PMX_KBD_ROWCOL68_MASK,
+ },
+};
+
+static struct spear_modemux keyboard_rowcol6_8_modemux[] = {
+ {
+ .muxregs = keyboard_rowcol6_8_muxreg,
+ .nmuxregs = ARRAY_SIZE(keyboard_rowcol6_8_muxreg),
+ },
+};
+
+static struct spear_pingroup keyboard_rowcol6_8_pingroup = {
+ .name = "keyboard_rowcol6_8_grp",
+ .pins = keyboard_rowcol6_8_pins,
+ .npins = ARRAY_SIZE(keyboard_rowcol6_8_pins),
+ .modemuxs = keyboard_rowcol6_8_modemux,
+ .nmodemuxs = ARRAY_SIZE(keyboard_rowcol6_8_modemux),
+};
+
+static const char *const keyboard_grps[] = { "keyboard_6x6_grp",
+ "keyboard_rowcol6_8_grp" };
+static struct spear_function keyboard_function = {
+ .name = "keyboard",
+ .groups = keyboard_grps,
+ .ngroups = ARRAY_SIZE(keyboard_grps),
+};
+
+/* Pad multiplexing for uart0 device */
+static const unsigned uart0_pins[] = { 100, 101 };
+static struct spear_muxreg uart0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_UART0_MASK,
+ .val = PMX_UART0_MASK,
+ },
+};
+
+static struct spear_modemux uart0_modemux[] = {
+ {
+ .muxregs = uart0_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart0_muxreg),
+ },
+};
+
+static struct spear_pingroup uart0_pingroup = {
+ .name = "uart0_grp",
+ .pins = uart0_pins,
+ .npins = ARRAY_SIZE(uart0_pins),
+ .modemuxs = uart0_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart0_modemux),
+};
+
+/* Pad multiplexing for uart0_modem device */
+static const unsigned uart0_modem_pins[] = { 12, 13, 14, 15, 16, 17 };
+static struct spear_muxreg uart0_modem_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = PMX_UART0_MODEM_MASK,
+ },
+};
+
+static struct spear_modemux uart0_modem_modemux[] = {
+ {
+ .muxregs = uart0_modem_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart0_modem_muxreg),
+ },
+};
+
+static struct spear_pingroup uart0_modem_pingroup = {
+ .name = "uart0_modem_grp",
+ .pins = uart0_modem_pins,
+ .npins = ARRAY_SIZE(uart0_modem_pins),
+ .modemuxs = uart0_modem_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart0_modem_modemux),
+};
+
+static const char *const uart0_grps[] = { "uart0_grp", "uart0_modem_grp" };
+static struct spear_function uart0_function = {
+ .name = "uart0",
+ .groups = uart0_grps,
+ .ngroups = ARRAY_SIZE(uart0_grps),
+};
+
+/* Pad multiplexing for gpt0_tmr0 device */
+static const unsigned gpt0_tmr0_pins[] = { 10, 11 };
+static struct spear_muxreg gpt0_tmr0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_GPT0_TMR0_MASK,
+ .val = PMX_GPT0_TMR0_MASK,
+ },
+};
+
+static struct spear_modemux gpt0_tmr0_modemux[] = {
+ {
+ .muxregs = gpt0_tmr0_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpt0_tmr0_muxreg),
+ },
+};
+
+static struct spear_pingroup gpt0_tmr0_pingroup = {
+ .name = "gpt0_tmr0_grp",
+ .pins = gpt0_tmr0_pins,
+ .npins = ARRAY_SIZE(gpt0_tmr0_pins),
+ .modemuxs = gpt0_tmr0_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpt0_tmr0_modemux),
+};
+
+/* Pad multiplexing for gpt0_tmr1 device */
+static const unsigned gpt0_tmr1_pins[] = { 8, 9 };
+static struct spear_muxreg gpt0_tmr1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_GPT0_TMR1_MASK,
+ .val = PMX_GPT0_TMR1_MASK,
+ },
+};
+
+static struct spear_modemux gpt0_tmr1_modemux[] = {
+ {
+ .muxregs = gpt0_tmr1_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpt0_tmr1_muxreg),
+ },
+};
+
+static struct spear_pingroup gpt0_tmr1_pingroup = {
+ .name = "gpt0_tmr1_grp",
+ .pins = gpt0_tmr1_pins,
+ .npins = ARRAY_SIZE(gpt0_tmr1_pins),
+ .modemuxs = gpt0_tmr1_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpt0_tmr1_modemux),
+};
+
+static const char *const gpt0_grps[] = { "gpt0_tmr0_grp", "gpt0_tmr1_grp" };
+static struct spear_function gpt0_function = {
+ .name = "gpt0",
+ .groups = gpt0_grps,
+ .ngroups = ARRAY_SIZE(gpt0_grps),
+};
+
+/* Pad multiplexing for gpt1_tmr0 device */
+static const unsigned gpt1_tmr0_pins[] = { 6, 7 };
+static struct spear_muxreg gpt1_tmr0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_GPT1_TMR0_MASK,
+ .val = PMX_GPT1_TMR0_MASK,
+ },
+};
+
+static struct spear_modemux gpt1_tmr0_modemux[] = {
+ {
+ .muxregs = gpt1_tmr0_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpt1_tmr0_muxreg),
+ },
+};
+
+static struct spear_pingroup gpt1_tmr0_pingroup = {
+ .name = "gpt1_tmr0_grp",
+ .pins = gpt1_tmr0_pins,
+ .npins = ARRAY_SIZE(gpt1_tmr0_pins),
+ .modemuxs = gpt1_tmr0_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpt1_tmr0_modemux),
+};
+
+/* Pad multiplexing for gpt1_tmr1 device */
+static const unsigned gpt1_tmr1_pins[] = { 4, 5 };
+static struct spear_muxreg gpt1_tmr1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_GPT1_TMR1_MASK,
+ .val = PMX_GPT1_TMR1_MASK,
+ },
+};
+
+static struct spear_modemux gpt1_tmr1_modemux[] = {
+ {
+ .muxregs = gpt1_tmr1_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpt1_tmr1_muxreg),
+ },
+};
+
+static struct spear_pingroup gpt1_tmr1_pingroup = {
+ .name = "gpt1_tmr1_grp",
+ .pins = gpt1_tmr1_pins,
+ .npins = ARRAY_SIZE(gpt1_tmr1_pins),
+ .modemuxs = gpt1_tmr1_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpt1_tmr1_modemux),
+};
+
+static const char *const gpt1_grps[] = { "gpt1_tmr1_grp", "gpt1_tmr0_grp" };
+static struct spear_function gpt1_function = {
+ .name = "gpt1",
+ .groups = gpt1_grps,
+ .ngroups = ARRAY_SIZE(gpt1_grps),
+};
+
+/* Pad multiplexing for mcif device */
+static const unsigned mcif_pins[] = { 86, 87, 88, 89, 90, 91, 92, 93, 213, 214,
+ 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
+ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
+ 243, 244, 245 };
+#define MCIF_MUXREG \
+ { \
+ .reg = PAD_FUNCTION_EN_0, \
+ .mask = PMX_MCI_DATA8_15_MASK, \
+ .val = PMX_MCI_DATA8_15_MASK, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_1, \
+ .mask = PMX_MCIFALL_1_MASK | PMX_NFWPRT1_MASK | \
+ PMX_NFWPRT2_MASK, \
+ .val = PMX_MCIFALL_1_MASK, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_2, \
+ .mask = PMX_MCIFALL_2_MASK, \
+ .val = PMX_MCIFALL_2_MASK, \
+ }
+
+/* sdhci device */
+static struct spear_muxreg sdhci_muxreg[] = {
+ MCIF_MUXREG,
+ {
+ .reg = PERIP_CFG,
+ .mask = MCIF_SEL_MASK,
+ .val = MCIF_SEL_SD,
+ },
+};
+
+static struct spear_modemux sdhci_modemux[] = {
+ {
+ .muxregs = sdhci_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_pingroup = {
+ .name = "sdhci_grp",
+ .pins = mcif_pins,
+ .npins = ARRAY_SIZE(mcif_pins),
+ .modemuxs = sdhci_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_modemux),
+};
+
+static const char *const sdhci_grps[] = { "sdhci_grp" };
+static struct spear_function sdhci_function = {
+ .name = "sdhci",
+ .groups = sdhci_grps,
+ .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* cf device */
+static struct spear_muxreg cf_muxreg[] = {
+ MCIF_MUXREG,
+ {
+ .reg = PERIP_CFG,
+ .mask = MCIF_SEL_MASK,
+ .val = MCIF_SEL_CF,
+ },
+};
+
+static struct spear_modemux cf_modemux[] = {
+ {
+ .muxregs = cf_muxreg,
+ .nmuxregs = ARRAY_SIZE(cf_muxreg),
+ },
+};
+
+static struct spear_pingroup cf_pingroup = {
+ .name = "cf_grp",
+ .pins = mcif_pins,
+ .npins = ARRAY_SIZE(mcif_pins),
+ .modemuxs = cf_modemux,
+ .nmodemuxs = ARRAY_SIZE(cf_modemux),
+};
+
+static const char *const cf_grps[] = { "cf_grp" };
+static struct spear_function cf_function = {
+ .name = "cf",
+ .groups = cf_grps,
+ .ngroups = ARRAY_SIZE(cf_grps),
+};
+
+/* xd device */
+static struct spear_muxreg xd_muxreg[] = {
+ MCIF_MUXREG,
+ {
+ .reg = PERIP_CFG,
+ .mask = MCIF_SEL_MASK,
+ .val = MCIF_SEL_XD,
+ },
+};
+
+static struct spear_modemux xd_modemux[] = {
+ {
+ .muxregs = xd_muxreg,
+ .nmuxregs = ARRAY_SIZE(xd_muxreg),
+ },
+};
+
+static struct spear_pingroup xd_pingroup = {
+ .name = "xd_grp",
+ .pins = mcif_pins,
+ .npins = ARRAY_SIZE(mcif_pins),
+ .modemuxs = xd_modemux,
+ .nmodemuxs = ARRAY_SIZE(xd_modemux),
+};
+
+static const char *const xd_grps[] = { "xd_grp" };
+static struct spear_function xd_function = {
+ .name = "xd",
+ .groups = xd_grps,
+ .ngroups = ARRAY_SIZE(xd_grps),
+};
+
+/* Pad multiplexing for touch_xy device */
+static const unsigned touch_xy_pins[] = { 97 };
+static struct spear_muxreg touch_xy_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_TOUCH_XY_MASK,
+ .val = PMX_TOUCH_XY_MASK,
+ },
+};
+
+static struct spear_modemux touch_xy_modemux[] = {
+ {
+ .muxregs = touch_xy_muxreg,
+ .nmuxregs = ARRAY_SIZE(touch_xy_muxreg),
+ },
+};
+
+static struct spear_pingroup touch_xy_pingroup = {
+ .name = "touch_xy_grp",
+ .pins = touch_xy_pins,
+ .npins = ARRAY_SIZE(touch_xy_pins),
+ .modemuxs = touch_xy_modemux,
+ .nmodemuxs = ARRAY_SIZE(touch_xy_modemux),
+};
+
+static const char *const touch_xy_grps[] = { "touch_xy_grp" };
+static struct spear_function touch_xy_function = {
+ .name = "touchscreen",
+ .groups = touch_xy_grps,
+ .ngroups = ARRAY_SIZE(touch_xy_grps),
+};
+
+/* Pad multiplexing for uart1 device */
+/* Muxed with I2C */
+static const unsigned uart1_dis_i2c_pins[] = { 102, 103 };
+static struct spear_muxreg uart1_dis_i2c_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_I2C0_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart1_dis_i2c_modemux[] = {
+ {
+ .muxregs = uart1_dis_i2c_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_dis_i2c_muxreg),
+ },
+};
+
+static struct spear_pingroup uart_1_dis_i2c_pingroup = {
+ .name = "uart1_disable_i2c_grp",
+ .pins = uart1_dis_i2c_pins,
+ .npins = ARRAY_SIZE(uart1_dis_i2c_pins),
+ .modemuxs = uart1_dis_i2c_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_dis_i2c_modemux),
+};
+
+/* Muxed with SD/MMC */
+static const unsigned uart1_dis_sd_pins[] = { 214, 215 };
+static struct spear_muxreg uart1_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_MCIDATA1_MASK |
+ PMX_MCIDATA2_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart1_dis_sd_modemux[] = {
+ {
+ .muxregs = uart1_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup uart_1_dis_sd_pingroup = {
+ .name = "uart1_disable_sd_grp",
+ .pins = uart1_dis_sd_pins,
+ .npins = ARRAY_SIZE(uart1_dis_sd_pins),
+ .modemuxs = uart1_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_dis_sd_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_disable_i2c_grp",
+ "uart1_disable_sd_grp" };
+static struct spear_function uart1_function = {
+ .name = "uart1",
+ .groups = uart1_grps,
+ .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* Pad multiplexing for uart2_3 device */
+static const unsigned uart2_3_pins[] = { 104, 105, 106, 107 };
+static struct spear_muxreg uart2_3_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_I2S0_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart2_3_modemux[] = {
+ {
+ .muxregs = uart2_3_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart2_3_muxreg),
+ },
+};
+
+static struct spear_pingroup uart_2_3_pingroup = {
+ .name = "uart2_3_grp",
+ .pins = uart2_3_pins,
+ .npins = ARRAY_SIZE(uart2_3_pins),
+ .modemuxs = uart2_3_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart2_3_modemux),
+};
+
+static const char *const uart2_3_grps[] = { "uart2_3_grp" };
+static struct spear_function uart2_3_function = {
+ .name = "uart2_3",
+ .groups = uart2_3_grps,
+ .ngroups = ARRAY_SIZE(uart2_3_grps),
+};
+
+/* Pad multiplexing for uart4 device */
+static const unsigned uart4_pins[] = { 108, 113 };
+static struct spear_muxreg uart4_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_I2S0_MASK | PMX_CLCD1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart4_modemux[] = {
+ {
+ .muxregs = uart4_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_muxreg),
+ },
+};
+
+static struct spear_pingroup uart_4_pingroup = {
+ .name = "uart4_grp",
+ .pins = uart4_pins,
+ .npins = ARRAY_SIZE(uart4_pins),
+ .modemuxs = uart4_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux),
+};
+
+static const char *const uart4_grps[] = { "uart4_grp" };
+static struct spear_function uart4_function = {
+ .name = "uart4",
+ .groups = uart4_grps,
+ .ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* Pad multiplexing for uart5 device */
+static const unsigned uart5_pins[] = { 114, 115 };
+static struct spear_muxreg uart5_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart5_modemux[] = {
+ {
+ .muxregs = uart5_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_muxreg),
+ },
+};
+
+static struct spear_pingroup uart_5_pingroup = {
+ .name = "uart5_grp",
+ .pins = uart5_pins,
+ .npins = ARRAY_SIZE(uart5_pins),
+ .modemuxs = uart5_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux),
+};
+
+static const char *const uart5_grps[] = { "uart5_grp" };
+static struct spear_function uart5_function = {
+ .name = "uart5",
+ .groups = uart5_grps,
+ .ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* Pad multiplexing for rs485_0_1_tdm_0_1 device */
+static const unsigned rs485_0_1_tdm_0_1_pins[] = { 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137 };
+static struct spear_muxreg rs485_0_1_tdm_0_1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux rs485_0_1_tdm_0_1_modemux[] = {
+ {
+ .muxregs = rs485_0_1_tdm_0_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(rs485_0_1_tdm_0_1_muxreg),
+ },
+};
+
+static struct spear_pingroup rs485_0_1_tdm_0_1_pingroup = {
+ .name = "rs485_0_1_tdm_0_1_grp",
+ .pins = rs485_0_1_tdm_0_1_pins,
+ .npins = ARRAY_SIZE(rs485_0_1_tdm_0_1_pins),
+ .modemuxs = rs485_0_1_tdm_0_1_modemux,
+ .nmodemuxs = ARRAY_SIZE(rs485_0_1_tdm_0_1_modemux),
+};
+
+static const char *const rs485_0_1_tdm_0_1_grps[] = { "rs485_0_1_tdm_0_1_grp" };
+static struct spear_function rs485_0_1_tdm_0_1_function = {
+ .name = "rs485_0_1_tdm_0_1",
+ .groups = rs485_0_1_tdm_0_1_grps,
+ .ngroups = ARRAY_SIZE(rs485_0_1_tdm_0_1_grps),
+};
+
+/* Pad multiplexing for i2c_1_2 device */
+static const unsigned i2c_1_2_pins[] = { 138, 139, 140, 141 };
+static struct spear_muxreg i2c_1_2_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_CLCD1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c_1_2_modemux[] = {
+ {
+ .muxregs = i2c_1_2_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c_1_2_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c_1_2_pingroup = {
+ .name = "i2c_1_2_grp",
+ .pins = i2c_1_2_pins,
+ .npins = ARRAY_SIZE(i2c_1_2_pins),
+ .modemuxs = i2c_1_2_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c_1_2_modemux),
+};
+
+static const char *const i2c_1_2_grps[] = { "i2c_1_2_grp" };
+static struct spear_function i2c_1_2_function = {
+ .name = "i2c_1_2",
+ .groups = i2c_1_2_grps,
+ .ngroups = ARRAY_SIZE(i2c_1_2_grps),
+};
+
+/* Pad multiplexing for i2c3_dis_smi_clcd device */
+/* Muxed with SMI & CLCD */
+static const unsigned i2c3_dis_smi_clcd_pins[] = { 142, 153 };
+static struct spear_muxreg i2c3_dis_smi_clcd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_CLCD1_MASK | PMX_SMI_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c3_dis_smi_clcd_modemux[] = {
+ {
+ .muxregs = i2c3_dis_smi_clcd_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c3_dis_smi_clcd_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c3_dis_smi_clcd_pingroup = {
+ .name = "i2c3_dis_smi_clcd_grp",
+ .pins = i2c3_dis_smi_clcd_pins,
+ .npins = ARRAY_SIZE(i2c3_dis_smi_clcd_pins),
+ .modemuxs = i2c3_dis_smi_clcd_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c3_dis_smi_clcd_modemux),
+};
+
+/* Pad multiplexing for i2c3_dis_sd_i2s0 device */
+/* Muxed with SD/MMC & I2S1 */
+static const unsigned i2c3_dis_sd_i2s0_pins[] = { 0, 216 };
+static struct spear_muxreg i2c3_dis_sd_i2s0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_I2S1_MASK | PMX_MCIDATA3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c3_dis_sd_i2s0_modemux[] = {
+ {
+ .muxregs = i2c3_dis_sd_i2s0_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c3_dis_sd_i2s0_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c3_dis_sd_i2s0_pingroup = {
+ .name = "i2c3_dis_sd_i2s0_grp",
+ .pins = i2c3_dis_sd_i2s0_pins,
+ .npins = ARRAY_SIZE(i2c3_dis_sd_i2s0_pins),
+ .modemuxs = i2c3_dis_sd_i2s0_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c3_dis_sd_i2s0_modemux),
+};
+
+static const char *const i2c3_grps[] = { "i2c3_dis_smi_clcd_grp",
+ "i2c3_dis_sd_i2s0_grp" };
+static struct spear_function i2c3_unction = {
+ .name = "i2c3_i2s1",
+ .groups = i2c3_grps,
+ .ngroups = ARRAY_SIZE(i2c3_grps),
+};
+
+/* Pad multiplexing for i2c_4_5_dis_smi device */
+/* Muxed with SMI */
+static const unsigned i2c_4_5_dis_smi_pins[] = { 154, 155, 156, 157 };
+static struct spear_muxreg i2c_4_5_dis_smi_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_SMI_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c_4_5_dis_smi_modemux[] = {
+ {
+ .muxregs = i2c_4_5_dis_smi_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c_4_5_dis_smi_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c_4_5_dis_smi_pingroup = {
+ .name = "i2c_4_5_dis_smi_grp",
+ .pins = i2c_4_5_dis_smi_pins,
+ .npins = ARRAY_SIZE(i2c_4_5_dis_smi_pins),
+ .modemuxs = i2c_4_5_dis_smi_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c_4_5_dis_smi_modemux),
+};
+
+/* Pad multiplexing for i2c4_dis_sd device */
+/* Muxed with SD/MMC */
+static const unsigned i2c4_dis_sd_pins[] = { 217, 218 };
+static struct spear_muxreg i2c4_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_MCIDATA4_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCIDATA5_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c4_dis_sd_modemux[] = {
+ {
+ .muxregs = i2c4_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c4_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c4_dis_sd_pingroup = {
+ .name = "i2c4_dis_sd_grp",
+ .pins = i2c4_dis_sd_pins,
+ .npins = ARRAY_SIZE(i2c4_dis_sd_pins),
+ .modemuxs = i2c4_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c4_dis_sd_modemux),
+};
+
+/* Pad multiplexing for i2c5_dis_sd device */
+/* Muxed with SD/MMC */
+static const unsigned i2c5_dis_sd_pins[] = { 219, 220 };
+static struct spear_muxreg i2c5_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCIDATA6_MASK |
+ PMX_MCIDATA7_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c5_dis_sd_modemux[] = {
+ {
+ .muxregs = i2c5_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c5_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c5_dis_sd_pingroup = {
+ .name = "i2c5_dis_sd_grp",
+ .pins = i2c5_dis_sd_pins,
+ .npins = ARRAY_SIZE(i2c5_dis_sd_pins),
+ .modemuxs = i2c5_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c5_dis_sd_modemux),
+};
+
+static const char *const i2c_4_5_grps[] = { "i2c5_dis_sd_grp",
+ "i2c4_dis_sd_grp", "i2c_4_5_dis_smi_grp" };
+static struct spear_function i2c_4_5_function = {
+ .name = "i2c_4_5",
+ .groups = i2c_4_5_grps,
+ .ngroups = ARRAY_SIZE(i2c_4_5_grps),
+};
+
+/* Pad multiplexing for i2c_6_7_dis_kbd device */
+/* Muxed with KBD */
+static const unsigned i2c_6_7_dis_kbd_pins[] = { 207, 208, 209, 210 };
+static struct spear_muxreg i2c_6_7_dis_kbd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_KBD_ROWCOL25_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c_6_7_dis_kbd_modemux[] = {
+ {
+ .muxregs = i2c_6_7_dis_kbd_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c_6_7_dis_kbd_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c_6_7_dis_kbd_pingroup = {
+ .name = "i2c_6_7_dis_kbd_grp",
+ .pins = i2c_6_7_dis_kbd_pins,
+ .npins = ARRAY_SIZE(i2c_6_7_dis_kbd_pins),
+ .modemuxs = i2c_6_7_dis_kbd_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c_6_7_dis_kbd_modemux),
+};
+
+/* Pad multiplexing for i2c6_dis_sd device */
+/* Muxed with SD/MMC */
+static const unsigned i2c6_dis_sd_pins[] = { 236, 237 };
+static struct spear_muxreg i2c6_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCIIORDRE_MASK |
+ PMX_MCIIOWRWE_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c6_dis_sd_modemux[] = {
+ {
+ .muxregs = i2c6_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c6_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c6_dis_sd_pingroup = {
+ .name = "i2c6_dis_sd_grp",
+ .pins = i2c6_dis_sd_pins,
+ .npins = ARRAY_SIZE(i2c6_dis_sd_pins),
+ .modemuxs = i2c6_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c6_dis_sd_modemux),
+};
+
+/* Pad multiplexing for i2c7_dis_sd device */
+static const unsigned i2c7_dis_sd_pins[] = { 238, 239 };
+static struct spear_muxreg i2c7_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCIRESETCF_MASK |
+ PMX_MCICS0CE_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c7_dis_sd_modemux[] = {
+ {
+ .muxregs = i2c7_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c7_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c7_dis_sd_pingroup = {
+ .name = "i2c7_dis_sd_grp",
+ .pins = i2c7_dis_sd_pins,
+ .npins = ARRAY_SIZE(i2c7_dis_sd_pins),
+ .modemuxs = i2c7_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c7_dis_sd_modemux),
+};
+
+static const char *const i2c_6_7_grps[] = { "i2c6_dis_sd_grp",
+ "i2c7_dis_sd_grp", "i2c_6_7_dis_kbd_grp" };
+static struct spear_function i2c_6_7_function = {
+ .name = "i2c_6_7",
+ .groups = i2c_6_7_grps,
+ .ngroups = ARRAY_SIZE(i2c_6_7_grps),
+};
+
+/* Pad multiplexing for can0_dis_nor device */
+/* Muxed with NOR */
+static const unsigned can0_dis_nor_pins[] = { 56, 57 };
+static struct spear_muxreg can0_dis_nor_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_0,
+ .mask = PMX_NFRSTPWDWN2_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_NFRSTPWDWN3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux can0_dis_nor_modemux[] = {
+ {
+ .muxregs = can0_dis_nor_muxreg,
+ .nmuxregs = ARRAY_SIZE(can0_dis_nor_muxreg),
+ },
+};
+
+static struct spear_pingroup can0_dis_nor_pingroup = {
+ .name = "can0_dis_nor_grp",
+ .pins = can0_dis_nor_pins,
+ .npins = ARRAY_SIZE(can0_dis_nor_pins),
+ .modemuxs = can0_dis_nor_modemux,
+ .nmodemuxs = ARRAY_SIZE(can0_dis_nor_modemux),
+};
+
+/* Pad multiplexing for can0_dis_sd device */
+/* Muxed with SD/MMC */
+static const unsigned can0_dis_sd_pins[] = { 240, 241 };
+static struct spear_muxreg can0_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCICFINTR_MASK | PMX_MCIIORDY_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux can0_dis_sd_modemux[] = {
+ {
+ .muxregs = can0_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(can0_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup can0_dis_sd_pingroup = {
+ .name = "can0_dis_sd_grp",
+ .pins = can0_dis_sd_pins,
+ .npins = ARRAY_SIZE(can0_dis_sd_pins),
+ .modemuxs = can0_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(can0_dis_sd_modemux),
+};
+
+static const char *const can0_grps[] = { "can0_dis_nor_grp", "can0_dis_sd_grp"
+};
+static struct spear_function can0_function = {
+ .name = "can0",
+ .groups = can0_grps,
+ .ngroups = ARRAY_SIZE(can0_grps),
+};
+
+/* Pad multiplexing for can1_dis_sd device */
+/* Muxed with SD/MMC */
+static const unsigned can1_dis_sd_pins[] = { 242, 243 };
+static struct spear_muxreg can1_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCICS1_MASK | PMX_MCIDMAACK_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux can1_dis_sd_modemux[] = {
+ {
+ .muxregs = can1_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(can1_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup can1_dis_sd_pingroup = {
+ .name = "can1_dis_sd_grp",
+ .pins = can1_dis_sd_pins,
+ .npins = ARRAY_SIZE(can1_dis_sd_pins),
+ .modemuxs = can1_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(can1_dis_sd_modemux),
+};
+
+/* Pad multiplexing for can1_dis_kbd device */
+/* Muxed with KBD */
+static const unsigned can1_dis_kbd_pins[] = { 201, 202 };
+static struct spear_muxreg can1_dis_kbd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_KBD_ROWCOL25_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux can1_dis_kbd_modemux[] = {
+ {
+ .muxregs = can1_dis_kbd_muxreg,
+ .nmuxregs = ARRAY_SIZE(can1_dis_kbd_muxreg),
+ },
+};
+
+static struct spear_pingroup can1_dis_kbd_pingroup = {
+ .name = "can1_dis_kbd_grp",
+ .pins = can1_dis_kbd_pins,
+ .npins = ARRAY_SIZE(can1_dis_kbd_pins),
+ .modemuxs = can1_dis_kbd_modemux,
+ .nmodemuxs = ARRAY_SIZE(can1_dis_kbd_modemux),
+};
+
+static const char *const can1_grps[] = { "can1_dis_sd_grp", "can1_dis_kbd_grp"
+};
+static struct spear_function can1_function = {
+ .name = "can1",
+ .groups = can1_grps,
+ .ngroups = ARRAY_SIZE(can1_grps),
+};
+
+/* Pad multiplexing for pci device */
+static const unsigned pci_sata_pins[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 };
+#define PCI_SATA_MUXREG \
+ { \
+ .reg = PAD_FUNCTION_EN_0, \
+ .mask = PMX_MCI_DATA8_15_MASK, \
+ .val = 0, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_1, \
+ .mask = PMX_PCI_REG1_MASK, \
+ .val = 0, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_2, \
+ .mask = PMX_PCI_REG2_MASK, \
+ .val = 0, \
+ }
+
+/* pad multiplexing for pcie0 device */
+static struct spear_muxreg pcie0_muxreg[] = {
+ PCI_SATA_MUXREG,
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = PCIE_CFG_VAL(0),
+ .val = PCIE_CFG_VAL(0),
+ },
+};
+
+static struct spear_modemux pcie0_modemux[] = {
+ {
+ .muxregs = pcie0_muxreg,
+ .nmuxregs = ARRAY_SIZE(pcie0_muxreg),
+ },
+};
+
+static struct spear_pingroup pcie0_pingroup = {
+ .name = "pcie0_grp",
+ .pins = pci_sata_pins,
+ .npins = ARRAY_SIZE(pci_sata_pins),
+ .modemuxs = pcie0_modemux,
+ .nmodemuxs = ARRAY_SIZE(pcie0_modemux),
+};
+
+/* pad multiplexing for pcie1 device */
+static struct spear_muxreg pcie1_muxreg[] = {
+ PCI_SATA_MUXREG,
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = PCIE_CFG_VAL(1),
+ .val = PCIE_CFG_VAL(1),
+ },
+};
+
+static struct spear_modemux pcie1_modemux[] = {
+ {
+ .muxregs = pcie1_muxreg,
+ .nmuxregs = ARRAY_SIZE(pcie1_muxreg),
+ },
+};
+
+static struct spear_pingroup pcie1_pingroup = {
+ .name = "pcie1_grp",
+ .pins = pci_sata_pins,
+ .npins = ARRAY_SIZE(pci_sata_pins),
+ .modemuxs = pcie1_modemux,
+ .nmodemuxs = ARRAY_SIZE(pcie1_modemux),
+};
+
+/* pad multiplexing for pcie2 device */
+static struct spear_muxreg pcie2_muxreg[] = {
+ PCI_SATA_MUXREG,
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = PCIE_CFG_VAL(2),
+ .val = PCIE_CFG_VAL(2),
+ },
+};
+
+static struct spear_modemux pcie2_modemux[] = {
+ {
+ .muxregs = pcie2_muxreg,
+ .nmuxregs = ARRAY_SIZE(pcie2_muxreg),
+ },
+};
+
+static struct spear_pingroup pcie2_pingroup = {
+ .name = "pcie2_grp",
+ .pins = pci_sata_pins,
+ .npins = ARRAY_SIZE(pci_sata_pins),
+ .modemuxs = pcie2_modemux,
+ .nmodemuxs = ARRAY_SIZE(pcie2_modemux),
+};
+
+static const char *const pci_grps[] = { "pcie0_grp", "pcie1_grp", "pcie2_grp" };
+static struct spear_function pci_function = {
+ .name = "pci",
+ .groups = pci_grps,
+ .ngroups = ARRAY_SIZE(pci_grps),
+};
+
+/* pad multiplexing for sata0 device */
+static struct spear_muxreg sata0_muxreg[] = {
+ PCI_SATA_MUXREG,
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = SATA_CFG_VAL(0),
+ .val = SATA_CFG_VAL(0),
+ },
+};
+
+static struct spear_modemux sata0_modemux[] = {
+ {
+ .muxregs = sata0_muxreg,
+ .nmuxregs = ARRAY_SIZE(sata0_muxreg),
+ },
+};
+
+static struct spear_pingroup sata0_pingroup = {
+ .name = "sata0_grp",
+ .pins = pci_sata_pins,
+ .npins = ARRAY_SIZE(pci_sata_pins),
+ .modemuxs = sata0_modemux,
+ .nmodemuxs = ARRAY_SIZE(sata0_modemux),
+};
+
+/* pad multiplexing for sata1 device */
+static struct spear_muxreg sata1_muxreg[] = {
+ PCI_SATA_MUXREG,
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = SATA_CFG_VAL(1),
+ .val = SATA_CFG_VAL(1),
+ },
+};
+
+static struct spear_modemux sata1_modemux[] = {
+ {
+ .muxregs = sata1_muxreg,
+ .nmuxregs = ARRAY_SIZE(sata1_muxreg),
+ },
+};
+
+static struct spear_pingroup sata1_pingroup = {
+ .name = "sata1_grp",
+ .pins = pci_sata_pins,
+ .npins = ARRAY_SIZE(pci_sata_pins),
+ .modemuxs = sata1_modemux,
+ .nmodemuxs = ARRAY_SIZE(sata1_modemux),
+};
+
+/* pad multiplexing for sata2 device */
+static struct spear_muxreg sata2_muxreg[] = {
+ PCI_SATA_MUXREG,
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = SATA_CFG_VAL(2),
+ .val = SATA_CFG_VAL(2),
+ },
+};
+
+static struct spear_modemux sata2_modemux[] = {
+ {
+ .muxregs = sata2_muxreg,
+ .nmuxregs = ARRAY_SIZE(sata2_muxreg),
+ },
+};
+
+static struct spear_pingroup sata2_pingroup = {
+ .name = "sata2_grp",
+ .pins = pci_sata_pins,
+ .npins = ARRAY_SIZE(pci_sata_pins),
+ .modemuxs = sata2_modemux,
+ .nmodemuxs = ARRAY_SIZE(sata2_modemux),
+};
+
+static const char *const sata_grps[] = { "sata0_grp", "sata1_grp", "sata2_grp"
+};
+static struct spear_function sata_function = {
+ .name = "sata",
+ .groups = sata_grps,
+ .ngroups = ARRAY_SIZE(sata_grps),
+};
+
+/* Pad multiplexing for ssp1_dis_kbd device */
+static const unsigned ssp1_dis_kbd_pins[] = { 203, 204, 205, 206 };
+static struct spear_muxreg ssp1_dis_kbd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PMX_KBD_ROWCOL25_MASK | PMX_KBD_COL1_MASK |
+ PMX_KBD_COL0_MASK | PMX_NFIO8_15_MASK | PMX_NFCE1_MASK |
+ PMX_NFCE2_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux ssp1_dis_kbd_modemux[] = {
+ {
+ .muxregs = ssp1_dis_kbd_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_dis_kbd_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp1_dis_kbd_pingroup = {
+ .name = "ssp1_dis_kbd_grp",
+ .pins = ssp1_dis_kbd_pins,
+ .npins = ARRAY_SIZE(ssp1_dis_kbd_pins),
+ .modemuxs = ssp1_dis_kbd_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_dis_kbd_modemux),
+};
+
+/* Pad multiplexing for ssp1_dis_sd device */
+static const unsigned ssp1_dis_sd_pins[] = { 224, 226, 227, 228 };
+static struct spear_muxreg ssp1_dis_sd_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCIADDR0ALE_MASK | PMX_MCIADDR2_MASK |
+ PMX_MCICECF_MASK | PMX_MCICEXD_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux ssp1_dis_sd_modemux[] = {
+ {
+ .muxregs = ssp1_dis_sd_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_dis_sd_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp1_dis_sd_pingroup = {
+ .name = "ssp1_dis_sd_grp",
+ .pins = ssp1_dis_sd_pins,
+ .npins = ARRAY_SIZE(ssp1_dis_sd_pins),
+ .modemuxs = ssp1_dis_sd_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_dis_sd_modemux),
+};
+
+static const char *const ssp1_grps[] = { "ssp1_dis_kbd_grp",
+ "ssp1_dis_sd_grp" };
+static struct spear_function ssp1_function = {
+ .name = "ssp1",
+ .groups = ssp1_grps,
+ .ngroups = ARRAY_SIZE(ssp1_grps),
+};
+
+/* Pad multiplexing for gpt64 device */
+static const unsigned gpt64_pins[] = { 230, 231, 232, 245 };
+static struct spear_muxreg gpt64_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PMX_MCICDCF1_MASK | PMX_MCICDCF2_MASK | PMX_MCICDXD_MASK
+ | PMX_MCILEDS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux gpt64_modemux[] = {
+ {
+ .muxregs = gpt64_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpt64_muxreg),
+ },
+};
+
+static struct spear_pingroup gpt64_pingroup = {
+ .name = "gpt64_grp",
+ .pins = gpt64_pins,
+ .npins = ARRAY_SIZE(gpt64_pins),
+ .modemuxs = gpt64_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpt64_modemux),
+};
+
+static const char *const gpt64_grps[] = { "gpt64_grp" };
+static struct spear_function gpt64_function = {
+ .name = "gpt64",
+ .groups = gpt64_grps,
+ .ngroups = ARRAY_SIZE(gpt64_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear1310_pingroups[] = {
+ &i2c0_pingroup,
+ &ssp0_pingroup,
+ &i2s0_pingroup,
+ &i2s1_pingroup,
+ &clcd_pingroup,
+ &clcd_high_res_pingroup,
+ &arm_gpio_pingroup,
+ &smi_2_chips_pingroup,
+ &smi_4_chips_pingroup,
+ &gmii_pingroup,
+ &rgmii_pingroup,
+ &smii_0_1_2_pingroup,
+ &ras_mii_txclk_pingroup,
+ &nand_8bit_pingroup,
+ &nand_16bit_pingroup,
+ &nand_4_chips_pingroup,
+ &keyboard_6x6_pingroup,
+ &keyboard_rowcol6_8_pingroup,
+ &uart0_pingroup,
+ &uart0_modem_pingroup,
+ &gpt0_tmr0_pingroup,
+ &gpt0_tmr1_pingroup,
+ &gpt1_tmr0_pingroup,
+ &gpt1_tmr1_pingroup,
+ &sdhci_pingroup,
+ &cf_pingroup,
+ &xd_pingroup,
+ &touch_xy_pingroup,
+ &ssp0_cs0_pingroup,
+ &ssp0_cs1_2_pingroup,
+ &uart_1_dis_i2c_pingroup,
+ &uart_1_dis_sd_pingroup,
+ &uart_2_3_pingroup,
+ &uart_4_pingroup,
+ &uart_5_pingroup,
+ &rs485_0_1_tdm_0_1_pingroup,
+ &i2c_1_2_pingroup,
+ &i2c3_dis_smi_clcd_pingroup,
+ &i2c3_dis_sd_i2s0_pingroup,
+ &i2c_4_5_dis_smi_pingroup,
+ &i2c4_dis_sd_pingroup,
+ &i2c5_dis_sd_pingroup,
+ &i2c_6_7_dis_kbd_pingroup,
+ &i2c6_dis_sd_pingroup,
+ &i2c7_dis_sd_pingroup,
+ &can0_dis_nor_pingroup,
+ &can0_dis_sd_pingroup,
+ &can1_dis_sd_pingroup,
+ &can1_dis_kbd_pingroup,
+ &pcie0_pingroup,
+ &pcie1_pingroup,
+ &pcie2_pingroup,
+ &sata0_pingroup,
+ &sata1_pingroup,
+ &sata2_pingroup,
+ &ssp1_dis_kbd_pingroup,
+ &ssp1_dis_sd_pingroup,
+ &gpt64_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear1310_functions[] = {
+ &i2c0_function,
+ &ssp0_function,
+ &i2s0_function,
+ &i2s1_function,
+ &clcd_function,
+ &arm_gpio_function,
+ &smi_function,
+ &gmii_function,
+ &rgmii_function,
+ &smii_0_1_2_function,
+ &ras_mii_txclk_function,
+ &nand_function,
+ &keyboard_function,
+ &uart0_function,
+ &gpt0_function,
+ &gpt1_function,
+ &sdhci_function,
+ &cf_function,
+ &xd_function,
+ &touch_xy_function,
+ &uart1_function,
+ &uart2_3_function,
+ &uart4_function,
+ &uart5_function,
+ &rs485_0_1_tdm_0_1_function,
+ &i2c_1_2_function,
+ &i2c3_unction,
+ &i2c_4_5_function,
+ &i2c_6_7_function,
+ &can0_function,
+ &can1_function,
+ &pci_function,
+ &sata_function,
+ &ssp1_function,
+ &gpt64_function,
+};
+
+static struct spear_pinctrl_machdata spear1310_machdata = {
+ .pins = spear1310_pins,
+ .npins = ARRAY_SIZE(spear1310_pins),
+ .groups = spear1310_pingroups,
+ .ngroups = ARRAY_SIZE(spear1310_pingroups),
+ .functions = spear1310_functions,
+ .nfunctions = ARRAY_SIZE(spear1310_functions),
+ .modes_supported = false,
+};
+
+static struct of_device_id spear1310_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "st,spear1310-pinmux",
+ },
+ {},
+};
+
+static int __devinit spear1310_pinctrl_probe(struct platform_device *pdev)
+{
+ return spear_pinctrl_probe(pdev, &spear1310_machdata);
+}
+
+static int __devexit spear1310_pinctrl_remove(struct platform_device *pdev)
+{
+ return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear1310_pinctrl_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spear1310_pinctrl_of_match,
+ },
+ .probe = spear1310_pinctrl_probe,
+ .remove = __devexit_p(spear1310_pinctrl_remove),
+};
+
+static int __init spear1310_pinctrl_init(void)
+{
+ return platform_driver_register(&spear1310_pinctrl_driver);
+}
+arch_initcall(spear1310_pinctrl_init);
+
+static void __exit spear1310_pinctrl_exit(void)
+{
+ platform_driver_unregister(&spear1310_pinctrl_driver);
+}
+module_exit(spear1310_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
new file mode 100644
index 000000000000..a8ab2a6f51bf
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -0,0 +1,1989 @@
+/*
+ * Driver for the ST Microelectronics SPEAr1340 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear.h"
+
+#define DRIVER_NAME "spear1340-pinmux"
+
+/* pins */
+static const struct pinctrl_pin_desc spear1340_pins[] = {
+ SPEAR_PIN_0_TO_101,
+ SPEAR_PIN_102_TO_245,
+ PINCTRL_PIN(246, "PLGPIO246"),
+ PINCTRL_PIN(247, "PLGPIO247"),
+ PINCTRL_PIN(248, "PLGPIO248"),
+ PINCTRL_PIN(249, "PLGPIO249"),
+ PINCTRL_PIN(250, "PLGPIO250"),
+ PINCTRL_PIN(251, "PLGPIO251"),
+};
+
+/* In SPEAr1340 there are two levels of pad muxing */
+/* - pads as gpio OR peripherals */
+#define PAD_FUNCTION_EN_1 0x668
+#define PAD_FUNCTION_EN_2 0x66C
+#define PAD_FUNCTION_EN_3 0x670
+#define PAD_FUNCTION_EN_4 0x674
+#define PAD_FUNCTION_EN_5 0x690
+#define PAD_FUNCTION_EN_6 0x694
+#define PAD_FUNCTION_EN_7 0x698
+#define PAD_FUNCTION_EN_8 0x69C
+
+/* - If peripherals, then primary OR alternate peripheral */
+#define PAD_SHARED_IP_EN_1 0x6A0
+#define PAD_SHARED_IP_EN_2 0x6A4
+
+/*
+ * Macro's for first level of pmx - pads as gpio OR peripherals. There are 8
+ * registers with 32 bits each for handling gpio pads, register 8 has only 26
+ * relevant bits.
+ */
+/* macro's for making pads as gpio's */
+#define PADS_AS_GPIO_REG0_MASK 0xFFFFFFFE
+#define PADS_AS_GPIO_REGS_MASK 0xFFFFFFFF
+#define PADS_AS_GPIO_REG7_MASK 0x07FFFFFF
+
+/* macro's for making pads as peripherals */
+#define FSMC_16_BIT_AND_KBD_ROW_COL_REG0_MASK 0x00000FFE
+#define UART0_ENH_AND_GPT_REG0_MASK 0x0003F000
+#define PWM1_AND_KBD_COL5_REG0_MASK 0x00040000
+#define I2C1_REG0_MASK 0x01080000
+#define SPDIF_IN_REG0_MASK 0x00100000
+#define PWM2_AND_GPT0_TMR0_CPT_REG0_MASK 0x00400000
+#define PWM3_AND_GPT0_TMR1_CLK_REG0_MASK 0x00800000
+#define PWM0_AND_SSP0_CS1_REG0_MASK 0x02000000
+#define VIP_AND_CAM3_REG0_MASK 0xFC200000
+#define VIP_AND_CAM3_REG1_MASK 0x0000000F
+#define VIP_REG1_MASK 0x00001EF0
+#define VIP_AND_CAM2_REG1_MASK 0x007FE100
+#define VIP_AND_CAM1_REG1_MASK 0xFF800000
+#define VIP_AND_CAM1_REG2_MASK 0x00000003
+#define VIP_AND_CAM0_REG2_MASK 0x00001FFC
+#define SMI_REG2_MASK 0x0021E000
+#define SSP0_REG2_MASK 0x001E0000
+#define TS_AND_SSP0_CS2_REG2_MASK 0x00400000
+#define UART0_REG2_MASK 0x01800000
+#define UART1_REG2_MASK 0x06000000
+#define I2S_IN_REG2_MASK 0xF8000000
+#define DEVS_GRP_AND_MIPHY_DBG_REG3_MASK 0x000001FE
+#define I2S_OUT_REG3_MASK 0x000001EF
+#define I2S_IN_REG3_MASK 0x00000010
+#define GMAC_REG3_MASK 0xFFFFFE00
+#define GMAC_REG4_MASK 0x0000001F
+#define DEVS_GRP_AND_MIPHY_DBG_REG4_MASK 0x7FFFFF20
+#define SSP0_CS3_REG4_MASK 0x00000020
+#define I2C0_REG4_MASK 0x000000C0
+#define CEC0_REG4_MASK 0x00000100
+#define CEC1_REG4_MASK 0x00000200
+#define SPDIF_OUT_REG4_MASK 0x00000400
+#define CLCD_REG4_MASK 0x7FFFF800
+#define CLCD_AND_ARM_TRACE_REG4_MASK 0x80000000
+#define CLCD_AND_ARM_TRACE_REG5_MASK 0xFFFFFFFF
+#define CLCD_AND_ARM_TRACE_REG6_MASK 0x00000001
+#define FSMC_PNOR_AND_MCIF_REG6_MASK 0x073FFFFE
+#define MCIF_REG6_MASK 0xF8C00000
+#define MCIF_REG7_MASK 0x000043FF
+#define FSMC_8BIT_REG7_MASK 0x07FFBC00
+
+/* other registers */
+#define PERIP_CFG 0x42C
+ /* PERIP_CFG register masks */
+ #define SSP_CS_CTL_HW 0
+ #define SSP_CS_CTL_SW 1
+ #define SSP_CS_CTL_MASK 1
+ #define SSP_CS_CTL_SHIFT 21
+ #define SSP_CS_VAL_MASK 1
+ #define SSP_CS_VAL_SHIFT 20
+ #define SSP_CS_SEL_CS0 0
+ #define SSP_CS_SEL_CS1 1
+ #define SSP_CS_SEL_CS2 2
+ #define SSP_CS_SEL_MASK 3
+ #define SSP_CS_SEL_SHIFT 18
+
+ #define I2S_CHNL_2_0 (0)
+ #define I2S_CHNL_3_1 (1)
+ #define I2S_CHNL_5_1 (2)
+ #define I2S_CHNL_7_1 (3)
+ #define I2S_CHNL_PLAY_SHIFT (4)
+ #define I2S_CHNL_PLAY_MASK (3 << 4)
+ #define I2S_CHNL_REC_SHIFT (6)
+ #define I2S_CHNL_REC_MASK (3 << 6)
+
+ #define SPDIF_OUT_ENB_MASK (1 << 2)
+ #define SPDIF_OUT_ENB_SHIFT 2
+
+ #define MCIF_SEL_SD 1
+ #define MCIF_SEL_CF 2
+ #define MCIF_SEL_XD 3
+ #define MCIF_SEL_MASK 3
+ #define MCIF_SEL_SHIFT 0
+
+#define GMAC_CLK_CFG 0x248
+ #define GMAC_PHY_IF_GMII_VAL (0 << 3)
+ #define GMAC_PHY_IF_RGMII_VAL (1 << 3)
+ #define GMAC_PHY_IF_SGMII_VAL (2 << 3)
+ #define GMAC_PHY_IF_RMII_VAL (4 << 3)
+ #define GMAC_PHY_IF_SEL_MASK (7 << 3)
+ #define GMAC_PHY_INPUT_ENB_VAL 0
+ #define GMAC_PHY_SYNT_ENB_VAL 1
+ #define GMAC_PHY_CLK_MASK 1
+ #define GMAC_PHY_CLK_SHIFT 2
+ #define GMAC_PHY_125M_PAD_VAL 0
+ #define GMAC_PHY_PLL2_VAL 1
+ #define GMAC_PHY_OSC3_VAL 2
+ #define GMAC_PHY_INPUT_CLK_MASK 3
+ #define GMAC_PHY_INPUT_CLK_SHIFT 0
+
+#define PCIE_SATA_CFG 0x424
+ /* PCIE CFG MASks */
+ #define PCIE_CFG_DEVICE_PRESENT (1 << 11)
+ #define PCIE_CFG_POWERUP_RESET (1 << 10)
+ #define PCIE_CFG_CORE_CLK_EN (1 << 9)
+ #define PCIE_CFG_AUX_CLK_EN (1 << 8)
+ #define SATA_CFG_TX_CLK_EN (1 << 4)
+ #define SATA_CFG_RX_CLK_EN (1 << 3)
+ #define SATA_CFG_POWERUP_RESET (1 << 2)
+ #define SATA_CFG_PM_CLK_EN (1 << 1)
+ #define PCIE_SATA_SEL_PCIE (0)
+ #define PCIE_SATA_SEL_SATA (1)
+ #define SATA_PCIE_CFG_MASK 0xF1F
+ #define PCIE_CFG_VAL (PCIE_SATA_SEL_PCIE | PCIE_CFG_AUX_CLK_EN | \
+ PCIE_CFG_CORE_CLK_EN | PCIE_CFG_POWERUP_RESET |\
+ PCIE_CFG_DEVICE_PRESENT)
+ #define SATA_CFG_VAL (PCIE_SATA_SEL_SATA | SATA_CFG_PM_CLK_EN | \
+ SATA_CFG_POWERUP_RESET | SATA_CFG_RX_CLK_EN | \
+ SATA_CFG_TX_CLK_EN)
+
+/* Macro's for second level of pmx - pads as primary OR alternate peripheral */
+/* Write 0 to enable FSMC_16_BIT */
+#define KBD_ROW_COL_MASK (1 << 0)
+
+/* Write 0 to enable UART0_ENH */
+#define GPT_MASK (1 << 1) /* Only clk & cpt */
+
+/* Write 0 to enable PWM1 */
+#define KBD_COL5_MASK (1 << 2)
+
+/* Write 0 to enable PWM2 */
+#define GPT0_TMR0_CPT_MASK (1 << 3) /* Only clk & cpt */
+
+/* Write 0 to enable PWM3 */
+#define GPT0_TMR1_CLK_MASK (1 << 4) /* Only clk & cpt */
+
+/* Write 0 to enable PWM0 */
+#define SSP0_CS1_MASK (1 << 5)
+
+/* Write 0 to enable VIP */
+#define CAM3_MASK (1 << 6)
+
+/* Write 0 to enable VIP */
+#define CAM2_MASK (1 << 7)
+
+/* Write 0 to enable VIP */
+#define CAM1_MASK (1 << 8)
+
+/* Write 0 to enable VIP */
+#define CAM0_MASK (1 << 9)
+
+/* Write 0 to enable TS */
+#define SSP0_CS2_MASK (1 << 10)
+
+/* Write 0 to enable FSMC PNOR */
+#define MCIF_MASK (1 << 11)
+
+/* Write 0 to enable CLCD */
+#define ARM_TRACE_MASK (1 << 12)
+
+/* Write 0 to enable I2S, SSP0_CS2, CEC0, 1, SPDIF out, CLCD */
+#define MIPHY_DBG_MASK (1 << 13)
+
+/*
+ * Pad multiplexing for making all pads as gpio's. This is done to override the
+ * values passed from bootloader and start from scratch.
+ */
+static const unsigned pads_as_gpio_pins[] = { 251 };
+static struct spear_muxreg pads_as_gpio_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PADS_AS_GPIO_REG0_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = PADS_AS_GPIO_REGS_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = PADS_AS_GPIO_REGS_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_4,
+ .mask = PADS_AS_GPIO_REGS_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = PADS_AS_GPIO_REGS_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_6,
+ .mask = PADS_AS_GPIO_REGS_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_7,
+ .mask = PADS_AS_GPIO_REGS_MASK,
+ .val = 0x0,
+ }, {
+ .reg = PAD_FUNCTION_EN_8,
+ .mask = PADS_AS_GPIO_REG7_MASK,
+ .val = 0x0,
+ },
+};
+
+static struct spear_modemux pads_as_gpio_modemux[] = {
+ {
+ .muxregs = pads_as_gpio_muxreg,
+ .nmuxregs = ARRAY_SIZE(pads_as_gpio_muxreg),
+ },
+};
+
+static struct spear_pingroup pads_as_gpio_pingroup = {
+ .name = "pads_as_gpio_grp",
+ .pins = pads_as_gpio_pins,
+ .npins = ARRAY_SIZE(pads_as_gpio_pins),
+ .modemuxs = pads_as_gpio_modemux,
+ .nmodemuxs = ARRAY_SIZE(pads_as_gpio_modemux),
+};
+
+static const char *const pads_as_gpio_grps[] = { "pads_as_gpio_grp" };
+static struct spear_function pads_as_gpio_function = {
+ .name = "pads_as_gpio",
+ .groups = pads_as_gpio_grps,
+ .ngroups = ARRAY_SIZE(pads_as_gpio_grps),
+};
+
+/* Pad multiplexing for fsmc_8bit device */
+static const unsigned fsmc_8bit_pins[] = { 233, 234, 235, 236, 238, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 248, 249 };
+static struct spear_muxreg fsmc_8bit_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_8,
+ .mask = FSMC_8BIT_REG7_MASK,
+ .val = FSMC_8BIT_REG7_MASK,
+ }
+};
+
+static struct spear_modemux fsmc_8bit_modemux[] = {
+ {
+ .muxregs = fsmc_8bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_8bit_pingroup = {
+ .name = "fsmc_8bit_grp",
+ .pins = fsmc_8bit_pins,
+ .npins = ARRAY_SIZE(fsmc_8bit_pins),
+ .modemuxs = fsmc_8bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_8bit_modemux),
+};
+
+/* Pad multiplexing for fsmc_16bit device */
+static const unsigned fsmc_16bit_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+static struct spear_muxreg fsmc_16bit_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = KBD_ROW_COL_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = FSMC_16_BIT_AND_KBD_ROW_COL_REG0_MASK,
+ .val = FSMC_16_BIT_AND_KBD_ROW_COL_REG0_MASK,
+ },
+};
+
+static struct spear_modemux fsmc_16bit_modemux[] = {
+ {
+ .muxregs = fsmc_16bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_16bit_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_16bit_pingroup = {
+ .name = "fsmc_16bit_grp",
+ .pins = fsmc_16bit_pins,
+ .npins = ARRAY_SIZE(fsmc_16bit_pins),
+ .modemuxs = fsmc_16bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_16bit_modemux),
+};
+
+/* pad multiplexing for fsmc_pnor device */
+static const unsigned fsmc_pnor_pins[] = { 192, 193, 194, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
+ 215, 216, 217 };
+static struct spear_muxreg fsmc_pnor_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = MCIF_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_7,
+ .mask = FSMC_PNOR_AND_MCIF_REG6_MASK,
+ .val = FSMC_PNOR_AND_MCIF_REG6_MASK,
+ },
+};
+
+static struct spear_modemux fsmc_pnor_modemux[] = {
+ {
+ .muxregs = fsmc_pnor_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_pnor_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_pnor_pingroup = {
+ .name = "fsmc_pnor_grp",
+ .pins = fsmc_pnor_pins,
+ .npins = ARRAY_SIZE(fsmc_pnor_pins),
+ .modemuxs = fsmc_pnor_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_pnor_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_8bit_grp", "fsmc_16bit_grp",
+ "fsmc_pnor_grp" };
+static struct spear_function fsmc_function = {
+ .name = "fsmc",
+ .groups = fsmc_grps,
+ .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* pad multiplexing for keyboard rows-cols device */
+static const unsigned keyboard_row_col_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10 };
+static struct spear_muxreg keyboard_row_col_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = KBD_ROW_COL_MASK,
+ .val = KBD_ROW_COL_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = FSMC_16_BIT_AND_KBD_ROW_COL_REG0_MASK,
+ .val = FSMC_16_BIT_AND_KBD_ROW_COL_REG0_MASK,
+ },
+};
+
+static struct spear_modemux keyboard_row_col_modemux[] = {
+ {
+ .muxregs = keyboard_row_col_muxreg,
+ .nmuxregs = ARRAY_SIZE(keyboard_row_col_muxreg),
+ },
+};
+
+static struct spear_pingroup keyboard_row_col_pingroup = {
+ .name = "keyboard_row_col_grp",
+ .pins = keyboard_row_col_pins,
+ .npins = ARRAY_SIZE(keyboard_row_col_pins),
+ .modemuxs = keyboard_row_col_modemux,
+ .nmodemuxs = ARRAY_SIZE(keyboard_row_col_modemux),
+};
+
+/* pad multiplexing for keyboard col5 device */
+static const unsigned keyboard_col5_pins[] = { 17 };
+static struct spear_muxreg keyboard_col5_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = KBD_COL5_MASK,
+ .val = KBD_COL5_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PWM1_AND_KBD_COL5_REG0_MASK,
+ .val = PWM1_AND_KBD_COL5_REG0_MASK,
+ },
+};
+
+static struct spear_modemux keyboard_col5_modemux[] = {
+ {
+ .muxregs = keyboard_col5_muxreg,
+ .nmuxregs = ARRAY_SIZE(keyboard_col5_muxreg),
+ },
+};
+
+static struct spear_pingroup keyboard_col5_pingroup = {
+ .name = "keyboard_col5_grp",
+ .pins = keyboard_col5_pins,
+ .npins = ARRAY_SIZE(keyboard_col5_pins),
+ .modemuxs = keyboard_col5_modemux,
+ .nmodemuxs = ARRAY_SIZE(keyboard_col5_modemux),
+};
+
+static const char *const keyboard_grps[] = { "keyboard_row_col_grp",
+ "keyboard_col5_grp" };
+static struct spear_function keyboard_function = {
+ .name = "keyboard",
+ .groups = keyboard_grps,
+ .ngroups = ARRAY_SIZE(keyboard_grps),
+};
+
+/* pad multiplexing for spdif_in device */
+static const unsigned spdif_in_pins[] = { 19 };
+static struct spear_muxreg spdif_in_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = SPDIF_IN_REG0_MASK,
+ .val = SPDIF_IN_REG0_MASK,
+ },
+};
+
+static struct spear_modemux spdif_in_modemux[] = {
+ {
+ .muxregs = spdif_in_muxreg,
+ .nmuxregs = ARRAY_SIZE(spdif_in_muxreg),
+ },
+};
+
+static struct spear_pingroup spdif_in_pingroup = {
+ .name = "spdif_in_grp",
+ .pins = spdif_in_pins,
+ .npins = ARRAY_SIZE(spdif_in_pins),
+ .modemuxs = spdif_in_modemux,
+ .nmodemuxs = ARRAY_SIZE(spdif_in_modemux),
+};
+
+static const char *const spdif_in_grps[] = { "spdif_in_grp" };
+static struct spear_function spdif_in_function = {
+ .name = "spdif_in",
+ .groups = spdif_in_grps,
+ .ngroups = ARRAY_SIZE(spdif_in_grps),
+};
+
+/* pad multiplexing for spdif_out device */
+static const unsigned spdif_out_pins[] = { 137 };
+static struct spear_muxreg spdif_out_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = SPDIF_OUT_REG4_MASK,
+ .val = SPDIF_OUT_REG4_MASK,
+ }, {
+ .reg = PERIP_CFG,
+ .mask = SPDIF_OUT_ENB_MASK,
+ .val = SPDIF_OUT_ENB_MASK,
+ }
+};
+
+static struct spear_modemux spdif_out_modemux[] = {
+ {
+ .muxregs = spdif_out_muxreg,
+ .nmuxregs = ARRAY_SIZE(spdif_out_muxreg),
+ },
+};
+
+static struct spear_pingroup spdif_out_pingroup = {
+ .name = "spdif_out_grp",
+ .pins = spdif_out_pins,
+ .npins = ARRAY_SIZE(spdif_out_pins),
+ .modemuxs = spdif_out_modemux,
+ .nmodemuxs = ARRAY_SIZE(spdif_out_modemux),
+};
+
+static const char *const spdif_out_grps[] = { "spdif_out_grp" };
+static struct spear_function spdif_out_function = {
+ .name = "spdif_out",
+ .groups = spdif_out_grps,
+ .ngroups = ARRAY_SIZE(spdif_out_grps),
+};
+
+/* pad multiplexing for gpt_0_1 device */
+static const unsigned gpt_0_1_pins[] = { 11, 12, 13, 14, 15, 16, 21, 22 };
+static struct spear_muxreg gpt_0_1_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = GPT_MASK | GPT0_TMR0_CPT_MASK | GPT0_TMR1_CLK_MASK,
+ .val = GPT_MASK | GPT0_TMR0_CPT_MASK | GPT0_TMR1_CLK_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = UART0_ENH_AND_GPT_REG0_MASK |
+ PWM2_AND_GPT0_TMR0_CPT_REG0_MASK |
+ PWM3_AND_GPT0_TMR1_CLK_REG0_MASK,
+ .val = UART0_ENH_AND_GPT_REG0_MASK |
+ PWM2_AND_GPT0_TMR0_CPT_REG0_MASK |
+ PWM3_AND_GPT0_TMR1_CLK_REG0_MASK,
+ },
+};
+
+static struct spear_modemux gpt_0_1_modemux[] = {
+ {
+ .muxregs = gpt_0_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpt_0_1_muxreg),
+ },
+};
+
+static struct spear_pingroup gpt_0_1_pingroup = {
+ .name = "gpt_0_1_grp",
+ .pins = gpt_0_1_pins,
+ .npins = ARRAY_SIZE(gpt_0_1_pins),
+ .modemuxs = gpt_0_1_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpt_0_1_modemux),
+};
+
+static const char *const gpt_0_1_grps[] = { "gpt_0_1_grp" };
+static struct spear_function gpt_0_1_function = {
+ .name = "gpt_0_1",
+ .groups = gpt_0_1_grps,
+ .ngroups = ARRAY_SIZE(gpt_0_1_grps),
+};
+
+/* pad multiplexing for pwm0 device */
+static const unsigned pwm0_pins[] = { 24 };
+static struct spear_muxreg pwm0_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = SSP0_CS1_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PWM0_AND_SSP0_CS1_REG0_MASK,
+ .val = PWM0_AND_SSP0_CS1_REG0_MASK,
+ },
+};
+
+static struct spear_modemux pwm0_modemux[] = {
+ {
+ .muxregs = pwm0_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm0_pingroup = {
+ .name = "pwm0_grp",
+ .pins = pwm0_pins,
+ .npins = ARRAY_SIZE(pwm0_pins),
+ .modemuxs = pwm0_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_modemux),
+};
+
+/* pad multiplexing for pwm1 device */
+static const unsigned pwm1_pins[] = { 17 };
+static struct spear_muxreg pwm1_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = KBD_COL5_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PWM1_AND_KBD_COL5_REG0_MASK,
+ .val = PWM1_AND_KBD_COL5_REG0_MASK,
+ },
+};
+
+static struct spear_modemux pwm1_modemux[] = {
+ {
+ .muxregs = pwm1_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm1_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm1_pingroup = {
+ .name = "pwm1_grp",
+ .pins = pwm1_pins,
+ .npins = ARRAY_SIZE(pwm1_pins),
+ .modemuxs = pwm1_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm1_modemux),
+};
+
+/* pad multiplexing for pwm2 device */
+static const unsigned pwm2_pins[] = { 21 };
+static struct spear_muxreg pwm2_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = GPT0_TMR0_CPT_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PWM2_AND_GPT0_TMR0_CPT_REG0_MASK,
+ .val = PWM2_AND_GPT0_TMR0_CPT_REG0_MASK,
+ },
+};
+
+static struct spear_modemux pwm2_modemux[] = {
+ {
+ .muxregs = pwm2_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm2_pingroup = {
+ .name = "pwm2_grp",
+ .pins = pwm2_pins,
+ .npins = ARRAY_SIZE(pwm2_pins),
+ .modemuxs = pwm2_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_modemux),
+};
+
+/* pad multiplexing for pwm3 device */
+static const unsigned pwm3_pins[] = { 22 };
+static struct spear_muxreg pwm3_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = GPT0_TMR1_CLK_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PWM3_AND_GPT0_TMR1_CLK_REG0_MASK,
+ .val = PWM3_AND_GPT0_TMR1_CLK_REG0_MASK,
+ },
+};
+
+static struct spear_modemux pwm3_modemux[] = {
+ {
+ .muxregs = pwm3_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm3_pingroup = {
+ .name = "pwm3_grp",
+ .pins = pwm3_pins,
+ .npins = ARRAY_SIZE(pwm3_pins),
+ .modemuxs = pwm3_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_modemux),
+};
+
+static const char *const pwm_grps[] = { "pwm0_grp", "pwm1_grp", "pwm2_grp",
+ "pwm3_grp" };
+static struct spear_function pwm_function = {
+ .name = "pwm",
+ .groups = pwm_grps,
+ .ngroups = ARRAY_SIZE(pwm_grps),
+};
+
+/* pad multiplexing for vip_mux device */
+static const unsigned vip_mux_pins[] = { 35, 36, 37, 38, 40, 41, 42, 43 };
+static struct spear_muxreg vip_mux_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_REG1_MASK,
+ .val = VIP_REG1_MASK,
+ },
+};
+
+static struct spear_modemux vip_mux_modemux[] = {
+ {
+ .muxregs = vip_mux_muxreg,
+ .nmuxregs = ARRAY_SIZE(vip_mux_muxreg),
+ },
+};
+
+static struct spear_pingroup vip_mux_pingroup = {
+ .name = "vip_mux_grp",
+ .pins = vip_mux_pins,
+ .npins = ARRAY_SIZE(vip_mux_pins),
+ .modemuxs = vip_mux_modemux,
+ .nmodemuxs = ARRAY_SIZE(vip_mux_modemux),
+};
+
+/* pad multiplexing for vip_mux_cam0 (disables cam0) device */
+static const unsigned vip_mux_cam0_pins[] = { 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75 };
+static struct spear_muxreg vip_mux_cam0_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM0_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = VIP_AND_CAM0_REG2_MASK,
+ .val = VIP_AND_CAM0_REG2_MASK,
+ },
+};
+
+static struct spear_modemux vip_mux_cam0_modemux[] = {
+ {
+ .muxregs = vip_mux_cam0_muxreg,
+ .nmuxregs = ARRAY_SIZE(vip_mux_cam0_muxreg),
+ },
+};
+
+static struct spear_pingroup vip_mux_cam0_pingroup = {
+ .name = "vip_mux_cam0_grp",
+ .pins = vip_mux_cam0_pins,
+ .npins = ARRAY_SIZE(vip_mux_cam0_pins),
+ .modemuxs = vip_mux_cam0_modemux,
+ .nmodemuxs = ARRAY_SIZE(vip_mux_cam0_modemux),
+};
+
+/* pad multiplexing for vip_mux_cam1 (disables cam1) device */
+static const unsigned vip_mux_cam1_pins[] = { 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 63, 64 };
+static struct spear_muxreg vip_mux_cam1_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM1_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_AND_CAM1_REG1_MASK,
+ .val = VIP_AND_CAM1_REG1_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = VIP_AND_CAM1_REG2_MASK,
+ .val = VIP_AND_CAM1_REG2_MASK,
+ },
+};
+
+static struct spear_modemux vip_mux_cam1_modemux[] = {
+ {
+ .muxregs = vip_mux_cam1_muxreg,
+ .nmuxregs = ARRAY_SIZE(vip_mux_cam1_muxreg),
+ },
+};
+
+static struct spear_pingroup vip_mux_cam1_pingroup = {
+ .name = "vip_mux_cam1_grp",
+ .pins = vip_mux_cam1_pins,
+ .npins = ARRAY_SIZE(vip_mux_cam1_pins),
+ .modemuxs = vip_mux_cam1_modemux,
+ .nmodemuxs = ARRAY_SIZE(vip_mux_cam1_modemux),
+};
+
+/* pad multiplexing for vip_mux_cam2 (disables cam2) device */
+static const unsigned vip_mux_cam2_pins[] = { 39, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53 };
+static struct spear_muxreg vip_mux_cam2_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM2_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_AND_CAM2_REG1_MASK,
+ .val = VIP_AND_CAM2_REG1_MASK,
+ },
+};
+
+static struct spear_modemux vip_mux_cam2_modemux[] = {
+ {
+ .muxregs = vip_mux_cam2_muxreg,
+ .nmuxregs = ARRAY_SIZE(vip_mux_cam2_muxreg),
+ },
+};
+
+static struct spear_pingroup vip_mux_cam2_pingroup = {
+ .name = "vip_mux_cam2_grp",
+ .pins = vip_mux_cam2_pins,
+ .npins = ARRAY_SIZE(vip_mux_cam2_pins),
+ .modemuxs = vip_mux_cam2_modemux,
+ .nmodemuxs = ARRAY_SIZE(vip_mux_cam2_modemux),
+};
+
+/* pad multiplexing for vip_mux_cam3 (disables cam3) device */
+static const unsigned vip_mux_cam3_pins[] = { 20, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34 };
+static struct spear_muxreg vip_mux_cam3_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM3_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = VIP_AND_CAM3_REG0_MASK,
+ .val = VIP_AND_CAM3_REG0_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_AND_CAM3_REG1_MASK,
+ .val = VIP_AND_CAM3_REG1_MASK,
+ },
+};
+
+static struct spear_modemux vip_mux_cam3_modemux[] = {
+ {
+ .muxregs = vip_mux_cam3_muxreg,
+ .nmuxregs = ARRAY_SIZE(vip_mux_cam3_muxreg),
+ },
+};
+
+static struct spear_pingroup vip_mux_cam3_pingroup = {
+ .name = "vip_mux_cam3_grp",
+ .pins = vip_mux_cam3_pins,
+ .npins = ARRAY_SIZE(vip_mux_cam3_pins),
+ .modemuxs = vip_mux_cam3_modemux,
+ .nmodemuxs = ARRAY_SIZE(vip_mux_cam3_modemux),
+};
+
+static const char *const vip_grps[] = { "vip_mux_grp", "vip_mux_cam0_grp" ,
+ "vip_mux_cam1_grp" , "vip_mux_cam2_grp", "vip_mux_cam3_grp" };
+static struct spear_function vip_function = {
+ .name = "vip",
+ .groups = vip_grps,
+ .ngroups = ARRAY_SIZE(vip_grps),
+};
+
+/* pad multiplexing for cam0 device */
+static const unsigned cam0_pins[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75
+};
+static struct spear_muxreg cam0_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM0_MASK,
+ .val = CAM0_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = VIP_AND_CAM0_REG2_MASK,
+ .val = VIP_AND_CAM0_REG2_MASK,
+ },
+};
+
+static struct spear_modemux cam0_modemux[] = {
+ {
+ .muxregs = cam0_muxreg,
+ .nmuxregs = ARRAY_SIZE(cam0_muxreg),
+ },
+};
+
+static struct spear_pingroup cam0_pingroup = {
+ .name = "cam0_grp",
+ .pins = cam0_pins,
+ .npins = ARRAY_SIZE(cam0_pins),
+ .modemuxs = cam0_modemux,
+ .nmodemuxs = ARRAY_SIZE(cam0_modemux),
+};
+
+static const char *const cam0_grps[] = { "cam0_grp" };
+static struct spear_function cam0_function = {
+ .name = "cam0",
+ .groups = cam0_grps,
+ .ngroups = ARRAY_SIZE(cam0_grps),
+};
+
+/* pad multiplexing for cam1 device */
+static const unsigned cam1_pins[] = { 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
+};
+static struct spear_muxreg cam1_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM1_MASK,
+ .val = CAM1_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_AND_CAM1_REG1_MASK,
+ .val = VIP_AND_CAM1_REG1_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = VIP_AND_CAM1_REG2_MASK,
+ .val = VIP_AND_CAM1_REG2_MASK,
+ },
+};
+
+static struct spear_modemux cam1_modemux[] = {
+ {
+ .muxregs = cam1_muxreg,
+ .nmuxregs = ARRAY_SIZE(cam1_muxreg),
+ },
+};
+
+static struct spear_pingroup cam1_pingroup = {
+ .name = "cam1_grp",
+ .pins = cam1_pins,
+ .npins = ARRAY_SIZE(cam1_pins),
+ .modemuxs = cam1_modemux,
+ .nmodemuxs = ARRAY_SIZE(cam1_modemux),
+};
+
+static const char *const cam1_grps[] = { "cam1_grp" };
+static struct spear_function cam1_function = {
+ .name = "cam1",
+ .groups = cam1_grps,
+ .ngroups = ARRAY_SIZE(cam1_grps),
+};
+
+/* pad multiplexing for cam2 device */
+static const unsigned cam2_pins[] = { 39, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53
+};
+static struct spear_muxreg cam2_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM2_MASK,
+ .val = CAM2_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_AND_CAM2_REG1_MASK,
+ .val = VIP_AND_CAM2_REG1_MASK,
+ },
+};
+
+static struct spear_modemux cam2_modemux[] = {
+ {
+ .muxregs = cam2_muxreg,
+ .nmuxregs = ARRAY_SIZE(cam2_muxreg),
+ },
+};
+
+static struct spear_pingroup cam2_pingroup = {
+ .name = "cam2_grp",
+ .pins = cam2_pins,
+ .npins = ARRAY_SIZE(cam2_pins),
+ .modemuxs = cam2_modemux,
+ .nmodemuxs = ARRAY_SIZE(cam2_modemux),
+};
+
+static const char *const cam2_grps[] = { "cam2_grp" };
+static struct spear_function cam2_function = {
+ .name = "cam2",
+ .groups = cam2_grps,
+ .ngroups = ARRAY_SIZE(cam2_grps),
+};
+
+/* pad multiplexing for cam3 device */
+static const unsigned cam3_pins[] = { 20, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34
+};
+static struct spear_muxreg cam3_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = CAM3_MASK,
+ .val = CAM3_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = VIP_AND_CAM3_REG0_MASK,
+ .val = VIP_AND_CAM3_REG0_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_2,
+ .mask = VIP_AND_CAM3_REG1_MASK,
+ .val = VIP_AND_CAM3_REG1_MASK,
+ },
+};
+
+static struct spear_modemux cam3_modemux[] = {
+ {
+ .muxregs = cam3_muxreg,
+ .nmuxregs = ARRAY_SIZE(cam3_muxreg),
+ },
+};
+
+static struct spear_pingroup cam3_pingroup = {
+ .name = "cam3_grp",
+ .pins = cam3_pins,
+ .npins = ARRAY_SIZE(cam3_pins),
+ .modemuxs = cam3_modemux,
+ .nmodemuxs = ARRAY_SIZE(cam3_modemux),
+};
+
+static const char *const cam3_grps[] = { "cam3_grp" };
+static struct spear_function cam3_function = {
+ .name = "cam3",
+ .groups = cam3_grps,
+ .ngroups = ARRAY_SIZE(cam3_grps),
+};
+
+/* pad multiplexing for smi device */
+static const unsigned smi_pins[] = { 76, 77, 78, 79, 84 };
+static struct spear_muxreg smi_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = SMI_REG2_MASK,
+ .val = SMI_REG2_MASK,
+ },
+};
+
+static struct spear_modemux smi_modemux[] = {
+ {
+ .muxregs = smi_muxreg,
+ .nmuxregs = ARRAY_SIZE(smi_muxreg),
+ },
+};
+
+static struct spear_pingroup smi_pingroup = {
+ .name = "smi_grp",
+ .pins = smi_pins,
+ .npins = ARRAY_SIZE(smi_pins),
+ .modemuxs = smi_modemux,
+ .nmodemuxs = ARRAY_SIZE(smi_modemux),
+};
+
+static const char *const smi_grps[] = { "smi_grp" };
+static struct spear_function smi_function = {
+ .name = "smi",
+ .groups = smi_grps,
+ .ngroups = ARRAY_SIZE(smi_grps),
+};
+
+/* pad multiplexing for ssp0 device */
+static const unsigned ssp0_pins[] = { 80, 81, 82, 83 };
+static struct spear_muxreg ssp0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = SSP0_REG2_MASK,
+ .val = SSP0_REG2_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_modemux[] = {
+ {
+ .muxregs = ssp0_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_pingroup = {
+ .name = "ssp0_grp",
+ .pins = ssp0_pins,
+ .npins = ARRAY_SIZE(ssp0_pins),
+ .modemuxs = ssp0_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_modemux),
+};
+
+/* pad multiplexing for ssp0_cs1 device */
+static const unsigned ssp0_cs1_pins[] = { 24 };
+static struct spear_muxreg ssp0_cs1_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = SSP0_CS1_MASK,
+ .val = SSP0_CS1_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = PWM0_AND_SSP0_CS1_REG0_MASK,
+ .val = PWM0_AND_SSP0_CS1_REG0_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_cs1_modemux[] = {
+ {
+ .muxregs = ssp0_cs1_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_cs1_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_cs1_pingroup = {
+ .name = "ssp0_cs1_grp",
+ .pins = ssp0_cs1_pins,
+ .npins = ARRAY_SIZE(ssp0_cs1_pins),
+ .modemuxs = ssp0_cs1_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_cs1_modemux),
+};
+
+/* pad multiplexing for ssp0_cs2 device */
+static const unsigned ssp0_cs2_pins[] = { 85 };
+static struct spear_muxreg ssp0_cs2_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = SSP0_CS2_MASK,
+ .val = SSP0_CS2_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = TS_AND_SSP0_CS2_REG2_MASK,
+ .val = TS_AND_SSP0_CS2_REG2_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_cs2_modemux[] = {
+ {
+ .muxregs = ssp0_cs2_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_cs2_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_cs2_pingroup = {
+ .name = "ssp0_cs2_grp",
+ .pins = ssp0_cs2_pins,
+ .npins = ARRAY_SIZE(ssp0_cs2_pins),
+ .modemuxs = ssp0_cs2_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_cs2_modemux),
+};
+
+/* pad multiplexing for ssp0_cs3 device */
+static const unsigned ssp0_cs3_pins[] = { 132 };
+static struct spear_muxreg ssp0_cs3_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = SSP0_CS3_REG4_MASK,
+ .val = SSP0_CS3_REG4_MASK,
+ },
+};
+
+static struct spear_modemux ssp0_cs3_modemux[] = {
+ {
+ .muxregs = ssp0_cs3_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp0_cs3_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp0_cs3_pingroup = {
+ .name = "ssp0_cs3_grp",
+ .pins = ssp0_cs3_pins,
+ .npins = ARRAY_SIZE(ssp0_cs3_pins),
+ .modemuxs = ssp0_cs3_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp0_cs3_modemux),
+};
+
+static const char *const ssp0_grps[] = { "ssp0_grp", "ssp0_cs1_grp",
+ "ssp0_cs2_grp", "ssp0_cs3_grp" };
+static struct spear_function ssp0_function = {
+ .name = "ssp0",
+ .groups = ssp0_grps,
+ .ngroups = ARRAY_SIZE(ssp0_grps),
+};
+
+/* pad multiplexing for uart0 device */
+static const unsigned uart0_pins[] = { 86, 87 };
+static struct spear_muxreg uart0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = UART0_REG2_MASK,
+ .val = UART0_REG2_MASK,
+ },
+};
+
+static struct spear_modemux uart0_modemux[] = {
+ {
+ .muxregs = uart0_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart0_muxreg),
+ },
+};
+
+static struct spear_pingroup uart0_pingroup = {
+ .name = "uart0_grp",
+ .pins = uart0_pins,
+ .npins = ARRAY_SIZE(uart0_pins),
+ .modemuxs = uart0_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart0_modemux),
+};
+
+/* pad multiplexing for uart0_enh device */
+static const unsigned uart0_enh_pins[] = { 11, 12, 13, 14, 15, 16 };
+static struct spear_muxreg uart0_enh_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = GPT_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = UART0_ENH_AND_GPT_REG0_MASK,
+ .val = UART0_ENH_AND_GPT_REG0_MASK,
+ },
+};
+
+static struct spear_modemux uart0_enh_modemux[] = {
+ {
+ .muxregs = uart0_enh_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart0_enh_muxreg),
+ },
+};
+
+static struct spear_pingroup uart0_enh_pingroup = {
+ .name = "uart0_enh_grp",
+ .pins = uart0_enh_pins,
+ .npins = ARRAY_SIZE(uart0_enh_pins),
+ .modemuxs = uart0_enh_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart0_enh_modemux),
+};
+
+static const char *const uart0_grps[] = { "uart0_grp", "uart0_enh_grp" };
+static struct spear_function uart0_function = {
+ .name = "uart0",
+ .groups = uart0_grps,
+ .ngroups = ARRAY_SIZE(uart0_grps),
+};
+
+/* pad multiplexing for uart1 device */
+static const unsigned uart1_pins[] = { 88, 89 };
+static struct spear_muxreg uart1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = UART1_REG2_MASK,
+ .val = UART1_REG2_MASK,
+ },
+};
+
+static struct spear_modemux uart1_modemux[] = {
+ {
+ .muxregs = uart1_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_muxreg),
+ },
+};
+
+static struct spear_pingroup uart1_pingroup = {
+ .name = "uart1_grp",
+ .pins = uart1_pins,
+ .npins = ARRAY_SIZE(uart1_pins),
+ .modemuxs = uart1_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+ .name = "uart1",
+ .groups = uart1_grps,
+ .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* pad multiplexing for i2s_in device */
+static const unsigned i2s_in_pins[] = { 90, 91, 92, 93, 94, 99 };
+static struct spear_muxreg i2s_in_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_3,
+ .mask = I2S_IN_REG2_MASK,
+ .val = I2S_IN_REG2_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_4,
+ .mask = I2S_IN_REG3_MASK,
+ .val = I2S_IN_REG3_MASK,
+ },
+};
+
+static struct spear_modemux i2s_in_modemux[] = {
+ {
+ .muxregs = i2s_in_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s_in_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s_in_pingroup = {
+ .name = "i2s_in_grp",
+ .pins = i2s_in_pins,
+ .npins = ARRAY_SIZE(i2s_in_pins),
+ .modemuxs = i2s_in_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s_in_modemux),
+};
+
+/* pad multiplexing for i2s_out device */
+static const unsigned i2s_out_pins[] = { 95, 96, 97, 98, 100, 101, 102, 103 };
+static struct spear_muxreg i2s_out_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_4,
+ .mask = I2S_OUT_REG3_MASK,
+ .val = I2S_OUT_REG3_MASK,
+ },
+};
+
+static struct spear_modemux i2s_out_modemux[] = {
+ {
+ .muxregs = i2s_out_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s_out_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s_out_pingroup = {
+ .name = "i2s_out_grp",
+ .pins = i2s_out_pins,
+ .npins = ARRAY_SIZE(i2s_out_pins),
+ .modemuxs = i2s_out_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s_out_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_in_grp", "i2s_out_grp" };
+static struct spear_function i2s_function = {
+ .name = "i2s",
+ .groups = i2s_grps,
+ .ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* pad multiplexing for gmac device */
+static const unsigned gmac_pins[] = { 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 131 };
+#define GMAC_MUXREG \
+ { \
+ .reg = PAD_FUNCTION_EN_4, \
+ .mask = GMAC_REG3_MASK, \
+ .val = GMAC_REG3_MASK, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_5, \
+ .mask = GMAC_REG4_MASK, \
+ .val = GMAC_REG4_MASK, \
+ }
+
+/* pad multiplexing for gmii device */
+static struct spear_muxreg gmii_muxreg[] = {
+ GMAC_MUXREG,
+ {
+ .reg = GMAC_CLK_CFG,
+ .mask = GMAC_PHY_IF_SEL_MASK,
+ .val = GMAC_PHY_IF_GMII_VAL,
+ },
+};
+
+static struct spear_modemux gmii_modemux[] = {
+ {
+ .muxregs = gmii_muxreg,
+ .nmuxregs = ARRAY_SIZE(gmii_muxreg),
+ },
+};
+
+static struct spear_pingroup gmii_pingroup = {
+ .name = "gmii_grp",
+ .pins = gmac_pins,
+ .npins = ARRAY_SIZE(gmac_pins),
+ .modemuxs = gmii_modemux,
+ .nmodemuxs = ARRAY_SIZE(gmii_modemux),
+};
+
+/* pad multiplexing for rgmii device */
+static struct spear_muxreg rgmii_muxreg[] = {
+ GMAC_MUXREG,
+ {
+ .reg = GMAC_CLK_CFG,
+ .mask = GMAC_PHY_IF_SEL_MASK,
+ .val = GMAC_PHY_IF_RGMII_VAL,
+ },
+};
+
+static struct spear_modemux rgmii_modemux[] = {
+ {
+ .muxregs = rgmii_muxreg,
+ .nmuxregs = ARRAY_SIZE(rgmii_muxreg),
+ },
+};
+
+static struct spear_pingroup rgmii_pingroup = {
+ .name = "rgmii_grp",
+ .pins = gmac_pins,
+ .npins = ARRAY_SIZE(gmac_pins),
+ .modemuxs = rgmii_modemux,
+ .nmodemuxs = ARRAY_SIZE(rgmii_modemux),
+};
+
+/* pad multiplexing for rmii device */
+static struct spear_muxreg rmii_muxreg[] = {
+ GMAC_MUXREG,
+ {
+ .reg = GMAC_CLK_CFG,
+ .mask = GMAC_PHY_IF_SEL_MASK,
+ .val = GMAC_PHY_IF_RMII_VAL,
+ },
+};
+
+static struct spear_modemux rmii_modemux[] = {
+ {
+ .muxregs = rmii_muxreg,
+ .nmuxregs = ARRAY_SIZE(rmii_muxreg),
+ },
+};
+
+static struct spear_pingroup rmii_pingroup = {
+ .name = "rmii_grp",
+ .pins = gmac_pins,
+ .npins = ARRAY_SIZE(gmac_pins),
+ .modemuxs = rmii_modemux,
+ .nmodemuxs = ARRAY_SIZE(rmii_modemux),
+};
+
+/* pad multiplexing for sgmii device */
+static struct spear_muxreg sgmii_muxreg[] = {
+ GMAC_MUXREG,
+ {
+ .reg = GMAC_CLK_CFG,
+ .mask = GMAC_PHY_IF_SEL_MASK,
+ .val = GMAC_PHY_IF_SGMII_VAL,
+ },
+};
+
+static struct spear_modemux sgmii_modemux[] = {
+ {
+ .muxregs = sgmii_muxreg,
+ .nmuxregs = ARRAY_SIZE(sgmii_muxreg),
+ },
+};
+
+static struct spear_pingroup sgmii_pingroup = {
+ .name = "sgmii_grp",
+ .pins = gmac_pins,
+ .npins = ARRAY_SIZE(gmac_pins),
+ .modemuxs = sgmii_modemux,
+ .nmodemuxs = ARRAY_SIZE(sgmii_modemux),
+};
+
+static const char *const gmac_grps[] = { "gmii_grp", "rgmii_grp", "rmii_grp",
+ "sgmii_grp" };
+static struct spear_function gmac_function = {
+ .name = "gmac",
+ .groups = gmac_grps,
+ .ngroups = ARRAY_SIZE(gmac_grps),
+};
+
+/* pad multiplexing for i2c0 device */
+static const unsigned i2c0_pins[] = { 133, 134 };
+static struct spear_muxreg i2c0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = I2C0_REG4_MASK,
+ .val = I2C0_REG4_MASK,
+ },
+};
+
+static struct spear_modemux i2c0_modemux[] = {
+ {
+ .muxregs = i2c0_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c0_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c0_pingroup = {
+ .name = "i2c0_grp",
+ .pins = i2c0_pins,
+ .npins = ARRAY_SIZE(i2c0_pins),
+ .modemuxs = i2c0_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c0_modemux),
+};
+
+static const char *const i2c0_grps[] = { "i2c0_grp" };
+static struct spear_function i2c0_function = {
+ .name = "i2c0",
+ .groups = i2c0_grps,
+ .ngroups = ARRAY_SIZE(i2c0_grps),
+};
+
+/* pad multiplexing for i2c1 device */
+static const unsigned i2c1_pins[] = { 18, 23 };
+static struct spear_muxreg i2c1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_1,
+ .mask = I2C1_REG0_MASK,
+ .val = I2C1_REG0_MASK,
+ },
+};
+
+static struct spear_modemux i2c1_modemux[] = {
+ {
+ .muxregs = i2c1_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c1_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c1_pingroup = {
+ .name = "i2c1_grp",
+ .pins = i2c1_pins,
+ .npins = ARRAY_SIZE(i2c1_pins),
+ .modemuxs = i2c1_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c1_modemux),
+};
+
+static const char *const i2c1_grps[] = { "i2c1_grp" };
+static struct spear_function i2c1_function = {
+ .name = "i2c1",
+ .groups = i2c1_grps,
+ .ngroups = ARRAY_SIZE(i2c1_grps),
+};
+
+/* pad multiplexing for cec0 device */
+static const unsigned cec0_pins[] = { 135 };
+static struct spear_muxreg cec0_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = CEC0_REG4_MASK,
+ .val = CEC0_REG4_MASK,
+ },
+};
+
+static struct spear_modemux cec0_modemux[] = {
+ {
+ .muxregs = cec0_muxreg,
+ .nmuxregs = ARRAY_SIZE(cec0_muxreg),
+ },
+};
+
+static struct spear_pingroup cec0_pingroup = {
+ .name = "cec0_grp",
+ .pins = cec0_pins,
+ .npins = ARRAY_SIZE(cec0_pins),
+ .modemuxs = cec0_modemux,
+ .nmodemuxs = ARRAY_SIZE(cec0_modemux),
+};
+
+static const char *const cec0_grps[] = { "cec0_grp" };
+static struct spear_function cec0_function = {
+ .name = "cec0",
+ .groups = cec0_grps,
+ .ngroups = ARRAY_SIZE(cec0_grps),
+};
+
+/* pad multiplexing for cec1 device */
+static const unsigned cec1_pins[] = { 136 };
+static struct spear_muxreg cec1_muxreg[] = {
+ {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = CEC1_REG4_MASK,
+ .val = CEC1_REG4_MASK,
+ },
+};
+
+static struct spear_modemux cec1_modemux[] = {
+ {
+ .muxregs = cec1_muxreg,
+ .nmuxregs = ARRAY_SIZE(cec1_muxreg),
+ },
+};
+
+static struct spear_pingroup cec1_pingroup = {
+ .name = "cec1_grp",
+ .pins = cec1_pins,
+ .npins = ARRAY_SIZE(cec1_pins),
+ .modemuxs = cec1_modemux,
+ .nmodemuxs = ARRAY_SIZE(cec1_modemux),
+};
+
+static const char *const cec1_grps[] = { "cec1_grp" };
+static struct spear_function cec1_function = {
+ .name = "cec1",
+ .groups = cec1_grps,
+ .ngroups = ARRAY_SIZE(cec1_grps),
+};
+
+/* pad multiplexing for mcif devices */
+static const unsigned mcif_pins[] = { 193, 194, 195, 196, 197, 198, 199, 200,
+ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
+ 229, 230, 231, 232, 237 };
+#define MCIF_MUXREG \
+ { \
+ .reg = PAD_SHARED_IP_EN_1, \
+ .mask = MCIF_MASK, \
+ .val = MCIF_MASK, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_7, \
+ .mask = FSMC_PNOR_AND_MCIF_REG6_MASK | MCIF_REG6_MASK, \
+ .val = FSMC_PNOR_AND_MCIF_REG6_MASK | MCIF_REG6_MASK, \
+ }, { \
+ .reg = PAD_FUNCTION_EN_8, \
+ .mask = MCIF_REG7_MASK, \
+ .val = MCIF_REG7_MASK, \
+ }
+
+/* Pad multiplexing for sdhci device */
+static struct spear_muxreg sdhci_muxreg[] = {
+ MCIF_MUXREG,
+ {
+ .reg = PERIP_CFG,
+ .mask = MCIF_SEL_MASK,
+ .val = MCIF_SEL_SD,
+ },
+};
+
+static struct spear_modemux sdhci_modemux[] = {
+ {
+ .muxregs = sdhci_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_pingroup = {
+ .name = "sdhci_grp",
+ .pins = mcif_pins,
+ .npins = ARRAY_SIZE(mcif_pins),
+ .modemuxs = sdhci_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_modemux),
+};
+
+static const char *const sdhci_grps[] = { "sdhci_grp" };
+static struct spear_function sdhci_function = {
+ .name = "sdhci",
+ .groups = sdhci_grps,
+ .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* Pad multiplexing for cf device */
+static struct spear_muxreg cf_muxreg[] = {
+ MCIF_MUXREG,
+ {
+ .reg = PERIP_CFG,
+ .mask = MCIF_SEL_MASK,
+ .val = MCIF_SEL_CF,
+ },
+};
+
+static struct spear_modemux cf_modemux[] = {
+ {
+ .muxregs = cf_muxreg,
+ .nmuxregs = ARRAY_SIZE(cf_muxreg),
+ },
+};
+
+static struct spear_pingroup cf_pingroup = {
+ .name = "cf_grp",
+ .pins = mcif_pins,
+ .npins = ARRAY_SIZE(mcif_pins),
+ .modemuxs = cf_modemux,
+ .nmodemuxs = ARRAY_SIZE(cf_modemux),
+};
+
+static const char *const cf_grps[] = { "cf_grp" };
+static struct spear_function cf_function = {
+ .name = "cf",
+ .groups = cf_grps,
+ .ngroups = ARRAY_SIZE(cf_grps),
+};
+
+/* Pad multiplexing for xd device */
+static struct spear_muxreg xd_muxreg[] = {
+ MCIF_MUXREG,
+ {
+ .reg = PERIP_CFG,
+ .mask = MCIF_SEL_MASK,
+ .val = MCIF_SEL_XD,
+ },
+};
+
+static struct spear_modemux xd_modemux[] = {
+ {
+ .muxregs = xd_muxreg,
+ .nmuxregs = ARRAY_SIZE(xd_muxreg),
+ },
+};
+
+static struct spear_pingroup xd_pingroup = {
+ .name = "xd_grp",
+ .pins = mcif_pins,
+ .npins = ARRAY_SIZE(mcif_pins),
+ .modemuxs = xd_modemux,
+ .nmodemuxs = ARRAY_SIZE(xd_modemux),
+};
+
+static const char *const xd_grps[] = { "xd_grp" };
+static struct spear_function xd_function = {
+ .name = "xd",
+ .groups = xd_grps,
+ .ngroups = ARRAY_SIZE(xd_grps),
+};
+
+/* pad multiplexing for clcd device */
+static const unsigned clcd_pins[] = { 138, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173,
+ 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
+ 188, 189, 190, 191 };
+static struct spear_muxreg clcd_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = ARM_TRACE_MASK | MIPHY_DBG_MASK,
+ .val = 0,
+ }, {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK,
+ .val = CLCD_REG4_MASK | CLCD_AND_ARM_TRACE_REG4_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_6,
+ .mask = CLCD_AND_ARM_TRACE_REG5_MASK,
+ .val = CLCD_AND_ARM_TRACE_REG5_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_7,
+ .mask = CLCD_AND_ARM_TRACE_REG6_MASK,
+ .val = CLCD_AND_ARM_TRACE_REG6_MASK,
+ },
+};
+
+static struct spear_modemux clcd_modemux[] = {
+ {
+ .muxregs = clcd_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_pingroup = {
+ .name = "clcd_grp",
+ .pins = clcd_pins,
+ .npins = ARRAY_SIZE(clcd_pins),
+ .modemuxs = clcd_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp" };
+static struct spear_function clcd_function = {
+ .name = "clcd",
+ .groups = clcd_grps,
+ .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* pad multiplexing for arm_trace device */
+static const unsigned arm_trace_pins[] = { 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
+ 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
+ 193, 194, 195, 196, 197, 198, 199, 200 };
+static struct spear_muxreg arm_trace_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = ARM_TRACE_MASK,
+ .val = ARM_TRACE_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = CLCD_AND_ARM_TRACE_REG4_MASK,
+ .val = CLCD_AND_ARM_TRACE_REG4_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_6,
+ .mask = CLCD_AND_ARM_TRACE_REG5_MASK,
+ .val = CLCD_AND_ARM_TRACE_REG5_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_7,
+ .mask = CLCD_AND_ARM_TRACE_REG6_MASK,
+ .val = CLCD_AND_ARM_TRACE_REG6_MASK,
+ },
+};
+
+static struct spear_modemux arm_trace_modemux[] = {
+ {
+ .muxregs = arm_trace_muxreg,
+ .nmuxregs = ARRAY_SIZE(arm_trace_muxreg),
+ },
+};
+
+static struct spear_pingroup arm_trace_pingroup = {
+ .name = "arm_trace_grp",
+ .pins = arm_trace_pins,
+ .npins = ARRAY_SIZE(arm_trace_pins),
+ .modemuxs = arm_trace_modemux,
+ .nmodemuxs = ARRAY_SIZE(arm_trace_modemux),
+};
+
+static const char *const arm_trace_grps[] = { "arm_trace_grp" };
+static struct spear_function arm_trace_function = {
+ .name = "arm_trace",
+ .groups = arm_trace_grps,
+ .ngroups = ARRAY_SIZE(arm_trace_grps),
+};
+
+/* pad multiplexing for miphy_dbg device */
+static const unsigned miphy_dbg_pins[] = { 96, 97, 98, 99, 100, 101, 102, 103,
+ 132, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147,
+ 148, 149, 150, 151, 152, 153, 154, 155, 156, 157 };
+static struct spear_muxreg miphy_dbg_muxreg[] = {
+ {
+ .reg = PAD_SHARED_IP_EN_1,
+ .mask = MIPHY_DBG_MASK,
+ .val = MIPHY_DBG_MASK,
+ }, {
+ .reg = PAD_FUNCTION_EN_5,
+ .mask = DEVS_GRP_AND_MIPHY_DBG_REG4_MASK,
+ .val = DEVS_GRP_AND_MIPHY_DBG_REG4_MASK,
+ },
+};
+
+static struct spear_modemux miphy_dbg_modemux[] = {
+ {
+ .muxregs = miphy_dbg_muxreg,
+ .nmuxregs = ARRAY_SIZE(miphy_dbg_muxreg),
+ },
+};
+
+static struct spear_pingroup miphy_dbg_pingroup = {
+ .name = "miphy_dbg_grp",
+ .pins = miphy_dbg_pins,
+ .npins = ARRAY_SIZE(miphy_dbg_pins),
+ .modemuxs = miphy_dbg_modemux,
+ .nmodemuxs = ARRAY_SIZE(miphy_dbg_modemux),
+};
+
+static const char *const miphy_dbg_grps[] = { "miphy_dbg_grp" };
+static struct spear_function miphy_dbg_function = {
+ .name = "miphy_dbg",
+ .groups = miphy_dbg_grps,
+ .ngroups = ARRAY_SIZE(miphy_dbg_grps),
+};
+
+/* pad multiplexing for pcie device */
+static const unsigned pcie_pins[] = { 250 };
+static struct spear_muxreg pcie_muxreg[] = {
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = SATA_PCIE_CFG_MASK,
+ .val = PCIE_CFG_VAL,
+ },
+};
+
+static struct spear_modemux pcie_modemux[] = {
+ {
+ .muxregs = pcie_muxreg,
+ .nmuxregs = ARRAY_SIZE(pcie_muxreg),
+ },
+};
+
+static struct spear_pingroup pcie_pingroup = {
+ .name = "pcie_grp",
+ .pins = pcie_pins,
+ .npins = ARRAY_SIZE(pcie_pins),
+ .modemuxs = pcie_modemux,
+ .nmodemuxs = ARRAY_SIZE(pcie_modemux),
+};
+
+static const char *const pcie_grps[] = { "pcie_grp" };
+static struct spear_function pcie_function = {
+ .name = "pcie",
+ .groups = pcie_grps,
+ .ngroups = ARRAY_SIZE(pcie_grps),
+};
+
+/* pad multiplexing for sata device */
+static const unsigned sata_pins[] = { 250 };
+static struct spear_muxreg sata_muxreg[] = {
+ {
+ .reg = PCIE_SATA_CFG,
+ .mask = SATA_PCIE_CFG_MASK,
+ .val = SATA_CFG_VAL,
+ },
+};
+
+static struct spear_modemux sata_modemux[] = {
+ {
+ .muxregs = sata_muxreg,
+ .nmuxregs = ARRAY_SIZE(sata_muxreg),
+ },
+};
+
+static struct spear_pingroup sata_pingroup = {
+ .name = "sata_grp",
+ .pins = sata_pins,
+ .npins = ARRAY_SIZE(sata_pins),
+ .modemuxs = sata_modemux,
+ .nmodemuxs = ARRAY_SIZE(sata_modemux),
+};
+
+static const char *const sata_grps[] = { "sata_grp" };
+static struct spear_function sata_function = {
+ .name = "sata",
+ .groups = sata_grps,
+ .ngroups = ARRAY_SIZE(sata_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear1340_pingroups[] = {
+ &pads_as_gpio_pingroup,
+ &fsmc_8bit_pingroup,
+ &fsmc_16bit_pingroup,
+ &fsmc_pnor_pingroup,
+ &keyboard_row_col_pingroup,
+ &keyboard_col5_pingroup,
+ &spdif_in_pingroup,
+ &spdif_out_pingroup,
+ &gpt_0_1_pingroup,
+ &pwm0_pingroup,
+ &pwm1_pingroup,
+ &pwm2_pingroup,
+ &pwm3_pingroup,
+ &vip_mux_pingroup,
+ &vip_mux_cam0_pingroup,
+ &vip_mux_cam1_pingroup,
+ &vip_mux_cam2_pingroup,
+ &vip_mux_cam3_pingroup,
+ &cam0_pingroup,
+ &cam1_pingroup,
+ &cam2_pingroup,
+ &cam3_pingroup,
+ &smi_pingroup,
+ &ssp0_pingroup,
+ &ssp0_cs1_pingroup,
+ &ssp0_cs2_pingroup,
+ &ssp0_cs3_pingroup,
+ &uart0_pingroup,
+ &uart0_enh_pingroup,
+ &uart1_pingroup,
+ &i2s_in_pingroup,
+ &i2s_out_pingroup,
+ &gmii_pingroup,
+ &rgmii_pingroup,
+ &rmii_pingroup,
+ &sgmii_pingroup,
+ &i2c0_pingroup,
+ &i2c1_pingroup,
+ &cec0_pingroup,
+ &cec1_pingroup,
+ &sdhci_pingroup,
+ &cf_pingroup,
+ &xd_pingroup,
+ &clcd_pingroup,
+ &arm_trace_pingroup,
+ &miphy_dbg_pingroup,
+ &pcie_pingroup,
+ &sata_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear1340_functions[] = {
+ &pads_as_gpio_function,
+ &fsmc_function,
+ &keyboard_function,
+ &spdif_in_function,
+ &spdif_out_function,
+ &gpt_0_1_function,
+ &pwm_function,
+ &vip_function,
+ &cam0_function,
+ &cam1_function,
+ &cam2_function,
+ &cam3_function,
+ &smi_function,
+ &ssp0_function,
+ &uart0_function,
+ &uart1_function,
+ &i2s_function,
+ &gmac_function,
+ &i2c0_function,
+ &i2c1_function,
+ &cec0_function,
+ &cec1_function,
+ &sdhci_function,
+ &cf_function,
+ &xd_function,
+ &clcd_function,
+ &arm_trace_function,
+ &miphy_dbg_function,
+ &pcie_function,
+ &sata_function,
+};
+
+static struct spear_pinctrl_machdata spear1340_machdata = {
+ .pins = spear1340_pins,
+ .npins = ARRAY_SIZE(spear1340_pins),
+ .groups = spear1340_pingroups,
+ .ngroups = ARRAY_SIZE(spear1340_pingroups),
+ .functions = spear1340_functions,
+ .nfunctions = ARRAY_SIZE(spear1340_functions),
+ .modes_supported = false,
+};
+
+static struct of_device_id spear1340_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "st,spear1340-pinmux",
+ },
+ {},
+};
+
+static int __devinit spear1340_pinctrl_probe(struct platform_device *pdev)
+{
+ return spear_pinctrl_probe(pdev, &spear1340_machdata);
+}
+
+static int __devexit spear1340_pinctrl_remove(struct platform_device *pdev)
+{
+ return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear1340_pinctrl_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spear1340_pinctrl_of_match,
+ },
+ .probe = spear1340_pinctrl_probe,
+ .remove = __devexit_p(spear1340_pinctrl_remove),
+};
+
+static int __init spear1340_pinctrl_init(void)
+{
+ return platform_driver_register(&spear1340_pinctrl_driver);
+}
+arch_initcall(spear1340_pinctrl_init);
+
+static void __exit spear1340_pinctrl_exit(void)
+{
+ platform_driver_unregister(&spear1340_pinctrl_driver);
+}
+module_exit(spear1340_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c
new file mode 100644
index 000000000000..9c82a35e4e78
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear300.c
@@ -0,0 +1,708 @@
+/*
+ * Driver for the ST Microelectronics SPEAr300 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear300-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG 0x00
+#define MODE_CONFIG_REG 0x04
+
+/* modes */
+#define NAND_MODE (1 << 0)
+#define NOR_MODE (1 << 1)
+#define PHOTO_FRAME_MODE (1 << 2)
+#define LEND_IP_PHONE_MODE (1 << 3)
+#define HEND_IP_PHONE_MODE (1 << 4)
+#define LEND_WIFI_PHONE_MODE (1 << 5)
+#define HEND_WIFI_PHONE_MODE (1 << 6)
+#define ATA_PABX_WI2S_MODE (1 << 7)
+#define ATA_PABX_I2S_MODE (1 << 8)
+#define CAML_LCDW_MODE (1 << 9)
+#define CAMU_LCD_MODE (1 << 10)
+#define CAMU_WLCD_MODE (1 << 11)
+#define CAML_LCD_MODE (1 << 12)
+
+static struct spear_pmx_mode pmx_mode_nand = {
+ .name = "nand",
+ .mode = NAND_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x00,
+};
+
+static struct spear_pmx_mode pmx_mode_nor = {
+ .name = "nor",
+ .mode = NOR_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x01,
+};
+
+static struct spear_pmx_mode pmx_mode_photo_frame = {
+ .name = "photo frame mode",
+ .mode = PHOTO_FRAME_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x02,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_ip_phone = {
+ .name = "lend ip phone mode",
+ .mode = LEND_IP_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x03,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_ip_phone = {
+ .name = "hend ip phone mode",
+ .mode = HEND_IP_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x04,
+};
+
+static struct spear_pmx_mode pmx_mode_lend_wifi_phone = {
+ .name = "lend wifi phone mode",
+ .mode = LEND_WIFI_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x05,
+};
+
+static struct spear_pmx_mode pmx_mode_hend_wifi_phone = {
+ .name = "hend wifi phone mode",
+ .mode = HEND_WIFI_PHONE_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x06,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_wi2s = {
+ .name = "ata pabx wi2s mode",
+ .mode = ATA_PABX_WI2S_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x07,
+};
+
+static struct spear_pmx_mode pmx_mode_ata_pabx_i2s = {
+ .name = "ata pabx i2s mode",
+ .mode = ATA_PABX_I2S_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x08,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcdw = {
+ .name = "caml lcdw mode",
+ .mode = CAML_LCDW_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x0C,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_lcd = {
+ .name = "camu lcd mode",
+ .mode = CAMU_LCD_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x0D,
+};
+
+static struct spear_pmx_mode pmx_mode_camu_wlcd = {
+ .name = "camu wlcd mode",
+ .mode = CAMU_WLCD_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0xE,
+};
+
+static struct spear_pmx_mode pmx_mode_caml_lcd = {
+ .name = "caml lcd mode",
+ .mode = CAML_LCD_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x0000000F,
+ .val = 0x0F,
+};
+
+static struct spear_pmx_mode *spear300_pmx_modes[] = {
+ &pmx_mode_nand,
+ &pmx_mode_nor,
+ &pmx_mode_photo_frame,
+ &pmx_mode_lend_ip_phone,
+ &pmx_mode_hend_ip_phone,
+ &pmx_mode_lend_wifi_phone,
+ &pmx_mode_hend_wifi_phone,
+ &pmx_mode_ata_pabx_wi2s,
+ &pmx_mode_ata_pabx_i2s,
+ &pmx_mode_caml_lcdw,
+ &pmx_mode_camu_lcd,
+ &pmx_mode_camu_wlcd,
+ &pmx_mode_caml_lcd,
+};
+
+/* fsmc_2chips_pins */
+static const unsigned fsmc_2chips_pins[] = { 1, 97 };
+static struct spear_muxreg fsmc_2chips_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux fsmc_2chips_modemux[] = {
+ {
+ .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+ .muxregs = fsmc_2chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_2chips_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_2chips_pingroup = {
+ .name = "fsmc_2chips_grp",
+ .pins = fsmc_2chips_pins,
+ .npins = ARRAY_SIZE(fsmc_2chips_pins),
+ .modemuxs = fsmc_2chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_2chips_modemux),
+};
+
+/* fsmc_4chips_pins */
+static const unsigned fsmc_4chips_pins[] = { 1, 2, 3, 97 };
+static struct spear_muxreg fsmc_4chips_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK | PMX_UART0_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux fsmc_4chips_modemux[] = {
+ {
+ .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
+ .muxregs = fsmc_4chips_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_4chips_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_4chips_pingroup = {
+ .name = "fsmc_4chips_grp",
+ .pins = fsmc_4chips_pins,
+ .npins = ARRAY_SIZE(fsmc_4chips_pins),
+ .modemuxs = fsmc_4chips_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_4chips_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_2chips_grp", "fsmc_4chips_grp"
+};
+static struct spear_function fsmc_function = {
+ .name = "fsmc",
+ .groups = fsmc_grps,
+ .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* clcd_lcdmode_pins */
+static const unsigned clcd_lcdmode_pins[] = { 49, 50 };
+static struct spear_muxreg clcd_lcdmode_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux clcd_lcdmode_modemux[] = {
+ {
+ .modes = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ CAMU_LCD_MODE | CAML_LCD_MODE,
+ .muxregs = clcd_lcdmode_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_lcdmode_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_lcdmode_pingroup = {
+ .name = "clcd_lcdmode_grp",
+ .pins = clcd_lcdmode_pins,
+ .npins = ARRAY_SIZE(clcd_lcdmode_pins),
+ .modemuxs = clcd_lcdmode_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_lcdmode_modemux),
+};
+
+/* clcd_pfmode_pins */
+static const unsigned clcd_pfmode_pins[] = { 47, 48, 49, 50 };
+static struct spear_muxreg clcd_pfmode_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux clcd_pfmode_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE,
+ .muxregs = clcd_pfmode_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_pfmode_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_pfmode_pingroup = {
+ .name = "clcd_pfmode_grp",
+ .pins = clcd_pfmode_pins,
+ .npins = ARRAY_SIZE(clcd_pfmode_pins),
+ .modemuxs = clcd_pfmode_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_pfmode_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_lcdmode_grp", "clcd_pfmode_grp"
+};
+static struct spear_function clcd_function = {
+ .name = "clcd",
+ .groups = clcd_grps,
+ .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 34, 35, 36, 37, 38 };
+static struct spear_muxreg tdm_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux tdm_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
+ | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE
+ | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = tdm_muxreg,
+ .nmuxregs = ARRAY_SIZE(tdm_muxreg),
+ },
+};
+
+static struct spear_pingroup tdm_pingroup = {
+ .name = "tdm_grp",
+ .pins = tdm_pins,
+ .npins = ARRAY_SIZE(tdm_pins),
+ .modemuxs = tdm_modemux,
+ .nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+ .name = "tdm",
+ .groups = tdm_grps,
+ .ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* i2c_clk_pins */
+static const unsigned i2c_clk_pins[] = { 45, 46, 47, 48 };
+static struct spear_muxreg i2c_clk_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2c_clk_modemux[] = {
+ {
+ .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
+ LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | CAML_LCDW_MODE
+ | CAML_LCD_MODE,
+ .muxregs = i2c_clk_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c_clk_muxreg),
+ },
+};
+
+static struct spear_pingroup i2c_clk_pingroup = {
+ .name = "i2c_clk_grp_grp",
+ .pins = i2c_clk_pins,
+ .npins = ARRAY_SIZE(i2c_clk_pins),
+ .modemuxs = i2c_clk_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c_clk_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c_clk_grp" };
+static struct spear_function i2c_function = {
+ .name = "i2c1",
+ .groups = i2c_grps,
+ .ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* caml_pins */
+static const unsigned caml_pins[] = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };
+static struct spear_muxreg caml_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux caml_modemux[] = {
+ {
+ .modes = CAML_LCDW_MODE | CAML_LCD_MODE,
+ .muxregs = caml_muxreg,
+ .nmuxregs = ARRAY_SIZE(caml_muxreg),
+ },
+};
+
+static struct spear_pingroup caml_pingroup = {
+ .name = "caml_grp",
+ .pins = caml_pins,
+ .npins = ARRAY_SIZE(caml_pins),
+ .modemuxs = caml_modemux,
+ .nmodemuxs = ARRAY_SIZE(caml_modemux),
+};
+
+/* camu_pins */
+static const unsigned camu_pins[] = { 16, 17, 18, 19, 20, 21, 45, 46, 47, 48 };
+static struct spear_muxreg camu_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK | PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux camu_modemux[] = {
+ {
+ .modes = CAMU_LCD_MODE | CAMU_WLCD_MODE,
+ .muxregs = camu_muxreg,
+ .nmuxregs = ARRAY_SIZE(camu_muxreg),
+ },
+};
+
+static struct spear_pingroup camu_pingroup = {
+ .name = "camu_grp",
+ .pins = camu_pins,
+ .npins = ARRAY_SIZE(camu_pins),
+ .modemuxs = camu_modemux,
+ .nmodemuxs = ARRAY_SIZE(camu_modemux),
+};
+
+static const char *const cam_grps[] = { "caml_grp", "camu_grp" };
+static struct spear_function cam_function = {
+ .name = "cam",
+ .groups = cam_grps,
+ .ngroups = ARRAY_SIZE(cam_grps),
+};
+
+/* dac_pins */
+static const unsigned dac_pins[] = { 43, 44 };
+static struct spear_muxreg dac_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux dac_modemux[] = {
+ {
+ .modes = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = dac_muxreg,
+ .nmuxregs = ARRAY_SIZE(dac_muxreg),
+ },
+};
+
+static struct spear_pingroup dac_pingroup = {
+ .name = "dac_grp",
+ .pins = dac_pins,
+ .npins = ARRAY_SIZE(dac_pins),
+ .modemuxs = dac_modemux,
+ .nmodemuxs = ARRAY_SIZE(dac_modemux),
+};
+
+static const char *const dac_grps[] = { "dac_grp" };
+static struct spear_function dac_function = {
+ .name = "dac",
+ .groups = dac_grps,
+ .ngroups = ARRAY_SIZE(dac_grps),
+};
+
+/* i2s_pins */
+static const unsigned i2s_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux i2s_modemux[] = {
+ {
+ .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
+ | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
+ ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
+ | CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = i2s_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s_pingroup = {
+ .name = "i2s_grp",
+ .pins = i2s_pins,
+ .npins = ARRAY_SIZE(i2s_pins),
+ .modemuxs = i2s_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+ .name = "i2s",
+ .groups = i2s_grps,
+ .ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* sdhci_4bit_pins */
+static const unsigned sdhci_4bit_pins[] = { 28, 29, 30, 31, 32, 33 };
+static struct spear_muxreg sdhci_4bit_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+ PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux sdhci_4bit_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+ HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+ CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE,
+ .muxregs = sdhci_4bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_4bit_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_4bit_pingroup = {
+ .name = "sdhci_4bit_grp",
+ .pins = sdhci_4bit_pins,
+ .npins = ARRAY_SIZE(sdhci_4bit_pins),
+ .modemuxs = sdhci_4bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_4bit_modemux),
+};
+
+/* sdhci_8bit_pins */
+static const unsigned sdhci_8bit_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33 };
+static struct spear_muxreg sdhci_8bit_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK |
+ PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
+ PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux sdhci_8bit_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
+ HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
+ HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
+ CAMU_WLCD_MODE | CAML_LCD_MODE,
+ .muxregs = sdhci_8bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_8bit_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_8bit_pingroup = {
+ .name = "sdhci_8bit_grp",
+ .pins = sdhci_8bit_pins,
+ .npins = ARRAY_SIZE(sdhci_8bit_pins),
+ .modemuxs = sdhci_8bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_8bit_modemux),
+};
+
+static const char *const sdhci_grps[] = { "sdhci_4bit_grp", "sdhci_8bit_grp" };
+static struct spear_function sdhci_function = {
+ .name = "sdhci",
+ .groups = sdhci_grps,
+ .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* gpio1_0_to_3_pins */
+static const unsigned gpio1_0_to_3_pins[] = { 39, 40, 41, 42 };
+static struct spear_muxreg gpio1_0_to_3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux gpio1_0_to_3_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE,
+ .muxregs = gpio1_0_to_3_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio1_0_to_3_muxreg),
+ },
+};
+
+static struct spear_pingroup gpio1_0_to_3_pingroup = {
+ .name = "gpio1_0_to_3_grp",
+ .pins = gpio1_0_to_3_pins,
+ .npins = ARRAY_SIZE(gpio1_0_to_3_pins),
+ .modemuxs = gpio1_0_to_3_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio1_0_to_3_modemux),
+};
+
+/* gpio1_4_to_7_pins */
+static const unsigned gpio1_4_to_7_pins[] = { 43, 44, 45, 46 };
+
+static struct spear_muxreg gpio1_4_to_7_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux gpio1_4_to_7_modemux[] = {
+ {
+ .modes = PHOTO_FRAME_MODE,
+ .muxregs = gpio1_4_to_7_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio1_4_to_7_muxreg),
+ },
+};
+
+static struct spear_pingroup gpio1_4_to_7_pingroup = {
+ .name = "gpio1_4_to_7_grp",
+ .pins = gpio1_4_to_7_pins,
+ .npins = ARRAY_SIZE(gpio1_4_to_7_pins),
+ .modemuxs = gpio1_4_to_7_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio1_4_to_7_modemux),
+};
+
+static const char *const gpio1_grps[] = { "gpio1_0_to_3_grp", "gpio1_4_to_7_grp"
+};
+static struct spear_function gpio1_function = {
+ .name = "gpio1",
+ .groups = gpio1_grps,
+ .ngroups = ARRAY_SIZE(gpio1_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear300_pingroups[] = {
+ SPEAR3XX_COMMON_PINGROUPS,
+ &fsmc_2chips_pingroup,
+ &fsmc_4chips_pingroup,
+ &clcd_lcdmode_pingroup,
+ &clcd_pfmode_pingroup,
+ &tdm_pingroup,
+ &i2c_clk_pingroup,
+ &caml_pingroup,
+ &camu_pingroup,
+ &dac_pingroup,
+ &i2s_pingroup,
+ &sdhci_4bit_pingroup,
+ &sdhci_8bit_pingroup,
+ &gpio1_0_to_3_pingroup,
+ &gpio1_4_to_7_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear300_functions[] = {
+ SPEAR3XX_COMMON_FUNCTIONS,
+ &fsmc_function,
+ &clcd_function,
+ &tdm_function,
+ &i2c_function,
+ &cam_function,
+ &dac_function,
+ &i2s_function,
+ &sdhci_function,
+ &gpio1_function,
+};
+
+static struct of_device_id spear300_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "st,spear300-pinmux",
+ },
+ {},
+};
+
+static int __devinit spear300_pinctrl_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ spear3xx_machdata.groups = spear300_pingroups;
+ spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups);
+ spear3xx_machdata.functions = spear300_functions;
+ spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions);
+
+ spear3xx_machdata.modes_supported = true;
+ spear3xx_machdata.pmx_modes = spear300_pmx_modes;
+ spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear300_pmx_modes);
+
+ pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+ ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int __devexit spear300_pinctrl_remove(struct platform_device *pdev)
+{
+ return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear300_pinctrl_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spear300_pinctrl_of_match,
+ },
+ .probe = spear300_pinctrl_probe,
+ .remove = __devexit_p(spear300_pinctrl_remove),
+};
+
+static int __init spear300_pinctrl_init(void)
+{
+ return platform_driver_register(&spear300_pinctrl_driver);
+}
+arch_initcall(spear300_pinctrl_init);
+
+static void __exit spear300_pinctrl_exit(void)
+{
+ platform_driver_unregister(&spear300_pinctrl_driver);
+}
+module_exit(spear300_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c
new file mode 100644
index 000000000000..1a9707605125
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear310.c
@@ -0,0 +1,431 @@
+/*
+ * Driver for the ST Microelectronics SPEAr310 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear310-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG 0x08
+
+/* emi_cs_0_to_5_pins */
+static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 };
+static struct spear_muxreg emi_cs_0_to_5_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux emi_cs_0_to_5_modemux[] = {
+ {
+ .muxregs = emi_cs_0_to_5_muxreg,
+ .nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg),
+ },
+};
+
+static struct spear_pingroup emi_cs_0_to_5_pingroup = {
+ .name = "emi_cs_0_to_5_grp",
+ .pins = emi_cs_0_to_5_pins,
+ .npins = ARRAY_SIZE(emi_cs_0_to_5_pins),
+ .modemuxs = emi_cs_0_to_5_modemux,
+ .nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux),
+};
+
+static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" };
+static struct spear_function emi_cs_0_to_5_function = {
+ .name = "emi",
+ .groups = emi_cs_0_to_5_grps,
+ .ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps),
+};
+
+/* uart1_pins */
+static const unsigned uart1_pins[] = { 0, 1 };
+static struct spear_muxreg uart1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart1_modemux[] = {
+ {
+ .muxregs = uart1_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_muxreg),
+ },
+};
+
+static struct spear_pingroup uart1_pingroup = {
+ .name = "uart1_grp",
+ .pins = uart1_pins,
+ .npins = ARRAY_SIZE(uart1_pins),
+ .modemuxs = uart1_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+ .name = "uart1",
+ .groups = uart1_grps,
+ .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* uart2_pins */
+static const unsigned uart2_pins[] = { 43, 44 };
+static struct spear_muxreg uart2_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart2_modemux[] = {
+ {
+ .muxregs = uart2_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart2_muxreg),
+ },
+};
+
+static struct spear_pingroup uart2_pingroup = {
+ .name = "uart2_grp",
+ .pins = uart2_pins,
+ .npins = ARRAY_SIZE(uart2_pins),
+ .modemuxs = uart2_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+ .name = "uart2",
+ .groups = uart2_grps,
+ .ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* uart3_pins */
+static const unsigned uart3_pins[] = { 37, 38 };
+static struct spear_muxreg uart3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart3_modemux[] = {
+ {
+ .muxregs = uart3_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_muxreg),
+ },
+};
+
+static struct spear_pingroup uart3_pingroup = {
+ .name = "uart3_grp",
+ .pins = uart3_pins,
+ .npins = ARRAY_SIZE(uart3_pins),
+ .modemuxs = uart3_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux),
+};
+
+static const char *const uart3_grps[] = { "uart3_grp" };
+static struct spear_function uart3_function = {
+ .name = "uart3",
+ .groups = uart3_grps,
+ .ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* uart4_pins */
+static const unsigned uart4_pins[] = { 39, 40 };
+static struct spear_muxreg uart4_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart4_modemux[] = {
+ {
+ .muxregs = uart4_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_muxreg),
+ },
+};
+
+static struct spear_pingroup uart4_pingroup = {
+ .name = "uart4_grp",
+ .pins = uart4_pins,
+ .npins = ARRAY_SIZE(uart4_pins),
+ .modemuxs = uart4_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux),
+};
+
+static const char *const uart4_grps[] = { "uart4_grp" };
+static struct spear_function uart4_function = {
+ .name = "uart4",
+ .groups = uart4_grps,
+ .ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* uart5_pins */
+static const unsigned uart5_pins[] = { 41, 42 };
+static struct spear_muxreg uart5_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux uart5_modemux[] = {
+ {
+ .muxregs = uart5_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_muxreg),
+ },
+};
+
+static struct spear_pingroup uart5_pingroup = {
+ .name = "uart5_grp",
+ .pins = uart5_pins,
+ .npins = ARRAY_SIZE(uart5_pins),
+ .modemuxs = uart5_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux),
+};
+
+static const char *const uart5_grps[] = { "uart5_grp" };
+static struct spear_function uart5_function = {
+ .name = "uart5",
+ .groups = uart5_grps,
+ .ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* fsmc_pins */
+static const unsigned fsmc_pins[] = { 34, 35, 36 };
+static struct spear_muxreg fsmc_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux fsmc_modemux[] = {
+ {
+ .muxregs = fsmc_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_pingroup = {
+ .name = "fsmc_grp",
+ .pins = fsmc_pins,
+ .npins = ARRAY_SIZE(fsmc_pins),
+ .modemuxs = fsmc_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_grp" };
+static struct spear_function fsmc_function = {
+ .name = "fsmc",
+ .groups = fsmc_grps,
+ .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* rs485_0_pins */
+static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 };
+static struct spear_muxreg rs485_0_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux rs485_0_modemux[] = {
+ {
+ .muxregs = rs485_0_muxreg,
+ .nmuxregs = ARRAY_SIZE(rs485_0_muxreg),
+ },
+};
+
+static struct spear_pingroup rs485_0_pingroup = {
+ .name = "rs485_0_grp",
+ .pins = rs485_0_pins,
+ .npins = ARRAY_SIZE(rs485_0_pins),
+ .modemuxs = rs485_0_modemux,
+ .nmodemuxs = ARRAY_SIZE(rs485_0_modemux),
+};
+
+static const char *const rs485_0_grps[] = { "rs485_0" };
+static struct spear_function rs485_0_function = {
+ .name = "rs485_0",
+ .groups = rs485_0_grps,
+ .ngroups = ARRAY_SIZE(rs485_0_grps),
+};
+
+/* rs485_1_pins */
+static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 };
+static struct spear_muxreg rs485_1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux rs485_1_modemux[] = {
+ {
+ .muxregs = rs485_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(rs485_1_muxreg),
+ },
+};
+
+static struct spear_pingroup rs485_1_pingroup = {
+ .name = "rs485_1_grp",
+ .pins = rs485_1_pins,
+ .npins = ARRAY_SIZE(rs485_1_pins),
+ .modemuxs = rs485_1_modemux,
+ .nmodemuxs = ARRAY_SIZE(rs485_1_modemux),
+};
+
+static const char *const rs485_1_grps[] = { "rs485_1" };
+static struct spear_function rs485_1_function = {
+ .name = "rs485_1",
+ .groups = rs485_1_grps,
+ .ngroups = ARRAY_SIZE(rs485_1_grps),
+};
+
+/* tdm_pins */
+static const unsigned tdm_pins[] = { 10, 11, 12, 13 };
+static struct spear_muxreg tdm_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_modemux tdm_modemux[] = {
+ {
+ .muxregs = tdm_muxreg,
+ .nmuxregs = ARRAY_SIZE(tdm_muxreg),
+ },
+};
+
+static struct spear_pingroup tdm_pingroup = {
+ .name = "tdm_grp",
+ .pins = tdm_pins,
+ .npins = ARRAY_SIZE(tdm_pins),
+ .modemuxs = tdm_modemux,
+ .nmodemuxs = ARRAY_SIZE(tdm_modemux),
+};
+
+static const char *const tdm_grps[] = { "tdm_grp" };
+static struct spear_function tdm_function = {
+ .name = "tdm",
+ .groups = tdm_grps,
+ .ngroups = ARRAY_SIZE(tdm_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear310_pingroups[] = {
+ SPEAR3XX_COMMON_PINGROUPS,
+ &emi_cs_0_to_5_pingroup,
+ &uart1_pingroup,
+ &uart2_pingroup,
+ &uart3_pingroup,
+ &uart4_pingroup,
+ &uart5_pingroup,
+ &fsmc_pingroup,
+ &rs485_0_pingroup,
+ &rs485_1_pingroup,
+ &tdm_pingroup,
+};
+
+/* functions */
+static struct spear_function *spear310_functions[] = {
+ SPEAR3XX_COMMON_FUNCTIONS,
+ &emi_cs_0_to_5_function,
+ &uart1_function,
+ &uart2_function,
+ &uart3_function,
+ &uart4_function,
+ &uart5_function,
+ &fsmc_function,
+ &rs485_0_function,
+ &rs485_1_function,
+ &tdm_function,
+};
+
+static struct of_device_id spear310_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "st,spear310-pinmux",
+ },
+ {},
+};
+
+static int __devinit spear310_pinctrl_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ spear3xx_machdata.groups = spear310_pingroups;
+ spear3xx_machdata.ngroups = ARRAY_SIZE(spear310_pingroups);
+ spear3xx_machdata.functions = spear310_functions;
+ spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
+
+ pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+ spear3xx_machdata.modes_supported = false;
+
+ ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int __devexit spear310_pinctrl_remove(struct platform_device *pdev)
+{
+ return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear310_pinctrl_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spear310_pinctrl_of_match,
+ },
+ .probe = spear310_pinctrl_probe,
+ .remove = __devexit_p(spear310_pinctrl_remove),
+};
+
+static int __init spear310_pinctrl_init(void)
+{
+ return platform_driver_register(&spear310_pinctrl_driver);
+}
+arch_initcall(spear310_pinctrl_init);
+
+static void __exit spear310_pinctrl_exit(void)
+{
+ platform_driver_unregister(&spear310_pinctrl_driver);
+}
+module_exit(spear310_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c
new file mode 100644
index 000000000000..de726e6c283a
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear320.c
@@ -0,0 +1,3468 @@
+/*
+ * Driver for the ST Microelectronics SPEAr320 pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "pinctrl-spear3xx.h"
+
+#define DRIVER_NAME "spear320-pinmux"
+
+/* addresses */
+#define PMX_CONFIG_REG 0x0C
+#define MODE_CONFIG_REG 0x10
+#define MODE_EXT_CONFIG_REG 0x18
+
+/* modes */
+#define AUTO_NET_SMII_MODE (1 << 0)
+#define AUTO_NET_MII_MODE (1 << 1)
+#define AUTO_EXP_MODE (1 << 2)
+#define SMALL_PRINTERS_MODE (1 << 3)
+#define EXTENDED_MODE (1 << 4)
+
+static struct spear_pmx_mode pmx_mode_auto_net_smii = {
+ .name = "Automation Networking SMII mode",
+ .mode = AUTO_NET_SMII_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x00000007,
+ .val = 0x0,
+};
+
+static struct spear_pmx_mode pmx_mode_auto_net_mii = {
+ .name = "Automation Networking MII mode",
+ .mode = AUTO_NET_MII_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x00000007,
+ .val = 0x1,
+};
+
+static struct spear_pmx_mode pmx_mode_auto_exp = {
+ .name = "Automation Expanded mode",
+ .mode = AUTO_EXP_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x00000007,
+ .val = 0x2,
+};
+
+static struct spear_pmx_mode pmx_mode_small_printers = {
+ .name = "Small Printers mode",
+ .mode = SMALL_PRINTERS_MODE,
+ .reg = MODE_CONFIG_REG,
+ .mask = 0x00000007,
+ .val = 0x3,
+};
+
+static struct spear_pmx_mode pmx_mode_extended = {
+ .name = "extended mode",
+ .mode = EXTENDED_MODE,
+ .reg = MODE_EXT_CONFIG_REG,
+ .mask = 0x00000001,
+ .val = 0x1,
+};
+
+static struct spear_pmx_mode *spear320_pmx_modes[] = {
+ &pmx_mode_auto_net_smii,
+ &pmx_mode_auto_net_mii,
+ &pmx_mode_auto_exp,
+ &pmx_mode_small_printers,
+ &pmx_mode_extended,
+};
+
+/* Extended mode registers and their offsets */
+#define EXT_CTRL_REG 0x0018
+ #define MII_MDIO_MASK (1 << 4)
+ #define MII_MDIO_10_11_VAL 0
+ #define MII_MDIO_81_VAL (1 << 4)
+ #define EMI_FSMC_DYNAMIC_MUX_MASK (1 << 5)
+ #define MAC_MODE_MII 0
+ #define MAC_MODE_RMII 1
+ #define MAC_MODE_SMII 2
+ #define MAC_MODE_SS_SMII 3
+ #define MAC_MODE_MASK 0x3
+ #define MAC1_MODE_SHIFT 16
+ #define MAC2_MODE_SHIFT 18
+
+#define IP_SEL_PAD_0_9_REG 0x00A4
+ #define PMX_PL_0_1_MASK (0x3F << 0)
+ #define PMX_UART2_PL_0_1_VAL 0x0
+ #define PMX_I2C2_PL_0_1_VAL (0x4 | (0x4 << 3))
+
+ #define PMX_PL_2_3_MASK (0x3F << 6)
+ #define PMX_I2C2_PL_2_3_VAL 0x0
+ #define PMX_UART6_PL_2_3_VAL ((0x1 << 6) | (0x1 << 9))
+ #define PMX_UART1_ENH_PL_2_3_VAL ((0x4 << 6) | (0x4 << 9))
+
+ #define PMX_PL_4_5_MASK (0x3F << 12)
+ #define PMX_UART5_PL_4_5_VAL ((0x1 << 12) | (0x1 << 15))
+ #define PMX_UART1_ENH_PL_4_5_VAL ((0x4 << 12) | (0x4 << 15))
+ #define PMX_PL_5_MASK (0x7 << 15)
+ #define PMX_TOUCH_Y_PL_5_VAL 0x0
+
+ #define PMX_PL_6_7_MASK (0x3F << 18)
+ #define PMX_PL_6_MASK (0x7 << 18)
+ #define PMX_PL_7_MASK (0x7 << 21)
+ #define PMX_UART4_PL_6_7_VAL ((0x1 << 18) | (0x1 << 21))
+ #define PMX_PWM_3_PL_6_VAL (0x2 << 18)
+ #define PMX_PWM_2_PL_7_VAL (0x2 << 21)
+ #define PMX_UART1_ENH_PL_6_7_VAL ((0x4 << 18) | (0x4 << 21))
+
+ #define PMX_PL_8_9_MASK (0x3F << 24)
+ #define PMX_UART3_PL_8_9_VAL ((0x1 << 24) | (0x1 << 27))
+ #define PMX_PWM_0_1_PL_8_9_VAL ((0x2 << 24) | (0x2 << 27))
+ #define PMX_I2C1_PL_8_9_VAL ((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_10_19_REG 0x00A8
+ #define PMX_PL_10_11_MASK (0x3F << 0)
+ #define PMX_SMII_PL_10_11_VAL 0
+ #define PMX_RMII_PL_10_11_VAL ((0x4 << 0) | (0x4 << 3))
+
+ #define PMX_PL_12_MASK (0x7 << 6)
+ #define PMX_PWM3_PL_12_VAL 0
+ #define PMX_SDHCI_CD_PL_12_VAL (0x4 << 6)
+
+ #define PMX_PL_13_14_MASK (0x3F << 9)
+ #define PMX_PL_13_MASK (0x7 << 9)
+ #define PMX_PL_14_MASK (0x7 << 12)
+ #define PMX_SSP2_PL_13_14_15_16_VAL 0
+ #define PMX_UART4_PL_13_14_VAL ((0x1 << 9) | (0x1 << 12))
+ #define PMX_RMII_PL_13_14_VAL ((0x4 << 9) | (0x4 << 12))
+ #define PMX_PWM2_PL_13_VAL (0x2 << 9)
+ #define PMX_PWM1_PL_14_VAL (0x2 << 12)
+
+ #define PMX_PL_15_MASK (0x7 << 15)
+ #define PMX_PWM0_PL_15_VAL (0x2 << 15)
+ #define PMX_PL_15_16_MASK (0x3F << 15)
+ #define PMX_UART3_PL_15_16_VAL ((0x1 << 15) | (0x1 << 18))
+ #define PMX_RMII_PL_15_16_VAL ((0x4 << 15) | (0x4 << 18))
+
+ #define PMX_PL_17_18_MASK (0x3F << 21)
+ #define PMX_SSP1_PL_17_18_19_20_VAL 0
+ #define PMX_RMII_PL_17_18_VAL ((0x4 << 21) | (0x4 << 24))
+
+ #define PMX_PL_19_MASK (0x7 << 27)
+ #define PMX_I2C2_PL_19_VAL (0x1 << 27)
+ #define PMX_RMII_PL_19_VAL (0x4 << 27)
+
+#define IP_SEL_PAD_20_29_REG 0x00AC
+ #define PMX_PL_20_MASK (0x7 << 0)
+ #define PMX_I2C2_PL_20_VAL (0x1 << 0)
+ #define PMX_RMII_PL_20_VAL (0x4 << 0)
+
+ #define PMX_PL_21_TO_27_MASK (0x1FFFFF << 3)
+ #define PMX_SMII_PL_21_TO_27_VAL 0
+ #define PMX_RMII_PL_21_TO_27_VAL ((0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12) | (0x4 << 15) | (0x4 << 18) | (0x4 << 21))
+
+ #define PMX_PL_28_29_MASK (0x3F << 24)
+ #define PMX_PL_28_MASK (0x7 << 24)
+ #define PMX_PL_29_MASK (0x7 << 27)
+ #define PMX_UART1_PL_28_29_VAL 0
+ #define PMX_PWM_3_PL_28_VAL (0x4 << 24)
+ #define PMX_PWM_2_PL_29_VAL (0x4 << 27)
+
+#define IP_SEL_PAD_30_39_REG 0x00B0
+ #define PMX_PL_30_31_MASK (0x3F << 0)
+ #define PMX_CAN1_PL_30_31_VAL (0)
+ #define PMX_PL_30_MASK (0x7 << 0)
+ #define PMX_PL_31_MASK (0x7 << 3)
+ #define PMX_PWM1_EXT_PL_30_VAL (0x4 << 0)
+ #define PMX_PWM0_EXT_PL_31_VAL (0x4 << 3)
+ #define PMX_UART1_ENH_PL_31_VAL (0x3 << 3)
+
+ #define PMX_PL_32_33_MASK (0x3F << 6)
+ #define PMX_CAN0_PL_32_33_VAL 0
+ #define PMX_UART1_ENH_PL_32_33_VAL ((0x3 << 6) | (0x3 << 9))
+ #define PMX_SSP2_PL_32_33_VAL ((0x4 << 6) | (0x4 << 9))
+
+ #define PMX_PL_34_MASK (0x7 << 12)
+ #define PMX_PWM2_PL_34_VAL 0
+ #define PMX_UART1_ENH_PL_34_VAL (0x2 << 12)
+ #define PMX_SSP2_PL_34_VAL (0x4 << 12)
+
+ #define PMX_PL_35_MASK (0x7 << 15)
+ #define PMX_I2S_REF_CLK_PL_35_VAL 0
+ #define PMX_UART1_ENH_PL_35_VAL (0x2 << 15)
+ #define PMX_SSP2_PL_35_VAL (0x4 << 15)
+
+ #define PMX_PL_36_MASK (0x7 << 18)
+ #define PMX_TOUCH_X_PL_36_VAL 0
+ #define PMX_UART1_ENH_PL_36_VAL (0x2 << 18)
+ #define PMX_SSP1_PL_36_VAL (0x4 << 18)
+
+ #define PMX_PL_37_38_MASK (0x3F << 21)
+ #define PMX_PWM0_1_PL_37_38_VAL 0
+ #define PMX_UART5_PL_37_38_VAL ((0x2 << 21) | (0x2 << 24))
+ #define PMX_SSP1_PL_37_38_VAL ((0x4 << 21) | (0x4 << 24))
+
+ #define PMX_PL_39_MASK (0x7 << 27)
+ #define PMX_I2S_PL_39_VAL 0
+ #define PMX_UART4_PL_39_VAL (0x2 << 27)
+ #define PMX_SSP1_PL_39_VAL (0x4 << 27)
+
+#define IP_SEL_PAD_40_49_REG 0x00B4
+ #define PMX_PL_40_MASK (0x7 << 0)
+ #define PMX_I2S_PL_40_VAL 0
+ #define PMX_UART4_PL_40_VAL (0x2 << 0)
+ #define PMX_PWM3_PL_40_VAL (0x4 << 0)
+
+ #define PMX_PL_41_42_MASK (0x3F << 3)
+ #define PMX_PL_41_MASK (0x7 << 3)
+ #define PMX_PL_42_MASK (0x7 << 6)
+ #define PMX_I2S_PL_41_42_VAL 0
+ #define PMX_UART3_PL_41_42_VAL ((0x2 << 3) | (0x2 << 6))
+ #define PMX_PWM2_PL_41_VAL (0x4 << 3)
+ #define PMX_PWM1_PL_42_VAL (0x4 << 6)
+
+ #define PMX_PL_43_MASK (0x7 << 9)
+ #define PMX_SDHCI_PL_43_VAL 0
+ #define PMX_UART1_ENH_PL_43_VAL (0x2 << 9)
+ #define PMX_PWM0_PL_43_VAL (0x4 << 9)
+
+ #define PMX_PL_44_45_MASK (0x3F << 12)
+ #define PMX_SDHCI_PL_44_45_VAL 0
+ #define PMX_UART1_ENH_PL_44_45_VAL ((0x2 << 12) | (0x2 << 15))
+ #define PMX_SSP2_PL_44_45_VAL ((0x4 << 12) | (0x4 << 15))
+
+ #define PMX_PL_46_47_MASK (0x3F << 18)
+ #define PMX_SDHCI_PL_46_47_VAL 0
+ #define PMX_FSMC_EMI_PL_46_47_VAL ((0x2 << 18) | (0x2 << 21))
+ #define PMX_SSP2_PL_46_47_VAL ((0x4 << 18) | (0x4 << 21))
+
+ #define PMX_PL_48_49_MASK (0x3F << 24)
+ #define PMX_SDHCI_PL_48_49_VAL 0
+ #define PMX_FSMC_EMI_PL_48_49_VAL ((0x2 << 24) | (0x2 << 27))
+ #define PMX_SSP1_PL_48_49_VAL ((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_50_59_REG 0x00B8
+ #define PMX_PL_50_51_MASK (0x3F << 0)
+ #define PMX_EMI_PL_50_51_VAL ((0x2 << 0) | (0x2 << 3))
+ #define PMX_SSP1_PL_50_51_VAL ((0x4 << 0) | (0x4 << 3))
+ #define PMX_PL_50_MASK (0x7 << 0)
+ #define PMX_PL_51_MASK (0x7 << 3)
+ #define PMX_SDHCI_PL_50_VAL 0
+ #define PMX_SDHCI_CD_PL_51_VAL 0
+
+ #define PMX_PL_52_53_MASK (0x3F << 6)
+ #define PMX_FSMC_PL_52_53_VAL 0
+ #define PMX_EMI_PL_52_53_VAL ((0x2 << 6) | (0x2 << 9))
+ #define PMX_UART3_PL_52_53_VAL ((0x4 << 6) | (0x4 << 9))
+
+ #define PMX_PL_54_55_56_MASK (0x1FF << 12)
+ #define PMX_FSMC_EMI_PL_54_55_56_VAL ((0x2 << 12) | (0x2 << 15) | (0x2 << 18))
+
+ #define PMX_PL_57_MASK (0x7 << 21)
+ #define PMX_FSMC_PL_57_VAL 0
+ #define PMX_PWM3_PL_57_VAL (0x4 << 21)
+
+ #define PMX_PL_58_59_MASK (0x3F << 24)
+ #define PMX_PL_58_MASK (0x7 << 24)
+ #define PMX_PL_59_MASK (0x7 << 27)
+ #define PMX_FSMC_EMI_PL_58_59_VAL ((0x2 << 24) | (0x2 << 27))
+ #define PMX_PWM2_PL_58_VAL (0x4 << 24)
+ #define PMX_PWM1_PL_59_VAL (0x4 << 27)
+
+#define IP_SEL_PAD_60_69_REG 0x00BC
+ #define PMX_PL_60_MASK (0x7 << 0)
+ #define PMX_FSMC_PL_60_VAL 0
+ #define PMX_PWM0_PL_60_VAL (0x4 << 0)
+
+ #define PMX_PL_61_TO_64_MASK (0xFFF << 3)
+ #define PMX_FSMC_PL_61_TO_64_VAL ((0x2 << 3) | (0x2 << 6) | (0x2 << 9) | (0x2 << 12))
+ #define PMX_SSP2_PL_61_TO_64_VAL ((0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12))
+
+ #define PMX_PL_65_TO_68_MASK (0xFFF << 15)
+ #define PMX_FSMC_PL_65_TO_68_VAL ((0x2 << 15) | (0x2 << 18) | (0x2 << 21) | (0x2 << 24))
+ #define PMX_SSP1_PL_65_TO_68_VAL ((0x4 << 15) | (0x4 << 18) | (0x4 << 21) | (0x4 << 24))
+
+ #define PMX_PL_69_MASK (0x7 << 27)
+ #define PMX_CLCD_PL_69_VAL (0)
+ #define PMX_EMI_PL_69_VAL (0x2 << 27)
+ #define PMX_SPP_PL_69_VAL (0x3 << 27)
+ #define PMX_UART5_PL_69_VAL (0x4 << 27)
+
+#define IP_SEL_PAD_70_79_REG 0x00C0
+ #define PMX_PL_70_MASK (0x7 << 0)
+ #define PMX_CLCD_PL_70_VAL (0)
+ #define PMX_FSMC_EMI_PL_70_VAL (0x2 << 0)
+ #define PMX_SPP_PL_70_VAL (0x3 << 0)
+ #define PMX_UART5_PL_70_VAL (0x4 << 0)
+
+ #define PMX_PL_71_72_MASK (0x3F << 3)
+ #define PMX_CLCD_PL_71_72_VAL (0)
+ #define PMX_FSMC_EMI_PL_71_72_VAL ((0x2 << 3) | (0x2 << 6))
+ #define PMX_SPP_PL_71_72_VAL ((0x3 << 3) | (0x3 << 6))
+ #define PMX_UART4_PL_71_72_VAL ((0x4 << 3) | (0x4 << 6))
+
+ #define PMX_PL_73_MASK (0x7 << 9)
+ #define PMX_CLCD_PL_73_VAL (0)
+ #define PMX_FSMC_EMI_PL_73_VAL (0x2 << 9)
+ #define PMX_SPP_PL_73_VAL (0x3 << 9)
+ #define PMX_UART3_PL_73_VAL (0x4 << 9)
+
+ #define PMX_PL_74_MASK (0x7 << 12)
+ #define PMX_CLCD_PL_74_VAL (0)
+ #define PMX_EMI_PL_74_VAL (0x2 << 12)
+ #define PMX_SPP_PL_74_VAL (0x3 << 12)
+ #define PMX_UART3_PL_74_VAL (0x4 << 12)
+
+ #define PMX_PL_75_76_MASK (0x3F << 15)
+ #define PMX_CLCD_PL_75_76_VAL (0)
+ #define PMX_EMI_PL_75_76_VAL ((0x2 << 15) | (0x2 << 18))
+ #define PMX_SPP_PL_75_76_VAL ((0x3 << 15) | (0x3 << 18))
+ #define PMX_I2C2_PL_75_76_VAL ((0x4 << 15) | (0x4 << 18))
+
+ #define PMX_PL_77_78_79_MASK (0x1FF << 21)
+ #define PMX_CLCD_PL_77_78_79_VAL (0)
+ #define PMX_EMI_PL_77_78_79_VAL ((0x2 << 21) | (0x2 << 24) | (0x2 << 27))
+ #define PMX_SPP_PL_77_78_79_VAL ((0x3 << 21) | (0x3 << 24) | (0x3 << 27))
+ #define PMX_RS485_PL_77_78_79_VAL ((0x4 << 21) | (0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_80_89_REG 0x00C4
+ #define PMX_PL_80_TO_85_MASK (0x3FFFF << 0)
+ #define PMX_CLCD_PL_80_TO_85_VAL 0
+ #define PMX_MII2_PL_80_TO_85_VAL ((0x1 << 0) | (0x1 << 3) | (0x1 << 6) | (0x1 << 9) | (0x1 << 12) | (0x1 << 15))
+ #define PMX_EMI_PL_80_TO_85_VAL ((0x2 << 0) | (0x2 << 3) | (0x2 << 6) | (0x2 << 9) | (0x2 << 12) | (0x2 << 15))
+ #define PMX_SPP_PL_80_TO_85_VAL ((0x3 << 0) | (0x3 << 3) | (0x3 << 6) | (0x3 << 9) | (0x3 << 12) | (0x3 << 15))
+ #define PMX_UART1_ENH_PL_80_TO_85_VAL ((0x4 << 0) | (0x4 << 3) | (0x4 << 6) | (0x4 << 9) | (0x4 << 12) | (0x4 << 15))
+
+ #define PMX_PL_86_87_MASK (0x3F << 18)
+ #define PMX_PL_86_MASK (0x7 << 18)
+ #define PMX_PL_87_MASK (0x7 << 21)
+ #define PMX_CLCD_PL_86_87_VAL 0
+ #define PMX_MII2_PL_86_87_VAL ((0x1 << 18) | (0x1 << 21))
+ #define PMX_EMI_PL_86_87_VAL ((0x2 << 18) | (0x2 << 21))
+ #define PMX_PWM3_PL_86_VAL (0x4 << 18)
+ #define PMX_PWM2_PL_87_VAL (0x4 << 21)
+
+ #define PMX_PL_88_89_MASK (0x3F << 24)
+ #define PMX_CLCD_PL_88_89_VAL 0
+ #define PMX_MII2_PL_88_89_VAL ((0x1 << 24) | (0x1 << 27))
+ #define PMX_EMI_PL_88_89_VAL ((0x2 << 24) | (0x2 << 27))
+ #define PMX_UART6_PL_88_89_VAL ((0x3 << 24) | (0x3 << 27))
+ #define PMX_PWM0_1_PL_88_89_VAL ((0x4 << 24) | (0x4 << 27))
+
+#define IP_SEL_PAD_90_99_REG 0x00C8
+ #define PMX_PL_90_91_MASK (0x3F << 0)
+ #define PMX_CLCD_PL_90_91_VAL 0
+ #define PMX_MII2_PL_90_91_VAL ((0x1 << 0) | (0x1 << 3))
+ #define PMX_EMI1_PL_90_91_VAL ((0x2 << 0) | (0x2 << 3))
+ #define PMX_UART5_PL_90_91_VAL ((0x3 << 0) | (0x3 << 3))
+ #define PMX_SSP2_PL_90_91_VAL ((0x4 << 0) | (0x4 << 3))
+
+ #define PMX_PL_92_93_MASK (0x3F << 6)
+ #define PMX_CLCD_PL_92_93_VAL 0
+ #define PMX_MII2_PL_92_93_VAL ((0x1 << 6) | (0x1 << 9))
+ #define PMX_EMI1_PL_92_93_VAL ((0x2 << 6) | (0x2 << 9))
+ #define PMX_UART4_PL_92_93_VAL ((0x3 << 6) | (0x3 << 9))
+ #define PMX_SSP2_PL_92_93_VAL ((0x4 << 6) | (0x4 << 9))
+
+ #define PMX_PL_94_95_MASK (0x3F << 12)
+ #define PMX_CLCD_PL_94_95_VAL 0
+ #define PMX_MII2_PL_94_95_VAL ((0x1 << 12) | (0x1 << 15))
+ #define PMX_EMI1_PL_94_95_VAL ((0x2 << 12) | (0x2 << 15))
+ #define PMX_UART3_PL_94_95_VAL ((0x3 << 12) | (0x3 << 15))
+ #define PMX_SSP1_PL_94_95_VAL ((0x4 << 12) | (0x4 << 15))
+
+ #define PMX_PL_96_97_MASK (0x3F << 18)
+ #define PMX_CLCD_PL_96_97_VAL 0
+ #define PMX_MII2_PL_96_97_VAL ((0x1 << 18) | (0x1 << 21))
+ #define PMX_EMI1_PL_96_97_VAL ((0x2 << 18) | (0x2 << 21))
+ #define PMX_I2C2_PL_96_97_VAL ((0x3 << 18) | (0x3 << 21))
+ #define PMX_SSP1_PL_96_97_VAL ((0x4 << 18) | (0x4 << 21))
+
+ #define PMX_PL_98_MASK (0x7 << 24)
+ #define PMX_CLCD_PL_98_VAL 0
+ #define PMX_I2C1_PL_98_VAL (0x2 << 24)
+ #define PMX_UART3_PL_98_VAL (0x4 << 24)
+
+ #define PMX_PL_99_MASK (0x7 << 27)
+ #define PMX_SDHCI_PL_99_VAL 0
+ #define PMX_I2C1_PL_99_VAL (0x2 << 27)
+ #define PMX_UART3_PL_99_VAL (0x4 << 27)
+
+#define IP_SEL_MIX_PAD_REG 0x00CC
+ #define PMX_PL_100_101_MASK (0x3F << 0)
+ #define PMX_SDHCI_PL_100_101_VAL 0
+ #define PMX_UART4_PL_100_101_VAL ((0x4 << 0) | (0x4 << 3))
+
+ #define PMX_SSP1_PORT_SEL_MASK (0x7 << 8)
+ #define PMX_SSP1_PORT_94_TO_97_VAL 0
+ #define PMX_SSP1_PORT_65_TO_68_VAL (0x1 << 8)
+ #define PMX_SSP1_PORT_48_TO_51_VAL (0x2 << 8)
+ #define PMX_SSP1_PORT_36_TO_39_VAL (0x3 << 8)
+ #define PMX_SSP1_PORT_17_TO_20_VAL (0x4 << 8)
+
+ #define PMX_SSP2_PORT_SEL_MASK (0x7 << 11)
+ #define PMX_SSP2_PORT_90_TO_93_VAL 0
+ #define PMX_SSP2_PORT_61_TO_64_VAL (0x1 << 11)
+ #define PMX_SSP2_PORT_44_TO_47_VAL (0x2 << 11)
+ #define PMX_SSP2_PORT_32_TO_35_VAL (0x3 << 11)
+ #define PMX_SSP2_PORT_13_TO_16_VAL (0x4 << 11)
+
+ #define PMX_UART1_ENH_PORT_SEL_MASK (0x3 << 14)
+ #define PMX_UART1_ENH_PORT_81_TO_85_VAL 0
+ #define PMX_UART1_ENH_PORT_44_45_34_36_VAL (0x1 << 14)
+ #define PMX_UART1_ENH_PORT_32_TO_34_36_VAL (0x2 << 14)
+ #define PMX_UART1_ENH_PORT_3_TO_5_7_VAL (0x3 << 14)
+
+ #define PMX_UART3_PORT_SEL_MASK (0x7 << 16)
+ #define PMX_UART3_PORT_94_VAL 0
+ #define PMX_UART3_PORT_73_VAL (0x1 << 16)
+ #define PMX_UART3_PORT_52_VAL (0x2 << 16)
+ #define PMX_UART3_PORT_41_VAL (0x3 << 16)
+ #define PMX_UART3_PORT_15_VAL (0x4 << 16)
+ #define PMX_UART3_PORT_8_VAL (0x5 << 16)
+ #define PMX_UART3_PORT_99_VAL (0x6 << 16)
+
+ #define PMX_UART4_PORT_SEL_MASK (0x7 << 19)
+ #define PMX_UART4_PORT_92_VAL 0
+ #define PMX_UART4_PORT_71_VAL (0x1 << 19)
+ #define PMX_UART4_PORT_39_VAL (0x2 << 19)
+ #define PMX_UART4_PORT_13_VAL (0x3 << 19)
+ #define PMX_UART4_PORT_6_VAL (0x4 << 19)
+ #define PMX_UART4_PORT_101_VAL (0x5 << 19)
+
+ #define PMX_UART5_PORT_SEL_MASK (0x3 << 22)
+ #define PMX_UART5_PORT_90_VAL 0
+ #define PMX_UART5_PORT_69_VAL (0x1 << 22)
+ #define PMX_UART5_PORT_37_VAL (0x2 << 22)
+ #define PMX_UART5_PORT_4_VAL (0x3 << 22)
+
+ #define PMX_UART6_PORT_SEL_MASK (0x1 << 24)
+ #define PMX_UART6_PORT_88_VAL 0
+ #define PMX_UART6_PORT_2_VAL (0x1 << 24)
+
+ #define PMX_I2C1_PORT_SEL_MASK (0x1 << 25)
+ #define PMX_I2C1_PORT_8_9_VAL 0
+ #define PMX_I2C1_PORT_98_99_VAL (0x1 << 25)
+
+ #define PMX_I2C2_PORT_SEL_MASK (0x3 << 26)
+ #define PMX_I2C2_PORT_96_97_VAL 0
+ #define PMX_I2C2_PORT_75_76_VAL (0x1 << 26)
+ #define PMX_I2C2_PORT_19_20_VAL (0x2 << 26)
+ #define PMX_I2C2_PORT_2_3_VAL (0x3 << 26)
+ #define PMX_I2C2_PORT_0_1_VAL (0x4 << 26)
+
+ #define PMX_SDHCI_CD_PORT_SEL_MASK (0x1 << 29)
+ #define PMX_SDHCI_CD_PORT_12_VAL 0
+ #define PMX_SDHCI_CD_PORT_51_VAL (0x1 << 29)
+
+/* Pad multiplexing for CLCD device */
+static const unsigned clcd_pins[] = { 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97 };
+static struct spear_muxreg clcd_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_69_MASK,
+ .val = PMX_CLCD_PL_69_VAL,
+ }, {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+ PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+ PMX_PL_77_78_79_MASK,
+ .val = PMX_CLCD_PL_70_VAL | PMX_CLCD_PL_71_72_VAL |
+ PMX_CLCD_PL_73_VAL | PMX_CLCD_PL_74_VAL |
+ PMX_CLCD_PL_75_76_VAL | PMX_CLCD_PL_77_78_79_VAL,
+ }, {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+ PMX_PL_88_89_MASK,
+ .val = PMX_CLCD_PL_80_TO_85_VAL | PMX_CLCD_PL_86_87_VAL |
+ PMX_CLCD_PL_88_89_VAL,
+ }, {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+ PMX_PL_94_95_MASK | PMX_PL_96_97_MASK | PMX_PL_98_MASK,
+ .val = PMX_CLCD_PL_90_91_VAL | PMX_CLCD_PL_92_93_VAL |
+ PMX_CLCD_PL_94_95_VAL | PMX_CLCD_PL_96_97_VAL |
+ PMX_CLCD_PL_98_VAL,
+ },
+};
+
+static struct spear_modemux clcd_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = clcd_muxreg,
+ .nmuxregs = ARRAY_SIZE(clcd_muxreg),
+ },
+};
+
+static struct spear_pingroup clcd_pingroup = {
+ .name = "clcd_grp",
+ .pins = clcd_pins,
+ .npins = ARRAY_SIZE(clcd_pins),
+ .modemuxs = clcd_modemux,
+ .nmodemuxs = ARRAY_SIZE(clcd_modemux),
+};
+
+static const char *const clcd_grps[] = { "clcd_grp" };
+static struct spear_function clcd_function = {
+ .name = "clcd",
+ .groups = clcd_grps,
+ .ngroups = ARRAY_SIZE(clcd_grps),
+};
+
+/* Pad multiplexing for EMI (Parallel NOR flash) device */
+static const unsigned emi_pins[] = { 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
+ 93, 94, 95, 96, 97 };
+static struct spear_muxreg emi_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg emi_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_46_47_MASK | PMX_PL_48_49_MASK,
+ .val = PMX_FSMC_EMI_PL_46_47_VAL | PMX_FSMC_EMI_PL_48_49_VAL,
+ }, {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_50_51_MASK | PMX_PL_52_53_MASK |
+ PMX_PL_54_55_56_MASK | PMX_PL_58_59_MASK,
+ .val = PMX_EMI_PL_50_51_VAL | PMX_EMI_PL_52_53_VAL |
+ PMX_FSMC_EMI_PL_54_55_56_VAL |
+ PMX_FSMC_EMI_PL_58_59_VAL,
+ }, {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_69_MASK,
+ .val = PMX_EMI_PL_69_VAL,
+ }, {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+ PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+ PMX_PL_77_78_79_MASK,
+ .val = PMX_FSMC_EMI_PL_70_VAL | PMX_FSMC_EMI_PL_71_72_VAL |
+ PMX_FSMC_EMI_PL_73_VAL | PMX_EMI_PL_74_VAL |
+ PMX_EMI_PL_75_76_VAL | PMX_EMI_PL_77_78_79_VAL,
+ }, {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+ PMX_PL_88_89_MASK,
+ .val = PMX_EMI_PL_80_TO_85_VAL | PMX_EMI_PL_86_87_VAL |
+ PMX_EMI_PL_88_89_VAL,
+ }, {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+ PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+ .val = PMX_EMI1_PL_90_91_VAL | PMX_EMI1_PL_92_93_VAL |
+ PMX_EMI1_PL_94_95_VAL | PMX_EMI1_PL_96_97_VAL,
+ }, {
+ .reg = EXT_CTRL_REG,
+ .mask = EMI_FSMC_DYNAMIC_MUX_MASK,
+ .val = EMI_FSMC_DYNAMIC_MUX_MASK,
+ },
+};
+
+static struct spear_modemux emi_modemux[] = {
+ {
+ .modes = AUTO_EXP_MODE | EXTENDED_MODE,
+ .muxregs = emi_muxreg,
+ .nmuxregs = ARRAY_SIZE(emi_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = emi_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(emi_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup emi_pingroup = {
+ .name = "emi_grp",
+ .pins = emi_pins,
+ .npins = ARRAY_SIZE(emi_pins),
+ .modemuxs = emi_modemux,
+ .nmodemuxs = ARRAY_SIZE(emi_modemux),
+};
+
+static const char *const emi_grps[] = { "emi_grp" };
+static struct spear_function emi_function = {
+ .name = "emi",
+ .groups = emi_grps,
+ .ngroups = ARRAY_SIZE(emi_grps),
+};
+
+/* Pad multiplexing for FSMC (NAND flash) device */
+static const unsigned fsmc_8bit_pins[] = { 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68 };
+static struct spear_muxreg fsmc_8bit_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_52_53_MASK | PMX_PL_54_55_56_MASK |
+ PMX_PL_57_MASK | PMX_PL_58_59_MASK,
+ .val = PMX_FSMC_PL_52_53_VAL | PMX_FSMC_EMI_PL_54_55_56_VAL |
+ PMX_FSMC_PL_57_VAL | PMX_FSMC_EMI_PL_58_59_VAL,
+ }, {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_60_MASK | PMX_PL_61_TO_64_MASK |
+ PMX_PL_65_TO_68_MASK,
+ .val = PMX_FSMC_PL_60_VAL | PMX_FSMC_PL_61_TO_64_VAL |
+ PMX_FSMC_PL_65_TO_68_VAL,
+ }, {
+ .reg = EXT_CTRL_REG,
+ .mask = EMI_FSMC_DYNAMIC_MUX_MASK,
+ .val = EMI_FSMC_DYNAMIC_MUX_MASK,
+ },
+};
+
+static struct spear_modemux fsmc_8bit_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = fsmc_8bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_8bit_pingroup = {
+ .name = "fsmc_8bit_grp",
+ .pins = fsmc_8bit_pins,
+ .npins = ARRAY_SIZE(fsmc_8bit_pins),
+ .modemuxs = fsmc_8bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_8bit_modemux),
+};
+
+static const unsigned fsmc_16bit_pins[] = { 46, 47, 48, 49, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73 };
+static struct spear_muxreg fsmc_16bit_autoexp_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg fsmc_16bit_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_46_47_MASK | PMX_PL_48_49_MASK,
+ .val = PMX_FSMC_EMI_PL_46_47_VAL | PMX_FSMC_EMI_PL_48_49_VAL,
+ }, {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK,
+ .val = PMX_FSMC_EMI_PL_70_VAL | PMX_FSMC_EMI_PL_71_72_VAL |
+ PMX_FSMC_EMI_PL_73_VAL,
+ }
+};
+
+static struct spear_modemux fsmc_16bit_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = fsmc_8bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_8bit_muxreg),
+ }, {
+ .modes = AUTO_EXP_MODE | EXTENDED_MODE,
+ .muxregs = fsmc_16bit_autoexp_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_16bit_autoexp_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = fsmc_16bit_muxreg,
+ .nmuxregs = ARRAY_SIZE(fsmc_16bit_muxreg),
+ },
+};
+
+static struct spear_pingroup fsmc_16bit_pingroup = {
+ .name = "fsmc_16bit_grp",
+ .pins = fsmc_16bit_pins,
+ .npins = ARRAY_SIZE(fsmc_16bit_pins),
+ .modemuxs = fsmc_16bit_modemux,
+ .nmodemuxs = ARRAY_SIZE(fsmc_16bit_modemux),
+};
+
+static const char *const fsmc_grps[] = { "fsmc_8bit_grp", "fsmc_16bit_grp" };
+static struct spear_function fsmc_function = {
+ .name = "fsmc",
+ .groups = fsmc_grps,
+ .ngroups = ARRAY_SIZE(fsmc_grps),
+};
+
+/* Pad multiplexing for SPP device */
+static const unsigned spp_pins[] = { 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85 };
+static struct spear_muxreg spp_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_69_MASK,
+ .val = PMX_SPP_PL_69_VAL,
+ }, {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_70_MASK | PMX_PL_71_72_MASK | PMX_PL_73_MASK |
+ PMX_PL_74_MASK | PMX_PL_75_76_MASK |
+ PMX_PL_77_78_79_MASK,
+ .val = PMX_SPP_PL_70_VAL | PMX_SPP_PL_71_72_VAL |
+ PMX_SPP_PL_73_VAL | PMX_SPP_PL_74_VAL |
+ PMX_SPP_PL_75_76_VAL | PMX_SPP_PL_77_78_79_VAL,
+ }, {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_80_TO_85_MASK,
+ .val = PMX_SPP_PL_80_TO_85_VAL,
+ },
+};
+
+static struct spear_modemux spp_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = spp_muxreg,
+ .nmuxregs = ARRAY_SIZE(spp_muxreg),
+ },
+};
+
+static struct spear_pingroup spp_pingroup = {
+ .name = "spp_grp",
+ .pins = spp_pins,
+ .npins = ARRAY_SIZE(spp_pins),
+ .modemuxs = spp_modemux,
+ .nmodemuxs = ARRAY_SIZE(spp_modemux),
+};
+
+static const char *const spp_grps[] = { "spp_grp" };
+static struct spear_function spp_function = {
+ .name = "spp",
+ .groups = spp_grps,
+ .ngroups = ARRAY_SIZE(spp_grps),
+};
+
+/* Pad multiplexing for SDHCI device */
+static const unsigned sdhci_led_pins[] = { 34 };
+static struct spear_muxreg sdhci_led_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg sdhci_led_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_34_MASK,
+ .val = PMX_PWM2_PL_34_VAL,
+ },
+};
+
+static struct spear_modemux sdhci_led_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+ .muxregs = sdhci_led_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_led_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = sdhci_led_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_led_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup sdhci_led_pingroup = {
+ .name = "sdhci_led_grp",
+ .pins = sdhci_led_pins,
+ .npins = ARRAY_SIZE(sdhci_led_pins),
+ .modemuxs = sdhci_led_modemux,
+ .nmodemuxs = ARRAY_SIZE(sdhci_led_modemux),
+};
+
+static const unsigned sdhci_cd_12_pins[] = { 12, 43, 44, 45, 46, 47, 48, 49,
+ 50};
+static const unsigned sdhci_cd_51_pins[] = { 43, 44, 45, 46, 47, 48, 49, 50, 51
+};
+static struct spear_muxreg sdhci_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg sdhci_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK | PMX_PL_46_47_MASK |
+ PMX_PL_48_49_MASK,
+ .val = PMX_SDHCI_PL_43_VAL | PMX_SDHCI_PL_44_45_VAL |
+ PMX_SDHCI_PL_46_47_VAL | PMX_SDHCI_PL_48_49_VAL,
+ }, {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_50_MASK,
+ .val = PMX_SDHCI_PL_50_VAL,
+ }, {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_99_MASK,
+ .val = PMX_SDHCI_PL_99_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_PL_100_101_MASK,
+ .val = PMX_SDHCI_PL_100_101_VAL,
+ },
+};
+
+static struct spear_muxreg sdhci_cd_12_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_12_MASK,
+ .val = PMX_SDHCI_CD_PL_12_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SDHCI_CD_PORT_SEL_MASK,
+ .val = PMX_SDHCI_CD_PORT_12_VAL,
+ },
+};
+
+static struct spear_muxreg sdhci_cd_51_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_51_MASK,
+ .val = PMX_SDHCI_CD_PL_51_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SDHCI_CD_PORT_SEL_MASK,
+ .val = PMX_SDHCI_CD_PORT_51_VAL,
+ },
+};
+
+#define pmx_sdhci_common_modemux \
+ { \
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | \
+ SMALL_PRINTERS_MODE | EXTENDED_MODE, \
+ .muxregs = sdhci_muxreg, \
+ .nmuxregs = ARRAY_SIZE(sdhci_muxreg), \
+ }, { \
+ .modes = EXTENDED_MODE, \
+ .muxregs = sdhci_ext_muxreg, \
+ .nmuxregs = ARRAY_SIZE(sdhci_ext_muxreg), \
+ }
+
+static struct spear_modemux sdhci_modemux[][3] = {
+ {
+ /* select pin 12 for cd */
+ pmx_sdhci_common_modemux,
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = sdhci_cd_12_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_cd_12_muxreg),
+ },
+ }, {
+ /* select pin 51 for cd */
+ pmx_sdhci_common_modemux,
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = sdhci_cd_51_muxreg,
+ .nmuxregs = ARRAY_SIZE(sdhci_cd_51_muxreg),
+ },
+ }
+};
+
+static struct spear_pingroup sdhci_pingroup[] = {
+ {
+ .name = "sdhci_cd_12_grp",
+ .pins = sdhci_cd_12_pins,
+ .npins = ARRAY_SIZE(sdhci_cd_12_pins),
+ .modemuxs = sdhci_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(sdhci_modemux[0]),
+ }, {
+ .name = "sdhci_cd_51_grp",
+ .pins = sdhci_cd_51_pins,
+ .npins = ARRAY_SIZE(sdhci_cd_51_pins),
+ .modemuxs = sdhci_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(sdhci_modemux[1]),
+ },
+};
+
+static const char *const sdhci_grps[] = { "sdhci_cd_12_grp", "sdhci_cd_51_grp",
+ "sdhci_led_grp" };
+
+static struct spear_function sdhci_function = {
+ .name = "sdhci",
+ .groups = sdhci_grps,
+ .ngroups = ARRAY_SIZE(sdhci_grps),
+};
+
+/* Pad multiplexing for I2S device */
+static const unsigned i2s_pins[] = { 35, 39, 40, 41, 42 };
+static struct spear_muxreg i2s_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ }, {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg i2s_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_35_MASK | PMX_PL_39_MASK,
+ .val = PMX_I2S_REF_CLK_PL_35_VAL | PMX_I2S_PL_39_VAL,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_40_MASK | PMX_PL_41_42_MASK,
+ .val = PMX_I2S_PL_40_VAL | PMX_I2S_PL_41_42_VAL,
+ },
+};
+
+static struct spear_modemux i2s_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+ .muxregs = i2s_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2s_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2s_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup i2s_pingroup = {
+ .name = "i2s_grp",
+ .pins = i2s_pins,
+ .npins = ARRAY_SIZE(i2s_pins),
+ .modemuxs = i2s_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2s_modemux),
+};
+
+static const char *const i2s_grps[] = { "i2s_grp" };
+static struct spear_function i2s_function = {
+ .name = "i2s",
+ .groups = i2s_grps,
+ .ngroups = ARRAY_SIZE(i2s_grps),
+};
+
+/* Pad multiplexing for UART1 device */
+static const unsigned uart1_pins[] = { 28, 29 };
+static struct spear_muxreg uart1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg uart1_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_28_29_MASK,
+ .val = PMX_UART1_PL_28_29_VAL,
+ },
+};
+
+static struct spear_modemux uart1_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+ | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = uart1_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart1_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup uart1_pingroup = {
+ .name = "uart1_grp",
+ .pins = uart1_pins,
+ .npins = ARRAY_SIZE(uart1_pins),
+ .modemuxs = uart1_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modemux),
+};
+
+static const char *const uart1_grps[] = { "uart1_grp" };
+static struct spear_function uart1_function = {
+ .name = "uart1",
+ .groups = uart1_grps,
+ .ngroups = ARRAY_SIZE(uart1_grps),
+};
+
+/* Pad multiplexing for UART1 Modem device */
+static const unsigned uart1_modem_2_to_7_pins[] = { 2, 3, 4, 5, 6, 7 };
+static const unsigned uart1_modem_31_to_36_pins[] = { 31, 32, 33, 34, 35, 36 };
+static const unsigned uart1_modem_34_to_45_pins[] = { 34, 35, 36, 43, 44, 45 };
+static const unsigned uart1_modem_80_to_85_pins[] = { 80, 81, 82, 83, 84, 85 };
+
+static struct spear_muxreg uart1_modem_ext_2_to_7_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MASK | PMX_I2C_MASK | PMX_SSP_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_2_3_MASK | PMX_PL_6_7_MASK,
+ .val = PMX_UART1_ENH_PL_2_3_VAL | PMX_UART1_ENH_PL_4_5_VAL |
+ PMX_UART1_ENH_PL_6_7_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+ .val = PMX_UART1_ENH_PORT_3_TO_5_7_VAL,
+ },
+};
+
+static struct spear_muxreg uart1_modem_31_to_36_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN3_MASK | PMX_GPIO_PIN4_MASK |
+ PMX_GPIO_PIN5_MASK | PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg uart1_modem_ext_31_to_36_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_31_MASK | PMX_PL_32_33_MASK | PMX_PL_34_MASK |
+ PMX_PL_35_MASK | PMX_PL_36_MASK,
+ .val = PMX_UART1_ENH_PL_31_VAL | PMX_UART1_ENH_PL_32_33_VAL |
+ PMX_UART1_ENH_PL_34_VAL | PMX_UART1_ENH_PL_35_VAL |
+ PMX_UART1_ENH_PL_36_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+ .val = PMX_UART1_ENH_PORT_32_TO_34_36_VAL,
+ },
+};
+
+static struct spear_muxreg uart1_modem_34_to_45_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK |
+ PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg uart1_modem_ext_34_to_45_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_34_MASK | PMX_PL_35_MASK | PMX_PL_36_MASK,
+ .val = PMX_UART1_ENH_PL_34_VAL | PMX_UART1_ENH_PL_35_VAL |
+ PMX_UART1_ENH_PL_36_VAL,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK,
+ .val = PMX_UART1_ENH_PL_43_VAL | PMX_UART1_ENH_PL_44_45_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+ .val = PMX_UART1_ENH_PORT_44_45_34_36_VAL,
+ },
+};
+
+static struct spear_muxreg uart1_modem_ext_80_to_85_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_80_TO_85_MASK,
+ .val = PMX_UART1_ENH_PL_80_TO_85_VAL,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_43_MASK | PMX_PL_44_45_MASK,
+ .val = PMX_UART1_ENH_PL_43_VAL | PMX_UART1_ENH_PL_44_45_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART1_ENH_PORT_SEL_MASK,
+ .val = PMX_UART1_ENH_PORT_81_TO_85_VAL,
+ },
+};
+
+static struct spear_modemux uart1_modem_2_to_7_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart1_modem_ext_2_to_7_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_modem_ext_2_to_7_muxreg),
+ },
+};
+
+static struct spear_modemux uart1_modem_31_to_36_modemux[] = {
+ {
+ .modes = SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = uart1_modem_31_to_36_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_modem_31_to_36_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart1_modem_ext_31_to_36_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_modem_ext_31_to_36_muxreg),
+ },
+};
+
+static struct spear_modemux uart1_modem_34_to_45_modemux[] = {
+ {
+ .modes = AUTO_EXP_MODE | EXTENDED_MODE,
+ .muxregs = uart1_modem_34_to_45_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_modem_34_to_45_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart1_modem_ext_34_to_45_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_modem_ext_34_to_45_muxreg),
+ },
+};
+
+static struct spear_modemux uart1_modem_80_to_85_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart1_modem_ext_80_to_85_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart1_modem_ext_80_to_85_muxreg),
+ },
+};
+
+static struct spear_pingroup uart1_modem_pingroup[] = {
+ {
+ .name = "uart1_modem_2_to_7_grp",
+ .pins = uart1_modem_2_to_7_pins,
+ .npins = ARRAY_SIZE(uart1_modem_2_to_7_pins),
+ .modemuxs = uart1_modem_2_to_7_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modem_2_to_7_modemux),
+ }, {
+ .name = "uart1_modem_31_to_36_grp",
+ .pins = uart1_modem_31_to_36_pins,
+ .npins = ARRAY_SIZE(uart1_modem_31_to_36_pins),
+ .modemuxs = uart1_modem_31_to_36_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modem_31_to_36_modemux),
+ }, {
+ .name = "uart1_modem_34_to_45_grp",
+ .pins = uart1_modem_34_to_45_pins,
+ .npins = ARRAY_SIZE(uart1_modem_34_to_45_pins),
+ .modemuxs = uart1_modem_34_to_45_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modem_34_to_45_modemux),
+ }, {
+ .name = "uart1_modem_80_to_85_grp",
+ .pins = uart1_modem_80_to_85_pins,
+ .npins = ARRAY_SIZE(uart1_modem_80_to_85_pins),
+ .modemuxs = uart1_modem_80_to_85_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart1_modem_80_to_85_modemux),
+ },
+};
+
+static const char *const uart1_modem_grps[] = { "uart1_modem_2_to_7_grp",
+ "uart1_modem_31_to_36_grp", "uart1_modem_34_to_45_grp",
+ "uart1_modem_80_to_85_grp" };
+static struct spear_function uart1_modem_function = {
+ .name = "uart1_modem",
+ .groups = uart1_modem_grps,
+ .ngroups = ARRAY_SIZE(uart1_modem_grps),
+};
+
+/* Pad multiplexing for UART2 device */
+static const unsigned uart2_pins[] = { 0, 1 };
+static struct spear_muxreg uart2_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg uart2_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_0_1_MASK,
+ .val = PMX_UART2_PL_0_1_VAL,
+ },
+};
+
+static struct spear_modemux uart2_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+ | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = uart2_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart2_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart2_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart2_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup uart2_pingroup = {
+ .name = "uart2_grp",
+ .pins = uart2_pins,
+ .npins = ARRAY_SIZE(uart2_pins),
+ .modemuxs = uart2_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart2_modemux),
+};
+
+static const char *const uart2_grps[] = { "uart2_grp" };
+static struct spear_function uart2_function = {
+ .name = "uart2",
+ .groups = uart2_grps,
+ .ngroups = ARRAY_SIZE(uart2_grps),
+};
+
+/* Pad multiplexing for uart3 device */
+static const unsigned uart3_pins[][2] = { { 8, 9 }, { 15, 16 }, { 41, 42 },
+ { 52, 53 }, { 73, 74 }, { 94, 95 }, { 98, 99 } };
+
+static struct spear_muxreg uart3_ext_8_9_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_8_9_MASK,
+ .val = PMX_UART3_PL_8_9_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_8_VAL,
+ },
+};
+
+static struct spear_muxreg uart3_ext_15_16_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_15_16_MASK,
+ .val = PMX_UART3_PL_15_16_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_15_VAL,
+ },
+};
+
+static struct spear_muxreg uart3_ext_41_42_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_41_42_MASK,
+ .val = PMX_UART3_PL_41_42_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_41_VAL,
+ },
+};
+
+static struct spear_muxreg uart3_ext_52_53_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_52_53_MASK,
+ .val = PMX_UART3_PL_52_53_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_52_VAL,
+ },
+};
+
+static struct spear_muxreg uart3_ext_73_74_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_73_MASK | PMX_PL_74_MASK,
+ .val = PMX_UART3_PL_73_VAL | PMX_UART3_PL_74_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_73_VAL,
+ },
+};
+
+static struct spear_muxreg uart3_ext_94_95_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_94_95_MASK,
+ .val = PMX_UART3_PL_94_95_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_94_VAL,
+ },
+};
+
+static struct spear_muxreg uart3_ext_98_99_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_98_MASK | PMX_PL_99_MASK,
+ .val = PMX_UART3_PL_98_VAL | PMX_UART3_PL_99_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART3_PORT_SEL_MASK,
+ .val = PMX_UART3_PORT_99_VAL,
+ },
+};
+
+static struct spear_modemux uart3_modemux[][1] = {
+ {
+ /* Select signals on pins 8_9 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_8_9_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_8_9_muxreg),
+ },
+ }, {
+ /* Select signals on pins 15_16 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_15_16_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_15_16_muxreg),
+ },
+ }, {
+ /* Select signals on pins 41_42 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_41_42_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_41_42_muxreg),
+ },
+ }, {
+ /* Select signals on pins 52_53 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_52_53_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_52_53_muxreg),
+ },
+ }, {
+ /* Select signals on pins 73_74 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_73_74_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_73_74_muxreg),
+ },
+ }, {
+ /* Select signals on pins 94_95 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_94_95_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_94_95_muxreg),
+ },
+ }, {
+ /* Select signals on pins 98_99 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart3_ext_98_99_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart3_ext_98_99_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup uart3_pingroup[] = {
+ {
+ .name = "uart3_8_9_grp",
+ .pins = uart3_pins[0],
+ .npins = ARRAY_SIZE(uart3_pins[0]),
+ .modemuxs = uart3_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[0]),
+ }, {
+ .name = "uart3_15_16_grp",
+ .pins = uart3_pins[1],
+ .npins = ARRAY_SIZE(uart3_pins[1]),
+ .modemuxs = uart3_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[1]),
+ }, {
+ .name = "uart3_41_42_grp",
+ .pins = uart3_pins[2],
+ .npins = ARRAY_SIZE(uart3_pins[2]),
+ .modemuxs = uart3_modemux[2],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[2]),
+ }, {
+ .name = "uart3_52_53_grp",
+ .pins = uart3_pins[3],
+ .npins = ARRAY_SIZE(uart3_pins[3]),
+ .modemuxs = uart3_modemux[3],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[3]),
+ }, {
+ .name = "uart3_73_74_grp",
+ .pins = uart3_pins[4],
+ .npins = ARRAY_SIZE(uart3_pins[4]),
+ .modemuxs = uart3_modemux[4],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[4]),
+ }, {
+ .name = "uart3_94_95_grp",
+ .pins = uart3_pins[5],
+ .npins = ARRAY_SIZE(uart3_pins[5]),
+ .modemuxs = uart3_modemux[5],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[5]),
+ }, {
+ .name = "uart3_98_99_grp",
+ .pins = uart3_pins[6],
+ .npins = ARRAY_SIZE(uart3_pins[6]),
+ .modemuxs = uart3_modemux[6],
+ .nmodemuxs = ARRAY_SIZE(uart3_modemux[6]),
+ },
+};
+
+static const char *const uart3_grps[] = { "uart3_8_9_grp", "uart3_15_16_grp",
+ "uart3_41_42_grp", "uart3_52_53_grp", "uart3_73_74_grp",
+ "uart3_94_95_grp", "uart3_98_99_grp" };
+
+static struct spear_function uart3_function = {
+ .name = "uart3",
+ .groups = uart3_grps,
+ .ngroups = ARRAY_SIZE(uart3_grps),
+};
+
+/* Pad multiplexing for uart4 device */
+static const unsigned uart4_pins[][2] = { { 6, 7 }, { 13, 14 }, { 39, 40 },
+ { 71, 72 }, { 92, 93 }, { 100, 101 } };
+
+static struct spear_muxreg uart4_ext_6_7_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_6_7_MASK,
+ .val = PMX_UART4_PL_6_7_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART4_PORT_SEL_MASK,
+ .val = PMX_UART4_PORT_6_VAL,
+ },
+};
+
+static struct spear_muxreg uart4_ext_13_14_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_13_14_MASK,
+ .val = PMX_UART4_PL_13_14_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART4_PORT_SEL_MASK,
+ .val = PMX_UART4_PORT_13_VAL,
+ },
+};
+
+static struct spear_muxreg uart4_ext_39_40_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_39_MASK,
+ .val = PMX_UART4_PL_39_VAL,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_40_MASK,
+ .val = PMX_UART4_PL_40_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART4_PORT_SEL_MASK,
+ .val = PMX_UART4_PORT_39_VAL,
+ },
+};
+
+static struct spear_muxreg uart4_ext_71_72_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_71_72_MASK,
+ .val = PMX_UART4_PL_71_72_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART4_PORT_SEL_MASK,
+ .val = PMX_UART4_PORT_71_VAL,
+ },
+};
+
+static struct spear_muxreg uart4_ext_92_93_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_92_93_MASK,
+ .val = PMX_UART4_PL_92_93_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART4_PORT_SEL_MASK,
+ .val = PMX_UART4_PORT_92_VAL,
+ },
+};
+
+static struct spear_muxreg uart4_ext_100_101_muxreg[] = {
+ {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_PL_100_101_MASK |
+ PMX_UART4_PORT_SEL_MASK,
+ .val = PMX_UART4_PL_100_101_VAL |
+ PMX_UART4_PORT_101_VAL,
+ },
+};
+
+static struct spear_modemux uart4_modemux[][1] = {
+ {
+ /* Select signals on pins 6_7 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart4_ext_6_7_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_ext_6_7_muxreg),
+ },
+ }, {
+ /* Select signals on pins 13_14 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart4_ext_13_14_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_ext_13_14_muxreg),
+ },
+ }, {
+ /* Select signals on pins 39_40 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart4_ext_39_40_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_ext_39_40_muxreg),
+ },
+ }, {
+ /* Select signals on pins 71_72 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart4_ext_71_72_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_ext_71_72_muxreg),
+ },
+ }, {
+ /* Select signals on pins 92_93 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart4_ext_92_93_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_ext_92_93_muxreg),
+ },
+ }, {
+ /* Select signals on pins 100_101_ */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart4_ext_100_101_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart4_ext_100_101_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup uart4_pingroup[] = {
+ {
+ .name = "uart4_6_7_grp",
+ .pins = uart4_pins[0],
+ .npins = ARRAY_SIZE(uart4_pins[0]),
+ .modemuxs = uart4_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux[0]),
+ }, {
+ .name = "uart4_13_14_grp",
+ .pins = uart4_pins[1],
+ .npins = ARRAY_SIZE(uart4_pins[1]),
+ .modemuxs = uart4_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux[1]),
+ }, {
+ .name = "uart4_39_40_grp",
+ .pins = uart4_pins[2],
+ .npins = ARRAY_SIZE(uart4_pins[2]),
+ .modemuxs = uart4_modemux[2],
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux[2]),
+ }, {
+ .name = "uart4_71_72_grp",
+ .pins = uart4_pins[3],
+ .npins = ARRAY_SIZE(uart4_pins[3]),
+ .modemuxs = uart4_modemux[3],
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux[3]),
+ }, {
+ .name = "uart4_92_93_grp",
+ .pins = uart4_pins[4],
+ .npins = ARRAY_SIZE(uart4_pins[4]),
+ .modemuxs = uart4_modemux[4],
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux[4]),
+ }, {
+ .name = "uart4_100_101_grp",
+ .pins = uart4_pins[5],
+ .npins = ARRAY_SIZE(uart4_pins[5]),
+ .modemuxs = uart4_modemux[5],
+ .nmodemuxs = ARRAY_SIZE(uart4_modemux[5]),
+ },
+};
+
+static const char *const uart4_grps[] = { "uart4_6_7_grp", "uart4_13_14_grp",
+ "uart4_39_40_grp", "uart4_71_72_grp", "uart4_92_93_grp",
+ "uart4_100_101_grp" };
+
+static struct spear_function uart4_function = {
+ .name = "uart4",
+ .groups = uart4_grps,
+ .ngroups = ARRAY_SIZE(uart4_grps),
+};
+
+/* Pad multiplexing for uart5 device */
+static const unsigned uart5_pins[][2] = { { 4, 5 }, { 37, 38 }, { 69, 70 },
+ { 90, 91 } };
+
+static struct spear_muxreg uart5_ext_4_5_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_I2C_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_4_5_MASK,
+ .val = PMX_UART5_PL_4_5_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART5_PORT_SEL_MASK,
+ .val = PMX_UART5_PORT_4_VAL,
+ },
+};
+
+static struct spear_muxreg uart5_ext_37_38_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_37_38_MASK,
+ .val = PMX_UART5_PL_37_38_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART5_PORT_SEL_MASK,
+ .val = PMX_UART5_PORT_37_VAL,
+ },
+};
+
+static struct spear_muxreg uart5_ext_69_70_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_69_MASK,
+ .val = PMX_UART5_PL_69_VAL,
+ }, {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_70_MASK,
+ .val = PMX_UART5_PL_70_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART5_PORT_SEL_MASK,
+ .val = PMX_UART5_PORT_69_VAL,
+ },
+};
+
+static struct spear_muxreg uart5_ext_90_91_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_90_91_MASK,
+ .val = PMX_UART5_PL_90_91_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART5_PORT_SEL_MASK,
+ .val = PMX_UART5_PORT_90_VAL,
+ },
+};
+
+static struct spear_modemux uart5_modemux[][1] = {
+ {
+ /* Select signals on pins 4_5 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart5_ext_4_5_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_ext_4_5_muxreg),
+ },
+ }, {
+ /* Select signals on pins 37_38 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart5_ext_37_38_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_ext_37_38_muxreg),
+ },
+ }, {
+ /* Select signals on pins 69_70 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart5_ext_69_70_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_ext_69_70_muxreg),
+ },
+ }, {
+ /* Select signals on pins 90_91 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart5_ext_90_91_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart5_ext_90_91_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup uart5_pingroup[] = {
+ {
+ .name = "uart5_4_5_grp",
+ .pins = uart5_pins[0],
+ .npins = ARRAY_SIZE(uart5_pins[0]),
+ .modemuxs = uart5_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux[0]),
+ }, {
+ .name = "uart5_37_38_grp",
+ .pins = uart5_pins[1],
+ .npins = ARRAY_SIZE(uart5_pins[1]),
+ .modemuxs = uart5_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux[1]),
+ }, {
+ .name = "uart5_69_70_grp",
+ .pins = uart5_pins[2],
+ .npins = ARRAY_SIZE(uart5_pins[2]),
+ .modemuxs = uart5_modemux[2],
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux[2]),
+ }, {
+ .name = "uart5_90_91_grp",
+ .pins = uart5_pins[3],
+ .npins = ARRAY_SIZE(uart5_pins[3]),
+ .modemuxs = uart5_modemux[3],
+ .nmodemuxs = ARRAY_SIZE(uart5_modemux[3]),
+ },
+};
+
+static const char *const uart5_grps[] = { "uart5_4_5_grp", "uart5_37_38_grp",
+ "uart5_69_70_grp", "uart5_90_91_grp" };
+static struct spear_function uart5_function = {
+ .name = "uart5",
+ .groups = uart5_grps,
+ .ngroups = ARRAY_SIZE(uart5_grps),
+};
+
+/* Pad multiplexing for uart6 device */
+static const unsigned uart6_pins[][2] = { { 2, 3 }, { 88, 89 } };
+static struct spear_muxreg uart6_ext_2_3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_2_3_MASK,
+ .val = PMX_UART6_PL_2_3_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART6_PORT_SEL_MASK,
+ .val = PMX_UART6_PORT_2_VAL,
+ },
+};
+
+static struct spear_muxreg uart6_ext_88_89_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_88_89_MASK,
+ .val = PMX_UART6_PL_88_89_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_UART6_PORT_SEL_MASK,
+ .val = PMX_UART6_PORT_88_VAL,
+ },
+};
+
+static struct spear_modemux uart6_modemux[][1] = {
+ {
+ /* Select signals on pins 2_3 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart6_ext_2_3_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart6_ext_2_3_muxreg),
+ },
+ }, {
+ /* Select signals on pins 88_89 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = uart6_ext_88_89_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart6_ext_88_89_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup uart6_pingroup[] = {
+ {
+ .name = "uart6_2_3_grp",
+ .pins = uart6_pins[0],
+ .npins = ARRAY_SIZE(uart6_pins[0]),
+ .modemuxs = uart6_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(uart6_modemux[0]),
+ }, {
+ .name = "uart6_88_89_grp",
+ .pins = uart6_pins[1],
+ .npins = ARRAY_SIZE(uart6_pins[1]),
+ .modemuxs = uart6_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(uart6_modemux[1]),
+ },
+};
+
+static const char *const uart6_grps[] = { "uart6_2_3_grp", "uart6_88_89_grp" };
+static struct spear_function uart6_function = {
+ .name = "uart6",
+ .groups = uart6_grps,
+ .ngroups = ARRAY_SIZE(uart6_grps),
+};
+
+/* UART - RS485 pmx */
+static const unsigned rs485_pins[] = { 77, 78, 79 };
+static struct spear_muxreg rs485_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_77_78_79_MASK,
+ .val = PMX_RS485_PL_77_78_79_VAL,
+ },
+};
+
+static struct spear_modemux rs485_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = rs485_muxreg,
+ .nmuxregs = ARRAY_SIZE(rs485_muxreg),
+ },
+};
+
+static struct spear_pingroup rs485_pingroup = {
+ .name = "rs485_grp",
+ .pins = rs485_pins,
+ .npins = ARRAY_SIZE(rs485_pins),
+ .modemuxs = rs485_modemux,
+ .nmodemuxs = ARRAY_SIZE(rs485_modemux),
+};
+
+static const char *const rs485_grps[] = { "rs485_grp" };
+static struct spear_function rs485_function = {
+ .name = "rs485",
+ .groups = rs485_grps,
+ .ngroups = ARRAY_SIZE(rs485_grps),
+};
+
+/* Pad multiplexing for Touchscreen device */
+static const unsigned touchscreen_pins[] = { 5, 36 };
+static struct spear_muxreg touchscreen_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_I2C_MASK | PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg touchscreen_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_5_MASK,
+ .val = PMX_TOUCH_Y_PL_5_VAL,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_36_MASK,
+ .val = PMX_TOUCH_X_PL_36_VAL,
+ },
+};
+
+static struct spear_modemux touchscreen_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | EXTENDED_MODE,
+ .muxregs = touchscreen_muxreg,
+ .nmuxregs = ARRAY_SIZE(touchscreen_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = touchscreen_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(touchscreen_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup touchscreen_pingroup = {
+ .name = "touchscreen_grp",
+ .pins = touchscreen_pins,
+ .npins = ARRAY_SIZE(touchscreen_pins),
+ .modemuxs = touchscreen_modemux,
+ .nmodemuxs = ARRAY_SIZE(touchscreen_modemux),
+};
+
+static const char *const touchscreen_grps[] = { "touchscreen_grp" };
+static struct spear_function touchscreen_function = {
+ .name = "touchscreen",
+ .groups = touchscreen_grps,
+ .ngroups = ARRAY_SIZE(touchscreen_grps),
+};
+
+/* Pad multiplexing for CAN device */
+static const unsigned can0_pins[] = { 32, 33 };
+static struct spear_muxreg can0_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg can0_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_32_33_MASK,
+ .val = PMX_CAN0_PL_32_33_VAL,
+ },
+};
+
+static struct spear_modemux can0_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+ | EXTENDED_MODE,
+ .muxregs = can0_muxreg,
+ .nmuxregs = ARRAY_SIZE(can0_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = can0_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(can0_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup can0_pingroup = {
+ .name = "can0_grp",
+ .pins = can0_pins,
+ .npins = ARRAY_SIZE(can0_pins),
+ .modemuxs = can0_modemux,
+ .nmodemuxs = ARRAY_SIZE(can0_modemux),
+};
+
+static const char *const can0_grps[] = { "can0_grp" };
+static struct spear_function can0_function = {
+ .name = "can0",
+ .groups = can0_grps,
+ .ngroups = ARRAY_SIZE(can0_grps),
+};
+
+static const unsigned can1_pins[] = { 30, 31 };
+static struct spear_muxreg can1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg can1_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_30_31_MASK,
+ .val = PMX_CAN1_PL_30_31_VAL,
+ },
+};
+
+static struct spear_modemux can1_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE
+ | EXTENDED_MODE,
+ .muxregs = can1_muxreg,
+ .nmuxregs = ARRAY_SIZE(can1_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = can1_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(can1_ext_muxreg),
+ },
+};
+
+static struct spear_pingroup can1_pingroup = {
+ .name = "can1_grp",
+ .pins = can1_pins,
+ .npins = ARRAY_SIZE(can1_pins),
+ .modemuxs = can1_modemux,
+ .nmodemuxs = ARRAY_SIZE(can1_modemux),
+};
+
+static const char *const can1_grps[] = { "can1_grp" };
+static struct spear_function can1_function = {
+ .name = "can1",
+ .groups = can1_grps,
+ .ngroups = ARRAY_SIZE(can1_grps),
+};
+
+/* Pad multiplexing for PWM0_1 device */
+static const unsigned pwm0_1_pins[][2] = { { 37, 38 }, { 14, 15 }, { 8, 9 },
+ { 30, 31 }, { 42, 43 }, { 59, 60 }, { 88, 89 } };
+
+static struct spear_muxreg pwm0_1_pin_8_9_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_8_9_MASK,
+ .val = PMX_PWM_0_1_PL_8_9_VAL,
+ },
+};
+
+static struct spear_muxreg pwm0_1_autoexpsmallpri_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg pwm0_1_pin_14_15_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_14_MASK | PMX_PL_15_MASK,
+ .val = PMX_PWM1_PL_14_VAL | PMX_PWM0_PL_15_VAL,
+ },
+};
+
+static struct spear_muxreg pwm0_1_pin_30_31_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_30_MASK | PMX_PL_31_MASK,
+ .val = PMX_PWM1_EXT_PL_30_VAL | PMX_PWM0_EXT_PL_31_VAL,
+ },
+};
+
+static struct spear_muxreg pwm0_1_net_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg pwm0_1_pin_37_38_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_37_38_MASK,
+ .val = PMX_PWM0_1_PL_37_38_VAL,
+ },
+};
+
+static struct spear_muxreg pwm0_1_pin_42_43_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK | PMX_TIMER_0_1_MASK ,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_42_MASK | PMX_PL_43_MASK,
+ .val = PMX_PWM1_PL_42_VAL |
+ PMX_PWM0_PL_43_VAL,
+ },
+};
+
+static struct spear_muxreg pwm0_1_pin_59_60_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_59_MASK,
+ .val = PMX_PWM1_PL_59_VAL,
+ }, {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_60_MASK,
+ .val = PMX_PWM0_PL_60_VAL,
+ },
+};
+
+static struct spear_muxreg pwm0_1_pin_88_89_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_88_89_MASK,
+ .val = PMX_PWM0_1_PL_88_89_VAL,
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_8_9_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_8_9_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_8_9_muxreg),
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_14_15_modemux[] = {
+ {
+ .modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = pwm0_1_autoexpsmallpri_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_autoexpsmallpri_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_14_15_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_14_15_muxreg),
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_30_31_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_30_31_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_30_31_muxreg),
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_37_38_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+ .muxregs = pwm0_1_net_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_net_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_37_38_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_37_38_muxreg),
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_42_43_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_42_43_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_42_43_muxreg),
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_59_60_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_59_60_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_59_60_muxreg),
+ },
+};
+
+static struct spear_modemux pwm0_1_pin_88_89_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm0_1_pin_88_89_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm0_1_pin_88_89_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm0_1_pingroup[] = {
+ {
+ .name = "pwm0_1_pin_8_9_grp",
+ .pins = pwm0_1_pins[0],
+ .npins = ARRAY_SIZE(pwm0_1_pins[0]),
+ .modemuxs = pwm0_1_pin_8_9_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_8_9_modemux),
+ }, {
+ .name = "pwm0_1_pin_14_15_grp",
+ .pins = pwm0_1_pins[1],
+ .npins = ARRAY_SIZE(pwm0_1_pins[1]),
+ .modemuxs = pwm0_1_pin_14_15_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_14_15_modemux),
+ }, {
+ .name = "pwm0_1_pin_30_31_grp",
+ .pins = pwm0_1_pins[2],
+ .npins = ARRAY_SIZE(pwm0_1_pins[2]),
+ .modemuxs = pwm0_1_pin_30_31_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_30_31_modemux),
+ }, {
+ .name = "pwm0_1_pin_37_38_grp",
+ .pins = pwm0_1_pins[3],
+ .npins = ARRAY_SIZE(pwm0_1_pins[3]),
+ .modemuxs = pwm0_1_pin_37_38_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_37_38_modemux),
+ }, {
+ .name = "pwm0_1_pin_42_43_grp",
+ .pins = pwm0_1_pins[4],
+ .npins = ARRAY_SIZE(pwm0_1_pins[4]),
+ .modemuxs = pwm0_1_pin_42_43_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_42_43_modemux),
+ }, {
+ .name = "pwm0_1_pin_59_60_grp",
+ .pins = pwm0_1_pins[5],
+ .npins = ARRAY_SIZE(pwm0_1_pins[5]),
+ .modemuxs = pwm0_1_pin_59_60_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_59_60_modemux),
+ }, {
+ .name = "pwm0_1_pin_88_89_grp",
+ .pins = pwm0_1_pins[6],
+ .npins = ARRAY_SIZE(pwm0_1_pins[6]),
+ .modemuxs = pwm0_1_pin_88_89_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm0_1_pin_88_89_modemux),
+ },
+};
+
+static const char *const pwm0_1_grps[] = { "pwm0_1_pin_8_9_grp",
+ "pwm0_1_pin_14_15_grp", "pwm0_1_pin_30_31_grp", "pwm0_1_pin_37_38_grp",
+ "pwm0_1_pin_42_43_grp", "pwm0_1_pin_59_60_grp", "pwm0_1_pin_88_89_grp"
+};
+
+static struct spear_function pwm0_1_function = {
+ .name = "pwm0_1",
+ .groups = pwm0_1_grps,
+ .ngroups = ARRAY_SIZE(pwm0_1_grps),
+};
+
+/* Pad multiplexing for PWM2 device */
+static const unsigned pwm2_pins[][1] = { { 7 }, { 13 }, { 29 }, { 34 }, { 41 },
+ { 58 }, { 87 } };
+static struct spear_muxreg pwm2_net_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_7_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_7_MASK,
+ .val = PMX_PWM_2_PL_7_VAL,
+ },
+};
+
+static struct spear_muxreg pwm2_autoexpsmallpri_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_13_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_13_MASK,
+ .val = PMX_PWM2_PL_13_VAL,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_29_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN1_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_29_MASK,
+ .val = PMX_PWM_2_PL_29_VAL,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_34_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_34_MASK,
+ .val = PMX_PWM2_PL_34_VAL,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_41_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_41_MASK,
+ .val = PMX_PWM2_PL_41_VAL,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_58_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_58_MASK,
+ .val = PMX_PWM2_PL_58_VAL,
+ },
+};
+
+static struct spear_muxreg pwm2_pin_87_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_87_MASK,
+ .val = PMX_PWM2_PL_87_VAL,
+ },
+};
+
+static struct spear_modemux pwm2_pin_7_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | EXTENDED_MODE,
+ .muxregs = pwm2_net_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_net_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_7_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_7_muxreg),
+ },
+};
+static struct spear_modemux pwm2_pin_13_modemux[] = {
+ {
+ .modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = pwm2_autoexpsmallpri_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_autoexpsmallpri_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_13_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_13_muxreg),
+ },
+};
+static struct spear_modemux pwm2_pin_29_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_29_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_29_muxreg),
+ },
+};
+static struct spear_modemux pwm2_pin_34_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_34_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_34_muxreg),
+ },
+};
+
+static struct spear_modemux pwm2_pin_41_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_41_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_41_muxreg),
+ },
+};
+
+static struct spear_modemux pwm2_pin_58_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_58_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_58_muxreg),
+ },
+};
+
+static struct spear_modemux pwm2_pin_87_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm2_pin_87_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm2_pin_87_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm2_pingroup[] = {
+ {
+ .name = "pwm2_pin_7_grp",
+ .pins = pwm2_pins[0],
+ .npins = ARRAY_SIZE(pwm2_pins[0]),
+ .modemuxs = pwm2_pin_7_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_7_modemux),
+ }, {
+ .name = "pwm2_pin_13_grp",
+ .pins = pwm2_pins[1],
+ .npins = ARRAY_SIZE(pwm2_pins[1]),
+ .modemuxs = pwm2_pin_13_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_13_modemux),
+ }, {
+ .name = "pwm2_pin_29_grp",
+ .pins = pwm2_pins[2],
+ .npins = ARRAY_SIZE(pwm2_pins[2]),
+ .modemuxs = pwm2_pin_29_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_29_modemux),
+ }, {
+ .name = "pwm2_pin_34_grp",
+ .pins = pwm2_pins[3],
+ .npins = ARRAY_SIZE(pwm2_pins[3]),
+ .modemuxs = pwm2_pin_34_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_34_modemux),
+ }, {
+ .name = "pwm2_pin_41_grp",
+ .pins = pwm2_pins[4],
+ .npins = ARRAY_SIZE(pwm2_pins[4]),
+ .modemuxs = pwm2_pin_41_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_41_modemux),
+ }, {
+ .name = "pwm2_pin_58_grp",
+ .pins = pwm2_pins[5],
+ .npins = ARRAY_SIZE(pwm2_pins[5]),
+ .modemuxs = pwm2_pin_58_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_58_modemux),
+ }, {
+ .name = "pwm2_pin_87_grp",
+ .pins = pwm2_pins[6],
+ .npins = ARRAY_SIZE(pwm2_pins[6]),
+ .modemuxs = pwm2_pin_87_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm2_pin_87_modemux),
+ },
+};
+
+static const char *const pwm2_grps[] = { "pwm2_pin_7_grp", "pwm2_pin_13_grp",
+ "pwm2_pin_29_grp", "pwm2_pin_34_grp", "pwm2_pin_41_grp",
+ "pwm2_pin_58_grp", "pwm2_pin_87_grp" };
+static struct spear_function pwm2_function = {
+ .name = "pwm2",
+ .groups = pwm2_grps,
+ .ngroups = ARRAY_SIZE(pwm2_grps),
+};
+
+/* Pad multiplexing for PWM3 device */
+static const unsigned pwm3_pins[][1] = { { 6 }, { 12 }, { 28 }, { 40 }, { 57 },
+ { 86 } };
+static struct spear_muxreg pwm3_pin_6_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_6_MASK,
+ .val = PMX_PWM_3_PL_6_VAL,
+ },
+};
+
+static struct spear_muxreg pwm3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg pwm3_pin_12_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_12_MASK,
+ .val = PMX_PWM3_PL_12_VAL,
+ },
+};
+
+static struct spear_muxreg pwm3_pin_28_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_GPIO_PIN0_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_28_MASK,
+ .val = PMX_PWM_3_PL_28_VAL,
+ },
+};
+
+static struct spear_muxreg pwm3_pin_40_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_40_MASK,
+ .val = PMX_PWM3_PL_40_VAL,
+ },
+};
+
+static struct spear_muxreg pwm3_pin_57_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_57_MASK,
+ .val = PMX_PWM3_PL_57_VAL,
+ },
+};
+
+static struct spear_muxreg pwm3_pin_86_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_86_MASK,
+ .val = PMX_PWM3_PL_86_VAL,
+ },
+};
+
+static struct spear_modemux pwm3_pin_6_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm3_pin_6_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_pin_6_muxreg),
+ },
+};
+
+static struct spear_modemux pwm3_pin_12_modemux[] = {
+ {
+ .modes = AUTO_EXP_MODE | SMALL_PRINTERS_MODE |
+ AUTO_NET_SMII_MODE | EXTENDED_MODE,
+ .muxregs = pwm3_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm3_pin_12_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_pin_12_muxreg),
+ },
+};
+
+static struct spear_modemux pwm3_pin_28_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm3_pin_28_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_pin_28_muxreg),
+ },
+};
+
+static struct spear_modemux pwm3_pin_40_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm3_pin_40_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_pin_40_muxreg),
+ },
+};
+
+static struct spear_modemux pwm3_pin_57_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm3_pin_57_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_pin_57_muxreg),
+ },
+};
+
+static struct spear_modemux pwm3_pin_86_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = pwm3_pin_86_muxreg,
+ .nmuxregs = ARRAY_SIZE(pwm3_pin_86_muxreg),
+ },
+};
+
+static struct spear_pingroup pwm3_pingroup[] = {
+ {
+ .name = "pwm3_pin_6_grp",
+ .pins = pwm3_pins[0],
+ .npins = ARRAY_SIZE(pwm3_pins[0]),
+ .modemuxs = pwm3_pin_6_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_pin_6_modemux),
+ }, {
+ .name = "pwm3_pin_12_grp",
+ .pins = pwm3_pins[1],
+ .npins = ARRAY_SIZE(pwm3_pins[1]),
+ .modemuxs = pwm3_pin_12_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_pin_12_modemux),
+ }, {
+ .name = "pwm3_pin_28_grp",
+ .pins = pwm3_pins[2],
+ .npins = ARRAY_SIZE(pwm3_pins[2]),
+ .modemuxs = pwm3_pin_28_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_pin_28_modemux),
+ }, {
+ .name = "pwm3_pin_40_grp",
+ .pins = pwm3_pins[3],
+ .npins = ARRAY_SIZE(pwm3_pins[3]),
+ .modemuxs = pwm3_pin_40_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_pin_40_modemux),
+ }, {
+ .name = "pwm3_pin_57_grp",
+ .pins = pwm3_pins[4],
+ .npins = ARRAY_SIZE(pwm3_pins[4]),
+ .modemuxs = pwm3_pin_57_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_pin_57_modemux),
+ }, {
+ .name = "pwm3_pin_86_grp",
+ .pins = pwm3_pins[5],
+ .npins = ARRAY_SIZE(pwm3_pins[5]),
+ .modemuxs = pwm3_pin_86_modemux,
+ .nmodemuxs = ARRAY_SIZE(pwm3_pin_86_modemux),
+ },
+};
+
+static const char *const pwm3_grps[] = { "pwm3_pin_6_grp", "pwm3_pin_12_grp",
+ "pwm3_pin_28_grp", "pwm3_pin_40_grp", "pwm3_pin_57_grp",
+ "pwm3_pin_86_grp" };
+static struct spear_function pwm3_function = {
+ .name = "pwm3",
+ .groups = pwm3_grps,
+ .ngroups = ARRAY_SIZE(pwm3_grps),
+};
+
+/* Pad multiplexing for SSP1 device */
+static const unsigned ssp1_pins[][2] = { { 17, 20 }, { 36, 39 }, { 48, 51 },
+ { 65, 68 }, { 94, 97 } };
+static struct spear_muxreg ssp1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg ssp1_ext_17_20_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_17_18_MASK | PMX_PL_19_MASK,
+ .val = PMX_SSP1_PL_17_18_19_20_VAL,
+ }, {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_20_MASK,
+ .val = PMX_SSP1_PL_17_18_19_20_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP1_PORT_SEL_MASK,
+ .val = PMX_SSP1_PORT_17_TO_20_VAL,
+ },
+};
+
+static struct spear_muxreg ssp1_ext_36_39_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_36_MASK | PMX_PL_37_38_MASK | PMX_PL_39_MASK,
+ .val = PMX_SSP1_PL_36_VAL | PMX_SSP1_PL_37_38_VAL |
+ PMX_SSP1_PL_39_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP1_PORT_SEL_MASK,
+ .val = PMX_SSP1_PORT_36_TO_39_VAL,
+ },
+};
+
+static struct spear_muxreg ssp1_ext_48_51_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_48_49_MASK,
+ .val = PMX_SSP1_PL_48_49_VAL,
+ }, {
+ .reg = IP_SEL_PAD_50_59_REG,
+ .mask = PMX_PL_50_51_MASK,
+ .val = PMX_SSP1_PL_50_51_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP1_PORT_SEL_MASK,
+ .val = PMX_SSP1_PORT_48_TO_51_VAL,
+ },
+};
+
+static struct spear_muxreg ssp1_ext_65_68_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_65_TO_68_MASK,
+ .val = PMX_SSP1_PL_65_TO_68_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP1_PORT_SEL_MASK,
+ .val = PMX_SSP1_PORT_65_TO_68_VAL,
+ },
+};
+
+static struct spear_muxreg ssp1_ext_94_97_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+ .val = PMX_SSP1_PL_94_95_VAL | PMX_SSP1_PL_96_97_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP1_PORT_SEL_MASK,
+ .val = PMX_SSP1_PORT_94_TO_97_VAL,
+ },
+};
+
+static struct spear_modemux ssp1_17_20_modemux[] = {
+ {
+ .modes = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE |
+ EXTENDED_MODE,
+ .muxregs = ssp1_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp1_ext_17_20_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_ext_17_20_muxreg),
+ },
+};
+
+static struct spear_modemux ssp1_36_39_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp1_ext_36_39_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_ext_36_39_muxreg),
+ },
+};
+
+static struct spear_modemux ssp1_48_51_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp1_ext_48_51_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_ext_48_51_muxreg),
+ },
+};
+static struct spear_modemux ssp1_65_68_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp1_ext_65_68_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_ext_65_68_muxreg),
+ },
+};
+
+static struct spear_modemux ssp1_94_97_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp1_ext_94_97_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp1_ext_94_97_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp1_pingroup[] = {
+ {
+ .name = "ssp1_17_20_grp",
+ .pins = ssp1_pins[0],
+ .npins = ARRAY_SIZE(ssp1_pins[0]),
+ .modemuxs = ssp1_17_20_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_17_20_modemux),
+ }, {
+ .name = "ssp1_36_39_grp",
+ .pins = ssp1_pins[1],
+ .npins = ARRAY_SIZE(ssp1_pins[1]),
+ .modemuxs = ssp1_36_39_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_36_39_modemux),
+ }, {
+ .name = "ssp1_48_51_grp",
+ .pins = ssp1_pins[2],
+ .npins = ARRAY_SIZE(ssp1_pins[2]),
+ .modemuxs = ssp1_48_51_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_48_51_modemux),
+ }, {
+ .name = "ssp1_65_68_grp",
+ .pins = ssp1_pins[3],
+ .npins = ARRAY_SIZE(ssp1_pins[3]),
+ .modemuxs = ssp1_65_68_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_65_68_modemux),
+ }, {
+ .name = "ssp1_94_97_grp",
+ .pins = ssp1_pins[4],
+ .npins = ARRAY_SIZE(ssp1_pins[4]),
+ .modemuxs = ssp1_94_97_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp1_94_97_modemux),
+ },
+};
+
+static const char *const ssp1_grps[] = { "ssp1_17_20_grp", "ssp1_36_39_grp",
+ "ssp1_48_51_grp", "ssp1_65_68_grp", "ssp1_94_97_grp"
+};
+static struct spear_function ssp1_function = {
+ .name = "ssp1",
+ .groups = ssp1_grps,
+ .ngroups = ARRAY_SIZE(ssp1_grps),
+};
+
+/* Pad multiplexing for SSP2 device */
+static const unsigned ssp2_pins[][2] = { { 13, 16 }, { 32, 35 }, { 44, 47 },
+ { 61, 64 }, { 90, 93 } };
+static struct spear_muxreg ssp2_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg ssp2_ext_13_16_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_13_14_MASK | PMX_PL_15_16_MASK,
+ .val = PMX_SSP2_PL_13_14_15_16_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP2_PORT_SEL_MASK,
+ .val = PMX_SSP2_PORT_13_TO_16_VAL,
+ },
+};
+
+static struct spear_muxreg ssp2_ext_32_35_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK | PMX_GPIO_PIN4_MASK |
+ PMX_GPIO_PIN5_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_30_39_REG,
+ .mask = PMX_PL_32_33_MASK | PMX_PL_34_MASK | PMX_PL_35_MASK,
+ .val = PMX_SSP2_PL_32_33_VAL | PMX_SSP2_PL_34_VAL |
+ PMX_SSP2_PL_35_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP2_PORT_SEL_MASK,
+ .val = PMX_SSP2_PORT_32_TO_35_VAL,
+ },
+};
+
+static struct spear_muxreg ssp2_ext_44_47_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_40_49_REG,
+ .mask = PMX_PL_44_45_MASK | PMX_PL_46_47_MASK,
+ .val = PMX_SSP2_PL_44_45_VAL | PMX_SSP2_PL_46_47_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP2_PORT_SEL_MASK,
+ .val = PMX_SSP2_PORT_44_TO_47_VAL,
+ },
+};
+
+static struct spear_muxreg ssp2_ext_61_64_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_60_69_REG,
+ .mask = PMX_PL_61_TO_64_MASK,
+ .val = PMX_SSP2_PL_61_TO_64_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP2_PORT_SEL_MASK,
+ .val = PMX_SSP2_PORT_61_TO_64_VAL,
+ },
+};
+
+static struct spear_muxreg ssp2_ext_90_93_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK,
+ .val = PMX_SSP2_PL_90_91_VAL | PMX_SSP2_PL_92_93_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_SSP2_PORT_SEL_MASK,
+ .val = PMX_SSP2_PORT_90_TO_93_VAL,
+ },
+};
+
+static struct spear_modemux ssp2_13_16_modemux[] = {
+ {
+ .modes = AUTO_NET_SMII_MODE | EXTENDED_MODE,
+ .muxregs = ssp2_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp2_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp2_ext_13_16_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp2_ext_13_16_muxreg),
+ },
+};
+
+static struct spear_modemux ssp2_32_35_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp2_ext_32_35_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp2_ext_32_35_muxreg),
+ },
+};
+
+static struct spear_modemux ssp2_44_47_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp2_ext_44_47_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp2_ext_44_47_muxreg),
+ },
+};
+
+static struct spear_modemux ssp2_61_64_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp2_ext_61_64_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp2_ext_61_64_muxreg),
+ },
+};
+
+static struct spear_modemux ssp2_90_93_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = ssp2_ext_90_93_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp2_ext_90_93_muxreg),
+ },
+};
+
+static struct spear_pingroup ssp2_pingroup[] = {
+ {
+ .name = "ssp2_13_16_grp",
+ .pins = ssp2_pins[0],
+ .npins = ARRAY_SIZE(ssp2_pins[0]),
+ .modemuxs = ssp2_13_16_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp2_13_16_modemux),
+ }, {
+ .name = "ssp2_32_35_grp",
+ .pins = ssp2_pins[1],
+ .npins = ARRAY_SIZE(ssp2_pins[1]),
+ .modemuxs = ssp2_32_35_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp2_32_35_modemux),
+ }, {
+ .name = "ssp2_44_47_grp",
+ .pins = ssp2_pins[2],
+ .npins = ARRAY_SIZE(ssp2_pins[2]),
+ .modemuxs = ssp2_44_47_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp2_44_47_modemux),
+ }, {
+ .name = "ssp2_61_64_grp",
+ .pins = ssp2_pins[3],
+ .npins = ARRAY_SIZE(ssp2_pins[3]),
+ .modemuxs = ssp2_61_64_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp2_61_64_modemux),
+ }, {
+ .name = "ssp2_90_93_grp",
+ .pins = ssp2_pins[4],
+ .npins = ARRAY_SIZE(ssp2_pins[4]),
+ .modemuxs = ssp2_90_93_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp2_90_93_modemux),
+ },
+};
+
+static const char *const ssp2_grps[] = { "ssp2_13_16_grp", "ssp2_32_35_grp",
+ "ssp2_44_47_grp", "ssp2_61_64_grp", "ssp2_90_93_grp" };
+static struct spear_function ssp2_function = {
+ .name = "ssp2",
+ .groups = ssp2_grps,
+ .ngroups = ARRAY_SIZE(ssp2_grps),
+};
+
+/* Pad multiplexing for cadence mii2 as mii device */
+static const unsigned mii2_pins[] = { 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97 };
+static struct spear_muxreg mii2_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_80_89_REG,
+ .mask = PMX_PL_80_TO_85_MASK | PMX_PL_86_87_MASK |
+ PMX_PL_88_89_MASK,
+ .val = PMX_MII2_PL_80_TO_85_VAL | PMX_MII2_PL_86_87_VAL |
+ PMX_MII2_PL_88_89_VAL,
+ }, {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_90_91_MASK | PMX_PL_92_93_MASK |
+ PMX_PL_94_95_MASK | PMX_PL_96_97_MASK,
+ .val = PMX_MII2_PL_90_91_VAL | PMX_MII2_PL_92_93_VAL |
+ PMX_MII2_PL_94_95_VAL | PMX_MII2_PL_96_97_VAL,
+ }, {
+ .reg = EXT_CTRL_REG,
+ .mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+ (MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+ MII_MDIO_MASK,
+ .val = (MAC_MODE_MII << MAC2_MODE_SHIFT) |
+ (MAC_MODE_MII << MAC1_MODE_SHIFT) |
+ MII_MDIO_81_VAL,
+ },
+};
+
+static struct spear_modemux mii2_modemux[] = {
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = mii2_muxreg,
+ .nmuxregs = ARRAY_SIZE(mii2_muxreg),
+ },
+};
+
+static struct spear_pingroup mii2_pingroup = {
+ .name = "mii2_grp",
+ .pins = mii2_pins,
+ .npins = ARRAY_SIZE(mii2_pins),
+ .modemuxs = mii2_modemux,
+ .nmodemuxs = ARRAY_SIZE(mii2_modemux),
+};
+
+static const char *const mii2_grps[] = { "mii2_grp" };
+static struct spear_function mii2_function = {
+ .name = "mii2",
+ .groups = mii2_grps,
+ .ngroups = ARRAY_SIZE(mii2_grps),
+};
+
+/* Pad multiplexing for cadence mii 1_2 as smii or rmii device */
+static const unsigned smii0_1_pins[] = { 10, 11, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27 };
+static const unsigned rmii0_1_pins[] = { 10, 11, 21, 22, 23, 24, 25, 26, 27 };
+static struct spear_muxreg mii0_1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ },
+};
+
+static struct spear_muxreg smii0_1_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_10_11_MASK,
+ .val = PMX_SMII_PL_10_11_VAL,
+ }, {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_21_TO_27_MASK,
+ .val = PMX_SMII_PL_21_TO_27_VAL,
+ }, {
+ .reg = EXT_CTRL_REG,
+ .mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+ (MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+ MII_MDIO_MASK,
+ .val = (MAC_MODE_SMII << MAC2_MODE_SHIFT)
+ | (MAC_MODE_SMII << MAC1_MODE_SHIFT)
+ | MII_MDIO_10_11_VAL,
+ },
+};
+
+static struct spear_muxreg rmii0_1_ext_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_10_11_MASK | PMX_PL_13_14_MASK |
+ PMX_PL_15_16_MASK | PMX_PL_17_18_MASK | PMX_PL_19_MASK,
+ .val = PMX_RMII_PL_10_11_VAL | PMX_RMII_PL_13_14_VAL |
+ PMX_RMII_PL_15_16_VAL | PMX_RMII_PL_17_18_VAL |
+ PMX_RMII_PL_19_VAL,
+ }, {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_20_MASK | PMX_PL_21_TO_27_MASK,
+ .val = PMX_RMII_PL_20_VAL | PMX_RMII_PL_21_TO_27_VAL,
+ }, {
+ .reg = EXT_CTRL_REG,
+ .mask = (MAC_MODE_MASK << MAC2_MODE_SHIFT) |
+ (MAC_MODE_MASK << MAC1_MODE_SHIFT) |
+ MII_MDIO_MASK,
+ .val = (MAC_MODE_RMII << MAC2_MODE_SHIFT)
+ | (MAC_MODE_RMII << MAC1_MODE_SHIFT)
+ | MII_MDIO_10_11_VAL,
+ },
+};
+
+static struct spear_modemux mii0_1_modemux[][2] = {
+ {
+ /* configure as smii */
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_EXP_MODE |
+ SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = mii0_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(mii0_1_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = smii0_1_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(smii0_1_ext_muxreg),
+ },
+ }, {
+ /* configure as rmii */
+ {
+ .modes = AUTO_NET_SMII_MODE | AUTO_EXP_MODE |
+ SMALL_PRINTERS_MODE | EXTENDED_MODE,
+ .muxregs = mii0_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(mii0_1_muxreg),
+ }, {
+ .modes = EXTENDED_MODE,
+ .muxregs = rmii0_1_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(rmii0_1_ext_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup mii0_1_pingroup[] = {
+ {
+ .name = "smii0_1_grp",
+ .pins = smii0_1_pins,
+ .npins = ARRAY_SIZE(smii0_1_pins),
+ .modemuxs = mii0_1_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(mii0_1_modemux[0]),
+ }, {
+ .name = "rmii0_1_grp",
+ .pins = rmii0_1_pins,
+ .npins = ARRAY_SIZE(rmii0_1_pins),
+ .modemuxs = mii0_1_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(mii0_1_modemux[1]),
+ },
+};
+
+static const char *const mii0_1_grps[] = { "smii0_1_grp", "rmii0_1_grp" };
+static struct spear_function mii0_1_function = {
+ .name = "mii0_1",
+ .groups = mii0_1_grps,
+ .ngroups = ARRAY_SIZE(mii0_1_grps),
+};
+
+/* Pad multiplexing for i2c1 device */
+static const unsigned i2c1_pins[][2] = { { 8, 9 }, { 98, 99 } };
+static struct spear_muxreg i2c1_ext_8_9_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_SSP_CS_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_8_9_MASK,
+ .val = PMX_I2C1_PL_8_9_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C1_PORT_SEL_MASK,
+ .val = PMX_I2C1_PORT_8_9_VAL,
+ },
+};
+
+static struct spear_muxreg i2c1_ext_98_99_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_98_MASK | PMX_PL_99_MASK,
+ .val = PMX_I2C1_PL_98_VAL | PMX_I2C1_PL_99_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C1_PORT_SEL_MASK,
+ .val = PMX_I2C1_PORT_98_99_VAL,
+ },
+};
+
+static struct spear_modemux i2c1_modemux[][1] = {
+ {
+ /* Select signals on pins 8-9 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c1_ext_8_9_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c1_ext_8_9_muxreg),
+ },
+ }, {
+ /* Select signals on pins 98-99 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c1_ext_98_99_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c1_ext_98_99_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup i2c1_pingroup[] = {
+ {
+ .name = "i2c1_8_9_grp",
+ .pins = i2c1_pins[0],
+ .npins = ARRAY_SIZE(i2c1_pins[0]),
+ .modemuxs = i2c1_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(i2c1_modemux[0]),
+ }, {
+ .name = "i2c1_98_99_grp",
+ .pins = i2c1_pins[1],
+ .npins = ARRAY_SIZE(i2c1_pins[1]),
+ .modemuxs = i2c1_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(i2c1_modemux[1]),
+ },
+};
+
+static const char *const i2c1_grps[] = { "i2c1_8_9_grp", "i2c1_98_99_grp" };
+static struct spear_function i2c1_function = {
+ .name = "i2c1",
+ .groups = i2c1_grps,
+ .ngroups = ARRAY_SIZE(i2c1_grps),
+};
+
+/* Pad multiplexing for i2c2 device */
+static const unsigned i2c2_pins[][2] = { { 0, 1 }, { 2, 3 }, { 19, 20 },
+ { 75, 76 }, { 96, 97 } };
+static struct spear_muxreg i2c2_ext_0_1_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_FIRDA_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_0_1_MASK,
+ .val = PMX_I2C2_PL_0_1_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C2_PORT_SEL_MASK,
+ .val = PMX_I2C2_PORT_0_1_VAL,
+ },
+};
+
+static struct spear_muxreg i2c2_ext_2_3_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_UART0_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_0_9_REG,
+ .mask = PMX_PL_2_3_MASK,
+ .val = PMX_I2C2_PL_2_3_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C2_PORT_SEL_MASK,
+ .val = PMX_I2C2_PORT_2_3_VAL,
+ },
+};
+
+static struct spear_muxreg i2c2_ext_19_20_muxreg[] = {
+ {
+ .reg = PMX_CONFIG_REG,
+ .mask = PMX_MII_MASK,
+ .val = 0,
+ }, {
+ .reg = IP_SEL_PAD_10_19_REG,
+ .mask = PMX_PL_19_MASK,
+ .val = PMX_I2C2_PL_19_VAL,
+ }, {
+ .reg = IP_SEL_PAD_20_29_REG,
+ .mask = PMX_PL_20_MASK,
+ .val = PMX_I2C2_PL_20_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C2_PORT_SEL_MASK,
+ .val = PMX_I2C2_PORT_19_20_VAL,
+ },
+};
+
+static struct spear_muxreg i2c2_ext_75_76_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_70_79_REG,
+ .mask = PMX_PL_75_76_MASK,
+ .val = PMX_I2C2_PL_75_76_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C2_PORT_SEL_MASK,
+ .val = PMX_I2C2_PORT_75_76_VAL,
+ },
+};
+
+static struct spear_muxreg i2c2_ext_96_97_muxreg[] = {
+ {
+ .reg = IP_SEL_PAD_90_99_REG,
+ .mask = PMX_PL_96_97_MASK,
+ .val = PMX_I2C2_PL_96_97_VAL,
+ }, {
+ .reg = IP_SEL_MIX_PAD_REG,
+ .mask = PMX_I2C2_PORT_SEL_MASK,
+ .val = PMX_I2C2_PORT_96_97_VAL,
+ },
+};
+
+static struct spear_modemux i2c2_modemux[][1] = {
+ {
+ /* Select signals on pins 0_1 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c2_ext_0_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c2_ext_0_1_muxreg),
+ },
+ }, {
+ /* Select signals on pins 2_3 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c2_ext_2_3_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c2_ext_2_3_muxreg),
+ },
+ }, {
+ /* Select signals on pins 19_20 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c2_ext_19_20_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c2_ext_19_20_muxreg),
+ },
+ }, {
+ /* Select signals on pins 75_76 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c2_ext_75_76_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c2_ext_75_76_muxreg),
+ },
+ }, {
+ /* Select signals on pins 96_97 */
+ {
+ .modes = EXTENDED_MODE,
+ .muxregs = i2c2_ext_96_97_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c2_ext_96_97_muxreg),
+ },
+ },
+};
+
+static struct spear_pingroup i2c2_pingroup[] = {
+ {
+ .name = "i2c2_0_1_grp",
+ .pins = i2c2_pins[0],
+ .npins = ARRAY_SIZE(i2c2_pins[0]),
+ .modemuxs = i2c2_modemux[0],
+ .nmodemuxs = ARRAY_SIZE(i2c2_modemux[0]),
+ }, {
+ .name = "i2c2_2_3_grp",
+ .pins = i2c2_pins[1],
+ .npins = ARRAY_SIZE(i2c2_pins[1]),
+ .modemuxs = i2c2_modemux[1],
+ .nmodemuxs = ARRAY_SIZE(i2c2_modemux[1]),
+ }, {
+ .name = "i2c2_19_20_grp",
+ .pins = i2c2_pins[2],
+ .npins = ARRAY_SIZE(i2c2_pins[2]),
+ .modemuxs = i2c2_modemux[2],
+ .nmodemuxs = ARRAY_SIZE(i2c2_modemux[2]),
+ }, {
+ .name = "i2c2_75_76_grp",
+ .pins = i2c2_pins[3],
+ .npins = ARRAY_SIZE(i2c2_pins[3]),
+ .modemuxs = i2c2_modemux[3],
+ .nmodemuxs = ARRAY_SIZE(i2c2_modemux[3]),
+ }, {
+ .name = "i2c2_96_97_grp",
+ .pins = i2c2_pins[4],
+ .npins = ARRAY_SIZE(i2c2_pins[4]),
+ .modemuxs = i2c2_modemux[4],
+ .nmodemuxs = ARRAY_SIZE(i2c2_modemux[4]),
+ },
+};
+
+static const char *const i2c2_grps[] = { "i2c2_0_1_grp", "i2c2_2_3_grp",
+ "i2c2_19_20_grp", "i2c2_75_76_grp", "i2c2_96_97_grp" };
+static struct spear_function i2c2_function = {
+ .name = "i2c2",
+ .groups = i2c2_grps,
+ .ngroups = ARRAY_SIZE(i2c2_grps),
+};
+
+/* pingroups */
+static struct spear_pingroup *spear320_pingroups[] = {
+ SPEAR3XX_COMMON_PINGROUPS,
+ &clcd_pingroup,
+ &emi_pingroup,
+ &fsmc_8bit_pingroup,
+ &fsmc_16bit_pingroup,
+ &spp_pingroup,
+ &sdhci_led_pingroup,
+ &sdhci_pingroup[0],
+ &sdhci_pingroup[1],
+ &i2s_pingroup,
+ &uart1_pingroup,
+ &uart1_modem_pingroup[0],
+ &uart1_modem_pingroup[1],
+ &uart1_modem_pingroup[2],
+ &uart1_modem_pingroup[3],
+ &uart2_pingroup,
+ &uart3_pingroup[0],
+ &uart3_pingroup[1],
+ &uart3_pingroup[2],
+ &uart3_pingroup[3],
+ &uart3_pingroup[4],
+ &uart3_pingroup[5],
+ &uart3_pingroup[6],
+ &uart4_pingroup[0],
+ &uart4_pingroup[1],
+ &uart4_pingroup[2],
+ &uart4_pingroup[3],
+ &uart4_pingroup[4],
+ &uart4_pingroup[5],
+ &uart5_pingroup[0],
+ &uart5_pingroup[1],
+ &uart5_pingroup[2],
+ &uart5_pingroup[3],
+ &uart6_pingroup[0],
+ &uart6_pingroup[1],
+ &rs485_pingroup,
+ &touchscreen_pingroup,
+ &can0_pingroup,
+ &can1_pingroup,
+ &pwm0_1_pingroup[0],
+ &pwm0_1_pingroup[1],
+ &pwm0_1_pingroup[2],
+ &pwm0_1_pingroup[3],
+ &pwm0_1_pingroup[4],
+ &pwm0_1_pingroup[5],
+ &pwm0_1_pingroup[6],
+ &pwm2_pingroup[0],
+ &pwm2_pingroup[1],
+ &pwm2_pingroup[2],
+ &pwm2_pingroup[3],
+ &pwm2_pingroup[4],
+ &pwm2_pingroup[5],
+ &pwm2_pingroup[6],
+ &pwm3_pingroup[0],
+ &pwm3_pingroup[1],
+ &pwm3_pingroup[2],
+ &pwm3_pingroup[3],
+ &pwm3_pingroup[4],
+ &pwm3_pingroup[5],
+ &ssp1_pingroup[0],
+ &ssp1_pingroup[1],
+ &ssp1_pingroup[2],
+ &ssp1_pingroup[3],
+ &ssp1_pingroup[4],
+ &ssp2_pingroup[0],
+ &ssp2_pingroup[1],
+ &ssp2_pingroup[2],
+ &ssp2_pingroup[3],
+ &ssp2_pingroup[4],
+ &mii2_pingroup,
+ &mii0_1_pingroup[0],
+ &mii0_1_pingroup[1],
+ &i2c1_pingroup[0],
+ &i2c1_pingroup[1],
+ &i2c2_pingroup[0],
+ &i2c2_pingroup[1],
+ &i2c2_pingroup[2],
+ &i2c2_pingroup[3],
+ &i2c2_pingroup[4],
+};
+
+/* functions */
+static struct spear_function *spear320_functions[] = {
+ SPEAR3XX_COMMON_FUNCTIONS,
+ &clcd_function,
+ &emi_function,
+ &fsmc_function,
+ &spp_function,
+ &sdhci_function,
+ &i2s_function,
+ &uart1_function,
+ &uart1_modem_function,
+ &uart2_function,
+ &uart3_function,
+ &uart4_function,
+ &uart5_function,
+ &uart6_function,
+ &rs485_function,
+ &touchscreen_function,
+ &can0_function,
+ &can1_function,
+ &pwm0_1_function,
+ &pwm2_function,
+ &pwm3_function,
+ &ssp1_function,
+ &ssp2_function,
+ &mii2_function,
+ &mii0_1_function,
+ &i2c1_function,
+ &i2c2_function,
+};
+
+static struct of_device_id spear320_pinctrl_of_match[] __devinitdata = {
+ {
+ .compatible = "st,spear320-pinmux",
+ },
+ {},
+};
+
+static int __devinit spear320_pinctrl_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ spear3xx_machdata.groups = spear320_pingroups;
+ spear3xx_machdata.ngroups = ARRAY_SIZE(spear320_pingroups);
+ spear3xx_machdata.functions = spear320_functions;
+ spear3xx_machdata.nfunctions = ARRAY_SIZE(spear320_functions);
+
+ spear3xx_machdata.modes_supported = true;
+ spear3xx_machdata.pmx_modes = spear320_pmx_modes;
+ spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes);
+
+ pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
+
+ ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int __devexit spear320_pinctrl_remove(struct platform_device *pdev)
+{
+ return spear_pinctrl_remove(pdev);
+}
+
+static struct platform_driver spear320_pinctrl_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spear320_pinctrl_of_match,
+ },
+ .probe = spear320_pinctrl_probe,
+ .remove = __devexit_p(spear320_pinctrl_remove),
+};
+
+static int __init spear320_pinctrl_init(void)
+{
+ return platform_driver_register(&spear320_pinctrl_driver);
+}
+arch_initcall(spear320_pinctrl_init);
+
+static void __exit spear320_pinctrl_exit(void)
+{
+ platform_driver_unregister(&spear320_pinctrl_driver);
+}
+module_exit(spear320_pinctrl_exit);
+
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
+MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match);
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c
new file mode 100644
index 000000000000..91c883bc46a6
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c
@@ -0,0 +1,487 @@
+/*
+ * Driver for the ST Microelectronics SPEAr3xx pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-spear3xx.h"
+
+/* pins */
+static const struct pinctrl_pin_desc spear3xx_pins[] = {
+ SPEAR_PIN_0_TO_101,
+};
+
+/* firda_pins */
+static const unsigned firda_pins[] = { 0, 1 };
+static struct spear_muxreg firda_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_FIRDA_MASK,
+ .val = PMX_FIRDA_MASK,
+ },
+};
+
+static struct spear_modemux firda_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = firda_muxreg,
+ .nmuxregs = ARRAY_SIZE(firda_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_firda_pingroup = {
+ .name = "firda_grp",
+ .pins = firda_pins,
+ .npins = ARRAY_SIZE(firda_pins),
+ .modemuxs = firda_modemux,
+ .nmodemuxs = ARRAY_SIZE(firda_modemux),
+};
+
+static const char *const firda_grps[] = { "firda_grp" };
+struct spear_function spear3xx_firda_function = {
+ .name = "firda",
+ .groups = firda_grps,
+ .ngroups = ARRAY_SIZE(firda_grps),
+};
+
+/* i2c_pins */
+static const unsigned i2c_pins[] = { 4, 5 };
+static struct spear_muxreg i2c_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_I2C_MASK,
+ .val = PMX_I2C_MASK,
+ },
+};
+
+static struct spear_modemux i2c_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = i2c_muxreg,
+ .nmuxregs = ARRAY_SIZE(i2c_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_i2c_pingroup = {
+ .name = "i2c0_grp",
+ .pins = i2c_pins,
+ .npins = ARRAY_SIZE(i2c_pins),
+ .modemuxs = i2c_modemux,
+ .nmodemuxs = ARRAY_SIZE(i2c_modemux),
+};
+
+static const char *const i2c_grps[] = { "i2c0_grp" };
+struct spear_function spear3xx_i2c_function = {
+ .name = "i2c0",
+ .groups = i2c_grps,
+ .ngroups = ARRAY_SIZE(i2c_grps),
+};
+
+/* ssp_cs_pins */
+static const unsigned ssp_cs_pins[] = { 34, 35, 36 };
+static struct spear_muxreg ssp_cs_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_SSP_CS_MASK,
+ .val = PMX_SSP_CS_MASK,
+ },
+};
+
+static struct spear_modemux ssp_cs_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = ssp_cs_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp_cs_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_ssp_cs_pingroup = {
+ .name = "ssp_cs_grp",
+ .pins = ssp_cs_pins,
+ .npins = ARRAY_SIZE(ssp_cs_pins),
+ .modemuxs = ssp_cs_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp_cs_modemux),
+};
+
+static const char *const ssp_cs_grps[] = { "ssp_cs_grp" };
+struct spear_function spear3xx_ssp_cs_function = {
+ .name = "ssp_cs",
+ .groups = ssp_cs_grps,
+ .ngroups = ARRAY_SIZE(ssp_cs_grps),
+};
+
+/* ssp_pins */
+static const unsigned ssp_pins[] = { 6, 7, 8, 9 };
+static struct spear_muxreg ssp_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_SSP_MASK,
+ .val = PMX_SSP_MASK,
+ },
+};
+
+static struct spear_modemux ssp_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = ssp_muxreg,
+ .nmuxregs = ARRAY_SIZE(ssp_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_ssp_pingroup = {
+ .name = "ssp0_grp",
+ .pins = ssp_pins,
+ .npins = ARRAY_SIZE(ssp_pins),
+ .modemuxs = ssp_modemux,
+ .nmodemuxs = ARRAY_SIZE(ssp_modemux),
+};
+
+static const char *const ssp_grps[] = { "ssp0_grp" };
+struct spear_function spear3xx_ssp_function = {
+ .name = "ssp0",
+ .groups = ssp_grps,
+ .ngroups = ARRAY_SIZE(ssp_grps),
+};
+
+/* mii_pins */
+static const unsigned mii_pins[] = { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27 };
+static struct spear_muxreg mii_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_MII_MASK,
+ .val = PMX_MII_MASK,
+ },
+};
+
+static struct spear_modemux mii_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = mii_muxreg,
+ .nmuxregs = ARRAY_SIZE(mii_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_mii_pingroup = {
+ .name = "mii0_grp",
+ .pins = mii_pins,
+ .npins = ARRAY_SIZE(mii_pins),
+ .modemuxs = mii_modemux,
+ .nmodemuxs = ARRAY_SIZE(mii_modemux),
+};
+
+static const char *const mii_grps[] = { "mii0_grp" };
+struct spear_function spear3xx_mii_function = {
+ .name = "mii0",
+ .groups = mii_grps,
+ .ngroups = ARRAY_SIZE(mii_grps),
+};
+
+/* gpio0_pin0_pins */
+static const unsigned gpio0_pin0_pins[] = { 28 };
+static struct spear_muxreg gpio0_pin0_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_GPIO_PIN0_MASK,
+ .val = PMX_GPIO_PIN0_MASK,
+ },
+};
+
+static struct spear_modemux gpio0_pin0_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = gpio0_pin0_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio0_pin0_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin0_pingroup = {
+ .name = "gpio0_pin0_grp",
+ .pins = gpio0_pin0_pins,
+ .npins = ARRAY_SIZE(gpio0_pin0_pins),
+ .modemuxs = gpio0_pin0_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio0_pin0_modemux),
+};
+
+/* gpio0_pin1_pins */
+static const unsigned gpio0_pin1_pins[] = { 29 };
+static struct spear_muxreg gpio0_pin1_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_GPIO_PIN1_MASK,
+ .val = PMX_GPIO_PIN1_MASK,
+ },
+};
+
+static struct spear_modemux gpio0_pin1_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = gpio0_pin1_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio0_pin1_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin1_pingroup = {
+ .name = "gpio0_pin1_grp",
+ .pins = gpio0_pin1_pins,
+ .npins = ARRAY_SIZE(gpio0_pin1_pins),
+ .modemuxs = gpio0_pin1_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio0_pin1_modemux),
+};
+
+/* gpio0_pin2_pins */
+static const unsigned gpio0_pin2_pins[] = { 30 };
+static struct spear_muxreg gpio0_pin2_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_GPIO_PIN2_MASK,
+ .val = PMX_GPIO_PIN2_MASK,
+ },
+};
+
+static struct spear_modemux gpio0_pin2_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = gpio0_pin2_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio0_pin2_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin2_pingroup = {
+ .name = "gpio0_pin2_grp",
+ .pins = gpio0_pin2_pins,
+ .npins = ARRAY_SIZE(gpio0_pin2_pins),
+ .modemuxs = gpio0_pin2_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio0_pin2_modemux),
+};
+
+/* gpio0_pin3_pins */
+static const unsigned gpio0_pin3_pins[] = { 31 };
+static struct spear_muxreg gpio0_pin3_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_GPIO_PIN3_MASK,
+ .val = PMX_GPIO_PIN3_MASK,
+ },
+};
+
+static struct spear_modemux gpio0_pin3_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = gpio0_pin3_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio0_pin3_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin3_pingroup = {
+ .name = "gpio0_pin3_grp",
+ .pins = gpio0_pin3_pins,
+ .npins = ARRAY_SIZE(gpio0_pin3_pins),
+ .modemuxs = gpio0_pin3_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio0_pin3_modemux),
+};
+
+/* gpio0_pin4_pins */
+static const unsigned gpio0_pin4_pins[] = { 32 };
+static struct spear_muxreg gpio0_pin4_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_GPIO_PIN4_MASK,
+ .val = PMX_GPIO_PIN4_MASK,
+ },
+};
+
+static struct spear_modemux gpio0_pin4_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = gpio0_pin4_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio0_pin4_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin4_pingroup = {
+ .name = "gpio0_pin4_grp",
+ .pins = gpio0_pin4_pins,
+ .npins = ARRAY_SIZE(gpio0_pin4_pins),
+ .modemuxs = gpio0_pin4_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio0_pin4_modemux),
+};
+
+/* gpio0_pin5_pins */
+static const unsigned gpio0_pin5_pins[] = { 33 };
+static struct spear_muxreg gpio0_pin5_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_GPIO_PIN5_MASK,
+ .val = PMX_GPIO_PIN5_MASK,
+ },
+};
+
+static struct spear_modemux gpio0_pin5_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = gpio0_pin5_muxreg,
+ .nmuxregs = ARRAY_SIZE(gpio0_pin5_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_gpio0_pin5_pingroup = {
+ .name = "gpio0_pin5_grp",
+ .pins = gpio0_pin5_pins,
+ .npins = ARRAY_SIZE(gpio0_pin5_pins),
+ .modemuxs = gpio0_pin5_modemux,
+ .nmodemuxs = ARRAY_SIZE(gpio0_pin5_modemux),
+};
+
+static const char *const gpio0_grps[] = { "gpio0_pin0_grp", "gpio0_pin1_grp",
+ "gpio0_pin2_grp", "gpio0_pin3_grp", "gpio0_pin4_grp", "gpio0_pin5_grp",
+};
+struct spear_function spear3xx_gpio0_function = {
+ .name = "gpio0",
+ .groups = gpio0_grps,
+ .ngroups = ARRAY_SIZE(gpio0_grps),
+};
+
+/* uart0_ext_pins */
+static const unsigned uart0_ext_pins[] = { 37, 38, 39, 40, 41, 42 };
+static struct spear_muxreg uart0_ext_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_UART0_MODEM_MASK,
+ .val = PMX_UART0_MODEM_MASK,
+ },
+};
+
+static struct spear_modemux uart0_ext_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = uart0_ext_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart0_ext_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_uart0_ext_pingroup = {
+ .name = "uart0_ext_grp",
+ .pins = uart0_ext_pins,
+ .npins = ARRAY_SIZE(uart0_ext_pins),
+ .modemuxs = uart0_ext_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart0_ext_modemux),
+};
+
+static const char *const uart0_ext_grps[] = { "uart0_ext_grp" };
+struct spear_function spear3xx_uart0_ext_function = {
+ .name = "uart0_ext",
+ .groups = uart0_ext_grps,
+ .ngroups = ARRAY_SIZE(uart0_ext_grps),
+};
+
+/* uart0_pins */
+static const unsigned uart0_pins[] = { 2, 3 };
+static struct spear_muxreg uart0_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_UART0_MASK,
+ .val = PMX_UART0_MASK,
+ },
+};
+
+static struct spear_modemux uart0_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = uart0_muxreg,
+ .nmuxregs = ARRAY_SIZE(uart0_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_uart0_pingroup = {
+ .name = "uart0_grp",
+ .pins = uart0_pins,
+ .npins = ARRAY_SIZE(uart0_pins),
+ .modemuxs = uart0_modemux,
+ .nmodemuxs = ARRAY_SIZE(uart0_modemux),
+};
+
+static const char *const uart0_grps[] = { "uart0_grp" };
+struct spear_function spear3xx_uart0_function = {
+ .name = "uart0",
+ .groups = uart0_grps,
+ .ngroups = ARRAY_SIZE(uart0_grps),
+};
+
+/* timer_0_1_pins */
+static const unsigned timer_0_1_pins[] = { 43, 44, 47, 48 };
+static struct spear_muxreg timer_0_1_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_TIMER_0_1_MASK,
+ .val = PMX_TIMER_0_1_MASK,
+ },
+};
+
+static struct spear_modemux timer_0_1_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = timer_0_1_muxreg,
+ .nmuxregs = ARRAY_SIZE(timer_0_1_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_timer_0_1_pingroup = {
+ .name = "timer_0_1_grp",
+ .pins = timer_0_1_pins,
+ .npins = ARRAY_SIZE(timer_0_1_pins),
+ .modemuxs = timer_0_1_modemux,
+ .nmodemuxs = ARRAY_SIZE(timer_0_1_modemux),
+};
+
+static const char *const timer_0_1_grps[] = { "timer_0_1_grp" };
+struct spear_function spear3xx_timer_0_1_function = {
+ .name = "timer_0_1",
+ .groups = timer_0_1_grps,
+ .ngroups = ARRAY_SIZE(timer_0_1_grps),
+};
+
+/* timer_2_3_pins */
+static const unsigned timer_2_3_pins[] = { 45, 46, 49, 50 };
+static struct spear_muxreg timer_2_3_muxreg[] = {
+ {
+ .reg = -1,
+ .mask = PMX_TIMER_2_3_MASK,
+ .val = PMX_TIMER_2_3_MASK,
+ },
+};
+
+static struct spear_modemux timer_2_3_modemux[] = {
+ {
+ .modes = ~0,
+ .muxregs = timer_2_3_muxreg,
+ .nmuxregs = ARRAY_SIZE(timer_2_3_muxreg),
+ },
+};
+
+struct spear_pingroup spear3xx_timer_2_3_pingroup = {
+ .name = "timer_2_3_grp",
+ .pins = timer_2_3_pins,
+ .npins = ARRAY_SIZE(timer_2_3_pins),
+ .modemuxs = timer_2_3_modemux,
+ .nmodemuxs = ARRAY_SIZE(timer_2_3_modemux),
+};
+
+static const char *const timer_2_3_grps[] = { "timer_2_3_grp" };
+struct spear_function spear3xx_timer_2_3_function = {
+ .name = "timer_2_3",
+ .groups = timer_2_3_grps,
+ .ngroups = ARRAY_SIZE(timer_2_3_grps),
+};
+
+struct spear_pinctrl_machdata spear3xx_machdata = {
+ .pins = spear3xx_pins,
+ .npins = ARRAY_SIZE(spear3xx_pins),
+};
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h
new file mode 100644
index 000000000000..5d5fdd8df7b8
--- /dev/null
+++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h
@@ -0,0 +1,92 @@
+/*
+ * Header file for the ST Microelectronics SPEAr3xx pinmux
+ *
+ * Copyright (C) 2012 ST Microelectronics
+ * Viresh Kumar <viresh.kumar@st.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PINMUX_SPEAR3XX_H__
+#define __PINMUX_SPEAR3XX_H__
+
+#include "pinctrl-spear.h"
+
+/* pad mux declarations */
+#define PMX_FIRDA_MASK (1 << 14)
+#define PMX_I2C_MASK (1 << 13)
+#define PMX_SSP_CS_MASK (1 << 12)
+#define PMX_SSP_MASK (1 << 11)
+#define PMX_MII_MASK (1 << 10)
+#define PMX_GPIO_PIN0_MASK (1 << 9)
+#define PMX_GPIO_PIN1_MASK (1 << 8)
+#define PMX_GPIO_PIN2_MASK (1 << 7)
+#define PMX_GPIO_PIN3_MASK (1 << 6)
+#define PMX_GPIO_PIN4_MASK (1 << 5)
+#define PMX_GPIO_PIN5_MASK (1 << 4)
+#define PMX_UART0_MODEM_MASK (1 << 3)
+#define PMX_UART0_MASK (1 << 2)
+#define PMX_TIMER_2_3_MASK (1 << 1)
+#define PMX_TIMER_0_1_MASK (1 << 0)
+
+extern struct spear_pingroup spear3xx_firda_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin0_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin1_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin2_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin3_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin4_pingroup;
+extern struct spear_pingroup spear3xx_gpio0_pin5_pingroup;
+extern struct spear_pingroup spear3xx_i2c_pingroup;
+extern struct spear_pingroup spear3xx_mii_pingroup;
+extern struct spear_pingroup spear3xx_ssp_cs_pingroup;
+extern struct spear_pingroup spear3xx_ssp_pingroup;
+extern struct spear_pingroup spear3xx_timer_0_1_pingroup;
+extern struct spear_pingroup spear3xx_timer_2_3_pingroup;
+extern struct spear_pingroup spear3xx_uart0_ext_pingroup;
+extern struct spear_pingroup spear3xx_uart0_pingroup;
+
+#define SPEAR3XX_COMMON_PINGROUPS \
+ &spear3xx_firda_pingroup, \
+ &spear3xx_gpio0_pin0_pingroup, \
+ &spear3xx_gpio0_pin1_pingroup, \
+ &spear3xx_gpio0_pin2_pingroup, \
+ &spear3xx_gpio0_pin3_pingroup, \
+ &spear3xx_gpio0_pin4_pingroup, \
+ &spear3xx_gpio0_pin5_pingroup, \
+ &spear3xx_i2c_pingroup, \
+ &spear3xx_mii_pingroup, \
+ &spear3xx_ssp_cs_pingroup, \
+ &spear3xx_ssp_pingroup, \
+ &spear3xx_timer_0_1_pingroup, \
+ &spear3xx_timer_2_3_pingroup, \
+ &spear3xx_uart0_ext_pingroup, \
+ &spear3xx_uart0_pingroup
+
+extern struct spear_function spear3xx_firda_function;
+extern struct spear_function spear3xx_gpio0_function;
+extern struct spear_function spear3xx_i2c_function;
+extern struct spear_function spear3xx_mii_function;
+extern struct spear_function spear3xx_ssp_cs_function;
+extern struct spear_function spear3xx_ssp_function;
+extern struct spear_function spear3xx_timer_0_1_function;
+extern struct spear_function spear3xx_timer_2_3_function;
+extern struct spear_function spear3xx_uart0_ext_function;
+extern struct spear_function spear3xx_uart0_function;
+
+#define SPEAR3XX_COMMON_FUNCTIONS \
+ &spear3xx_firda_function, \
+ &spear3xx_gpio0_function, \
+ &spear3xx_i2c_function, \
+ &spear3xx_mii_function, \
+ &spear3xx_ssp_cs_function, \
+ &spear3xx_ssp_function, \
+ &spear3xx_timer_0_1_function, \
+ &spear3xx_timer_2_3_function, \
+ &spear3xx_uart0_ext_function, \
+ &spear3xx_uart0_function
+
+extern struct spear_pinctrl_machdata spear3xx_machdata;
+
+#endif /* __PINMUX_SPEAR3XX_H__ */