1 /*
2  * Allwinner V3s SoCs pinctrl driver.
3  *
4  * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz>
5  *
6  * Based on pinctrl-sun8i-h3.c, which is:
7  * Copyright (C) 2015 Jens Kuske <jenskuske@gmail.com>
8  *
9  * Based on pinctrl-sun8i-a23.c, which is:
10  * Copyright (C) 2014 Chen-Yu Tsai <wens@csie.org>
11  * Copyright (C) 2014 Maxime Ripard <maxime.ripard@free-electrons.com>
12  *
13  * This file is licensed under the terms of the GNU General Public
14  * License version 2.  This program is licensed "as is" without any
15  * warranty of any kind, whether express or implied.
16  */
17 
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/of.h>
21 #include <linux/of_device.h>
22 #include <linux/pinctrl/pinctrl.h>
23 
24 #include "pinctrl-sunxi.h"
25 
26 static const struct sunxi_desc_pin sun8i_v3s_pins[] = {
27 	/* Hole */
28 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 0),
29 		  SUNXI_FUNCTION(0x0, "gpio_in"),
30 		  SUNXI_FUNCTION(0x1, "gpio_out"),
31 		  SUNXI_FUNCTION(0x2, "uart2"),		/* TX */
32 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)),	/* PB_EINT0 */
33 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 1),
34 		  SUNXI_FUNCTION(0x0, "gpio_in"),
35 		  SUNXI_FUNCTION(0x1, "gpio_out"),
36 		  SUNXI_FUNCTION(0x2, "uart2"),		/* RX */
37 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)),	/* PB_EINT1 */
38 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 2),
39 		  SUNXI_FUNCTION(0x0, "gpio_in"),
40 		  SUNXI_FUNCTION(0x1, "gpio_out"),
41 		  SUNXI_FUNCTION(0x2, "uart2"),		/* RTS */
42 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)),	/* PB_EINT2 */
43 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 3),
44 		  SUNXI_FUNCTION(0x0, "gpio_in"),
45 		  SUNXI_FUNCTION(0x1, "gpio_out"),
46 		  SUNXI_FUNCTION(0x2, "uart2"),		/* D1 */
47 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)),	/* PB_EINT3 */
48 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 4),
49 		  SUNXI_FUNCTION(0x0, "gpio_in"),
50 		  SUNXI_FUNCTION(0x1, "gpio_out"),
51 		  SUNXI_FUNCTION(0x2, "pwm0"),
52 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)),	/* PB_EINT4 */
53 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 5),
54 		  SUNXI_FUNCTION(0x0, "gpio_in"),
55 		  SUNXI_FUNCTION(0x1, "gpio_out"),
56 		  SUNXI_FUNCTION(0x2, "pwm1"),
57 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)),	/* PB_EINT5 */
58 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 6),
59 		  SUNXI_FUNCTION(0x0, "gpio_in"),
60 		  SUNXI_FUNCTION(0x1, "gpio_out"),
61 		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SCK */
62 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)),	/* PB_EINT6 */
63 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 7),
64 		  SUNXI_FUNCTION(0x0, "gpio_in"),
65 		  SUNXI_FUNCTION(0x1, "gpio_out"),
66 		  SUNXI_FUNCTION(0x2, "i2c0"),		/* SDA */
67 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)),	/* PB_EINT7 */
68 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 8),
69 		  SUNXI_FUNCTION(0x0, "gpio_in"),
70 		  SUNXI_FUNCTION(0x1, "gpio_out"),
71 		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SDA */
72 		  SUNXI_FUNCTION(0x3, "uart0"),		/* TX */
73 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)),	/* PB_EINT8 */
74 	SUNXI_PIN(SUNXI_PINCTRL_PIN(B, 9),
75 		  SUNXI_FUNCTION(0x0, "gpio_in"),
76 		  SUNXI_FUNCTION(0x1, "gpio_out"),
77 		  SUNXI_FUNCTION(0x2, "i2c1"),		/* SCK */
78 		  SUNXI_FUNCTION(0x3, "uart0"),		/* RX */
79 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)),	/* PB_EINT9 */
80 	/* Hole */
81 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 0),
82 		  SUNXI_FUNCTION(0x0, "gpio_in"),
83 		  SUNXI_FUNCTION(0x1, "gpio_out"),
84 		  SUNXI_FUNCTION(0x2, "mmc2"),		/* CLK */
85 		  SUNXI_FUNCTION(0x3, "spi0")),		/* MISO */
86 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 1),
87 		  SUNXI_FUNCTION(0x0, "gpio_in"),
88 		  SUNXI_FUNCTION(0x1, "gpio_out"),
89 		  SUNXI_FUNCTION(0x2, "mmc2"),		/* CMD */
90 		  SUNXI_FUNCTION(0x3, "spi0")),		/* CLK */
91 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 2),
92 		  SUNXI_FUNCTION(0x0, "gpio_in"),
93 		  SUNXI_FUNCTION(0x1, "gpio_out"),
94 		  SUNXI_FUNCTION(0x2, "mmc2"),		/* RST */
95 		  SUNXI_FUNCTION(0x3, "spi0")),		/* CS */
96 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 3),
97 		  SUNXI_FUNCTION(0x0, "gpio_in"),
98 		  SUNXI_FUNCTION(0x1, "gpio_out"),
99 		  SUNXI_FUNCTION(0x2, "mmc2"),		/* D0 */
100 		  SUNXI_FUNCTION(0x3, "spi0")),		/* MOSI */
101 	/* Hole */
102 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 0),
103 		  SUNXI_FUNCTION(0x0, "gpio_in"),
104 		  SUNXI_FUNCTION(0x1, "gpio_out"),
105 		  SUNXI_FUNCTION(0x2, "csi"),		/* PCLK */
106 		  SUNXI_FUNCTION(0x3, "lcd")),		/* CLK */
107 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 1),
108 		  SUNXI_FUNCTION(0x0, "gpio_in"),
109 		  SUNXI_FUNCTION(0x1, "gpio_out"),
110 		  SUNXI_FUNCTION(0x2, "csi"),		/* MCLK */
111 		  SUNXI_FUNCTION(0x3, "lcd")),		/* DE */
112 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 2),
113 		  SUNXI_FUNCTION(0x0, "gpio_in"),
114 		  SUNXI_FUNCTION(0x1, "gpio_out"),
115 		  SUNXI_FUNCTION(0x2, "csi"),		/* HSYNC */
116 		  SUNXI_FUNCTION(0x3, "lcd")),		/* HSYNC */
117 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 3),
118 		  SUNXI_FUNCTION(0x0, "gpio_in"),
119 		  SUNXI_FUNCTION(0x1, "gpio_out"),
120 		  SUNXI_FUNCTION(0x2, "csi"),		/* VSYNC */
121 		  SUNXI_FUNCTION(0x3, "lcd")),		/* VSYNC */
122 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 4),
123 		  SUNXI_FUNCTION(0x0, "gpio_in"),
124 		  SUNXI_FUNCTION(0x1, "gpio_out"),
125 		  SUNXI_FUNCTION(0x2, "csi"),		/* D0 */
126 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D2 */
127 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 5),
128 		  SUNXI_FUNCTION(0x0, "gpio_in"),
129 		  SUNXI_FUNCTION(0x1, "gpio_out"),
130 		  SUNXI_FUNCTION(0x2, "csi"),		/* D1 */
131 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D3 */
132 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 6),
133 		  SUNXI_FUNCTION(0x0, "gpio_in"),
134 		  SUNXI_FUNCTION(0x1, "gpio_out"),
135 		  SUNXI_FUNCTION(0x2, "csi"),		/* D2 */
136 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D4 */
137 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 7),
138 		  SUNXI_FUNCTION(0x0, "gpio_in"),
139 		  SUNXI_FUNCTION(0x1, "gpio_out"),
140 		  SUNXI_FUNCTION(0x2, "csi"),		/* D3 */
141 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D5 */
142 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 8),
143 		  SUNXI_FUNCTION(0x0, "gpio_in"),
144 		  SUNXI_FUNCTION(0x1, "gpio_out"),
145 		  SUNXI_FUNCTION(0x2, "csi"),		/* D4 */
146 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D6 */
147 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 9),
148 		  SUNXI_FUNCTION(0x0, "gpio_in"),
149 		  SUNXI_FUNCTION(0x1, "gpio_out"),
150 		  SUNXI_FUNCTION(0x2, "csi"),		/* D5 */
151 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D7 */
152 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 10),
153 		  SUNXI_FUNCTION(0x0, "gpio_in"),
154 		  SUNXI_FUNCTION(0x1, "gpio_out"),
155 		  SUNXI_FUNCTION(0x2, "csi"),		/* D6 */
156 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D10 */
157 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 11),
158 		  SUNXI_FUNCTION(0x0, "gpio_in"),
159 		  SUNXI_FUNCTION(0x1, "gpio_out"),
160 		  SUNXI_FUNCTION(0x2, "csi"),		/* D7 */
161 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D11 */
162 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 12),
163 		  SUNXI_FUNCTION(0x0, "gpio_in"),
164 		  SUNXI_FUNCTION(0x1, "gpio_out"),
165 		  SUNXI_FUNCTION(0x2, "csi"),		/* D8 */
166 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D12 */
167 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 13),
168 		  SUNXI_FUNCTION(0x0, "gpio_in"),
169 		  SUNXI_FUNCTION(0x1, "gpio_out"),
170 		  SUNXI_FUNCTION(0x2, "csi"),		/* D9 */
171 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D13 */
172 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 14),
173 		  SUNXI_FUNCTION(0x0, "gpio_in"),
174 		  SUNXI_FUNCTION(0x1, "gpio_out"),
175 		  SUNXI_FUNCTION(0x2, "csi"),		/* D10 */
176 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D14 */
177 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 15),
178 		  SUNXI_FUNCTION(0x0, "gpio_in"),
179 		  SUNXI_FUNCTION(0x1, "gpio_out"),
180 		  SUNXI_FUNCTION(0x2, "csi"),		/* D11 */
181 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D15 */
182 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 16),
183 		  SUNXI_FUNCTION(0x0, "gpio_in"),
184 		  SUNXI_FUNCTION(0x1, "gpio_out"),
185 		  SUNXI_FUNCTION(0x2, "csi"),		/* D12 */
186 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D18 */
187 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 17),
188 		  SUNXI_FUNCTION(0x0, "gpio_in"),
189 		  SUNXI_FUNCTION(0x1, "gpio_out"),
190 		  SUNXI_FUNCTION(0x2, "csi"),		/* D13 */
191 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D19 */
192 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 18),
193 		  SUNXI_FUNCTION(0x0, "gpio_in"),
194 		  SUNXI_FUNCTION(0x1, "gpio_out"),
195 		  SUNXI_FUNCTION(0x2, "csi"),		/* D14 */
196 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D20 */
197 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 19),
198 		  SUNXI_FUNCTION(0x0, "gpio_in"),
199 		  SUNXI_FUNCTION(0x1, "gpio_out"),
200 		  SUNXI_FUNCTION(0x2, "csi"),		/* D15 */
201 		  SUNXI_FUNCTION(0x3, "lcd")),		/* D21 */
202 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 20),
203 		  SUNXI_FUNCTION(0x0, "gpio_in"),
204 		  SUNXI_FUNCTION(0x1, "gpio_out"),
205 		  SUNXI_FUNCTION(0x2, "csi"),		/* FIELD */
206 		  SUNXI_FUNCTION(0x3, "csi_mipi")),	/* MCLK */
207 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 21),
208 		  SUNXI_FUNCTION(0x0, "gpio_in"),
209 		  SUNXI_FUNCTION(0x1, "gpio_out"),
210 		  SUNXI_FUNCTION(0x2, "csi"),		/* SCK */
211 		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SCK */
212 		  SUNXI_FUNCTION(0x4, "uart1")),	/* TX */
213 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 22),
214 		  SUNXI_FUNCTION(0x0, "gpio_in"),
215 		  SUNXI_FUNCTION(0x1, "gpio_out"),
216 		  SUNXI_FUNCTION(0x2, "csi"),		/* SDA */
217 		  SUNXI_FUNCTION(0x3, "i2c1"),		/* SDA */
218 		  SUNXI_FUNCTION(0x4, "uart1")),	/* RX */
219 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 23),
220 		  SUNXI_FUNCTION(0x0, "gpio_in"),
221 		  SUNXI_FUNCTION(0x1, "gpio_out"),
222 		  SUNXI_FUNCTION(0x3, "lcd"),		/* D22 */
223 		  SUNXI_FUNCTION(0x4, "uart1")),	/* RTS */
224 	SUNXI_PIN(SUNXI_PINCTRL_PIN(E, 24),
225 		  SUNXI_FUNCTION(0x0, "gpio_in"),
226 		  SUNXI_FUNCTION(0x1, "gpio_out"),
227 		  SUNXI_FUNCTION(0x3, "lcd"),		/* D23 */
228 		  SUNXI_FUNCTION(0x4, "uart1")),	/* CTS */
229 	/* Hole */
230 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 0),
231 		  SUNXI_FUNCTION(0x0, "gpio_in"),
232 		  SUNXI_FUNCTION(0x1, "gpio_out"),
233 		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D1 */
234 		  SUNXI_FUNCTION(0x3, "jtag")),		/* MS */
235 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 1),
236 		  SUNXI_FUNCTION(0x0, "gpio_in"),
237 		  SUNXI_FUNCTION(0x1, "gpio_out"),
238 		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D0 */
239 		  SUNXI_FUNCTION(0x3, "jtag")),		/* DI */
240 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 2),
241 		  SUNXI_FUNCTION(0x0, "gpio_in"),
242 		  SUNXI_FUNCTION(0x1, "gpio_out"),
243 		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CLK */
244 		  SUNXI_FUNCTION(0x3, "uart0")),	/* TX */
245 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 3),
246 		  SUNXI_FUNCTION(0x0, "gpio_in"),
247 		  SUNXI_FUNCTION(0x1, "gpio_out"),
248 		  SUNXI_FUNCTION(0x2, "mmc0"),		/* CMD */
249 		  SUNXI_FUNCTION(0x3, "jtag")),		/* DO */
250 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 4),
251 		  SUNXI_FUNCTION(0x0, "gpio_in"),
252 		  SUNXI_FUNCTION(0x1, "gpio_out"),
253 		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D3 */
254 		  SUNXI_FUNCTION(0x3, "uart0")),	/* RX */
255 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 5),
256 		  SUNXI_FUNCTION(0x0, "gpio_in"),
257 		  SUNXI_FUNCTION(0x1, "gpio_out"),
258 		  SUNXI_FUNCTION(0x2, "mmc0"),		/* D2 */
259 		  SUNXI_FUNCTION(0x3, "jtag")),		/* CK */
260 	SUNXI_PIN(SUNXI_PINCTRL_PIN(F, 6),
261 		  SUNXI_FUNCTION(0x0, "gpio_in"),
262 		  SUNXI_FUNCTION(0x1, "gpio_out")),
263 	/* Hole */
264 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 0),
265 		  SUNXI_FUNCTION(0x0, "gpio_in"),
266 		  SUNXI_FUNCTION(0x1, "gpio_out"),
267 		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CLK */
268 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 0)),	/* PG_EINT0 */
269 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 1),
270 		  SUNXI_FUNCTION(0x0, "gpio_in"),
271 		  SUNXI_FUNCTION(0x1, "gpio_out"),
272 		  SUNXI_FUNCTION(0x2, "mmc1"),		/* CMD */
273 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 1)),	/* PG_EINT1 */
274 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 2),
275 		  SUNXI_FUNCTION(0x0, "gpio_in"),
276 		  SUNXI_FUNCTION(0x1, "gpio_out"),
277 		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D0 */
278 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 2)),	/* PG_EINT2 */
279 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 3),
280 		  SUNXI_FUNCTION(0x0, "gpio_in"),
281 		  SUNXI_FUNCTION(0x1, "gpio_out"),
282 		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D1 */
283 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 3)),	/* PG_EINT3 */
284 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 4),
285 		  SUNXI_FUNCTION(0x0, "gpio_in"),
286 		  SUNXI_FUNCTION(0x1, "gpio_out"),
287 		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D2 */
288 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 4)),	/* PG_EINT4 */
289 	SUNXI_PIN(SUNXI_PINCTRL_PIN(G, 5),
290 		  SUNXI_FUNCTION(0x0, "gpio_in"),
291 		  SUNXI_FUNCTION(0x1, "gpio_out"),
292 		  SUNXI_FUNCTION(0x2, "mmc1"),		/* D3 */
293 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 1, 5)),	/* PG_EINT5 */
294 };
295 
296 static const struct sunxi_pinctrl_desc sun8i_v3s_pinctrl_data = {
297 	.pins = sun8i_v3s_pins,
298 	.npins = ARRAY_SIZE(sun8i_v3s_pins),
299 	.irq_banks = 2,
300 	.irq_read_needs_mux = true
301 };
302 
303 static int sun8i_v3s_pinctrl_probe(struct platform_device *pdev)
304 {
305 	return sunxi_pinctrl_init(pdev,
306 				  &sun8i_v3s_pinctrl_data);
307 }
308 
309 static const struct of_device_id sun8i_v3s_pinctrl_match[] = {
310 	{ .compatible = "allwinner,sun8i-v3s-pinctrl", },
311 	{}
312 };
313 
314 static struct platform_driver sun8i_v3s_pinctrl_driver = {
315 	.probe	= sun8i_v3s_pinctrl_probe,
316 	.driver	= {
317 		.name		= "sun8i-v3s-pinctrl",
318 		.of_match_table	= sun8i_v3s_pinctrl_match,
319 	},
320 };
321 builtin_platform_driver(sun8i_v3s_pinctrl_driver);
322