Commit | Line | Data |
---|---|---|
52130b60 VK |
1 | /* |
2 | * Driver for the ST Microelectronics SPEAr310 pinmux | |
3 | * | |
4 | * Copyright (C) 2012 ST Microelectronics | |
10d8935f | 5 | * Viresh Kumar <viresh.linux@gmail.com> |
52130b60 VK |
6 | * |
7 | * This file is licensed under the terms of the GNU General Public | |
8 | * License version 2. This program is licensed "as is" without any | |
9 | * warranty of any kind, whether express or implied. | |
10 | */ | |
11 | ||
12 | #include <linux/err.h> | |
13 | #include <linux/init.h> | |
14 | #include <linux/module.h> | |
15 | #include <linux/of_device.h> | |
16 | #include <linux/platform_device.h> | |
17 | #include "pinctrl-spear3xx.h" | |
18 | ||
19 | #define DRIVER_NAME "spear310-pinmux" | |
20 | ||
21 | /* addresses */ | |
22 | #define PMX_CONFIG_REG 0x08 | |
23 | ||
24 | /* emi_cs_0_to_5_pins */ | |
25 | static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 }; | |
26 | static struct spear_muxreg emi_cs_0_to_5_muxreg[] = { | |
27 | { | |
28 | .reg = PMX_CONFIG_REG, | |
29 | .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, | |
30 | .val = 0, | |
31 | }, | |
32 | }; | |
33 | ||
34 | static struct spear_modemux emi_cs_0_to_5_modemux[] = { | |
35 | { | |
36 | .muxregs = emi_cs_0_to_5_muxreg, | |
37 | .nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg), | |
38 | }, | |
39 | }; | |
40 | ||
41 | static struct spear_pingroup emi_cs_0_to_5_pingroup = { | |
42 | .name = "emi_cs_0_to_5_grp", | |
43 | .pins = emi_cs_0_to_5_pins, | |
44 | .npins = ARRAY_SIZE(emi_cs_0_to_5_pins), | |
45 | .modemuxs = emi_cs_0_to_5_modemux, | |
46 | .nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux), | |
47 | }; | |
48 | ||
49 | static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" }; | |
50 | static struct spear_function emi_cs_0_to_5_function = { | |
51 | .name = "emi", | |
52 | .groups = emi_cs_0_to_5_grps, | |
53 | .ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps), | |
54 | }; | |
55 | ||
56 | /* uart1_pins */ | |
57 | static const unsigned uart1_pins[] = { 0, 1 }; | |
58 | static struct spear_muxreg uart1_muxreg[] = { | |
59 | { | |
60 | .reg = PMX_CONFIG_REG, | |
61 | .mask = PMX_FIRDA_MASK, | |
62 | .val = 0, | |
63 | }, | |
64 | }; | |
65 | ||
66 | static struct spear_modemux uart1_modemux[] = { | |
67 | { | |
68 | .muxregs = uart1_muxreg, | |
69 | .nmuxregs = ARRAY_SIZE(uart1_muxreg), | |
70 | }, | |
71 | }; | |
72 | ||
73 | static struct spear_pingroup uart1_pingroup = { | |
74 | .name = "uart1_grp", | |
75 | .pins = uart1_pins, | |
76 | .npins = ARRAY_SIZE(uart1_pins), | |
77 | .modemuxs = uart1_modemux, | |
78 | .nmodemuxs = ARRAY_SIZE(uart1_modemux), | |
79 | }; | |
80 | ||
81 | static const char *const uart1_grps[] = { "uart1_grp" }; | |
82 | static struct spear_function uart1_function = { | |
83 | .name = "uart1", | |
84 | .groups = uart1_grps, | |
85 | .ngroups = ARRAY_SIZE(uart1_grps), | |
86 | }; | |
87 | ||
88 | /* uart2_pins */ | |
89 | static const unsigned uart2_pins[] = { 43, 44 }; | |
90 | static struct spear_muxreg uart2_muxreg[] = { | |
91 | { | |
92 | .reg = PMX_CONFIG_REG, | |
93 | .mask = PMX_TIMER_0_1_MASK, | |
94 | .val = 0, | |
95 | }, | |
96 | }; | |
97 | ||
98 | static struct spear_modemux uart2_modemux[] = { | |
99 | { | |
100 | .muxregs = uart2_muxreg, | |
101 | .nmuxregs = ARRAY_SIZE(uart2_muxreg), | |
102 | }, | |
103 | }; | |
104 | ||
105 | static struct spear_pingroup uart2_pingroup = { | |
106 | .name = "uart2_grp", | |
107 | .pins = uart2_pins, | |
108 | .npins = ARRAY_SIZE(uart2_pins), | |
109 | .modemuxs = uart2_modemux, | |
110 | .nmodemuxs = ARRAY_SIZE(uart2_modemux), | |
111 | }; | |
112 | ||
113 | static const char *const uart2_grps[] = { "uart2_grp" }; | |
114 | static struct spear_function uart2_function = { | |
115 | .name = "uart2", | |
116 | .groups = uart2_grps, | |
117 | .ngroups = ARRAY_SIZE(uart2_grps), | |
118 | }; | |
119 | ||
120 | /* uart3_pins */ | |
121 | static const unsigned uart3_pins[] = { 37, 38 }; | |
122 | static struct spear_muxreg uart3_muxreg[] = { | |
123 | { | |
124 | .reg = PMX_CONFIG_REG, | |
125 | .mask = PMX_UART0_MODEM_MASK, | |
126 | .val = 0, | |
127 | }, | |
128 | }; | |
129 | ||
130 | static struct spear_modemux uart3_modemux[] = { | |
131 | { | |
132 | .muxregs = uart3_muxreg, | |
133 | .nmuxregs = ARRAY_SIZE(uart3_muxreg), | |
134 | }, | |
135 | }; | |
136 | ||
137 | static struct spear_pingroup uart3_pingroup = { | |
138 | .name = "uart3_grp", | |
139 | .pins = uart3_pins, | |
140 | .npins = ARRAY_SIZE(uart3_pins), | |
141 | .modemuxs = uart3_modemux, | |
142 | .nmodemuxs = ARRAY_SIZE(uart3_modemux), | |
143 | }; | |
144 | ||
145 | static const char *const uart3_grps[] = { "uart3_grp" }; | |
146 | static struct spear_function uart3_function = { | |
147 | .name = "uart3", | |
148 | .groups = uart3_grps, | |
149 | .ngroups = ARRAY_SIZE(uart3_grps), | |
150 | }; | |
151 | ||
152 | /* uart4_pins */ | |
153 | static const unsigned uart4_pins[] = { 39, 40 }; | |
154 | static struct spear_muxreg uart4_muxreg[] = { | |
155 | { | |
156 | .reg = PMX_CONFIG_REG, | |
157 | .mask = PMX_UART0_MODEM_MASK, | |
158 | .val = 0, | |
159 | }, | |
160 | }; | |
161 | ||
162 | static struct spear_modemux uart4_modemux[] = { | |
163 | { | |
164 | .muxregs = uart4_muxreg, | |
165 | .nmuxregs = ARRAY_SIZE(uart4_muxreg), | |
166 | }, | |
167 | }; | |
168 | ||
169 | static struct spear_pingroup uart4_pingroup = { | |
170 | .name = "uart4_grp", | |
171 | .pins = uart4_pins, | |
172 | .npins = ARRAY_SIZE(uart4_pins), | |
173 | .modemuxs = uart4_modemux, | |
174 | .nmodemuxs = ARRAY_SIZE(uart4_modemux), | |
175 | }; | |
176 | ||
177 | static const char *const uart4_grps[] = { "uart4_grp" }; | |
178 | static struct spear_function uart4_function = { | |
179 | .name = "uart4", | |
180 | .groups = uart4_grps, | |
181 | .ngroups = ARRAY_SIZE(uart4_grps), | |
182 | }; | |
183 | ||
184 | /* uart5_pins */ | |
185 | static const unsigned uart5_pins[] = { 41, 42 }; | |
186 | static struct spear_muxreg uart5_muxreg[] = { | |
187 | { | |
188 | .reg = PMX_CONFIG_REG, | |
189 | .mask = PMX_UART0_MODEM_MASK, | |
190 | .val = 0, | |
191 | }, | |
192 | }; | |
193 | ||
194 | static struct spear_modemux uart5_modemux[] = { | |
195 | { | |
196 | .muxregs = uart5_muxreg, | |
197 | .nmuxregs = ARRAY_SIZE(uart5_muxreg), | |
198 | }, | |
199 | }; | |
200 | ||
201 | static struct spear_pingroup uart5_pingroup = { | |
202 | .name = "uart5_grp", | |
203 | .pins = uart5_pins, | |
204 | .npins = ARRAY_SIZE(uart5_pins), | |
205 | .modemuxs = uart5_modemux, | |
206 | .nmodemuxs = ARRAY_SIZE(uart5_modemux), | |
207 | }; | |
208 | ||
209 | static const char *const uart5_grps[] = { "uart5_grp" }; | |
210 | static struct spear_function uart5_function = { | |
211 | .name = "uart5", | |
212 | .groups = uart5_grps, | |
213 | .ngroups = ARRAY_SIZE(uart5_grps), | |
214 | }; | |
215 | ||
216 | /* fsmc_pins */ | |
217 | static const unsigned fsmc_pins[] = { 34, 35, 36 }; | |
218 | static struct spear_muxreg fsmc_muxreg[] = { | |
219 | { | |
220 | .reg = PMX_CONFIG_REG, | |
221 | .mask = PMX_SSP_CS_MASK, | |
222 | .val = 0, | |
223 | }, | |
224 | }; | |
225 | ||
226 | static struct spear_modemux fsmc_modemux[] = { | |
227 | { | |
228 | .muxregs = fsmc_muxreg, | |
229 | .nmuxregs = ARRAY_SIZE(fsmc_muxreg), | |
230 | }, | |
231 | }; | |
232 | ||
233 | static struct spear_pingroup fsmc_pingroup = { | |
234 | .name = "fsmc_grp", | |
235 | .pins = fsmc_pins, | |
236 | .npins = ARRAY_SIZE(fsmc_pins), | |
237 | .modemuxs = fsmc_modemux, | |
238 | .nmodemuxs = ARRAY_SIZE(fsmc_modemux), | |
239 | }; | |
240 | ||
241 | static const char *const fsmc_grps[] = { "fsmc_grp" }; | |
242 | static struct spear_function fsmc_function = { | |
243 | .name = "fsmc", | |
244 | .groups = fsmc_grps, | |
245 | .ngroups = ARRAY_SIZE(fsmc_grps), | |
246 | }; | |
247 | ||
248 | /* rs485_0_pins */ | |
249 | static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 }; | |
250 | static struct spear_muxreg rs485_0_muxreg[] = { | |
251 | { | |
252 | .reg = PMX_CONFIG_REG, | |
253 | .mask = PMX_MII_MASK, | |
254 | .val = 0, | |
255 | }, | |
256 | }; | |
257 | ||
258 | static struct spear_modemux rs485_0_modemux[] = { | |
259 | { | |
260 | .muxregs = rs485_0_muxreg, | |
261 | .nmuxregs = ARRAY_SIZE(rs485_0_muxreg), | |
262 | }, | |
263 | }; | |
264 | ||
265 | static struct spear_pingroup rs485_0_pingroup = { | |
266 | .name = "rs485_0_grp", | |
267 | .pins = rs485_0_pins, | |
268 | .npins = ARRAY_SIZE(rs485_0_pins), | |
269 | .modemuxs = rs485_0_modemux, | |
270 | .nmodemuxs = ARRAY_SIZE(rs485_0_modemux), | |
271 | }; | |
272 | ||
273 | static const char *const rs485_0_grps[] = { "rs485_0" }; | |
274 | static struct spear_function rs485_0_function = { | |
275 | .name = "rs485_0", | |
276 | .groups = rs485_0_grps, | |
277 | .ngroups = ARRAY_SIZE(rs485_0_grps), | |
278 | }; | |
279 | ||
280 | /* rs485_1_pins */ | |
281 | static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 }; | |
282 | static struct spear_muxreg rs485_1_muxreg[] = { | |
283 | { | |
284 | .reg = PMX_CONFIG_REG, | |
285 | .mask = PMX_MII_MASK, | |
286 | .val = 0, | |
287 | }, | |
288 | }; | |
289 | ||
290 | static struct spear_modemux rs485_1_modemux[] = { | |
291 | { | |
292 | .muxregs = rs485_1_muxreg, | |
293 | .nmuxregs = ARRAY_SIZE(rs485_1_muxreg), | |
294 | }, | |
295 | }; | |
296 | ||
297 | static struct spear_pingroup rs485_1_pingroup = { | |
298 | .name = "rs485_1_grp", | |
299 | .pins = rs485_1_pins, | |
300 | .npins = ARRAY_SIZE(rs485_1_pins), | |
301 | .modemuxs = rs485_1_modemux, | |
302 | .nmodemuxs = ARRAY_SIZE(rs485_1_modemux), | |
303 | }; | |
304 | ||
305 | static const char *const rs485_1_grps[] = { "rs485_1" }; | |
306 | static struct spear_function rs485_1_function = { | |
307 | .name = "rs485_1", | |
308 | .groups = rs485_1_grps, | |
309 | .ngroups = ARRAY_SIZE(rs485_1_grps), | |
310 | }; | |
311 | ||
312 | /* tdm_pins */ | |
313 | static const unsigned tdm_pins[] = { 10, 11, 12, 13 }; | |
314 | static struct spear_muxreg tdm_muxreg[] = { | |
315 | { | |
316 | .reg = PMX_CONFIG_REG, | |
317 | .mask = PMX_MII_MASK, | |
318 | .val = 0, | |
319 | }, | |
320 | }; | |
321 | ||
322 | static struct spear_modemux tdm_modemux[] = { | |
323 | { | |
324 | .muxregs = tdm_muxreg, | |
325 | .nmuxregs = ARRAY_SIZE(tdm_muxreg), | |
326 | }, | |
327 | }; | |
328 | ||
329 | static struct spear_pingroup tdm_pingroup = { | |
330 | .name = "tdm_grp", | |
331 | .pins = tdm_pins, | |
332 | .npins = ARRAY_SIZE(tdm_pins), | |
333 | .modemuxs = tdm_modemux, | |
334 | .nmodemuxs = ARRAY_SIZE(tdm_modemux), | |
335 | }; | |
336 | ||
337 | static const char *const tdm_grps[] = { "tdm_grp" }; | |
338 | static struct spear_function tdm_function = { | |
339 | .name = "tdm", | |
340 | .groups = tdm_grps, | |
341 | .ngroups = ARRAY_SIZE(tdm_grps), | |
342 | }; | |
343 | ||
344 | /* pingroups */ | |
345 | static struct spear_pingroup *spear310_pingroups[] = { | |
346 | SPEAR3XX_COMMON_PINGROUPS, | |
347 | &emi_cs_0_to_5_pingroup, | |
348 | &uart1_pingroup, | |
349 | &uart2_pingroup, | |
350 | &uart3_pingroup, | |
351 | &uart4_pingroup, | |
352 | &uart5_pingroup, | |
353 | &fsmc_pingroup, | |
354 | &rs485_0_pingroup, | |
355 | &rs485_1_pingroup, | |
356 | &tdm_pingroup, | |
357 | }; | |
358 | ||
359 | /* functions */ | |
360 | static struct spear_function *spear310_functions[] = { | |
361 | SPEAR3XX_COMMON_FUNCTIONS, | |
362 | &emi_cs_0_to_5_function, | |
363 | &uart1_function, | |
364 | &uart2_function, | |
365 | &uart3_function, | |
366 | &uart4_function, | |
367 | &uart5_function, | |
368 | &fsmc_function, | |
369 | &rs485_0_function, | |
370 | &rs485_1_function, | |
371 | &tdm_function, | |
372 | }; | |
373 | ||
374 | static struct of_device_id spear310_pinctrl_of_match[] __devinitdata = { | |
375 | { | |
376 | .compatible = "st,spear310-pinmux", | |
377 | }, | |
378 | {}, | |
379 | }; | |
380 | ||
381 | static int __devinit spear310_pinctrl_probe(struct platform_device *pdev) | |
382 | { | |
383 | int ret; | |
384 | ||
385 | spear3xx_machdata.groups = spear310_pingroups; | |
386 | spear3xx_machdata.ngroups = ARRAY_SIZE(spear310_pingroups); | |
387 | spear3xx_machdata.functions = spear310_functions; | |
388 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); | |
389 | ||
390 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); | |
391 | ||
392 | spear3xx_machdata.modes_supported = false; | |
393 | ||
394 | ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); | |
395 | if (ret) | |
396 | return ret; | |
397 | ||
398 | return 0; | |
399 | } | |
400 | ||
401 | static int __devexit spear310_pinctrl_remove(struct platform_device *pdev) | |
402 | { | |
403 | return spear_pinctrl_remove(pdev); | |
404 | } | |
405 | ||
406 | static struct platform_driver spear310_pinctrl_driver = { | |
407 | .driver = { | |
408 | .name = DRIVER_NAME, | |
409 | .owner = THIS_MODULE, | |
410 | .of_match_table = spear310_pinctrl_of_match, | |
411 | }, | |
412 | .probe = spear310_pinctrl_probe, | |
413 | .remove = __devexit_p(spear310_pinctrl_remove), | |
414 | }; | |
415 | ||
416 | static int __init spear310_pinctrl_init(void) | |
417 | { | |
418 | return platform_driver_register(&spear310_pinctrl_driver); | |
419 | } | |
420 | arch_initcall(spear310_pinctrl_init); | |
421 | ||
422 | static void __exit spear310_pinctrl_exit(void) | |
423 | { | |
424 | platform_driver_unregister(&spear310_pinctrl_driver); | |
425 | } | |
426 | module_exit(spear310_pinctrl_exit); | |
427 | ||
10d8935f | 428 | MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); |
52130b60 VK |
429 | MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); |
430 | MODULE_LICENSE("GPL v2"); | |
431 | MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match); |