diff options
author | Olof Johansson <olof@lixom.net> | 2012-09-22 17:23:11 -0400 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2012-09-22 17:23:11 -0400 |
commit | c740ae7404b4b606545d008c7981d0138df44461 (patch) | |
tree | 421d6ba80e346d429b6991e56e7018369da3d8d0 /drivers/pinctrl | |
parent | 0d601f613b8557cf6489f06251ae5dc383b811d0 (diff) | |
parent | 3415b08fc69af283cb19883c32fc4c62c84c55d7 (diff) |
Merge branch 'kirkwood/drivers' of git://git.infradead.org/users/jcooper/linux into late/kirkwood
From Jason Cooper:
New drivers:
- pinctrl (dove, kirkwood, mvebu)
- gpio (mvebu)
* 'kirkwood/drivers' of git://git.infradead.org/users/jcooper/linux:
arm: mvebu: add gpio support in defconfig
arm: mvebu: add DT information for GPIO banks on Armada 370 and XP
arm: mvebu: use GPIO support now that a driver is available
Documentation: add description of DT binding for the gpio-mvebu driver
gpio: introduce gpio-mvebu driver for Marvell SoCs
arm: mvebu: select the pinctrl drivers for Armada 370 and Armada XP platforms
arm: mvebu: split Kconfig options for Armada 370 and XP
ARM: mvebu: adjust Armada XP evaluation board DTS
ARM: mvebu: Add pinctrl support to Armada 370 SoC
ARM: mvebu: Add pinctrl support to Armada XP SoCs
pinctrl: mvebu: add pinctrl driver for Armada XP
pinctrl: mvebu: add pinctrl driver for Armada 370
pinctrl: mvebu: kirkwood pinctrl driver
pinctrl: mvebu: dove pinctrl driver
pinctrl: mvebu: pinctrl driver core
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/Kconfig | 22 | ||||
-rw-r--r-- | drivers/pinctrl/Makefile | 5 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-armada-370.c | 421 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-armada-xp.c | 468 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-dove.c | 620 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-kirkwood.c | 472 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-mvebu.c | 754 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-mvebu.h | 192 |
8 files changed, 2954 insertions, 0 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 54e3588bef62..a75414496369 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -145,6 +145,28 @@ config PINCTRL_COH901 | |||
145 | COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 | 145 | COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 |
146 | ports of 8 GPIO pins each. | 146 | ports of 8 GPIO pins each. |
147 | 147 | ||
148 | config PINCTRL_MVEBU | ||
149 | bool | ||
150 | depends on ARCH_MVEBU | ||
151 | select PINMUX | ||
152 | select PINCONF | ||
153 | |||
154 | config PINCTRL_DOVE | ||
155 | bool | ||
156 | select PINCTRL_MVEBU | ||
157 | |||
158 | config PINCTRL_KIRKWOOD | ||
159 | bool | ||
160 | select PINCTRL_MVEBU | ||
161 | |||
162 | config PINCTRL_ARMADA_370 | ||
163 | bool | ||
164 | select PINCTRL_MVEBU | ||
165 | |||
166 | config PINCTRL_ARMADA_XP | ||
167 | bool | ||
168 | select PINCTRL_MVEBU | ||
169 | |||
148 | source "drivers/pinctrl/spear/Kconfig" | 170 | source "drivers/pinctrl/spear/Kconfig" |
149 | 171 | ||
150 | endmenu | 172 | endmenu |
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f40b1f81ff2c..f2ea0504efc7 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -29,5 +29,10 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o | |||
29 | obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o | 29 | obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o |
30 | obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o | 30 | obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o |
31 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o | 31 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o |
32 | obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o | ||
33 | obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o | ||
34 | obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o | ||
35 | obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||
36 | obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o | ||
32 | 37 | ||
33 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 38 | obj-$(CONFIG_PLAT_SPEAR) += spear/ |
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/pinctrl-armada-370.c new file mode 100644 index 000000000000..c907647de6ad --- /dev/null +++ b/drivers/pinctrl/pinctrl-armada-370.c | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Marvell Armada 370 pinctrl driver based on mvebu pinctrl core | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/err.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_device.h> | ||
22 | #include <linux/pinctrl/pinctrl.h> | ||
23 | |||
24 | #include "pinctrl-mvebu.h" | ||
25 | |||
26 | static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = { | ||
27 | MPP_MODE(0, | ||
28 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
29 | MPP_FUNCTION(0x1, "uart0", "rxd")), | ||
30 | MPP_MODE(1, | ||
31 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
32 | MPP_FUNCTION(0x1, "uart0", "txd")), | ||
33 | MPP_MODE(2, | ||
34 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
35 | MPP_FUNCTION(0x1, "i2c0", "sck"), | ||
36 | MPP_FUNCTION(0x2, "uart0", "txd")), | ||
37 | MPP_MODE(3, | ||
38 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
39 | MPP_FUNCTION(0x1, "i2c0", "sda"), | ||
40 | MPP_FUNCTION(0x2, "uart0", "rxd")), | ||
41 | MPP_MODE(4, | ||
42 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
43 | MPP_FUNCTION(0x1, "cpu_pd", "vdd")), | ||
44 | MPP_MODE(5, | ||
45 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
46 | MPP_FUNCTION(0x1, "ge0", "txclko"), | ||
47 | MPP_FUNCTION(0x2, "uart1", "txd"), | ||
48 | MPP_FUNCTION(0x4, "spi1", "clk"), | ||
49 | MPP_FUNCTION(0x5, "audio", "mclk")), | ||
50 | MPP_MODE(6, | ||
51 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
52 | MPP_FUNCTION(0x1, "ge0", "txd0"), | ||
53 | MPP_FUNCTION(0x2, "sata0", "prsnt"), | ||
54 | MPP_FUNCTION(0x4, "tdm", "rst"), | ||
55 | MPP_FUNCTION(0x5, "audio", "sdo")), | ||
56 | MPP_MODE(7, | ||
57 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
58 | MPP_FUNCTION(0x1, "ge0", "txd1"), | ||
59 | MPP_FUNCTION(0x4, "tdm", "tdx"), | ||
60 | MPP_FUNCTION(0x5, "audio", "lrclk")), | ||
61 | MPP_MODE(8, | ||
62 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
63 | MPP_FUNCTION(0x1, "ge0", "txd2"), | ||
64 | MPP_FUNCTION(0x2, "uart0", "rts"), | ||
65 | MPP_FUNCTION(0x4, "tdm", "drx"), | ||
66 | MPP_FUNCTION(0x5, "audio", "bclk")), | ||
67 | MPP_MODE(9, | ||
68 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
69 | MPP_FUNCTION(0x1, "ge0", "txd3"), | ||
70 | MPP_FUNCTION(0x2, "uart1", "txd"), | ||
71 | MPP_FUNCTION(0x3, "sd0", "clk"), | ||
72 | MPP_FUNCTION(0x5, "audio", "spdifo")), | ||
73 | MPP_MODE(10, | ||
74 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
75 | MPP_FUNCTION(0x1, "ge0", "txctl"), | ||
76 | MPP_FUNCTION(0x2, "uart0", "cts"), | ||
77 | MPP_FUNCTION(0x4, "tdm", "fsync"), | ||
78 | MPP_FUNCTION(0x5, "audio", "sdi")), | ||
79 | MPP_MODE(11, | ||
80 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
81 | MPP_FUNCTION(0x1, "ge0", "rxd0"), | ||
82 | MPP_FUNCTION(0x2, "uart1", "rxd"), | ||
83 | MPP_FUNCTION(0x3, "sd0", "cmd"), | ||
84 | MPP_FUNCTION(0x4, "spi0", "cs1"), | ||
85 | MPP_FUNCTION(0x5, "sata1", "prsnt"), | ||
86 | MPP_FUNCTION(0x6, "spi1", "cs1")), | ||
87 | MPP_MODE(12, | ||
88 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
89 | MPP_FUNCTION(0x1, "ge0", "rxd1"), | ||
90 | MPP_FUNCTION(0x2, "i2c1", "sda"), | ||
91 | MPP_FUNCTION(0x3, "sd0", "d0"), | ||
92 | MPP_FUNCTION(0x4, "spi1", "cs0"), | ||
93 | MPP_FUNCTION(0x5, "audio", "spdifi")), | ||
94 | MPP_MODE(13, | ||
95 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
96 | MPP_FUNCTION(0x1, "ge0", "rxd2"), | ||
97 | MPP_FUNCTION(0x2, "i2c1", "sck"), | ||
98 | MPP_FUNCTION(0x3, "sd0", "d1"), | ||
99 | MPP_FUNCTION(0x4, "tdm", "pclk"), | ||
100 | MPP_FUNCTION(0x5, "audio", "rmclk")), | ||
101 | MPP_MODE(14, | ||
102 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
103 | MPP_FUNCTION(0x1, "ge0", "rxd3"), | ||
104 | MPP_FUNCTION(0x2, "pcie", "clkreq0"), | ||
105 | MPP_FUNCTION(0x3, "sd0", "d2"), | ||
106 | MPP_FUNCTION(0x4, "spi1", "mosi"), | ||
107 | MPP_FUNCTION(0x5, "spi0", "cs2")), | ||
108 | MPP_MODE(15, | ||
109 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
110 | MPP_FUNCTION(0x1, "ge0", "rxctl"), | ||
111 | MPP_FUNCTION(0x2, "pcie", "clkreq1"), | ||
112 | MPP_FUNCTION(0x3, "sd0", "d3"), | ||
113 | MPP_FUNCTION(0x4, "spi1", "miso"), | ||
114 | MPP_FUNCTION(0x5, "spi0", "cs3")), | ||
115 | MPP_MODE(16, | ||
116 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
117 | MPP_FUNCTION(0x1, "ge0", "rxclk"), | ||
118 | MPP_FUNCTION(0x2, "uart1", "rxd"), | ||
119 | MPP_FUNCTION(0x4, "tdm", "int"), | ||
120 | MPP_FUNCTION(0x5, "audio", "extclk")), | ||
121 | MPP_MODE(17, | ||
122 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
123 | MPP_FUNCTION(0x1, "ge", "mdc")), | ||
124 | MPP_MODE(18, | ||
125 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
126 | MPP_FUNCTION(0x1, "ge", "mdio")), | ||
127 | MPP_MODE(19, | ||
128 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
129 | MPP_FUNCTION(0x1, "ge0", "txclk"), | ||
130 | MPP_FUNCTION(0x2, "ge1", "txclkout"), | ||
131 | MPP_FUNCTION(0x4, "tdm", "pclk")), | ||
132 | MPP_MODE(20, | ||
133 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
134 | MPP_FUNCTION(0x1, "ge0", "txd4"), | ||
135 | MPP_FUNCTION(0x2, "ge1", "txd0")), | ||
136 | MPP_MODE(21, | ||
137 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
138 | MPP_FUNCTION(0x1, "ge0", "txd5"), | ||
139 | MPP_FUNCTION(0x2, "ge1", "txd1"), | ||
140 | MPP_FUNCTION(0x4, "uart1", "txd")), | ||
141 | MPP_MODE(22, | ||
142 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
143 | MPP_FUNCTION(0x1, "ge0", "txd6"), | ||
144 | MPP_FUNCTION(0x2, "ge1", "txd2"), | ||
145 | MPP_FUNCTION(0x4, "uart0", "rts")), | ||
146 | MPP_MODE(23, | ||
147 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
148 | MPP_FUNCTION(0x1, "ge0", "txd7"), | ||
149 | MPP_FUNCTION(0x2, "ge1", "txd3"), | ||
150 | MPP_FUNCTION(0x4, "spi1", "mosi")), | ||
151 | MPP_MODE(24, | ||
152 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
153 | MPP_FUNCTION(0x1, "ge0", "col"), | ||
154 | MPP_FUNCTION(0x2, "ge1", "txctl"), | ||
155 | MPP_FUNCTION(0x4, "spi1", "cs0")), | ||
156 | MPP_MODE(25, | ||
157 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
158 | MPP_FUNCTION(0x1, "ge0", "rxerr"), | ||
159 | MPP_FUNCTION(0x2, "ge1", "rxd0"), | ||
160 | MPP_FUNCTION(0x4, "uart1", "rxd")), | ||
161 | MPP_MODE(26, | ||
162 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
163 | MPP_FUNCTION(0x1, "ge0", "crs"), | ||
164 | MPP_FUNCTION(0x2, "ge1", "rxd1"), | ||
165 | MPP_FUNCTION(0x4, "spi1", "miso")), | ||
166 | MPP_MODE(27, | ||
167 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
168 | MPP_FUNCTION(0x1, "ge0", "rxd4"), | ||
169 | MPP_FUNCTION(0x2, "ge1", "rxd2"), | ||
170 | MPP_FUNCTION(0x4, "uart0", "cts")), | ||
171 | MPP_MODE(28, | ||
172 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
173 | MPP_FUNCTION(0x1, "ge0", "rxd5"), | ||
174 | MPP_FUNCTION(0x2, "ge1", "rxd3")), | ||
175 | MPP_MODE(29, | ||
176 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
177 | MPP_FUNCTION(0x1, "ge0", "rxd6"), | ||
178 | MPP_FUNCTION(0x2, "ge1", "rxctl"), | ||
179 | MPP_FUNCTION(0x4, "i2c1", "sda")), | ||
180 | MPP_MODE(30, | ||
181 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
182 | MPP_FUNCTION(0x1, "ge0", "rxd7"), | ||
183 | MPP_FUNCTION(0x2, "ge1", "rxclk"), | ||
184 | MPP_FUNCTION(0x4, "i2c1", "sck")), | ||
185 | MPP_MODE(31, | ||
186 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
187 | MPP_FUNCTION(0x3, "tclk", NULL), | ||
188 | MPP_FUNCTION(0x4, "ge0", "txerr")), | ||
189 | MPP_MODE(32, | ||
190 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
191 | MPP_FUNCTION(0x1, "spi0", "cs0")), | ||
192 | MPP_MODE(33, | ||
193 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
194 | MPP_FUNCTION(0x1, "dev", "bootcs"), | ||
195 | MPP_FUNCTION(0x2, "spi0", "cs0")), | ||
196 | MPP_MODE(34, | ||
197 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
198 | MPP_FUNCTION(0x1, "dev", "wen0"), | ||
199 | MPP_FUNCTION(0x2, "spi0", "mosi")), | ||
200 | MPP_MODE(35, | ||
201 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
202 | MPP_FUNCTION(0x1, "dev", "oen"), | ||
203 | MPP_FUNCTION(0x2, "spi0", "sck")), | ||
204 | MPP_MODE(36, | ||
205 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
206 | MPP_FUNCTION(0x1, "dev", "a1"), | ||
207 | MPP_FUNCTION(0x2, "spi0", "miso")), | ||
208 | MPP_MODE(37, | ||
209 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
210 | MPP_FUNCTION(0x1, "dev", "a0"), | ||
211 | MPP_FUNCTION(0x2, "sata0", "prsnt")), | ||
212 | MPP_MODE(38, | ||
213 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
214 | MPP_FUNCTION(0x1, "dev", "ready"), | ||
215 | MPP_FUNCTION(0x2, "uart1", "cts"), | ||
216 | MPP_FUNCTION(0x3, "uart0", "cts")), | ||
217 | MPP_MODE(39, | ||
218 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
219 | MPP_FUNCTION(0x1, "dev", "ad0"), | ||
220 | MPP_FUNCTION(0x2, "audio", "spdifo")), | ||
221 | MPP_MODE(40, | ||
222 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
223 | MPP_FUNCTION(0x1, "dev", "ad1"), | ||
224 | MPP_FUNCTION(0x2, "uart1", "rts"), | ||
225 | MPP_FUNCTION(0x3, "uart0", "rts")), | ||
226 | MPP_MODE(41, | ||
227 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
228 | MPP_FUNCTION(0x1, "dev", "ad2"), | ||
229 | MPP_FUNCTION(0x2, "uart1", "rxd")), | ||
230 | MPP_MODE(42, | ||
231 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
232 | MPP_FUNCTION(0x1, "dev", "ad3"), | ||
233 | MPP_FUNCTION(0x2, "uart1", "txd")), | ||
234 | MPP_MODE(43, | ||
235 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
236 | MPP_FUNCTION(0x1, "dev", "ad4"), | ||
237 | MPP_FUNCTION(0x2, "audio", "bclk")), | ||
238 | MPP_MODE(44, | ||
239 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
240 | MPP_FUNCTION(0x1, "dev", "ad5"), | ||
241 | MPP_FUNCTION(0x2, "audio", "mclk")), | ||
242 | MPP_MODE(45, | ||
243 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
244 | MPP_FUNCTION(0x1, "dev", "ad6"), | ||
245 | MPP_FUNCTION(0x2, "audio", "lrclk")), | ||
246 | MPP_MODE(46, | ||
247 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
248 | MPP_FUNCTION(0x1, "dev", "ad7"), | ||
249 | MPP_FUNCTION(0x2, "audio", "sdo")), | ||
250 | MPP_MODE(47, | ||
251 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
252 | MPP_FUNCTION(0x1, "dev", "ad8"), | ||
253 | MPP_FUNCTION(0x3, "sd0", "clk"), | ||
254 | MPP_FUNCTION(0x5, "audio", "spdifo")), | ||
255 | MPP_MODE(48, | ||
256 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
257 | MPP_FUNCTION(0x1, "dev", "ad9"), | ||
258 | MPP_FUNCTION(0x2, "uart0", "rts"), | ||
259 | MPP_FUNCTION(0x3, "sd0", "cmd"), | ||
260 | MPP_FUNCTION(0x4, "sata1", "prsnt"), | ||
261 | MPP_FUNCTION(0x5, "spi0", "cs1")), | ||
262 | MPP_MODE(49, | ||
263 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
264 | MPP_FUNCTION(0x1, "dev", "ad10"), | ||
265 | MPP_FUNCTION(0x2, "pcie", "clkreq1"), | ||
266 | MPP_FUNCTION(0x3, "sd0", "d0"), | ||
267 | MPP_FUNCTION(0x4, "spi1", "cs0"), | ||
268 | MPP_FUNCTION(0x5, "audio", "spdifi")), | ||
269 | MPP_MODE(50, | ||
270 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
271 | MPP_FUNCTION(0x1, "dev", "ad11"), | ||
272 | MPP_FUNCTION(0x2, "uart0", "cts"), | ||
273 | MPP_FUNCTION(0x3, "sd0", "d1"), | ||
274 | MPP_FUNCTION(0x4, "spi1", "miso"), | ||
275 | MPP_FUNCTION(0x5, "audio", "rmclk")), | ||
276 | MPP_MODE(51, | ||
277 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
278 | MPP_FUNCTION(0x1, "dev", "ad12"), | ||
279 | MPP_FUNCTION(0x2, "i2c1", "sda"), | ||
280 | MPP_FUNCTION(0x3, "sd0", "d2"), | ||
281 | MPP_FUNCTION(0x4, "spi1", "mosi")), | ||
282 | MPP_MODE(52, | ||
283 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
284 | MPP_FUNCTION(0x1, "dev", "ad13"), | ||
285 | MPP_FUNCTION(0x2, "i2c1", "sck"), | ||
286 | MPP_FUNCTION(0x3, "sd0", "d3"), | ||
287 | MPP_FUNCTION(0x4, "spi1", "sck")), | ||
288 | MPP_MODE(53, | ||
289 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
290 | MPP_FUNCTION(0x1, "dev", "ad14"), | ||
291 | MPP_FUNCTION(0x2, "sd0", "clk"), | ||
292 | MPP_FUNCTION(0x3, "tdm", "pclk"), | ||
293 | MPP_FUNCTION(0x4, "spi0", "cs2"), | ||
294 | MPP_FUNCTION(0x5, "pcie", "clkreq1")), | ||
295 | MPP_MODE(54, | ||
296 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
297 | MPP_FUNCTION(0x1, "dev", "ad15"), | ||
298 | MPP_FUNCTION(0x3, "tdm", "dtx")), | ||
299 | MPP_MODE(55, | ||
300 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
301 | MPP_FUNCTION(0x1, "dev", "cs1"), | ||
302 | MPP_FUNCTION(0x2, "uart1", "txd"), | ||
303 | MPP_FUNCTION(0x3, "tdm", "rst"), | ||
304 | MPP_FUNCTION(0x4, "sata1", "prsnt"), | ||
305 | MPP_FUNCTION(0x5, "sata0", "prsnt")), | ||
306 | MPP_MODE(56, | ||
307 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
308 | MPP_FUNCTION(0x1, "dev", "cs2"), | ||
309 | MPP_FUNCTION(0x2, "uart1", "cts"), | ||
310 | MPP_FUNCTION(0x3, "uart0", "cts"), | ||
311 | MPP_FUNCTION(0x4, "spi0", "cs3"), | ||
312 | MPP_FUNCTION(0x5, "pcie", "clkreq0"), | ||
313 | MPP_FUNCTION(0x6, "spi1", "cs1")), | ||
314 | MPP_MODE(57, | ||
315 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
316 | MPP_FUNCTION(0x1, "dev", "cs3"), | ||
317 | MPP_FUNCTION(0x2, "uart1", "rxd"), | ||
318 | MPP_FUNCTION(0x3, "tdm", "fsync"), | ||
319 | MPP_FUNCTION(0x4, "sata0", "prsnt"), | ||
320 | MPP_FUNCTION(0x5, "audio", "sdo")), | ||
321 | MPP_MODE(58, | ||
322 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
323 | MPP_FUNCTION(0x1, "dev", "cs0"), | ||
324 | MPP_FUNCTION(0x2, "uart1", "rts"), | ||
325 | MPP_FUNCTION(0x3, "tdm", "int"), | ||
326 | MPP_FUNCTION(0x5, "audio", "extclk"), | ||
327 | MPP_FUNCTION(0x6, "uart0", "rts")), | ||
328 | MPP_MODE(59, | ||
329 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
330 | MPP_FUNCTION(0x1, "dev", "ale0"), | ||
331 | MPP_FUNCTION(0x2, "uart1", "rts"), | ||
332 | MPP_FUNCTION(0x3, "uart0", "rts"), | ||
333 | MPP_FUNCTION(0x5, "audio", "bclk")), | ||
334 | MPP_MODE(60, | ||
335 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
336 | MPP_FUNCTION(0x1, "dev", "ale1"), | ||
337 | MPP_FUNCTION(0x2, "uart1", "rxd"), | ||
338 | MPP_FUNCTION(0x3, "sata0", "prsnt"), | ||
339 | MPP_FUNCTION(0x4, "pcie", "rst-out"), | ||
340 | MPP_FUNCTION(0x5, "audio", "sdi")), | ||
341 | MPP_MODE(61, | ||
342 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
343 | MPP_FUNCTION(0x1, "dev", "wen1"), | ||
344 | MPP_FUNCTION(0x2, "uart1", "txd"), | ||
345 | MPP_FUNCTION(0x5, "audio", "rclk")), | ||
346 | MPP_MODE(62, | ||
347 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
348 | MPP_FUNCTION(0x1, "dev", "a2"), | ||
349 | MPP_FUNCTION(0x2, "uart1", "cts"), | ||
350 | MPP_FUNCTION(0x3, "tdm", "drx"), | ||
351 | MPP_FUNCTION(0x4, "pcie", "clkreq0"), | ||
352 | MPP_FUNCTION(0x5, "audio", "mclk"), | ||
353 | MPP_FUNCTION(0x6, "uart0", "cts")), | ||
354 | MPP_MODE(63, | ||
355 | MPP_FUNCTION(0x0, "gpo", NULL), | ||
356 | MPP_FUNCTION(0x1, "spi0", "sck"), | ||
357 | MPP_FUNCTION(0x2, "tclk", NULL)), | ||
358 | MPP_MODE(64, | ||
359 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
360 | MPP_FUNCTION(0x1, "spi0", "miso"), | ||
361 | MPP_FUNCTION(0x2, "spi0-1", "cs1")), | ||
362 | MPP_MODE(65, | ||
363 | MPP_FUNCTION(0x0, "gpio", NULL), | ||
364 | MPP_FUNCTION(0x1, "spi0", "mosi"), | ||
365 | MPP_FUNCTION(0x2, "spi0-1", "cs2")), | ||
366 | }; | ||
367 | |||
368 | static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info; | ||
369 | |||
370 | static struct of_device_id armada_370_pinctrl_of_match[] __devinitdata = { | ||
371 | { .compatible = "marvell,mv88f6710-pinctrl" }, | ||
372 | { }, | ||
373 | }; | ||
374 | |||
375 | static struct mvebu_mpp_ctrl mv88f6710_mpp_controls[] = { | ||
376 | MPP_REG_CTRL(0, 65), | ||
377 | }; | ||
378 | |||
379 | static struct pinctrl_gpio_range mv88f6710_mpp_gpio_ranges[] = { | ||
380 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
381 | MPP_GPIO_RANGE(1, 32, 32, 32), | ||
382 | MPP_GPIO_RANGE(2, 64, 64, 2), | ||
383 | }; | ||
384 | |||
385 | static int __devinit armada_370_pinctrl_probe(struct platform_device *pdev) | ||
386 | { | ||
387 | struct mvebu_pinctrl_soc_info *soc = &armada_370_pinctrl_info; | ||
388 | |||
389 | soc->variant = 0; /* no variants for Armada 370 */ | ||
390 | soc->controls = mv88f6710_mpp_controls; | ||
391 | soc->ncontrols = ARRAY_SIZE(mv88f6710_mpp_controls); | ||
392 | soc->modes = mv88f6710_mpp_modes; | ||
393 | soc->nmodes = ARRAY_SIZE(mv88f6710_mpp_modes); | ||
394 | soc->gpioranges = mv88f6710_mpp_gpio_ranges; | ||
395 | soc->ngpioranges = ARRAY_SIZE(mv88f6710_mpp_gpio_ranges); | ||
396 | |||
397 | pdev->dev.platform_data = soc; | ||
398 | |||
399 | return mvebu_pinctrl_probe(pdev); | ||
400 | } | ||
401 | |||
402 | static int __devexit armada_370_pinctrl_remove(struct platform_device *pdev) | ||
403 | { | ||
404 | return mvebu_pinctrl_remove(pdev); | ||
405 | } | ||
406 | |||
407 | static struct platform_driver armada_370_pinctrl_driver = { | ||
408 | .driver = { | ||
409 | .name = "armada-370-pinctrl", | ||
410 | .owner = THIS_MODULE, | ||
411 | .of_match_table = of_match_ptr(armada_370_pinctrl_of_match), | ||
412 | }, | ||
413 | .probe = armada_370_pinctrl_probe, | ||
414 | .remove = __devexit_p(armada_370_pinctrl_remove), | ||
415 | }; | ||
416 | |||
417 | module_platform_driver(armada_370_pinctrl_driver); | ||
418 | |||
419 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||
420 | MODULE_DESCRIPTION("Marvell Armada 370 pinctrl driver"); | ||
421 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/pinctrl-armada-xp.c new file mode 100644 index 000000000000..40bd52a46b4e --- /dev/null +++ b/drivers/pinctrl/pinctrl-armada-xp.c | |||
@@ -0,0 +1,468 @@ | |||
1 | /* | ||
2 | * Marvell Armada XP pinctrl driver based on mvebu pinctrl core | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * | ||
6 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This file supports the three variants of Armada XP SoCs that are | ||
14 | * available: mv78230, mv78260 and mv78460. From a pin muxing | ||
15 | * perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460 | ||
16 | * both have 67 MPP pins (more GPIOs and address lines for the memory | ||
17 | * bus mainly). The only difference between the mv78260 and the | ||
18 | * mv78460 in terms of pin muxing is the addition of two functions on | ||
19 | * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two | ||
20 | * cores, mv78460 has four cores). | ||
21 | */ | ||
22 | |||
23 | #include <linux/err.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/of.h> | ||
30 | #include <linux/of_device.h> | ||
31 | #include <linux/pinctrl/pinctrl.h> | ||
32 | #include <linux/bitops.h> | ||
33 | |||
34 | #include "pinctrl-mvebu.h" | ||
35 | |||
36 | enum armada_xp_variant { | ||
37 | V_MV78230 = BIT(0), | ||
38 | V_MV78260 = BIT(1), | ||
39 | V_MV78460 = BIT(2), | ||
40 | V_MV78230_PLUS = (V_MV78230 | V_MV78260 | V_MV78460), | ||
41 | V_MV78260_PLUS = (V_MV78260 | V_MV78460), | ||
42 | }; | ||
43 | |||
44 | static struct mvebu_mpp_mode armada_xp_mpp_modes[] = { | ||
45 | MPP_MODE(0, | ||
46 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
47 | MPP_VAR_FUNCTION(0x1, "ge0", "txclko", V_MV78230_PLUS), | ||
48 | MPP_VAR_FUNCTION(0x4, "lcd", "d0", V_MV78230_PLUS)), | ||
49 | MPP_MODE(1, | ||
50 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
51 | MPP_VAR_FUNCTION(0x1, "ge0", "txd0", V_MV78230_PLUS), | ||
52 | MPP_VAR_FUNCTION(0x4, "lcd", "d1", V_MV78230_PLUS)), | ||
53 | MPP_MODE(2, | ||
54 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
55 | MPP_VAR_FUNCTION(0x1, "ge0", "txd1", V_MV78230_PLUS), | ||
56 | MPP_VAR_FUNCTION(0x4, "lcd", "d2", V_MV78230_PLUS)), | ||
57 | MPP_MODE(3, | ||
58 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
59 | MPP_VAR_FUNCTION(0x1, "ge0", "txd2", V_MV78230_PLUS), | ||
60 | MPP_VAR_FUNCTION(0x4, "lcd", "d3", V_MV78230_PLUS)), | ||
61 | MPP_MODE(4, | ||
62 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
63 | MPP_VAR_FUNCTION(0x1, "ge0", "txd3", V_MV78230_PLUS), | ||
64 | MPP_VAR_FUNCTION(0x4, "lcd", "d4", V_MV78230_PLUS)), | ||
65 | MPP_MODE(5, | ||
66 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
67 | MPP_VAR_FUNCTION(0x1, "ge0", "txctl", V_MV78230_PLUS), | ||
68 | MPP_VAR_FUNCTION(0x4, "lcd", "d5", V_MV78230_PLUS)), | ||
69 | MPP_MODE(6, | ||
70 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
71 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd0", V_MV78230_PLUS), | ||
72 | MPP_VAR_FUNCTION(0x4, "lcd", "d6", V_MV78230_PLUS)), | ||
73 | MPP_MODE(7, | ||
74 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
75 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd1", V_MV78230_PLUS), | ||
76 | MPP_VAR_FUNCTION(0x4, "lcd", "d7", V_MV78230_PLUS)), | ||
77 | MPP_MODE(8, | ||
78 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
79 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd2", V_MV78230_PLUS), | ||
80 | MPP_VAR_FUNCTION(0x4, "lcd", "d8", V_MV78230_PLUS)), | ||
81 | MPP_MODE(9, | ||
82 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
83 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd3", V_MV78230_PLUS), | ||
84 | MPP_VAR_FUNCTION(0x4, "lcd", "d9", V_MV78230_PLUS)), | ||
85 | MPP_MODE(10, | ||
86 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
87 | MPP_VAR_FUNCTION(0x1, "ge0", "rxctl", V_MV78230_PLUS), | ||
88 | MPP_VAR_FUNCTION(0x4, "lcd", "d10", V_MV78230_PLUS)), | ||
89 | MPP_MODE(11, | ||
90 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
91 | MPP_VAR_FUNCTION(0x1, "ge0", "rxclk", V_MV78230_PLUS), | ||
92 | MPP_VAR_FUNCTION(0x4, "lcd", "d11", V_MV78230_PLUS)), | ||
93 | MPP_MODE(12, | ||
94 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
95 | MPP_VAR_FUNCTION(0x1, "ge0", "txd4", V_MV78230_PLUS), | ||
96 | MPP_VAR_FUNCTION(0x2, "ge1", "clkout", V_MV78230_PLUS), | ||
97 | MPP_VAR_FUNCTION(0x4, "lcd", "d12", V_MV78230_PLUS)), | ||
98 | MPP_MODE(13, | ||
99 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
100 | MPP_VAR_FUNCTION(0x1, "ge0", "txd5", V_MV78230_PLUS), | ||
101 | MPP_VAR_FUNCTION(0x2, "ge1", "txd0", V_MV78230_PLUS), | ||
102 | MPP_VAR_FUNCTION(0x4, "lcd", "d13", V_MV78230_PLUS)), | ||
103 | MPP_MODE(14, | ||
104 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
105 | MPP_VAR_FUNCTION(0x1, "ge0", "txd6", V_MV78230_PLUS), | ||
106 | MPP_VAR_FUNCTION(0x2, "ge1", "txd1", V_MV78230_PLUS), | ||
107 | MPP_VAR_FUNCTION(0x4, "lcd", "d14", V_MV78230_PLUS)), | ||
108 | MPP_MODE(15, | ||
109 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
110 | MPP_VAR_FUNCTION(0x1, "ge0", "txd7", V_MV78230_PLUS), | ||
111 | MPP_VAR_FUNCTION(0x2, "ge1", "txd2", V_MV78230_PLUS), | ||
112 | MPP_VAR_FUNCTION(0x4, "lcd", "d15", V_MV78230_PLUS)), | ||
113 | MPP_MODE(16, | ||
114 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
115 | MPP_VAR_FUNCTION(0x1, "ge0", "txclk", V_MV78230_PLUS), | ||
116 | MPP_VAR_FUNCTION(0x2, "ge1", "txd3", V_MV78230_PLUS), | ||
117 | MPP_VAR_FUNCTION(0x4, "lcd", "d16", V_MV78230_PLUS)), | ||
118 | MPP_MODE(17, | ||
119 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
120 | MPP_VAR_FUNCTION(0x1, "ge0", "col", V_MV78230_PLUS), | ||
121 | MPP_VAR_FUNCTION(0x2, "ge1", "txctl", V_MV78230_PLUS), | ||
122 | MPP_VAR_FUNCTION(0x4, "lcd", "d17", V_MV78230_PLUS)), | ||
123 | MPP_MODE(18, | ||
124 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
125 | MPP_VAR_FUNCTION(0x1, "ge0", "rxerr", V_MV78230_PLUS), | ||
126 | MPP_VAR_FUNCTION(0x2, "ge1", "rxd0", V_MV78230_PLUS), | ||
127 | MPP_VAR_FUNCTION(0x3, "ptp", "trig", V_MV78230_PLUS), | ||
128 | MPP_VAR_FUNCTION(0x4, "lcd", "d18", V_MV78230_PLUS)), | ||
129 | MPP_MODE(19, | ||
130 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
131 | MPP_VAR_FUNCTION(0x1, "ge0", "crs", V_MV78230_PLUS), | ||
132 | MPP_VAR_FUNCTION(0x2, "ge1", "rxd1", V_MV78230_PLUS), | ||
133 | MPP_VAR_FUNCTION(0x3, "ptp", "evreq", V_MV78230_PLUS), | ||
134 | MPP_VAR_FUNCTION(0x4, "lcd", "d19", V_MV78230_PLUS)), | ||
135 | MPP_MODE(20, | ||
136 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
137 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd4", V_MV78230_PLUS), | ||
138 | MPP_VAR_FUNCTION(0x2, "ge1", "rxd2", V_MV78230_PLUS), | ||
139 | MPP_VAR_FUNCTION(0x3, "ptp", "clk", V_MV78230_PLUS), | ||
140 | MPP_VAR_FUNCTION(0x4, "lcd", "d20", V_MV78230_PLUS)), | ||
141 | MPP_MODE(21, | ||
142 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
143 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd5", V_MV78230_PLUS), | ||
144 | MPP_VAR_FUNCTION(0x2, "ge1", "rxd3", V_MV78230_PLUS), | ||
145 | MPP_VAR_FUNCTION(0x3, "mem", "bat", V_MV78230_PLUS), | ||
146 | MPP_VAR_FUNCTION(0x4, "lcd", "d21", V_MV78230_PLUS)), | ||
147 | MPP_MODE(22, | ||
148 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
149 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd6", V_MV78230_PLUS), | ||
150 | MPP_VAR_FUNCTION(0x2, "ge1", "rxctl", V_MV78230_PLUS), | ||
151 | MPP_VAR_FUNCTION(0x3, "sata0", "prsnt", V_MV78230_PLUS), | ||
152 | MPP_VAR_FUNCTION(0x4, "lcd", "d22", V_MV78230_PLUS)), | ||
153 | MPP_MODE(23, | ||
154 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
155 | MPP_VAR_FUNCTION(0x1, "ge0", "rxd7", V_MV78230_PLUS), | ||
156 | MPP_VAR_FUNCTION(0x2, "ge1", "rxclk", V_MV78230_PLUS), | ||
157 | MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS), | ||
158 | MPP_VAR_FUNCTION(0x4, "lcd", "d23", V_MV78230_PLUS)), | ||
159 | MPP_MODE(24, | ||
160 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
161 | MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS), | ||
162 | MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS), | ||
163 | MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS), | ||
164 | MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)), | ||
165 | MPP_MODE(25, | ||
166 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
167 | MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS), | ||
168 | MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS), | ||
169 | MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS), | ||
170 | MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)), | ||
171 | MPP_MODE(26, | ||
172 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
173 | MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS), | ||
174 | MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS), | ||
175 | MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), | ||
176 | MPP_MODE(27, | ||
177 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
178 | MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS), | ||
179 | MPP_VAR_FUNCTION(0x3, "tdm", "dtx", V_MV78230_PLUS), | ||
180 | MPP_VAR_FUNCTION(0x4, "lcd", "e", V_MV78230_PLUS)), | ||
181 | MPP_MODE(28, | ||
182 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
183 | MPP_VAR_FUNCTION(0x1, "ptp", "evreq", V_MV78230_PLUS), | ||
184 | MPP_VAR_FUNCTION(0x3, "tdm", "drx", V_MV78230_PLUS), | ||
185 | MPP_VAR_FUNCTION(0x4, "lcd", "pwm", V_MV78230_PLUS)), | ||
186 | MPP_MODE(29, | ||
187 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
188 | MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS), | ||
189 | MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS), | ||
190 | MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS), | ||
191 | MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), | ||
192 | MPP_MODE(30, | ||
193 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
194 | MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS), | ||
195 | MPP_VAR_FUNCTION(0x3, "tdm", "int1", V_MV78230_PLUS)), | ||
196 | MPP_MODE(31, | ||
197 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
198 | MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS), | ||
199 | MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS), | ||
200 | MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), | ||
201 | MPP_MODE(32, | ||
202 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
203 | MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS), | ||
204 | MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS), | ||
205 | MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)), | ||
206 | MPP_MODE(33, | ||
207 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
208 | MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS), | ||
209 | MPP_VAR_FUNCTION(0x3, "tdm", "int4", V_MV78230_PLUS), | ||
210 | MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS)), | ||
211 | MPP_MODE(34, | ||
212 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
213 | MPP_VAR_FUNCTION(0x1, "sd0", "d2", V_MV78230_PLUS), | ||
214 | MPP_VAR_FUNCTION(0x2, "sata0", "prsnt", V_MV78230_PLUS), | ||
215 | MPP_VAR_FUNCTION(0x3, "tdm", "int5", V_MV78230_PLUS)), | ||
216 | MPP_MODE(35, | ||
217 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
218 | MPP_VAR_FUNCTION(0x1, "sd0", "d3", V_MV78230_PLUS), | ||
219 | MPP_VAR_FUNCTION(0x2, "sata1", "prsnt", V_MV78230_PLUS), | ||
220 | MPP_VAR_FUNCTION(0x3, "tdm", "int6", V_MV78230_PLUS)), | ||
221 | MPP_MODE(36, | ||
222 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
223 | MPP_VAR_FUNCTION(0x1, "spi", "mosi", V_MV78230_PLUS)), | ||
224 | MPP_MODE(37, | ||
225 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
226 | MPP_VAR_FUNCTION(0x1, "spi", "miso", V_MV78230_PLUS)), | ||
227 | MPP_MODE(38, | ||
228 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
229 | MPP_VAR_FUNCTION(0x1, "spi", "sck", V_MV78230_PLUS)), | ||
230 | MPP_MODE(39, | ||
231 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
232 | MPP_VAR_FUNCTION(0x1, "spi", "cs0", V_MV78230_PLUS)), | ||
233 | MPP_MODE(40, | ||
234 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
235 | MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS), | ||
236 | MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS), | ||
237 | MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS), | ||
238 | MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS), | ||
239 | MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)), | ||
240 | MPP_MODE(41, | ||
241 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
242 | MPP_VAR_FUNCTION(0x1, "spi", "cs2", V_MV78230_PLUS), | ||
243 | MPP_VAR_FUNCTION(0x2, "uart2", "rts", V_MV78230_PLUS), | ||
244 | MPP_VAR_FUNCTION(0x3, "sata1", "prsnt", V_MV78230_PLUS), | ||
245 | MPP_VAR_FUNCTION(0x4, "lcd", "vga-vsync", V_MV78230_PLUS), | ||
246 | MPP_VAR_FUNCTION(0x5, "pcie", "clkreq1", V_MV78230_PLUS)), | ||
247 | MPP_MODE(42, | ||
248 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
249 | MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS), | ||
250 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS), | ||
251 | MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS), | ||
252 | MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS), | ||
253 | MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)), | ||
254 | MPP_MODE(43, | ||
255 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
256 | MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS), | ||
257 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS), | ||
258 | MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS), | ||
259 | MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS), | ||
260 | MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)), | ||
261 | MPP_MODE(44, | ||
262 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
263 | MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS), | ||
264 | MPP_VAR_FUNCTION(0x2, "uart3", "rxd", V_MV78230_PLUS), | ||
265 | MPP_VAR_FUNCTION(0x3, "spi", "cs4", V_MV78230_PLUS), | ||
266 | MPP_VAR_FUNCTION(0x4, "mem", "bat", V_MV78230_PLUS), | ||
267 | MPP_VAR_FUNCTION(0x5, "pcie", "clkreq2", V_MV78230_PLUS)), | ||
268 | MPP_MODE(45, | ||
269 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
270 | MPP_VAR_FUNCTION(0x1, "uart2", "rts", V_MV78230_PLUS), | ||
271 | MPP_VAR_FUNCTION(0x2, "uart3", "txd", V_MV78230_PLUS), | ||
272 | MPP_VAR_FUNCTION(0x3, "spi", "cs5", V_MV78230_PLUS), | ||
273 | MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V_MV78230_PLUS)), | ||
274 | MPP_MODE(46, | ||
275 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
276 | MPP_VAR_FUNCTION(0x1, "uart3", "rts", V_MV78230_PLUS), | ||
277 | MPP_VAR_FUNCTION(0x2, "uart1", "rts", V_MV78230_PLUS), | ||
278 | MPP_VAR_FUNCTION(0x3, "spi", "cs6", V_MV78230_PLUS), | ||
279 | MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V_MV78230_PLUS)), | ||
280 | MPP_MODE(47, | ||
281 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
282 | MPP_VAR_FUNCTION(0x1, "uart3", "cts", V_MV78230_PLUS), | ||
283 | MPP_VAR_FUNCTION(0x2, "uart1", "cts", V_MV78230_PLUS), | ||
284 | MPP_VAR_FUNCTION(0x3, "spi", "cs7", V_MV78230_PLUS), | ||
285 | MPP_VAR_FUNCTION(0x4, "ref", "clkout", V_MV78230_PLUS), | ||
286 | MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)), | ||
287 | MPP_MODE(48, | ||
288 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS), | ||
289 | MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS), | ||
290 | MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)), | ||
291 | MPP_MODE(49, | ||
292 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
293 | MPP_VAR_FUNCTION(0x1, "dev", "we3", V_MV78260_PLUS)), | ||
294 | MPP_MODE(50, | ||
295 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
296 | MPP_VAR_FUNCTION(0x1, "dev", "we2", V_MV78260_PLUS)), | ||
297 | MPP_MODE(51, | ||
298 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
299 | MPP_VAR_FUNCTION(0x1, "dev", "ad16", V_MV78260_PLUS)), | ||
300 | MPP_MODE(52, | ||
301 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
302 | MPP_VAR_FUNCTION(0x1, "dev", "ad17", V_MV78260_PLUS)), | ||
303 | MPP_MODE(53, | ||
304 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
305 | MPP_VAR_FUNCTION(0x1, "dev", "ad18", V_MV78260_PLUS)), | ||
306 | MPP_MODE(54, | ||
307 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
308 | MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)), | ||
309 | MPP_MODE(55, | ||
310 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
311 | MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS), | ||
312 | MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)), | ||
313 | MPP_MODE(56, | ||
314 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
315 | MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS), | ||
316 | MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)), | ||
317 | MPP_MODE(57, | ||
318 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
319 | MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS), | ||
320 | MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)), | ||
321 | MPP_MODE(58, | ||
322 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
323 | MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)), | ||
324 | MPP_MODE(59, | ||
325 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
326 | MPP_VAR_FUNCTION(0x1, "dev", "ad24", V_MV78260_PLUS)), | ||
327 | MPP_MODE(60, | ||
328 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
329 | MPP_VAR_FUNCTION(0x1, "dev", "ad25", V_MV78260_PLUS)), | ||
330 | MPP_MODE(61, | ||
331 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
332 | MPP_VAR_FUNCTION(0x1, "dev", "ad26", V_MV78260_PLUS)), | ||
333 | MPP_MODE(62, | ||
334 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
335 | MPP_VAR_FUNCTION(0x1, "dev", "ad27", V_MV78260_PLUS)), | ||
336 | MPP_MODE(63, | ||
337 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
338 | MPP_VAR_FUNCTION(0x1, "dev", "ad28", V_MV78260_PLUS)), | ||
339 | MPP_MODE(64, | ||
340 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
341 | MPP_VAR_FUNCTION(0x1, "dev", "ad29", V_MV78260_PLUS)), | ||
342 | MPP_MODE(65, | ||
343 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
344 | MPP_VAR_FUNCTION(0x1, "dev", "ad30", V_MV78260_PLUS)), | ||
345 | MPP_MODE(66, | ||
346 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS), | ||
347 | MPP_VAR_FUNCTION(0x1, "dev", "ad31", V_MV78260_PLUS)), | ||
348 | }; | ||
349 | |||
350 | static struct mvebu_pinctrl_soc_info armada_xp_pinctrl_info; | ||
351 | |||
352 | static struct of_device_id armada_xp_pinctrl_of_match[] __devinitdata = { | ||
353 | { | ||
354 | .compatible = "marvell,mv78230-pinctrl", | ||
355 | .data = (void *) V_MV78230, | ||
356 | }, | ||
357 | { | ||
358 | .compatible = "marvell,mv78260-pinctrl", | ||
359 | .data = (void *) V_MV78260, | ||
360 | }, | ||
361 | { | ||
362 | .compatible = "marvell,mv78460-pinctrl", | ||
363 | .data = (void *) V_MV78460, | ||
364 | }, | ||
365 | { }, | ||
366 | }; | ||
367 | |||
368 | static struct mvebu_mpp_ctrl mv78230_mpp_controls[] = { | ||
369 | MPP_REG_CTRL(0, 48), | ||
370 | }; | ||
371 | |||
372 | static struct pinctrl_gpio_range mv78230_mpp_gpio_ranges[] = { | ||
373 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
374 | MPP_GPIO_RANGE(1, 32, 32, 17), | ||
375 | }; | ||
376 | |||
377 | static struct mvebu_mpp_ctrl mv78260_mpp_controls[] = { | ||
378 | MPP_REG_CTRL(0, 66), | ||
379 | }; | ||
380 | |||
381 | static struct pinctrl_gpio_range mv78260_mpp_gpio_ranges[] = { | ||
382 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
383 | MPP_GPIO_RANGE(1, 32, 32, 32), | ||
384 | MPP_GPIO_RANGE(2, 64, 64, 3), | ||
385 | }; | ||
386 | |||
387 | static struct mvebu_mpp_ctrl mv78460_mpp_controls[] = { | ||
388 | MPP_REG_CTRL(0, 66), | ||
389 | }; | ||
390 | |||
391 | static struct pinctrl_gpio_range mv78460_mpp_gpio_ranges[] = { | ||
392 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
393 | MPP_GPIO_RANGE(1, 32, 32, 32), | ||
394 | MPP_GPIO_RANGE(2, 64, 64, 3), | ||
395 | }; | ||
396 | |||
397 | static int __devinit armada_xp_pinctrl_probe(struct platform_device *pdev) | ||
398 | { | ||
399 | struct mvebu_pinctrl_soc_info *soc = &armada_xp_pinctrl_info; | ||
400 | const struct of_device_id *match = | ||
401 | of_match_device(armada_xp_pinctrl_of_match, &pdev->dev); | ||
402 | |||
403 | if (!match) | ||
404 | return -ENODEV; | ||
405 | |||
406 | soc->variant = (unsigned) match->data & 0xff; | ||
407 | |||
408 | switch (soc->variant) { | ||
409 | case V_MV78230: | ||
410 | soc->controls = mv78230_mpp_controls; | ||
411 | soc->ncontrols = ARRAY_SIZE(mv78230_mpp_controls); | ||
412 | soc->modes = armada_xp_mpp_modes; | ||
413 | /* We don't necessarily want the full list of the | ||
414 | * armada_xp_mpp_modes, but only the first 'n' ones | ||
415 | * that are available on this SoC */ | ||
416 | soc->nmodes = mv78230_mpp_controls[0].npins; | ||
417 | soc->gpioranges = mv78230_mpp_gpio_ranges; | ||
418 | soc->ngpioranges = ARRAY_SIZE(mv78230_mpp_gpio_ranges); | ||
419 | break; | ||
420 | case V_MV78260: | ||
421 | soc->controls = mv78260_mpp_controls; | ||
422 | soc->ncontrols = ARRAY_SIZE(mv78260_mpp_controls); | ||
423 | soc->modes = armada_xp_mpp_modes; | ||
424 | /* We don't necessarily want the full list of the | ||
425 | * armada_xp_mpp_modes, but only the first 'n' ones | ||
426 | * that are available on this SoC */ | ||
427 | soc->nmodes = mv78260_mpp_controls[0].npins; | ||
428 | soc->gpioranges = mv78260_mpp_gpio_ranges; | ||
429 | soc->ngpioranges = ARRAY_SIZE(mv78260_mpp_gpio_ranges); | ||
430 | break; | ||
431 | case V_MV78460: | ||
432 | soc->controls = mv78460_mpp_controls; | ||
433 | soc->ncontrols = ARRAY_SIZE(mv78460_mpp_controls); | ||
434 | soc->modes = armada_xp_mpp_modes; | ||
435 | /* We don't necessarily want the full list of the | ||
436 | * armada_xp_mpp_modes, but only the first 'n' ones | ||
437 | * that are available on this SoC */ | ||
438 | soc->nmodes = mv78460_mpp_controls[0].npins; | ||
439 | soc->gpioranges = mv78460_mpp_gpio_ranges; | ||
440 | soc->ngpioranges = ARRAY_SIZE(mv78460_mpp_gpio_ranges); | ||
441 | break; | ||
442 | } | ||
443 | |||
444 | pdev->dev.platform_data = soc; | ||
445 | |||
446 | return mvebu_pinctrl_probe(pdev); | ||
447 | } | ||
448 | |||
449 | static int __devexit armada_xp_pinctrl_remove(struct platform_device *pdev) | ||
450 | { | ||
451 | return mvebu_pinctrl_remove(pdev); | ||
452 | } | ||
453 | |||
454 | static struct platform_driver armada_xp_pinctrl_driver = { | ||
455 | .driver = { | ||
456 | .name = "armada-xp-pinctrl", | ||
457 | .owner = THIS_MODULE, | ||
458 | .of_match_table = of_match_ptr(armada_xp_pinctrl_of_match), | ||
459 | }, | ||
460 | .probe = armada_xp_pinctrl_probe, | ||
461 | .remove = __devexit_p(armada_xp_pinctrl_remove), | ||
462 | }; | ||
463 | |||
464 | module_platform_driver(armada_xp_pinctrl_driver); | ||
465 | |||
466 | MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); | ||
467 | MODULE_DESCRIPTION("Marvell Armada XP pinctrl driver"); | ||
468 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/pinctrl-dove.c new file mode 100644 index 000000000000..ffe74b27d66d --- /dev/null +++ b/drivers/pinctrl/pinctrl-dove.c | |||
@@ -0,0 +1,620 @@ | |||
1 | /* | ||
2 | * Marvell Dove pinctrl driver based on mvebu pinctrl core | ||
3 | * | ||
4 | * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/err.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/bitops.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_device.h> | ||
21 | #include <linux/pinctrl/pinctrl.h> | ||
22 | |||
23 | #include "pinctrl-mvebu.h" | ||
24 | |||
25 | #define DOVE_SB_REGS_VIRT_BASE 0xfde00000 | ||
26 | #define DOVE_MPP_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0200) | ||
27 | #define DOVE_PMU_MPP_GENERAL_CTRL (DOVE_MPP_VIRT_BASE + 0x10) | ||
28 | #define DOVE_AU0_AC97_SEL BIT(16) | ||
29 | #define DOVE_GLOBAL_CONFIG_1 (DOVE_SB_REGS_VIRT_BASE | 0xe802C) | ||
30 | #define DOVE_TWSI_ENABLE_OPTION1 BIT(7) | ||
31 | #define DOVE_GLOBAL_CONFIG_2 (DOVE_SB_REGS_VIRT_BASE | 0xe8030) | ||
32 | #define DOVE_TWSI_ENABLE_OPTION2 BIT(20) | ||
33 | #define DOVE_TWSI_ENABLE_OPTION3 BIT(21) | ||
34 | #define DOVE_TWSI_OPTION3_GPIO BIT(22) | ||
35 | #define DOVE_SSP_CTRL_STATUS_1 (DOVE_SB_REGS_VIRT_BASE | 0xe8034) | ||
36 | #define DOVE_SSP_ON_AU1 BIT(0) | ||
37 | #define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c) | ||
38 | #define DOVE_AU1_SPDIFO_GPIO_EN BIT(1) | ||
39 | #define DOVE_NAND_GPIO_EN BIT(0) | ||
40 | #define DOVE_GPIO_LO_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xd0400) | ||
41 | #define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40) | ||
42 | #define DOVE_SPI_GPIO_SEL BIT(5) | ||
43 | #define DOVE_UART1_GPIO_SEL BIT(4) | ||
44 | #define DOVE_AU1_GPIO_SEL BIT(3) | ||
45 | #define DOVE_CAM_GPIO_SEL BIT(2) | ||
46 | #define DOVE_SD1_GPIO_SEL BIT(1) | ||
47 | #define DOVE_SD0_GPIO_SEL BIT(0) | ||
48 | |||
49 | #define MPPS_PER_REG 8 | ||
50 | #define MPP_BITS 4 | ||
51 | #define MPP_MASK 0xf | ||
52 | |||
53 | #define CONFIG_PMU BIT(4) | ||
54 | |||
55 | static int dove_pmu_mpp_ctrl_get(struct mvebu_mpp_ctrl *ctrl, | ||
56 | unsigned long *config) | ||
57 | { | ||
58 | unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; | ||
59 | unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; | ||
60 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | ||
61 | unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off); | ||
62 | |||
63 | if (pmu & (1 << ctrl->pid)) | ||
64 | *config = CONFIG_PMU; | ||
65 | else | ||
66 | *config = (mpp >> shift) & MPP_MASK; | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int dove_pmu_mpp_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | ||
71 | unsigned long config) | ||
72 | { | ||
73 | unsigned off = (ctrl->pid / MPPS_PER_REG) * MPP_BITS; | ||
74 | unsigned shift = (ctrl->pid % MPPS_PER_REG) * MPP_BITS; | ||
75 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | ||
76 | unsigned long mpp = readl(DOVE_MPP_VIRT_BASE + off); | ||
77 | |||
78 | if (config == CONFIG_PMU) | ||
79 | writel(pmu | (1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); | ||
80 | else { | ||
81 | writel(pmu & ~(1 << ctrl->pid), DOVE_PMU_MPP_GENERAL_CTRL); | ||
82 | mpp &= ~(MPP_MASK << shift); | ||
83 | mpp |= config << shift; | ||
84 | writel(mpp, DOVE_MPP_VIRT_BASE + off); | ||
85 | } | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int dove_mpp4_ctrl_get(struct mvebu_mpp_ctrl *ctrl, | ||
90 | unsigned long *config) | ||
91 | { | ||
92 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | ||
93 | unsigned long mask; | ||
94 | |||
95 | switch (ctrl->pid) { | ||
96 | case 24: /* mpp_camera */ | ||
97 | mask = DOVE_CAM_GPIO_SEL; | ||
98 | break; | ||
99 | case 40: /* mpp_sdio0 */ | ||
100 | mask = DOVE_SD0_GPIO_SEL; | ||
101 | break; | ||
102 | case 46: /* mpp_sdio1 */ | ||
103 | mask = DOVE_SD1_GPIO_SEL; | ||
104 | break; | ||
105 | case 58: /* mpp_spi0 */ | ||
106 | mask = DOVE_SPI_GPIO_SEL; | ||
107 | break; | ||
108 | case 62: /* mpp_uart1 */ | ||
109 | mask = DOVE_UART1_GPIO_SEL; | ||
110 | break; | ||
111 | default: | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | |||
115 | *config = ((mpp4 & mask) != 0); | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int dove_mpp4_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | ||
121 | unsigned long config) | ||
122 | { | ||
123 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | ||
124 | unsigned long mask; | ||
125 | |||
126 | switch (ctrl->pid) { | ||
127 | case 24: /* mpp_camera */ | ||
128 | mask = DOVE_CAM_GPIO_SEL; | ||
129 | break; | ||
130 | case 40: /* mpp_sdio0 */ | ||
131 | mask = DOVE_SD0_GPIO_SEL; | ||
132 | break; | ||
133 | case 46: /* mpp_sdio1 */ | ||
134 | mask = DOVE_SD1_GPIO_SEL; | ||
135 | break; | ||
136 | case 58: /* mpp_spi0 */ | ||
137 | mask = DOVE_SPI_GPIO_SEL; | ||
138 | break; | ||
139 | case 62: /* mpp_uart1 */ | ||
140 | mask = DOVE_UART1_GPIO_SEL; | ||
141 | break; | ||
142 | default: | ||
143 | return -EINVAL; | ||
144 | } | ||
145 | |||
146 | mpp4 &= ~mask; | ||
147 | if (config) | ||
148 | mpp4 |= mask; | ||
149 | |||
150 | writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); | ||
151 | |||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int dove_nand_ctrl_get(struct mvebu_mpp_ctrl *ctrl, | ||
156 | unsigned long *config) | ||
157 | { | ||
158 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
159 | |||
160 | *config = ((gmpp & DOVE_NAND_GPIO_EN) != 0); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int dove_nand_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | ||
166 | unsigned long config) | ||
167 | { | ||
168 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
169 | |||
170 | gmpp &= ~DOVE_NAND_GPIO_EN; | ||
171 | if (config) | ||
172 | gmpp |= DOVE_NAND_GPIO_EN; | ||
173 | |||
174 | writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int dove_audio0_ctrl_get(struct mvebu_mpp_ctrl *ctrl, | ||
180 | unsigned long *config) | ||
181 | { | ||
182 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | ||
183 | |||
184 | *config = ((pmu & DOVE_AU0_AC97_SEL) != 0); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int dove_audio0_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | ||
190 | unsigned long config) | ||
191 | { | ||
192 | unsigned long pmu = readl(DOVE_PMU_MPP_GENERAL_CTRL); | ||
193 | |||
194 | pmu &= ~DOVE_AU0_AC97_SEL; | ||
195 | if (config) | ||
196 | pmu |= DOVE_AU0_AC97_SEL; | ||
197 | writel(pmu, DOVE_PMU_MPP_GENERAL_CTRL); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int dove_audio1_ctrl_get(struct mvebu_mpp_ctrl *ctrl, | ||
203 | unsigned long *config) | ||
204 | { | ||
205 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | ||
206 | unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); | ||
207 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
208 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
209 | |||
210 | *config = 0; | ||
211 | if (mpp4 & DOVE_AU1_GPIO_SEL) | ||
212 | *config |= BIT(3); | ||
213 | if (sspc1 & DOVE_SSP_ON_AU1) | ||
214 | *config |= BIT(2); | ||
215 | if (gmpp & DOVE_AU1_SPDIFO_GPIO_EN) | ||
216 | *config |= BIT(1); | ||
217 | if (gcfg2 & DOVE_TWSI_OPTION3_GPIO) | ||
218 | *config |= BIT(0); | ||
219 | |||
220 | /* SSP/TWSI only if I2S1 not set*/ | ||
221 | if ((*config & BIT(3)) == 0) | ||
222 | *config &= ~(BIT(2) | BIT(0)); | ||
223 | /* TWSI only if SPDIFO not set*/ | ||
224 | if ((*config & BIT(1)) == 0) | ||
225 | *config &= ~BIT(0); | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int dove_audio1_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | ||
230 | unsigned long config) | ||
231 | { | ||
232 | unsigned long mpp4 = readl(DOVE_MPP_CTRL4_VIRT_BASE); | ||
233 | unsigned long sspc1 = readl(DOVE_SSP_CTRL_STATUS_1); | ||
234 | unsigned long gmpp = readl(DOVE_MPP_GENERAL_VIRT_BASE); | ||
235 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
236 | |||
237 | if (config & BIT(0)) | ||
238 | gcfg2 |= DOVE_TWSI_OPTION3_GPIO; | ||
239 | if (config & BIT(1)) | ||
240 | gmpp |= DOVE_AU1_SPDIFO_GPIO_EN; | ||
241 | if (config & BIT(2)) | ||
242 | sspc1 |= DOVE_SSP_ON_AU1; | ||
243 | if (config & BIT(3)) | ||
244 | mpp4 |= DOVE_AU1_GPIO_SEL; | ||
245 | |||
246 | writel(mpp4, DOVE_MPP_CTRL4_VIRT_BASE); | ||
247 | writel(sspc1, DOVE_SSP_CTRL_STATUS_1); | ||
248 | writel(gmpp, DOVE_MPP_GENERAL_VIRT_BASE); | ||
249 | writel(gcfg2, DOVE_GLOBAL_CONFIG_2); | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | /* mpp[52:57] gpio pins depend heavily on current config; | ||
255 | * gpio_req does not try to mux in gpio capabilities to not | ||
256 | * break other functions. If you require all mpps as gpio | ||
257 | * enforce gpio setting by pinctrl mapping. | ||
258 | */ | ||
259 | static int dove_audio1_ctrl_gpio_req(struct mvebu_mpp_ctrl *ctrl, u8 pid) | ||
260 | { | ||
261 | unsigned long config; | ||
262 | |||
263 | dove_audio1_ctrl_get(ctrl, &config); | ||
264 | |||
265 | switch (config) { | ||
266 | case 0x02: /* i2s1 : gpio[56:57] */ | ||
267 | case 0x0e: /* ssp : gpio[56:57] */ | ||
268 | if (pid >= 56) | ||
269 | return 0; | ||
270 | return -ENOTSUPP; | ||
271 | case 0x08: /* spdifo : gpio[52:55] */ | ||
272 | case 0x0b: /* twsi : gpio[52:55] */ | ||
273 | if (pid <= 55) | ||
274 | return 0; | ||
275 | return -ENOTSUPP; | ||
276 | case 0x0a: /* all gpio */ | ||
277 | return 0; | ||
278 | /* 0x00 : i2s1/spdifo : no gpio */ | ||
279 | /* 0x0c : ssp/spdifo : no gpio */ | ||
280 | /* 0x0f : ssp/twsi : no gpio */ | ||
281 | } | ||
282 | return -ENOTSUPP; | ||
283 | } | ||
284 | |||
285 | /* mpp[52:57] has gpio pins capable of in and out */ | ||
286 | static int dove_audio1_ctrl_gpio_dir(struct mvebu_mpp_ctrl *ctrl, u8 pid, | ||
287 | bool input) | ||
288 | { | ||
289 | if (pid < 52 || pid > 57) | ||
290 | return -ENOTSUPP; | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int dove_twsi_ctrl_get(struct mvebu_mpp_ctrl *ctrl, | ||
295 | unsigned long *config) | ||
296 | { | ||
297 | unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); | ||
298 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
299 | |||
300 | *config = 0; | ||
301 | if (gcfg1 & DOVE_TWSI_ENABLE_OPTION1) | ||
302 | *config = 1; | ||
303 | else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION2) | ||
304 | *config = 2; | ||
305 | else if (gcfg2 & DOVE_TWSI_ENABLE_OPTION3) | ||
306 | *config = 3; | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int dove_twsi_ctrl_set(struct mvebu_mpp_ctrl *ctrl, | ||
312 | unsigned long config) | ||
313 | { | ||
314 | unsigned long gcfg1 = readl(DOVE_GLOBAL_CONFIG_1); | ||
315 | unsigned long gcfg2 = readl(DOVE_GLOBAL_CONFIG_2); | ||
316 | |||
317 | gcfg1 &= ~DOVE_TWSI_ENABLE_OPTION1; | ||
318 | gcfg2 &= ~(DOVE_TWSI_ENABLE_OPTION2 | DOVE_TWSI_ENABLE_OPTION2); | ||
319 | |||
320 | switch (config) { | ||
321 | case 1: | ||
322 | gcfg1 |= DOVE_TWSI_ENABLE_OPTION1; | ||
323 | break; | ||
324 | case 2: | ||
325 | gcfg2 |= DOVE_TWSI_ENABLE_OPTION2; | ||
326 | break; | ||
327 | case 3: | ||
328 | gcfg2 |= DOVE_TWSI_ENABLE_OPTION3; | ||
329 | break; | ||
330 | } | ||
331 | |||
332 | writel(gcfg1, DOVE_GLOBAL_CONFIG_1); | ||
333 | writel(gcfg2, DOVE_GLOBAL_CONFIG_2); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | static struct mvebu_mpp_ctrl dove_mpp_controls[] = { | ||
339 | MPP_FUNC_CTRL(0, 0, "mpp0", dove_pmu_mpp_ctrl), | ||
340 | MPP_FUNC_CTRL(1, 1, "mpp1", dove_pmu_mpp_ctrl), | ||
341 | MPP_FUNC_CTRL(2, 2, "mpp2", dove_pmu_mpp_ctrl), | ||
342 | MPP_FUNC_CTRL(3, 3, "mpp3", dove_pmu_mpp_ctrl), | ||
343 | MPP_FUNC_CTRL(4, 4, "mpp4", dove_pmu_mpp_ctrl), | ||
344 | MPP_FUNC_CTRL(5, 5, "mpp5", dove_pmu_mpp_ctrl), | ||
345 | MPP_FUNC_CTRL(6, 6, "mpp6", dove_pmu_mpp_ctrl), | ||
346 | MPP_FUNC_CTRL(7, 7, "mpp7", dove_pmu_mpp_ctrl), | ||
347 | MPP_FUNC_CTRL(8, 8, "mpp8", dove_pmu_mpp_ctrl), | ||
348 | MPP_FUNC_CTRL(9, 9, "mpp9", dove_pmu_mpp_ctrl), | ||
349 | MPP_FUNC_CTRL(10, 10, "mpp10", dove_pmu_mpp_ctrl), | ||
350 | MPP_FUNC_CTRL(11, 11, "mpp11", dove_pmu_mpp_ctrl), | ||
351 | MPP_FUNC_CTRL(12, 12, "mpp12", dove_pmu_mpp_ctrl), | ||
352 | MPP_FUNC_CTRL(13, 13, "mpp13", dove_pmu_mpp_ctrl), | ||
353 | MPP_FUNC_CTRL(14, 14, "mpp14", dove_pmu_mpp_ctrl), | ||
354 | MPP_FUNC_CTRL(15, 15, "mpp15", dove_pmu_mpp_ctrl), | ||
355 | MPP_REG_CTRL(16, 23), | ||
356 | MPP_FUNC_CTRL(24, 39, "mpp_camera", dove_mpp4_ctrl), | ||
357 | MPP_FUNC_CTRL(40, 45, "mpp_sdio0", dove_mpp4_ctrl), | ||
358 | MPP_FUNC_CTRL(46, 51, "mpp_sdio1", dove_mpp4_ctrl), | ||
359 | MPP_FUNC_GPIO_CTRL(52, 57, "mpp_audio1", dove_audio1_ctrl), | ||
360 | MPP_FUNC_CTRL(58, 61, "mpp_spi0", dove_mpp4_ctrl), | ||
361 | MPP_FUNC_CTRL(62, 63, "mpp_uart1", dove_mpp4_ctrl), | ||
362 | MPP_FUNC_CTRL(64, 71, "mpp_nand", dove_nand_ctrl), | ||
363 | MPP_FUNC_CTRL(72, 72, "audio0", dove_audio0_ctrl), | ||
364 | MPP_FUNC_CTRL(73, 73, "twsi", dove_twsi_ctrl), | ||
365 | }; | ||
366 | |||
367 | static struct mvebu_mpp_mode dove_mpp_modes[] = { | ||
368 | MPP_MODE(0, | ||
369 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
370 | MPP_FUNCTION(0x02, "uart2", "rts"), | ||
371 | MPP_FUNCTION(0x03, "sdio0", "cd"), | ||
372 | MPP_FUNCTION(0x0f, "lcd0", "pwm"), | ||
373 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
374 | MPP_MODE(1, | ||
375 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
376 | MPP_FUNCTION(0x02, "uart2", "cts"), | ||
377 | MPP_FUNCTION(0x03, "sdio0", "wp"), | ||
378 | MPP_FUNCTION(0x0f, "lcd1", "pwm"), | ||
379 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
380 | MPP_MODE(2, | ||
381 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
382 | MPP_FUNCTION(0x01, "sata", "prsnt"), | ||
383 | MPP_FUNCTION(0x02, "uart2", "txd"), | ||
384 | MPP_FUNCTION(0x03, "sdio0", "buspwr"), | ||
385 | MPP_FUNCTION(0x04, "uart1", "rts"), | ||
386 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
387 | MPP_MODE(3, | ||
388 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
389 | MPP_FUNCTION(0x01, "sata", "act"), | ||
390 | MPP_FUNCTION(0x02, "uart2", "rxd"), | ||
391 | MPP_FUNCTION(0x03, "sdio0", "ledctrl"), | ||
392 | MPP_FUNCTION(0x04, "uart1", "cts"), | ||
393 | MPP_FUNCTION(0x0f, "lcd-spi", "cs1"), | ||
394 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
395 | MPP_MODE(4, | ||
396 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
397 | MPP_FUNCTION(0x02, "uart3", "rts"), | ||
398 | MPP_FUNCTION(0x03, "sdio1", "cd"), | ||
399 | MPP_FUNCTION(0x04, "spi1", "miso"), | ||
400 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
401 | MPP_MODE(5, | ||
402 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
403 | MPP_FUNCTION(0x02, "uart3", "cts"), | ||
404 | MPP_FUNCTION(0x03, "sdio1", "wp"), | ||
405 | MPP_FUNCTION(0x04, "spi1", "cs"), | ||
406 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
407 | MPP_MODE(6, | ||
408 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
409 | MPP_FUNCTION(0x02, "uart3", "txd"), | ||
410 | MPP_FUNCTION(0x03, "sdio1", "buspwr"), | ||
411 | MPP_FUNCTION(0x04, "spi1", "mosi"), | ||
412 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
413 | MPP_MODE(7, | ||
414 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
415 | MPP_FUNCTION(0x02, "uart3", "rxd"), | ||
416 | MPP_FUNCTION(0x03, "sdio1", "ledctrl"), | ||
417 | MPP_FUNCTION(0x04, "spi1", "sck"), | ||
418 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
419 | MPP_MODE(8, | ||
420 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
421 | MPP_FUNCTION(0x01, "watchdog", "rstout"), | ||
422 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
423 | MPP_MODE(9, | ||
424 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
425 | MPP_FUNCTION(0x05, "pex1", "clkreq"), | ||
426 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
427 | MPP_MODE(10, | ||
428 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
429 | MPP_FUNCTION(0x05, "ssp", "sclk"), | ||
430 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
431 | MPP_MODE(11, | ||
432 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
433 | MPP_FUNCTION(0x01, "sata", "prsnt"), | ||
434 | MPP_FUNCTION(0x02, "sata-1", "act"), | ||
435 | MPP_FUNCTION(0x03, "sdio0", "ledctrl"), | ||
436 | MPP_FUNCTION(0x04, "sdio1", "ledctrl"), | ||
437 | MPP_FUNCTION(0x05, "pex0", "clkreq"), | ||
438 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
439 | MPP_MODE(12, | ||
440 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
441 | MPP_FUNCTION(0x01, "sata", "act"), | ||
442 | MPP_FUNCTION(0x02, "uart2", "rts"), | ||
443 | MPP_FUNCTION(0x03, "audio0", "extclk"), | ||
444 | MPP_FUNCTION(0x04, "sdio1", "cd"), | ||
445 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
446 | MPP_MODE(13, | ||
447 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
448 | MPP_FUNCTION(0x02, "uart2", "cts"), | ||
449 | MPP_FUNCTION(0x03, "audio1", "extclk"), | ||
450 | MPP_FUNCTION(0x04, "sdio1", "wp"), | ||
451 | MPP_FUNCTION(0x05, "ssp", "extclk"), | ||
452 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
453 | MPP_MODE(14, | ||
454 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
455 | MPP_FUNCTION(0x02, "uart2", "txd"), | ||
456 | MPP_FUNCTION(0x04, "sdio1", "buspwr"), | ||
457 | MPP_FUNCTION(0x05, "ssp", "rxd"), | ||
458 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
459 | MPP_MODE(15, | ||
460 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
461 | MPP_FUNCTION(0x02, "uart2", "rxd"), | ||
462 | MPP_FUNCTION(0x04, "sdio1", "ledctrl"), | ||
463 | MPP_FUNCTION(0x05, "ssp", "sfrm"), | ||
464 | MPP_FUNCTION(0x10, "pmu", NULL)), | ||
465 | MPP_MODE(16, | ||
466 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
467 | MPP_FUNCTION(0x02, "uart3", "rts"), | ||
468 | MPP_FUNCTION(0x03, "sdio0", "cd"), | ||
469 | MPP_FUNCTION(0x04, "lcd-spi", "cs1"), | ||
470 | MPP_FUNCTION(0x05, "ac97", "sdi1")), | ||
471 | MPP_MODE(17, | ||
472 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
473 | MPP_FUNCTION(0x01, "ac97-1", "sysclko"), | ||
474 | MPP_FUNCTION(0x02, "uart3", "cts"), | ||
475 | MPP_FUNCTION(0x03, "sdio0", "wp"), | ||
476 | MPP_FUNCTION(0x04, "twsi", "sda"), | ||
477 | MPP_FUNCTION(0x05, "ac97", "sdi2")), | ||
478 | MPP_MODE(18, | ||
479 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
480 | MPP_FUNCTION(0x02, "uart3", "txd"), | ||
481 | MPP_FUNCTION(0x03, "sdio0", "buspwr"), | ||
482 | MPP_FUNCTION(0x04, "lcd0", "pwm"), | ||
483 | MPP_FUNCTION(0x05, "ac97", "sdi3")), | ||
484 | MPP_MODE(19, | ||
485 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
486 | MPP_FUNCTION(0x02, "uart3", "rxd"), | ||
487 | MPP_FUNCTION(0x03, "sdio0", "ledctrl"), | ||
488 | MPP_FUNCTION(0x04, "twsi", "sck")), | ||
489 | MPP_MODE(20, | ||
490 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
491 | MPP_FUNCTION(0x01, "ac97", "sysclko"), | ||
492 | MPP_FUNCTION(0x02, "lcd-spi", "miso"), | ||
493 | MPP_FUNCTION(0x03, "sdio1", "cd"), | ||
494 | MPP_FUNCTION(0x05, "sdio0", "cd"), | ||
495 | MPP_FUNCTION(0x06, "spi1", "miso")), | ||
496 | MPP_MODE(21, | ||
497 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
498 | MPP_FUNCTION(0x01, "uart1", "rts"), | ||
499 | MPP_FUNCTION(0x02, "lcd-spi", "cs0"), | ||
500 | MPP_FUNCTION(0x03, "sdio1", "wp"), | ||
501 | MPP_FUNCTION(0x04, "ssp", "sfrm"), | ||
502 | MPP_FUNCTION(0x05, "sdio0", "wp"), | ||
503 | MPP_FUNCTION(0x06, "spi1", "cs")), | ||
504 | MPP_MODE(22, | ||
505 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
506 | MPP_FUNCTION(0x01, "uart1", "cts"), | ||
507 | MPP_FUNCTION(0x02, "lcd-spi", "mosi"), | ||
508 | MPP_FUNCTION(0x03, "sdio1", "buspwr"), | ||
509 | MPP_FUNCTION(0x04, "ssp", "txd"), | ||
510 | MPP_FUNCTION(0x05, "sdio0", "buspwr"), | ||
511 | MPP_FUNCTION(0x06, "spi1", "mosi")), | ||
512 | MPP_MODE(23, | ||
513 | MPP_FUNCTION(0x00, "gpio", NULL), | ||
514 | MPP_FUNCTION(0x02, "lcd-spi", "sck"), | ||
515 | MPP_FUNCTION(0x03, "sdio1", "ledctrl"), | ||
516 | MPP_FUNCTION(0x04, "ssp", "sclk"), | ||
517 | MPP_FUNCTION(0x05, "sdio0", "ledctrl"), | ||
518 | MPP_FUNCTION(0x06, "spi1", "sck")), | ||
519 | MPP_MODE(24, | ||
520 | MPP_FUNCTION(0x00, "camera", NULL), | ||
521 | MPP_FUNCTION(0x01, "gpio", NULL)), | ||
522 | MPP_MODE(40, | ||
523 | MPP_FUNCTION(0x00, "sdio0", NULL), | ||
524 | MPP_FUNCTION(0x01, "gpio", NULL)), | ||
525 | MPP_MODE(46, | ||
526 | MPP_FUNCTION(0x00, "sdio1", NULL), | ||
527 | MPP_FUNCTION(0x01, "gpio", NULL)), | ||
528 | MPP_MODE(52, | ||
529 | MPP_FUNCTION(0x00, "i2s1/spdifo", NULL), | ||
530 | MPP_FUNCTION(0x02, "i2s1", NULL), | ||
531 | MPP_FUNCTION(0x08, "spdifo", NULL), | ||
532 | MPP_FUNCTION(0x0a, "gpio", NULL), | ||
533 | MPP_FUNCTION(0x0b, "twsi", NULL), | ||
534 | MPP_FUNCTION(0x0c, "ssp/spdifo", NULL), | ||
535 | MPP_FUNCTION(0x0e, "ssp", NULL), | ||
536 | MPP_FUNCTION(0x0f, "ssp/twsi", NULL)), | ||
537 | MPP_MODE(58, | ||
538 | MPP_FUNCTION(0x00, "spi0", NULL), | ||
539 | MPP_FUNCTION(0x01, "gpio", NULL)), | ||
540 | MPP_MODE(62, | ||
541 | MPP_FUNCTION(0x00, "uart1", NULL), | ||
542 | MPP_FUNCTION(0x01, "gpio", NULL)), | ||
543 | MPP_MODE(64, | ||
544 | MPP_FUNCTION(0x00, "nand", NULL), | ||
545 | MPP_FUNCTION(0x01, "gpo", NULL)), | ||
546 | MPP_MODE(72, | ||
547 | MPP_FUNCTION(0x00, "i2s", NULL), | ||
548 | MPP_FUNCTION(0x01, "ac97", NULL)), | ||
549 | MPP_MODE(73, | ||
550 | MPP_FUNCTION(0x00, "twsi-none", NULL), | ||
551 | MPP_FUNCTION(0x01, "twsi-opt1", NULL), | ||
552 | MPP_FUNCTION(0x02, "twsi-opt2", NULL), | ||
553 | MPP_FUNCTION(0x03, "twsi-opt3", NULL)), | ||
554 | }; | ||
555 | |||
556 | static struct pinctrl_gpio_range dove_mpp_gpio_ranges[] = { | ||
557 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
558 | MPP_GPIO_RANGE(1, 32, 32, 32), | ||
559 | MPP_GPIO_RANGE(2, 64, 64, 8), | ||
560 | }; | ||
561 | |||
562 | static struct mvebu_pinctrl_soc_info dove_pinctrl_info = { | ||
563 | .controls = dove_mpp_controls, | ||
564 | .ncontrols = ARRAY_SIZE(dove_mpp_controls), | ||
565 | .modes = dove_mpp_modes, | ||
566 | .nmodes = ARRAY_SIZE(dove_mpp_modes), | ||
567 | .gpioranges = dove_mpp_gpio_ranges, | ||
568 | .ngpioranges = ARRAY_SIZE(dove_mpp_gpio_ranges), | ||
569 | .variant = 0, | ||
570 | }; | ||
571 | |||
572 | static struct clk *clk; | ||
573 | |||
574 | static struct of_device_id dove_pinctrl_of_match[] __devinitdata = { | ||
575 | { .compatible = "marvell,dove-pinctrl", .data = &dove_pinctrl_info }, | ||
576 | { } | ||
577 | }; | ||
578 | |||
579 | static int __devinit dove_pinctrl_probe(struct platform_device *pdev) | ||
580 | { | ||
581 | const struct of_device_id *match = | ||
582 | of_match_device(dove_pinctrl_of_match, &pdev->dev); | ||
583 | pdev->dev.platform_data = match->data; | ||
584 | |||
585 | /* | ||
586 | * General MPP Configuration Register is part of pdma registers. | ||
587 | * grab clk to make sure it is ticking. | ||
588 | */ | ||
589 | clk = devm_clk_get(&pdev->dev, NULL); | ||
590 | if (!IS_ERR(clk)) | ||
591 | clk_prepare_enable(clk); | ||
592 | |||
593 | return mvebu_pinctrl_probe(pdev); | ||
594 | } | ||
595 | |||
596 | static int __devexit dove_pinctrl_remove(struct platform_device *pdev) | ||
597 | { | ||
598 | int ret; | ||
599 | |||
600 | ret = mvebu_pinctrl_remove(pdev); | ||
601 | if (!IS_ERR(clk)) | ||
602 | clk_disable_unprepare(clk); | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | static struct platform_driver dove_pinctrl_driver = { | ||
607 | .driver = { | ||
608 | .name = "dove-pinctrl", | ||
609 | .owner = THIS_MODULE, | ||
610 | .of_match_table = of_match_ptr(dove_pinctrl_of_match), | ||
611 | }, | ||
612 | .probe = dove_pinctrl_probe, | ||
613 | .remove = __devexit_p(dove_pinctrl_remove), | ||
614 | }; | ||
615 | |||
616 | module_platform_driver(dove_pinctrl_driver); | ||
617 | |||
618 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); | ||
619 | MODULE_DESCRIPTION("Marvell Dove pinctrl driver"); | ||
620 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/pinctrl-kirkwood.c new file mode 100644 index 000000000000..9a74ef674a0e --- /dev/null +++ b/drivers/pinctrl/pinctrl-kirkwood.c | |||
@@ -0,0 +1,472 @@ | |||
1 | /* | ||
2 | * Marvell Kirkwood pinctrl driver based on mvebu pinctrl core | ||
3 | * | ||
4 | * Author: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/err.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/pinctrl/pinctrl.h> | ||
21 | |||
22 | #include "pinctrl-mvebu.h" | ||
23 | |||
24 | #define V(f6180, f6190, f6192, f6281, f6282) \ | ||
25 | ((f6180 << 0) | (f6190 << 1) | (f6192 << 2) | \ | ||
26 | (f6281 << 3) | (f6282 << 4)) | ||
27 | |||
28 | enum kirkwood_variant { | ||
29 | VARIANT_MV88F6180 = V(1, 0, 0, 0, 0), | ||
30 | VARIANT_MV88F6190 = V(0, 1, 0, 0, 0), | ||
31 | VARIANT_MV88F6192 = V(0, 0, 1, 0, 0), | ||
32 | VARIANT_MV88F6281 = V(0, 0, 0, 1, 0), | ||
33 | VARIANT_MV88F6282 = V(0, 0, 0, 0, 1), | ||
34 | }; | ||
35 | |||
36 | static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { | ||
37 | MPP_MODE(0, | ||
38 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
39 | MPP_VAR_FUNCTION(0x1, "nand", "io2", V(1, 1, 1, 1, 1)), | ||
40 | MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1))), | ||
41 | MPP_MODE(1, | ||
42 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
43 | MPP_VAR_FUNCTION(0x1, "nand", "io3", V(1, 1, 1, 1, 1)), | ||
44 | MPP_VAR_FUNCTION(0x2, "spi", "mosi", V(1, 1, 1, 1, 1))), | ||
45 | MPP_MODE(2, | ||
46 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
47 | MPP_VAR_FUNCTION(0x1, "nand", "io4", V(1, 1, 1, 1, 1)), | ||
48 | MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1))), | ||
49 | MPP_MODE(3, | ||
50 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
51 | MPP_VAR_FUNCTION(0x1, "nand", "io5", V(1, 1, 1, 1, 1)), | ||
52 | MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1))), | ||
53 | MPP_MODE(4, | ||
54 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
55 | MPP_VAR_FUNCTION(0x1, "nand", "io6", V(1, 1, 1, 1, 1)), | ||
56 | MPP_VAR_FUNCTION(0x2, "uart0", "rxd", V(1, 1, 1, 1, 1)), | ||
57 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
58 | MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1)), | ||
59 | MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0))), | ||
60 | MPP_MODE(5, | ||
61 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
62 | MPP_VAR_FUNCTION(0x1, "nand", "io7", V(1, 1, 1, 1, 1)), | ||
63 | MPP_VAR_FUNCTION(0x2, "uart0", "txd", V(1, 1, 1, 1, 1)), | ||
64 | MPP_VAR_FUNCTION(0x4, "ptp", "trig", V(1, 1, 1, 1, 0)), | ||
65 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
66 | MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), | ||
67 | MPP_MODE(6, | ||
68 | MPP_VAR_FUNCTION(0x0, "sysrst", "out", V(1, 1, 1, 1, 1)), | ||
69 | MPP_VAR_FUNCTION(0x1, "spi", "mosi", V(1, 1, 1, 1, 1)), | ||
70 | MPP_VAR_FUNCTION(0x2, "ptp", "trig", V(1, 1, 1, 1, 0))), | ||
71 | MPP_MODE(7, | ||
72 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
73 | MPP_VAR_FUNCTION(0x1, "pex", "rsto", V(1, 1, 1, 1, 0)), | ||
74 | MPP_VAR_FUNCTION(0x2, "spi", "cs", V(1, 1, 1, 1, 1)), | ||
75 | MPP_VAR_FUNCTION(0x3, "ptp", "trig", V(1, 1, 1, 1, 0)), | ||
76 | MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), | ||
77 | MPP_MODE(8, | ||
78 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
79 | MPP_VAR_FUNCTION(0x1, "twsi0", "sda", V(1, 1, 1, 1, 1)), | ||
80 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), | ||
81 | MPP_VAR_FUNCTION(0x3, "uart1", "rts", V(1, 1, 1, 1, 1)), | ||
82 | MPP_VAR_FUNCTION(0x4, "mii-1", "rxerr", V(0, 1, 1, 1, 1)), | ||
83 | MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), | ||
84 | MPP_VAR_FUNCTION(0xc, "ptp", "clk", V(1, 1, 1, 1, 0)), | ||
85 | MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), | ||
86 | MPP_MODE(9, | ||
87 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
88 | MPP_VAR_FUNCTION(0x1, "twsi0", "sck", V(1, 1, 1, 1, 1)), | ||
89 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), | ||
90 | MPP_VAR_FUNCTION(0x3, "uart1", "cts", V(1, 1, 1, 1, 1)), | ||
91 | MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), | ||
92 | MPP_VAR_FUNCTION(0xc, "ptp", "evreq", V(1, 1, 1, 1, 0)), | ||
93 | MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), | ||
94 | MPP_MODE(10, | ||
95 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
96 | MPP_VAR_FUNCTION(0x2, "spi", "sck", V(1, 1, 1, 1, 1)), | ||
97 | MPP_VAR_FUNCTION(0X3, "uart0", "txd", V(1, 1, 1, 1, 1)), | ||
98 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
99 | MPP_VAR_FUNCTION(0xc, "ptp", "trig", V(1, 1, 1, 1, 0))), | ||
100 | MPP_MODE(11, | ||
101 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
102 | MPP_VAR_FUNCTION(0x2, "spi", "miso", V(1, 1, 1, 1, 1)), | ||
103 | MPP_VAR_FUNCTION(0x3, "uart0", "rxd", V(1, 1, 1, 1, 1)), | ||
104 | MPP_VAR_FUNCTION(0x4, "ptp-1", "evreq", V(1, 1, 1, 1, 0)), | ||
105 | MPP_VAR_FUNCTION(0xc, "ptp-2", "trig", V(1, 1, 1, 1, 0)), | ||
106 | MPP_VAR_FUNCTION(0xd, "ptp", "clk", V(1, 1, 1, 1, 0)), | ||
107 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1))), | ||
108 | MPP_MODE(12, | ||
109 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 0, 1)), | ||
110 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), | ||
111 | MPP_VAR_FUNCTION(0x1, "sdio", "clk", V(1, 1, 1, 1, 1)), | ||
112 | MPP_VAR_FUNCTION(0xa, "audio", "spdifo", V(0, 0, 0, 0, 1)), | ||
113 | MPP_VAR_FUNCTION(0xb, "spi", "mosi", V(0, 0, 0, 0, 1)), | ||
114 | MPP_VAR_FUNCTION(0xd, "twsi1", "sda", V(0, 0, 0, 0, 1))), | ||
115 | MPP_MODE(13, | ||
116 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
117 | MPP_VAR_FUNCTION(0x1, "sdio", "cmd", V(1, 1, 1, 1, 1)), | ||
118 | MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), | ||
119 | MPP_VAR_FUNCTION(0xa, "audio", "rmclk", V(0, 0, 0, 0, 1)), | ||
120 | MPP_VAR_FUNCTION(0xb, "lcd", "pwm", V(0, 0, 0, 0, 1))), | ||
121 | MPP_MODE(14, | ||
122 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
123 | MPP_VAR_FUNCTION(0x1, "sdio", "d0", V(1, 1, 1, 1, 1)), | ||
124 | MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), | ||
125 | MPP_VAR_FUNCTION(0x4, "sata1", "prsnt", V(0, 0, 1, 1, 1)), | ||
126 | MPP_VAR_FUNCTION(0xa, "audio", "spdifi", V(0, 0, 0, 0, 1)), | ||
127 | MPP_VAR_FUNCTION(0xb, "audio-1", "sdi", V(0, 0, 0, 0, 1)), | ||
128 | MPP_VAR_FUNCTION(0xd, "mii", "col", V(1, 1, 1, 1, 1))), | ||
129 | MPP_MODE(15, | ||
130 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
131 | MPP_VAR_FUNCTION(0x1, "sdio", "d1", V(1, 1, 1, 1, 1)), | ||
132 | MPP_VAR_FUNCTION(0x2, "uart0", "rts", V(1, 1, 1, 1, 1)), | ||
133 | MPP_VAR_FUNCTION(0x3, "uart1", "txd", V(1, 1, 1, 1, 1)), | ||
134 | MPP_VAR_FUNCTION(0x4, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
135 | MPP_VAR_FUNCTION(0xb, "spi", "cs", V(0, 0, 0, 0, 1))), | ||
136 | MPP_MODE(16, | ||
137 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
138 | MPP_VAR_FUNCTION(0x1, "sdio", "d2", V(1, 1, 1, 1, 1)), | ||
139 | MPP_VAR_FUNCTION(0x2, "uart0", "cts", V(1, 1, 1, 1, 1)), | ||
140 | MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V(1, 1, 1, 1, 1)), | ||
141 | MPP_VAR_FUNCTION(0x4, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
142 | MPP_VAR_FUNCTION(0xb, "lcd", "extclk", V(0, 0, 0, 0, 1)), | ||
143 | MPP_VAR_FUNCTION(0xd, "mii", "crs", V(1, 1, 1, 1, 1))), | ||
144 | MPP_MODE(17, | ||
145 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
146 | MPP_VAR_FUNCTION(0x1, "sdio", "d3", V(1, 1, 1, 1, 1)), | ||
147 | MPP_VAR_FUNCTION(0x4, "sata0", "prsnt", V(0, 1, 1, 1, 1)), | ||
148 | MPP_VAR_FUNCTION(0xa, "sata1", "act", V(0, 0, 0, 0, 1)), | ||
149 | MPP_VAR_FUNCTION(0xd, "twsi1", "sck", V(0, 0, 0, 0, 1))), | ||
150 | MPP_MODE(18, | ||
151 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
152 | MPP_VAR_FUNCTION(0x1, "nand", "io0", V(1, 1, 1, 1, 1)), | ||
153 | MPP_VAR_FUNCTION(0x2, "pex", "clkreq", V(0, 0, 0, 0, 1))), | ||
154 | MPP_MODE(19, | ||
155 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1)), | ||
156 | MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1))), | ||
157 | MPP_MODE(20, | ||
158 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
159 | MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1)), | ||
160 | MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), | ||
161 | MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1)), | ||
162 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1)), | ||
163 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1)), | ||
164 | MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1)), | ||
165 | MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0))), | ||
166 | MPP_MODE(21, | ||
167 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
168 | MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1)), | ||
169 | MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1)), | ||
170 | MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1)), | ||
171 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0)), | ||
172 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1)), | ||
173 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
174 | MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1))), | ||
175 | MPP_MODE(22, | ||
176 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
177 | MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1)), | ||
178 | MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1)), | ||
179 | MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1)), | ||
180 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0)), | ||
181 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1)), | ||
182 | MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1)), | ||
183 | MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1))), | ||
184 | MPP_MODE(23, | ||
185 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
186 | MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1)), | ||
187 | MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1)), | ||
188 | MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1)), | ||
189 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0)), | ||
190 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1)), | ||
191 | MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1)), | ||
192 | MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1))), | ||
193 | MPP_MODE(24, | ||
194 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
195 | MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1)), | ||
196 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1)), | ||
197 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1)), | ||
198 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0)), | ||
199 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1)), | ||
200 | MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1))), | ||
201 | MPP_MODE(25, | ||
202 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
203 | MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1)), | ||
204 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1)), | ||
205 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1)), | ||
206 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0)), | ||
207 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1)), | ||
208 | MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1))), | ||
209 | MPP_MODE(26, | ||
210 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
211 | MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1)), | ||
212 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1)), | ||
213 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1)), | ||
214 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0)), | ||
215 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1)), | ||
216 | MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1))), | ||
217 | MPP_MODE(27, | ||
218 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
219 | MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1)), | ||
220 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1)), | ||
221 | MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1)), | ||
222 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0)), | ||
223 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1)), | ||
224 | MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1))), | ||
225 | MPP_MODE(28, | ||
226 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
227 | MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1)), | ||
228 | MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1)), | ||
229 | MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1)), | ||
230 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0)), | ||
231 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1)), | ||
232 | MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1))), | ||
233 | MPP_MODE(29, | ||
234 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1)), | ||
235 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1)), | ||
236 | MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1)), | ||
237 | MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1)), | ||
238 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0)), | ||
239 | MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1))), | ||
240 | MPP_MODE(30, | ||
241 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
242 | MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 1, 1, 1)), | ||
243 | MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 1, 1, 1)), | ||
244 | MPP_VAR_FUNCTION(0x3, "ge1", "rxctl", V(0, 1, 1, 1, 1)), | ||
245 | MPP_VAR_FUNCTION(0xb, "lcd", "d10", V(0, 0, 0, 0, 1))), | ||
246 | MPP_MODE(31, | ||
247 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
248 | MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 1, 1, 1)), | ||
249 | MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 1, 1, 1)), | ||
250 | MPP_VAR_FUNCTION(0x3, "ge1", "rxclk", V(0, 1, 1, 1, 1)), | ||
251 | MPP_VAR_FUNCTION(0xb, "lcd", "d11", V(0, 0, 0, 0, 1))), | ||
252 | MPP_MODE(32, | ||
253 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
254 | MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 1, 1, 1)), | ||
255 | MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 1, 1, 1)), | ||
256 | MPP_VAR_FUNCTION(0x3, "ge1", "txclko", V(0, 1, 1, 1, 1)), | ||
257 | MPP_VAR_FUNCTION(0xb, "lcd", "d12", V(0, 0, 0, 0, 1))), | ||
258 | MPP_MODE(33, | ||
259 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 1, 1, 1, 1)), | ||
260 | MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 1, 1, 1)), | ||
261 | MPP_VAR_FUNCTION(0x3, "ge1", "txctl", V(0, 1, 1, 1, 1)), | ||
262 | MPP_VAR_FUNCTION(0xb, "lcd", "d13", V(0, 0, 0, 0, 1))), | ||
263 | MPP_MODE(34, | ||
264 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
265 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 1, 1, 1)), | ||
266 | MPP_VAR_FUNCTION(0x3, "ge1", "txen", V(0, 1, 1, 1, 1)), | ||
267 | MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1)), | ||
268 | MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1))), | ||
269 | MPP_MODE(35, | ||
270 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1)), | ||
271 | MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1)), | ||
272 | MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1)), | ||
273 | MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1)), | ||
274 | MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1)), | ||
275 | MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1))), | ||
276 | MPP_MODE(36, | ||
277 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
278 | MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1)), | ||
279 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1)), | ||
280 | MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1)), | ||
281 | MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1))), | ||
282 | MPP_MODE(37, | ||
283 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
284 | MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1)), | ||
285 | MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1)), | ||
286 | MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1)), | ||
287 | MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1))), | ||
288 | MPP_MODE(38, | ||
289 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
290 | MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1)), | ||
291 | MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1)), | ||
292 | MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1)), | ||
293 | MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1))), | ||
294 | MPP_MODE(39, | ||
295 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
296 | MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1)), | ||
297 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1)), | ||
298 | MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1)), | ||
299 | MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1))), | ||
300 | MPP_MODE(40, | ||
301 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
302 | MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1)), | ||
303 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1)), | ||
304 | MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1)), | ||
305 | MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1))), | ||
306 | MPP_MODE(41, | ||
307 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
308 | MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1)), | ||
309 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1)), | ||
310 | MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1)), | ||
311 | MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1))), | ||
312 | MPP_MODE(42, | ||
313 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
314 | MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1)), | ||
315 | MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1)), | ||
316 | MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1)), | ||
317 | MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1))), | ||
318 | MPP_MODE(43, | ||
319 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
320 | MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1)), | ||
321 | MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1)), | ||
322 | MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1)), | ||
323 | MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1))), | ||
324 | MPP_MODE(44, | ||
325 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
326 | MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1)), | ||
327 | MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1)), | ||
328 | MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1)), | ||
329 | MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1))), | ||
330 | MPP_MODE(45, | ||
331 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
332 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 1)), | ||
333 | MPP_VAR_FUNCTION(0x2, "tdm", "pclk", V(0, 0, 0, 1, 1)), | ||
334 | MPP_VAR_FUNCTION(0xb, "lcd", "e", V(0, 0, 0, 0, 1))), | ||
335 | MPP_MODE(46, | ||
336 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
337 | MPP_VAR_FUNCTION(0x1, "ts", "mp10", V(0, 0, 0, 1, 1)), | ||
338 | MPP_VAR_FUNCTION(0x2, "tdm", "fs", V(0, 0, 0, 1, 1)), | ||
339 | MPP_VAR_FUNCTION(0xb, "lcd", "hsync", V(0, 0, 0, 0, 1))), | ||
340 | MPP_MODE(47, | ||
341 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
342 | MPP_VAR_FUNCTION(0x1, "ts", "mp11", V(0, 0, 0, 1, 1)), | ||
343 | MPP_VAR_FUNCTION(0x2, "tdm", "drx", V(0, 0, 0, 1, 1)), | ||
344 | MPP_VAR_FUNCTION(0xb, "lcd", "vsync", V(0, 0, 0, 0, 1))), | ||
345 | MPP_MODE(48, | ||
346 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1)), | ||
347 | MPP_VAR_FUNCTION(0x1, "ts", "mp12", V(0, 0, 0, 1, 1)), | ||
348 | MPP_VAR_FUNCTION(0x2, "tdm", "dtx", V(0, 0, 0, 1, 1)), | ||
349 | MPP_VAR_FUNCTION(0xb, "lcd", "d16", V(0, 0, 0, 0, 1))), | ||
350 | MPP_MODE(49, | ||
351 | MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 0)), | ||
352 | MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(0, 0, 0, 0, 1)), | ||
353 | MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 0, 1, 0)), | ||
354 | MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 0, 1, 1)), | ||
355 | MPP_VAR_FUNCTION(0x5, "ptp", "clk", V(0, 0, 0, 1, 0)), | ||
356 | MPP_VAR_FUNCTION(0xa, "pex", "clkreq", V(0, 0, 0, 0, 1)), | ||
357 | MPP_VAR_FUNCTION(0xb, "lcd", "d17", V(0, 0, 0, 0, 1))), | ||
358 | }; | ||
359 | |||
360 | static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { | ||
361 | MPP_REG_CTRL(0, 29), | ||
362 | }; | ||
363 | |||
364 | static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { | ||
365 | MPP_GPIO_RANGE(0, 0, 0, 30), | ||
366 | }; | ||
367 | |||
368 | static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { | ||
369 | MPP_REG_CTRL(0, 35), | ||
370 | }; | ||
371 | |||
372 | static struct pinctrl_gpio_range mv88f619x_gpio_ranges[] = { | ||
373 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
374 | MPP_GPIO_RANGE(1, 32, 32, 4), | ||
375 | }; | ||
376 | |||
377 | static struct mvebu_mpp_ctrl mv88f628x_mpp_controls[] = { | ||
378 | MPP_REG_CTRL(0, 49), | ||
379 | }; | ||
380 | |||
381 | static struct pinctrl_gpio_range mv88f628x_gpio_ranges[] = { | ||
382 | MPP_GPIO_RANGE(0, 0, 0, 32), | ||
383 | MPP_GPIO_RANGE(1, 32, 32, 18), | ||
384 | }; | ||
385 | |||
386 | static struct mvebu_pinctrl_soc_info mv88f6180_info = { | ||
387 | .variant = VARIANT_MV88F6180, | ||
388 | .controls = mv88f6180_mpp_controls, | ||
389 | .ncontrols = ARRAY_SIZE(mv88f6180_mpp_controls), | ||
390 | .modes = mv88f6xxx_mpp_modes, | ||
391 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
392 | .gpioranges = mv88f6180_gpio_ranges, | ||
393 | .ngpioranges = ARRAY_SIZE(mv88f6180_gpio_ranges), | ||
394 | }; | ||
395 | |||
396 | static struct mvebu_pinctrl_soc_info mv88f6190_info = { | ||
397 | .variant = VARIANT_MV88F6190, | ||
398 | .controls = mv88f619x_mpp_controls, | ||
399 | .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), | ||
400 | .modes = mv88f6xxx_mpp_modes, | ||
401 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
402 | .gpioranges = mv88f619x_gpio_ranges, | ||
403 | .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), | ||
404 | }; | ||
405 | |||
406 | static struct mvebu_pinctrl_soc_info mv88f6192_info = { | ||
407 | .variant = VARIANT_MV88F6192, | ||
408 | .controls = mv88f619x_mpp_controls, | ||
409 | .ncontrols = ARRAY_SIZE(mv88f619x_mpp_controls), | ||
410 | .modes = mv88f6xxx_mpp_modes, | ||
411 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
412 | .gpioranges = mv88f619x_gpio_ranges, | ||
413 | .ngpioranges = ARRAY_SIZE(mv88f619x_gpio_ranges), | ||
414 | }; | ||
415 | |||
416 | static struct mvebu_pinctrl_soc_info mv88f6281_info = { | ||
417 | .variant = VARIANT_MV88F6281, | ||
418 | .controls = mv88f628x_mpp_controls, | ||
419 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
420 | .modes = mv88f6xxx_mpp_modes, | ||
421 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
422 | .gpioranges = mv88f628x_gpio_ranges, | ||
423 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
424 | }; | ||
425 | |||
426 | static struct mvebu_pinctrl_soc_info mv88f6282_info = { | ||
427 | .variant = VARIANT_MV88F6282, | ||
428 | .controls = mv88f628x_mpp_controls, | ||
429 | .ncontrols = ARRAY_SIZE(mv88f628x_mpp_controls), | ||
430 | .modes = mv88f6xxx_mpp_modes, | ||
431 | .nmodes = ARRAY_SIZE(mv88f6xxx_mpp_modes), | ||
432 | .gpioranges = mv88f628x_gpio_ranges, | ||
433 | .ngpioranges = ARRAY_SIZE(mv88f628x_gpio_ranges), | ||
434 | }; | ||
435 | |||
436 | static struct of_device_id kirkwood_pinctrl_of_match[] __devinitdata = { | ||
437 | { .compatible = "marvell,88f6180-pinctrl", .data = &mv88f6180_info }, | ||
438 | { .compatible = "marvell,88f6190-pinctrl", .data = &mv88f6190_info }, | ||
439 | { .compatible = "marvell,88f6192-pinctrl", .data = &mv88f6192_info }, | ||
440 | { .compatible = "marvell,88f6281-pinctrl", .data = &mv88f6281_info }, | ||
441 | { .compatible = "marvell,88f6282-pinctrl", .data = &mv88f6282_info }, | ||
442 | { } | ||
443 | }; | ||
444 | |||
445 | static int __devinit kirkwood_pinctrl_probe(struct platform_device *pdev) | ||
446 | { | ||
447 | const struct of_device_id *match = | ||
448 | of_match_device(kirkwood_pinctrl_of_match, &pdev->dev); | ||
449 | pdev->dev.platform_data = match->data; | ||
450 | return mvebu_pinctrl_probe(pdev); | ||
451 | } | ||
452 | |||
453 | static int __devexit kirkwood_pinctrl_remove(struct platform_device *pdev) | ||
454 | { | ||
455 | return mvebu_pinctrl_remove(pdev); | ||
456 | } | ||
457 | |||
458 | static struct platform_driver kirkwood_pinctrl_driver = { | ||
459 | .driver = { | ||
460 | .name = "kirkwood-pinctrl", | ||
461 | .owner = THIS_MODULE, | ||
462 | .of_match_table = of_match_ptr(kirkwood_pinctrl_of_match), | ||
463 | }, | ||
464 | .probe = kirkwood_pinctrl_probe, | ||
465 | .remove = __devexit_p(kirkwood_pinctrl_remove), | ||
466 | }; | ||
467 | |||
468 | module_platform_driver(kirkwood_pinctrl_driver); | ||
469 | |||
470 | MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>"); | ||
471 | MODULE_DESCRIPTION("Marvell Kirkwood pinctrl driver"); | ||
472 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/pinctrl-mvebu.c new file mode 100644 index 000000000000..8e6266c6249a --- /dev/null +++ b/drivers/pinctrl/pinctrl-mvebu.c | |||
@@ -0,0 +1,754 @@ | |||
1 | /* | ||
2 | * Marvell MVEBU pinctrl core driver | ||
3 | * | ||
4 | * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/of_platform.h> | ||
20 | #include <linux/err.h> | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/pinctrl/machine.h> | ||
23 | #include <linux/pinctrl/pinconf.h> | ||
24 | #include <linux/pinctrl/pinctrl.h> | ||
25 | #include <linux/pinctrl/pinmux.h> | ||
26 | |||
27 | #include "core.h" | ||
28 | #include "pinctrl-mvebu.h" | ||
29 | |||
30 | #define MPPS_PER_REG 8 | ||
31 | #define MPP_BITS 4 | ||
32 | #define MPP_MASK 0xf | ||
33 | |||
34 | struct mvebu_pinctrl_function { | ||
35 | const char *name; | ||
36 | const char **groups; | ||
37 | unsigned num_groups; | ||
38 | }; | ||
39 | |||
40 | struct mvebu_pinctrl_group { | ||
41 | const char *name; | ||
42 | struct mvebu_mpp_ctrl *ctrl; | ||
43 | struct mvebu_mpp_ctrl_setting *settings; | ||
44 | unsigned num_settings; | ||
45 | unsigned gid; | ||
46 | unsigned *pins; | ||
47 | unsigned npins; | ||
48 | }; | ||
49 | |||
50 | struct mvebu_pinctrl { | ||
51 | struct device *dev; | ||
52 | struct pinctrl_dev *pctldev; | ||
53 | struct pinctrl_desc desc; | ||
54 | void __iomem *base; | ||
55 | struct mvebu_pinctrl_group *groups; | ||
56 | unsigned num_groups; | ||
57 | struct mvebu_pinctrl_function *functions; | ||
58 | unsigned num_functions; | ||
59 | u8 variant; | ||
60 | }; | ||
61 | |||
62 | static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_pid( | ||
63 | struct mvebu_pinctrl *pctl, unsigned pid) | ||
64 | { | ||
65 | unsigned n; | ||
66 | for (n = 0; n < pctl->num_groups; n++) { | ||
67 | if (pid >= pctl->groups[n].pins[0] && | ||
68 | pid < pctl->groups[n].pins[0] + | ||
69 | pctl->groups[n].npins) | ||
70 | return &pctl->groups[n]; | ||
71 | } | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | static struct mvebu_pinctrl_group *mvebu_pinctrl_find_group_by_name( | ||
76 | struct mvebu_pinctrl *pctl, const char *name) | ||
77 | { | ||
78 | unsigned n; | ||
79 | for (n = 0; n < pctl->num_groups; n++) { | ||
80 | if (strcmp(name, pctl->groups[n].name) == 0) | ||
81 | return &pctl->groups[n]; | ||
82 | } | ||
83 | return NULL; | ||
84 | } | ||
85 | |||
86 | static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_val( | ||
87 | struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp, | ||
88 | unsigned long config) | ||
89 | { | ||
90 | unsigned n; | ||
91 | for (n = 0; n < grp->num_settings; n++) { | ||
92 | if (config == grp->settings[n].val) { | ||
93 | if (!pctl->variant || (pctl->variant & | ||
94 | grp->settings[n].variant)) | ||
95 | return &grp->settings[n]; | ||
96 | } | ||
97 | } | ||
98 | return NULL; | ||
99 | } | ||
100 | |||
101 | static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_setting_by_name( | ||
102 | struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp, | ||
103 | const char *name) | ||
104 | { | ||
105 | unsigned n; | ||
106 | for (n = 0; n < grp->num_settings; n++) { | ||
107 | if (strcmp(name, grp->settings[n].name) == 0) { | ||
108 | if (!pctl->variant || (pctl->variant & | ||
109 | grp->settings[n].variant)) | ||
110 | return &grp->settings[n]; | ||
111 | } | ||
112 | } | ||
113 | return NULL; | ||
114 | } | ||
115 | |||
116 | static struct mvebu_mpp_ctrl_setting *mvebu_pinctrl_find_gpio_setting( | ||
117 | struct mvebu_pinctrl *pctl, struct mvebu_pinctrl_group *grp) | ||
118 | { | ||
119 | unsigned n; | ||
120 | for (n = 0; n < grp->num_settings; n++) { | ||
121 | if (grp->settings[n].flags & | ||
122 | (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { | ||
123 | if (!pctl->variant || (pctl->variant & | ||
124 | grp->settings[n].variant)) | ||
125 | return &grp->settings[n]; | ||
126 | } | ||
127 | } | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | static struct mvebu_pinctrl_function *mvebu_pinctrl_find_function_by_name( | ||
132 | struct mvebu_pinctrl *pctl, const char *name) | ||
133 | { | ||
134 | unsigned n; | ||
135 | for (n = 0; n < pctl->num_functions; n++) { | ||
136 | if (strcmp(name, pctl->functions[n].name) == 0) | ||
137 | return &pctl->functions[n]; | ||
138 | } | ||
139 | return NULL; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Common mpp pin configuration registers on MVEBU are | ||
144 | * registers of eight 4-bit values for each mpp setting. | ||
145 | * Register offset and bit mask are calculated accordingly below. | ||
146 | */ | ||
147 | static int mvebu_common_mpp_get(struct mvebu_pinctrl *pctl, | ||
148 | struct mvebu_pinctrl_group *grp, | ||
149 | unsigned long *config) | ||
150 | { | ||
151 | unsigned pin = grp->gid; | ||
152 | unsigned off = (pin / MPPS_PER_REG) * MPP_BITS; | ||
153 | unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS; | ||
154 | |||
155 | *config = readl(pctl->base + off); | ||
156 | *config >>= shift; | ||
157 | *config &= MPP_MASK; | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static int mvebu_common_mpp_set(struct mvebu_pinctrl *pctl, | ||
163 | struct mvebu_pinctrl_group *grp, | ||
164 | unsigned long config) | ||
165 | { | ||
166 | unsigned pin = grp->gid; | ||
167 | unsigned off = (pin / MPPS_PER_REG) * MPP_BITS; | ||
168 | unsigned shift = (pin % MPPS_PER_REG) * MPP_BITS; | ||
169 | unsigned long reg; | ||
170 | |||
171 | reg = readl(pctl->base + off); | ||
172 | reg &= ~(MPP_MASK << shift); | ||
173 | reg |= (config << shift); | ||
174 | writel(reg, pctl->base + off); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev, | ||
180 | unsigned gid, unsigned long *config) | ||
181 | { | ||
182 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
183 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; | ||
184 | |||
185 | if (!grp->ctrl) | ||
186 | return -EINVAL; | ||
187 | |||
188 | if (grp->ctrl->mpp_get) | ||
189 | return grp->ctrl->mpp_get(grp->ctrl, config); | ||
190 | |||
191 | return mvebu_common_mpp_get(pctl, grp, config); | ||
192 | } | ||
193 | |||
194 | static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev, | ||
195 | unsigned gid, unsigned long config) | ||
196 | { | ||
197 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
198 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; | ||
199 | |||
200 | if (!grp->ctrl) | ||
201 | return -EINVAL; | ||
202 | |||
203 | if (grp->ctrl->mpp_set) | ||
204 | return grp->ctrl->mpp_set(grp->ctrl, config); | ||
205 | |||
206 | return mvebu_common_mpp_set(pctl, grp, config); | ||
207 | } | ||
208 | |||
209 | static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, | ||
210 | struct seq_file *s, unsigned gid) | ||
211 | { | ||
212 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
213 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; | ||
214 | struct mvebu_mpp_ctrl_setting *curr; | ||
215 | unsigned long config; | ||
216 | unsigned n; | ||
217 | |||
218 | if (mvebu_pinconf_group_get(pctldev, gid, &config)) | ||
219 | return; | ||
220 | |||
221 | curr = mvebu_pinctrl_find_setting_by_val(pctl, grp, config); | ||
222 | |||
223 | if (curr) { | ||
224 | seq_printf(s, "current: %s", curr->name); | ||
225 | if (curr->subname) | ||
226 | seq_printf(s, "(%s)", curr->subname); | ||
227 | if (curr->flags & (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { | ||
228 | seq_printf(s, "("); | ||
229 | if (curr->flags & MVEBU_SETTING_GPI) | ||
230 | seq_printf(s, "i"); | ||
231 | if (curr->flags & MVEBU_SETTING_GPO) | ||
232 | seq_printf(s, "o"); | ||
233 | seq_printf(s, ")"); | ||
234 | } | ||
235 | } else | ||
236 | seq_printf(s, "current: UNKNOWN"); | ||
237 | |||
238 | if (grp->num_settings > 1) { | ||
239 | seq_printf(s, ", available = ["); | ||
240 | for (n = 0; n < grp->num_settings; n++) { | ||
241 | if (curr == &grp->settings[n]) | ||
242 | continue; | ||
243 | |||
244 | /* skip unsupported settings for this variant */ | ||
245 | if (pctl->variant && | ||
246 | !(pctl->variant & grp->settings[n].variant)) | ||
247 | continue; | ||
248 | |||
249 | seq_printf(s, " %s", grp->settings[n].name); | ||
250 | if (grp->settings[n].subname) | ||
251 | seq_printf(s, "(%s)", grp->settings[n].subname); | ||
252 | if (grp->settings[n].flags & | ||
253 | (MVEBU_SETTING_GPO | MVEBU_SETTING_GPI)) { | ||
254 | seq_printf(s, "("); | ||
255 | if (grp->settings[n].flags & MVEBU_SETTING_GPI) | ||
256 | seq_printf(s, "i"); | ||
257 | if (grp->settings[n].flags & MVEBU_SETTING_GPO) | ||
258 | seq_printf(s, "o"); | ||
259 | seq_printf(s, ")"); | ||
260 | } | ||
261 | } | ||
262 | seq_printf(s, " ]"); | ||
263 | } | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | static struct pinconf_ops mvebu_pinconf_ops = { | ||
268 | .pin_config_group_get = mvebu_pinconf_group_get, | ||
269 | .pin_config_group_set = mvebu_pinconf_group_set, | ||
270 | .pin_config_group_dbg_show = mvebu_pinconf_group_dbg_show, | ||
271 | }; | ||
272 | |||
273 | static int mvebu_pinmux_get_funcs_count(struct pinctrl_dev *pctldev) | ||
274 | { | ||
275 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
276 | |||
277 | return pctl->num_functions; | ||
278 | } | ||
279 | |||
280 | static const char *mvebu_pinmux_get_func_name(struct pinctrl_dev *pctldev, | ||
281 | unsigned fid) | ||
282 | { | ||
283 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
284 | |||
285 | return pctl->functions[fid].name; | ||
286 | } | ||
287 | |||
288 | static int mvebu_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned fid, | ||
289 | const char * const **groups, | ||
290 | unsigned * const num_groups) | ||
291 | { | ||
292 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
293 | |||
294 | *groups = pctl->functions[fid].groups; | ||
295 | *num_groups = pctl->functions[fid].num_groups; | ||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid, | ||
300 | unsigned gid) | ||
301 | { | ||
302 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
303 | struct mvebu_pinctrl_function *func = &pctl->functions[fid]; | ||
304 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; | ||
305 | struct mvebu_mpp_ctrl_setting *setting; | ||
306 | int ret; | ||
307 | |||
308 | setting = mvebu_pinctrl_find_setting_by_name(pctl, grp, | ||
309 | func->name); | ||
310 | if (!setting) { | ||
311 | dev_err(pctl->dev, | ||
312 | "unable to find setting %s in group %s\n", | ||
313 | func->name, func->groups[gid]); | ||
314 | return -EINVAL; | ||
315 | } | ||
316 | |||
317 | ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); | ||
318 | if (ret) { | ||
319 | dev_err(pctl->dev, "cannot set group %s to %s\n", | ||
320 | func->groups[gid], func->name); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
328 | struct pinctrl_gpio_range *range, unsigned offset) | ||
329 | { | ||
330 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
331 | struct mvebu_pinctrl_group *grp; | ||
332 | struct mvebu_mpp_ctrl_setting *setting; | ||
333 | |||
334 | grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); | ||
335 | if (!grp) | ||
336 | return -EINVAL; | ||
337 | |||
338 | if (grp->ctrl->mpp_gpio_req) | ||
339 | return grp->ctrl->mpp_gpio_req(grp->ctrl, offset); | ||
340 | |||
341 | setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); | ||
342 | if (!setting) | ||
343 | return -ENOTSUPP; | ||
344 | |||
345 | return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); | ||
346 | } | ||
347 | |||
348 | static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | ||
349 | struct pinctrl_gpio_range *range, unsigned offset, bool input) | ||
350 | { | ||
351 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
352 | struct mvebu_pinctrl_group *grp; | ||
353 | struct mvebu_mpp_ctrl_setting *setting; | ||
354 | |||
355 | grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); | ||
356 | if (!grp) | ||
357 | return -EINVAL; | ||
358 | |||
359 | if (grp->ctrl->mpp_gpio_dir) | ||
360 | return grp->ctrl->mpp_gpio_dir(grp->ctrl, offset, input); | ||
361 | |||
362 | setting = mvebu_pinctrl_find_gpio_setting(pctl, grp); | ||
363 | if (!setting) | ||
364 | return -ENOTSUPP; | ||
365 | |||
366 | if ((input && (setting->flags & MVEBU_SETTING_GPI)) || | ||
367 | (!input && (setting->flags & MVEBU_SETTING_GPO))) | ||
368 | return 0; | ||
369 | |||
370 | return -ENOTSUPP; | ||
371 | } | ||
372 | |||
373 | static struct pinmux_ops mvebu_pinmux_ops = { | ||
374 | .get_functions_count = mvebu_pinmux_get_funcs_count, | ||
375 | .get_function_name = mvebu_pinmux_get_func_name, | ||
376 | .get_function_groups = mvebu_pinmux_get_groups, | ||
377 | .gpio_request_enable = mvebu_pinmux_gpio_request_enable, | ||
378 | .gpio_set_direction = mvebu_pinmux_gpio_set_direction, | ||
379 | .enable = mvebu_pinmux_enable, | ||
380 | }; | ||
381 | |||
382 | static int mvebu_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) | ||
383 | { | ||
384 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
385 | return pctl->num_groups; | ||
386 | } | ||
387 | |||
388 | static const char *mvebu_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||
389 | unsigned gid) | ||
390 | { | ||
391 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
392 | return pctl->groups[gid].name; | ||
393 | } | ||
394 | |||
395 | static int mvebu_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||
396 | unsigned gid, const unsigned **pins, | ||
397 | unsigned *num_pins) | ||
398 | { | ||
399 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
400 | *pins = pctl->groups[gid].pins; | ||
401 | *num_pins = pctl->groups[gid].npins; | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
406 | struct device_node *np, | ||
407 | struct pinctrl_map **map, | ||
408 | unsigned *num_maps) | ||
409 | { | ||
410 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | ||
411 | struct property *prop; | ||
412 | const char *function; | ||
413 | const char *group; | ||
414 | int ret, nmaps, n; | ||
415 | |||
416 | *map = NULL; | ||
417 | *num_maps = 0; | ||
418 | |||
419 | ret = of_property_read_string(np, "marvell,function", &function); | ||
420 | if (ret) { | ||
421 | dev_err(pctl->dev, | ||
422 | "missing marvell,function in node %s\n", np->name); | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | nmaps = of_property_count_strings(np, "marvell,pins"); | ||
427 | if (nmaps < 0) { | ||
428 | dev_err(pctl->dev, | ||
429 | "missing marvell,pins in node %s\n", np->name); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL); | ||
434 | if (map == NULL) { | ||
435 | dev_err(pctl->dev, | ||
436 | "cannot allocate pinctrl_map memory for %s\n", | ||
437 | np->name); | ||
438 | return -ENOMEM; | ||
439 | } | ||
440 | |||
441 | n = 0; | ||
442 | of_property_for_each_string(np, "marvell,pins", prop, group) { | ||
443 | struct mvebu_pinctrl_group *grp = | ||
444 | mvebu_pinctrl_find_group_by_name(pctl, group); | ||
445 | |||
446 | if (!grp) { | ||
447 | dev_err(pctl->dev, "unknown pin %s", group); | ||
448 | continue; | ||
449 | } | ||
450 | |||
451 | if (!mvebu_pinctrl_find_setting_by_name(pctl, grp, function)) { | ||
452 | dev_err(pctl->dev, "unsupported function %s on pin %s", | ||
453 | function, group); | ||
454 | continue; | ||
455 | } | ||
456 | |||
457 | (*map)[n].type = PIN_MAP_TYPE_MUX_GROUP; | ||
458 | (*map)[n].data.mux.group = group; | ||
459 | (*map)[n].data.mux.function = function; | ||
460 | n++; | ||
461 | } | ||
462 | |||
463 | *num_maps = nmaps; | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static void mvebu_pinctrl_dt_free_map(struct pinctrl_dev *pctldev, | ||
469 | struct pinctrl_map *map, unsigned num_maps) | ||
470 | { | ||
471 | kfree(map); | ||
472 | } | ||
473 | |||
474 | static struct pinctrl_ops mvebu_pinctrl_ops = { | ||
475 | .get_groups_count = mvebu_pinctrl_get_groups_count, | ||
476 | .get_group_name = mvebu_pinctrl_get_group_name, | ||
477 | .get_group_pins = mvebu_pinctrl_get_group_pins, | ||
478 | .dt_node_to_map = mvebu_pinctrl_dt_node_to_map, | ||
479 | .dt_free_map = mvebu_pinctrl_dt_free_map, | ||
480 | }; | ||
481 | |||
482 | static int __devinit _add_function(struct mvebu_pinctrl_function *funcs, | ||
483 | const char *name) | ||
484 | { | ||
485 | while (funcs->num_groups) { | ||
486 | /* function already there */ | ||
487 | if (strcmp(funcs->name, name) == 0) { | ||
488 | funcs->num_groups++; | ||
489 | return -EEXIST; | ||
490 | } | ||
491 | funcs++; | ||
492 | } | ||
493 | funcs->name = name; | ||
494 | funcs->num_groups = 1; | ||
495 | return 0; | ||
496 | } | ||
497 | |||
498 | static int __devinit mvebu_pinctrl_build_functions(struct platform_device *pdev, | ||
499 | struct mvebu_pinctrl *pctl) | ||
500 | { | ||
501 | struct mvebu_pinctrl_function *funcs; | ||
502 | int num = 0; | ||
503 | int n, s; | ||
504 | |||
505 | /* we allocate functions for number of pins and hope | ||
506 | * there are less unique functions than pins available */ | ||
507 | funcs = devm_kzalloc(&pdev->dev, pctl->desc.npins * | ||
508 | sizeof(struct mvebu_pinctrl_function), GFP_KERNEL); | ||
509 | if (!funcs) | ||
510 | return -ENOMEM; | ||
511 | |||
512 | for (n = 0; n < pctl->num_groups; n++) { | ||
513 | struct mvebu_pinctrl_group *grp = &pctl->groups[n]; | ||
514 | for (s = 0; s < grp->num_settings; s++) { | ||
515 | /* skip unsupported settings on this variant */ | ||
516 | if (pctl->variant && | ||
517 | !(pctl->variant & grp->settings[s].variant)) | ||
518 | continue; | ||
519 | |||
520 | /* check for unique functions and count groups */ | ||
521 | if (_add_function(funcs, grp->settings[s].name)) | ||
522 | continue; | ||
523 | |||
524 | num++; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | /* with the number of unique functions and it's groups known, | ||
529 | reallocate functions and assign group names */ | ||
530 | funcs = krealloc(funcs, num * sizeof(struct mvebu_pinctrl_function), | ||
531 | GFP_KERNEL); | ||
532 | if (!funcs) | ||
533 | return -ENOMEM; | ||
534 | |||
535 | pctl->num_functions = num; | ||
536 | pctl->functions = funcs; | ||
537 | |||
538 | for (n = 0; n < pctl->num_groups; n++) { | ||
539 | struct mvebu_pinctrl_group *grp = &pctl->groups[n]; | ||
540 | for (s = 0; s < grp->num_settings; s++) { | ||
541 | struct mvebu_pinctrl_function *f; | ||
542 | const char **groups; | ||
543 | |||
544 | /* skip unsupported settings on this variant */ | ||
545 | if (pctl->variant && | ||
546 | !(pctl->variant & grp->settings[s].variant)) | ||
547 | continue; | ||
548 | |||
549 | f = mvebu_pinctrl_find_function_by_name(pctl, | ||
550 | grp->settings[s].name); | ||
551 | |||
552 | /* allocate group name array if not done already */ | ||
553 | if (!f->groups) { | ||
554 | f->groups = devm_kzalloc(&pdev->dev, | ||
555 | f->num_groups * sizeof(char *), | ||
556 | GFP_KERNEL); | ||
557 | if (!f->groups) | ||
558 | return -ENOMEM; | ||
559 | } | ||
560 | |||
561 | /* find next free group name and assign current name */ | ||
562 | groups = f->groups; | ||
563 | while (*groups) | ||
564 | groups++; | ||
565 | *groups = grp->name; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | int __devinit mvebu_pinctrl_probe(struct platform_device *pdev) | ||
573 | { | ||
574 | struct mvebu_pinctrl_soc_info *soc = dev_get_platdata(&pdev->dev); | ||
575 | struct device_node *np = pdev->dev.of_node; | ||
576 | struct mvebu_pinctrl *pctl; | ||
577 | void __iomem *base; | ||
578 | struct pinctrl_pin_desc *pdesc; | ||
579 | unsigned gid, n, k; | ||
580 | int ret; | ||
581 | |||
582 | if (!soc || !soc->controls || !soc->modes) { | ||
583 | dev_err(&pdev->dev, "wrong pinctrl soc info\n"); | ||
584 | return -EINVAL; | ||
585 | } | ||
586 | |||
587 | base = of_iomap(np, 0); | ||
588 | if (!base) { | ||
589 | dev_err(&pdev->dev, "unable to get base address\n"); | ||
590 | return -ENODEV; | ||
591 | } | ||
592 | |||
593 | pctl = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_pinctrl), | ||
594 | GFP_KERNEL); | ||
595 | if (!pctl) { | ||
596 | dev_err(&pdev->dev, "unable to alloc driver\n"); | ||
597 | return -ENOMEM; | ||
598 | } | ||
599 | |||
600 | pctl->desc.name = dev_name(&pdev->dev); | ||
601 | pctl->desc.owner = THIS_MODULE; | ||
602 | pctl->desc.pctlops = &mvebu_pinctrl_ops; | ||
603 | pctl->desc.pmxops = &mvebu_pinmux_ops; | ||
604 | pctl->desc.confops = &mvebu_pinconf_ops; | ||
605 | pctl->variant = soc->variant; | ||
606 | pctl->base = base; | ||
607 | pctl->dev = &pdev->dev; | ||
608 | platform_set_drvdata(pdev, pctl); | ||
609 | |||
610 | /* count controls and create names for mvebu generic | ||
611 | register controls; also does sanity checks */ | ||
612 | pctl->num_groups = 0; | ||
613 | pctl->desc.npins = 0; | ||
614 | for (n = 0; n < soc->ncontrols; n++) { | ||
615 | struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; | ||
616 | char *names; | ||
617 | |||
618 | pctl->desc.npins += ctrl->npins; | ||
619 | /* initial control pins */ | ||
620 | for (k = 0; k < ctrl->npins; k++) | ||
621 | ctrl->pins[k] = ctrl->pid + k; | ||
622 | |||
623 | /* special soc specific control */ | ||
624 | if (ctrl->mpp_get || ctrl->mpp_set) { | ||
625 | if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) { | ||
626 | dev_err(&pdev->dev, "wrong soc control info\n"); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | pctl->num_groups += 1; | ||
630 | continue; | ||
631 | } | ||
632 | |||
633 | /* generic mvebu register control */ | ||
634 | names = devm_kzalloc(&pdev->dev, ctrl->npins * 8, GFP_KERNEL); | ||
635 | if (!names) { | ||
636 | dev_err(&pdev->dev, "failed to alloc mpp names\n"); | ||
637 | return -ENOMEM; | ||
638 | } | ||
639 | for (k = 0; k < ctrl->npins; k++) | ||
640 | sprintf(names + 8*k, "mpp%d", ctrl->pid+k); | ||
641 | ctrl->name = names; | ||
642 | pctl->num_groups += ctrl->npins; | ||
643 | } | ||
644 | |||
645 | pdesc = devm_kzalloc(&pdev->dev, pctl->desc.npins * | ||
646 | sizeof(struct pinctrl_pin_desc), GFP_KERNEL); | ||
647 | if (!pdesc) { | ||
648 | dev_err(&pdev->dev, "failed to alloc pinctrl pins\n"); | ||
649 | return -ENOMEM; | ||
650 | } | ||
651 | |||
652 | for (n = 0; n < pctl->desc.npins; n++) | ||
653 | pdesc[n].number = n; | ||
654 | pctl->desc.pins = pdesc; | ||
655 | |||
656 | pctl->groups = devm_kzalloc(&pdev->dev, pctl->num_groups * | ||
657 | sizeof(struct mvebu_pinctrl_group), GFP_KERNEL); | ||
658 | if (!pctl->groups) { | ||
659 | dev_err(&pdev->dev, "failed to alloc pinctrl groups\n"); | ||
660 | return -ENOMEM; | ||
661 | } | ||
662 | |||
663 | /* assign mpp controls to groups */ | ||
664 | gid = 0; | ||
665 | for (n = 0; n < soc->ncontrols; n++) { | ||
666 | struct mvebu_mpp_ctrl *ctrl = &soc->controls[n]; | ||
667 | pctl->groups[gid].gid = gid; | ||
668 | pctl->groups[gid].ctrl = ctrl; | ||
669 | pctl->groups[gid].name = ctrl->name; | ||
670 | pctl->groups[gid].pins = ctrl->pins; | ||
671 | pctl->groups[gid].npins = ctrl->npins; | ||
672 | |||
673 | /* generic mvebu register control maps to a number of groups */ | ||
674 | if (!ctrl->mpp_get && !ctrl->mpp_set) { | ||
675 | pctl->groups[gid].npins = 1; | ||
676 | |||
677 | for (k = 1; k < ctrl->npins; k++) { | ||
678 | gid++; | ||
679 | pctl->groups[gid].gid = gid; | ||
680 | pctl->groups[gid].ctrl = ctrl; | ||
681 | pctl->groups[gid].name = &ctrl->name[8*k]; | ||
682 | pctl->groups[gid].pins = &ctrl->pins[k]; | ||
683 | pctl->groups[gid].npins = 1; | ||
684 | } | ||
685 | } | ||
686 | gid++; | ||
687 | } | ||
688 | |||
689 | /* assign mpp modes to groups */ | ||
690 | for (n = 0; n < soc->nmodes; n++) { | ||
691 | struct mvebu_mpp_mode *mode = &soc->modes[n]; | ||
692 | struct mvebu_pinctrl_group *grp = | ||
693 | mvebu_pinctrl_find_group_by_pid(pctl, mode->pid); | ||
694 | unsigned num_settings; | ||
695 | |||
696 | if (!grp) { | ||
697 | dev_warn(&pdev->dev, "unknown pinctrl group %d\n", | ||
698 | mode->pid); | ||
699 | continue; | ||
700 | } | ||
701 | |||
702 | for (num_settings = 0; ;) { | ||
703 | struct mvebu_mpp_ctrl_setting *set = | ||
704 | &mode->settings[num_settings]; | ||
705 | |||
706 | if (!set->name) | ||
707 | break; | ||
708 | num_settings++; | ||
709 | |||
710 | /* skip unsupported settings for this variant */ | ||
711 | if (pctl->variant && !(pctl->variant & set->variant)) | ||
712 | continue; | ||
713 | |||
714 | /* find gpio/gpo/gpi settings */ | ||
715 | if (strcmp(set->name, "gpio") == 0) | ||
716 | set->flags = MVEBU_SETTING_GPI | | ||
717 | MVEBU_SETTING_GPO; | ||
718 | else if (strcmp(set->name, "gpo") == 0) | ||
719 | set->flags = MVEBU_SETTING_GPO; | ||
720 | else if (strcmp(set->name, "gpi") == 0) | ||
721 | set->flags = MVEBU_SETTING_GPI; | ||
722 | } | ||
723 | |||
724 | grp->settings = mode->settings; | ||
725 | grp->num_settings = num_settings; | ||
726 | } | ||
727 | |||
728 | ret = mvebu_pinctrl_build_functions(pdev, pctl); | ||
729 | if (ret) { | ||
730 | dev_err(&pdev->dev, "unable to build functions\n"); | ||
731 | return ret; | ||
732 | } | ||
733 | |||
734 | pctl->pctldev = pinctrl_register(&pctl->desc, &pdev->dev, pctl); | ||
735 | if (!pctl->pctldev) { | ||
736 | dev_err(&pdev->dev, "unable to register pinctrl driver\n"); | ||
737 | return -EINVAL; | ||
738 | } | ||
739 | |||
740 | dev_info(&pdev->dev, "registered pinctrl driver\n"); | ||
741 | |||
742 | /* register gpio ranges */ | ||
743 | for (n = 0; n < soc->ngpioranges; n++) | ||
744 | pinctrl_add_gpio_range(pctl->pctldev, &soc->gpioranges[n]); | ||
745 | |||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | int __devexit mvebu_pinctrl_remove(struct platform_device *pdev) | ||
750 | { | ||
751 | struct mvebu_pinctrl *pctl = platform_get_drvdata(pdev); | ||
752 | pinctrl_unregister(pctl->pctldev); | ||
753 | return 0; | ||
754 | } | ||
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/pinctrl-mvebu.h new file mode 100644 index 000000000000..90bd3beee860 --- /dev/null +++ b/drivers/pinctrl/pinctrl-mvebu.h | |||
@@ -0,0 +1,192 @@ | |||
1 | /* | ||
2 | * Marvell MVEBU pinctrl driver | ||
3 | * | ||
4 | * Authors: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
5 | * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef __PINCTRL_MVEBU_H__ | ||
14 | #define __PINCTRL_MVEBU_H__ | ||
15 | |||
16 | /** | ||
17 | * struct mvebu_mpp_ctrl - describe a mpp control | ||
18 | * @name: name of the control group | ||
19 | * @pid: first pin id handled by this control | ||
20 | * @npins: number of pins controlled by this control | ||
21 | * @mpp_get: (optional) special function to get mpp setting | ||
22 | * @mpp_set: (optional) special function to set mpp setting | ||
23 | * @mpp_gpio_req: (optional) special function to request gpio | ||
24 | * @mpp_gpio_dir: (optional) special function to set gpio direction | ||
25 | * | ||
26 | * A mpp_ctrl describes a muxable unit, e.g. pin, group of pins, or | ||
27 | * internal function, inside the SoC. Each muxable unit can be switched | ||
28 | * between two or more different settings, e.g. assign mpp pin 13 to | ||
29 | * uart1 or sata. | ||
30 | * | ||
31 | * If optional mpp_get/_set functions are set these are used to get/set | ||
32 | * a specific mode. Otherwise it is assumed that the mpp control is based | ||
33 | * on 4-bit groups in subsequent registers. The optional mpp_gpio_req/_dir | ||
34 | * functions can be used to allow pin settings with varying gpio pins. | ||
35 | */ | ||
36 | struct mvebu_mpp_ctrl { | ||
37 | const char *name; | ||
38 | u8 pid; | ||
39 | u8 npins; | ||
40 | unsigned *pins; | ||
41 | int (*mpp_get)(struct mvebu_mpp_ctrl *ctrl, unsigned long *config); | ||
42 | int (*mpp_set)(struct mvebu_mpp_ctrl *ctrl, unsigned long config); | ||
43 | int (*mpp_gpio_req)(struct mvebu_mpp_ctrl *ctrl, u8 pid); | ||
44 | int (*mpp_gpio_dir)(struct mvebu_mpp_ctrl *ctrl, u8 pid, bool input); | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * struct mvebu_mpp_ctrl_setting - describe a mpp ctrl setting | ||
49 | * @val: ctrl setting value | ||
50 | * @name: ctrl setting name, e.g. uart2, spi0 - unique per mpp_mode | ||
51 | * @subname: (optional) additional ctrl setting name, e.g. rts, cts | ||
52 | * @variant: (optional) variant identifier mask | ||
53 | * @flags: (private) flags to store gpi/gpo/gpio capabilities | ||
54 | * | ||
55 | * A ctrl_setting describes a specific internal mux function that a mpp pin | ||
56 | * can be switched to. The value (val) will be written in the corresponding | ||
57 | * register for common mpp pin configuration registers on MVEBU. SoC specific | ||
58 | * mpp_get/_set function may use val to distinguish between different settings. | ||
59 | * | ||
60 | * The name will be used to switch to this setting in DT description, e.g. | ||
61 | * marvell,function = "uart2". subname is only for debugging purposes. | ||
62 | * | ||
63 | * If name is one of "gpi", "gpo", "gpio" gpio capabilities are | ||
64 | * parsed during initialization and stored in flags. | ||
65 | * | ||
66 | * The variant can be used to combine different revisions of one SoC to a | ||
67 | * common pinctrl driver. It is matched (AND) with variant of soc_info to | ||
68 | * determine if a setting is available on the current SoC revision. | ||
69 | */ | ||
70 | struct mvebu_mpp_ctrl_setting { | ||
71 | u8 val; | ||
72 | const char *name; | ||
73 | const char *subname; | ||
74 | u8 variant; | ||
75 | u8 flags; | ||
76 | #define MVEBU_SETTING_GPO (1 << 0) | ||
77 | #define MVEBU_SETTING_GPI (1 << 1) | ||
78 | }; | ||
79 | |||
80 | /** | ||
81 | * struct mvebu_mpp_mode - link ctrl and settings | ||
82 | * @pid: first pin id handled by this mode | ||
83 | * @settings: list of settings available for this mode | ||
84 | * | ||
85 | * A mode connects all available settings with the corresponding mpp_ctrl | ||
86 | * given by pid. | ||
87 | */ | ||
88 | struct mvebu_mpp_mode { | ||
89 | u8 pid; | ||
90 | struct mvebu_mpp_ctrl_setting *settings; | ||
91 | }; | ||
92 | |||
93 | /** | ||
94 | * struct mvebu_pinctrl_soc_info - SoC specific info passed to pinctrl-mvebu | ||
95 | * @variant: variant mask of soc_info | ||
96 | * @controls: list of available mvebu_mpp_ctrls | ||
97 | * @ncontrols: number of available mvebu_mpp_ctrls | ||
98 | * @modes: list of available mvebu_mpp_modes | ||
99 | * @nmodes: number of available mvebu_mpp_modes | ||
100 | * @gpioranges: list of pinctrl_gpio_ranges | ||
101 | * @ngpioranges: number of available pinctrl_gpio_ranges | ||
102 | * | ||
103 | * This struct describes all pinctrl related information for a specific SoC. | ||
104 | * If variant is unequal 0 it will be matched (AND) with variant of each | ||
105 | * setting and allows to distinguish between different revisions of one SoC. | ||
106 | */ | ||
107 | struct mvebu_pinctrl_soc_info { | ||
108 | u8 variant; | ||
109 | struct mvebu_mpp_ctrl *controls; | ||
110 | int ncontrols; | ||
111 | struct mvebu_mpp_mode *modes; | ||
112 | int nmodes; | ||
113 | struct pinctrl_gpio_range *gpioranges; | ||
114 | int ngpioranges; | ||
115 | }; | ||
116 | |||
117 | #define MPP_REG_CTRL(_idl, _idh) \ | ||
118 | { \ | ||
119 | .name = NULL, \ | ||
120 | .pid = _idl, \ | ||
121 | .npins = _idh - _idl + 1, \ | ||
122 | .pins = (unsigned[_idh - _idl + 1]) { }, \ | ||
123 | .mpp_get = NULL, \ | ||
124 | .mpp_set = NULL, \ | ||
125 | .mpp_gpio_req = NULL, \ | ||
126 | .mpp_gpio_dir = NULL, \ | ||
127 | } | ||
128 | |||
129 | #define MPP_FUNC_CTRL(_idl, _idh, _name, _func) \ | ||
130 | { \ | ||
131 | .name = _name, \ | ||
132 | .pid = _idl, \ | ||
133 | .npins = _idh - _idl + 1, \ | ||
134 | .pins = (unsigned[_idh - _idl + 1]) { }, \ | ||
135 | .mpp_get = _func ## _get, \ | ||
136 | .mpp_set = _func ## _set, \ | ||
137 | .mpp_gpio_req = NULL, \ | ||
138 | .mpp_gpio_dir = NULL, \ | ||
139 | } | ||
140 | |||
141 | #define MPP_FUNC_GPIO_CTRL(_idl, _idh, _name, _func) \ | ||
142 | { \ | ||
143 | .name = _name, \ | ||
144 | .pid = _idl, \ | ||
145 | .npins = _idh - _idl + 1, \ | ||
146 | .pins = (unsigned[_idh - _idl + 1]) { }, \ | ||
147 | .mpp_get = _func ## _get, \ | ||
148 | .mpp_set = _func ## _set, \ | ||
149 | .mpp_gpio_req = _func ## _gpio_req, \ | ||
150 | .mpp_gpio_dir = _func ## _gpio_dir, \ | ||
151 | } | ||
152 | |||
153 | #define _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ | ||
154 | { \ | ||
155 | .val = _val, \ | ||
156 | .name = _name, \ | ||
157 | .subname = _subname, \ | ||
158 | .variant = _mask, \ | ||
159 | .flags = 0, \ | ||
160 | } | ||
161 | |||
162 | #if defined(CONFIG_DEBUG_FS) | ||
163 | #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ | ||
164 | _MPP_VAR_FUNCTION(_val, _name, _subname, _mask) | ||
165 | #else | ||
166 | #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \ | ||
167 | _MPP_VAR_FUNCTION(_val, _name, NULL, _mask) | ||
168 | #endif | ||
169 | |||
170 | #define MPP_FUNCTION(_val, _name, _subname) \ | ||
171 | MPP_VAR_FUNCTION(_val, _name, _subname, (u8)-1) | ||
172 | |||
173 | #define MPP_MODE(_id, ...) \ | ||
174 | { \ | ||
175 | .pid = _id, \ | ||
176 | .settings = (struct mvebu_mpp_ctrl_setting[]){ \ | ||
177 | __VA_ARGS__, { } }, \ | ||
178 | } | ||
179 | |||
180 | #define MPP_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins) \ | ||
181 | { \ | ||
182 | .name = "mvebu-gpio", \ | ||
183 | .id = _id, \ | ||
184 | .pin_base = _pinbase, \ | ||
185 | .base = _gpiobase, \ | ||
186 | .npins = _npins, \ | ||
187 | } | ||
188 | |||
189 | int mvebu_pinctrl_probe(struct platform_device *pdev); | ||
190 | int mvebu_pinctrl_remove(struct platform_device *pdev); | ||
191 | |||
192 | #endif | ||