1 | /* |
2 | * Driver for the ST Microelectronics SPEAr300 pinmux |
3 | * |
4 | * Copyright (C) 2012 ST Microelectronics |
5 | * Viresh Kumar <vireshk@kernel.org> |
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/mod_devicetable.h> |
15 | #include <linux/platform_device.h> |
16 | #include "pinctrl-spear3xx.h" |
17 | |
18 | #define DRIVER_NAME "spear300-pinmux" |
19 | |
20 | /* addresses */ |
21 | #define PMX_CONFIG_REG 0x00 |
22 | #define MODE_CONFIG_REG 0x04 |
23 | |
24 | /* modes */ |
25 | #define NAND_MODE (1 << 0) |
26 | #define NOR_MODE (1 << 1) |
27 | #define PHOTO_FRAME_MODE (1 << 2) |
28 | #define LEND_IP_PHONE_MODE (1 << 3) |
29 | #define HEND_IP_PHONE_MODE (1 << 4) |
30 | #define LEND_WIFI_PHONE_MODE (1 << 5) |
31 | #define HEND_WIFI_PHONE_MODE (1 << 6) |
32 | #define ATA_PABX_WI2S_MODE (1 << 7) |
33 | #define ATA_PABX_I2S_MODE (1 << 8) |
34 | #define CAML_LCDW_MODE (1 << 9) |
35 | #define CAMU_LCD_MODE (1 << 10) |
36 | #define CAMU_WLCD_MODE (1 << 11) |
37 | #define CAML_LCD_MODE (1 << 12) |
38 | |
39 | static struct spear_pmx_mode pmx_mode_nand = { |
40 | .name = "nand" , |
41 | .mode = NAND_MODE, |
42 | .reg = MODE_CONFIG_REG, |
43 | .mask = 0x0000000F, |
44 | .val = 0x00, |
45 | }; |
46 | |
47 | static struct spear_pmx_mode pmx_mode_nor = { |
48 | .name = "nor" , |
49 | .mode = NOR_MODE, |
50 | .reg = MODE_CONFIG_REG, |
51 | .mask = 0x0000000F, |
52 | .val = 0x01, |
53 | }; |
54 | |
55 | static struct spear_pmx_mode pmx_mode_photo_frame = { |
56 | .name = "photo frame mode" , |
57 | .mode = PHOTO_FRAME_MODE, |
58 | .reg = MODE_CONFIG_REG, |
59 | .mask = 0x0000000F, |
60 | .val = 0x02, |
61 | }; |
62 | |
63 | static struct spear_pmx_mode pmx_mode_lend_ip_phone = { |
64 | .name = "lend ip phone mode" , |
65 | .mode = LEND_IP_PHONE_MODE, |
66 | .reg = MODE_CONFIG_REG, |
67 | .mask = 0x0000000F, |
68 | .val = 0x03, |
69 | }; |
70 | |
71 | static struct spear_pmx_mode pmx_mode_hend_ip_phone = { |
72 | .name = "hend ip phone mode" , |
73 | .mode = HEND_IP_PHONE_MODE, |
74 | .reg = MODE_CONFIG_REG, |
75 | .mask = 0x0000000F, |
76 | .val = 0x04, |
77 | }; |
78 | |
79 | static struct spear_pmx_mode pmx_mode_lend_wifi_phone = { |
80 | .name = "lend wifi phone mode" , |
81 | .mode = LEND_WIFI_PHONE_MODE, |
82 | .reg = MODE_CONFIG_REG, |
83 | .mask = 0x0000000F, |
84 | .val = 0x05, |
85 | }; |
86 | |
87 | static struct spear_pmx_mode pmx_mode_hend_wifi_phone = { |
88 | .name = "hend wifi phone mode" , |
89 | .mode = HEND_WIFI_PHONE_MODE, |
90 | .reg = MODE_CONFIG_REG, |
91 | .mask = 0x0000000F, |
92 | .val = 0x06, |
93 | }; |
94 | |
95 | static struct spear_pmx_mode pmx_mode_ata_pabx_wi2s = { |
96 | .name = "ata pabx wi2s mode" , |
97 | .mode = ATA_PABX_WI2S_MODE, |
98 | .reg = MODE_CONFIG_REG, |
99 | .mask = 0x0000000F, |
100 | .val = 0x07, |
101 | }; |
102 | |
103 | static struct spear_pmx_mode pmx_mode_ata_pabx_i2s = { |
104 | .name = "ata pabx i2s mode" , |
105 | .mode = ATA_PABX_I2S_MODE, |
106 | .reg = MODE_CONFIG_REG, |
107 | .mask = 0x0000000F, |
108 | .val = 0x08, |
109 | }; |
110 | |
111 | static struct spear_pmx_mode pmx_mode_caml_lcdw = { |
112 | .name = "caml lcdw mode" , |
113 | .mode = CAML_LCDW_MODE, |
114 | .reg = MODE_CONFIG_REG, |
115 | .mask = 0x0000000F, |
116 | .val = 0x0C, |
117 | }; |
118 | |
119 | static struct spear_pmx_mode pmx_mode_camu_lcd = { |
120 | .name = "camu lcd mode" , |
121 | .mode = CAMU_LCD_MODE, |
122 | .reg = MODE_CONFIG_REG, |
123 | .mask = 0x0000000F, |
124 | .val = 0x0D, |
125 | }; |
126 | |
127 | static struct spear_pmx_mode pmx_mode_camu_wlcd = { |
128 | .name = "camu wlcd mode" , |
129 | .mode = CAMU_WLCD_MODE, |
130 | .reg = MODE_CONFIG_REG, |
131 | .mask = 0x0000000F, |
132 | .val = 0xE, |
133 | }; |
134 | |
135 | static struct spear_pmx_mode pmx_mode_caml_lcd = { |
136 | .name = "caml lcd mode" , |
137 | .mode = CAML_LCD_MODE, |
138 | .reg = MODE_CONFIG_REG, |
139 | .mask = 0x0000000F, |
140 | .val = 0x0F, |
141 | }; |
142 | |
143 | static struct spear_pmx_mode *spear300_pmx_modes[] = { |
144 | &pmx_mode_nand, |
145 | &pmx_mode_nor, |
146 | &pmx_mode_photo_frame, |
147 | &pmx_mode_lend_ip_phone, |
148 | &pmx_mode_hend_ip_phone, |
149 | &pmx_mode_lend_wifi_phone, |
150 | &pmx_mode_hend_wifi_phone, |
151 | &pmx_mode_ata_pabx_wi2s, |
152 | &pmx_mode_ata_pabx_i2s, |
153 | &pmx_mode_caml_lcdw, |
154 | &pmx_mode_camu_lcd, |
155 | &pmx_mode_camu_wlcd, |
156 | &pmx_mode_caml_lcd, |
157 | }; |
158 | |
159 | /* fsmc_2chips_pins */ |
160 | static const unsigned fsmc_2chips_pins[] = { 1, 97 }; |
161 | static struct spear_muxreg fsmc_2chips_muxreg[] = { |
162 | { |
163 | .reg = PMX_CONFIG_REG, |
164 | .mask = PMX_FIRDA_MASK, |
165 | .val = 0, |
166 | }, |
167 | }; |
168 | |
169 | static struct spear_modemux fsmc_2chips_modemux[] = { |
170 | { |
171 | .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | |
172 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, |
173 | .muxregs = fsmc_2chips_muxreg, |
174 | .nmuxregs = ARRAY_SIZE(fsmc_2chips_muxreg), |
175 | }, |
176 | }; |
177 | |
178 | static struct spear_pingroup fsmc_2chips_pingroup = { |
179 | .name = "fsmc_2chips_grp" , |
180 | .pins = fsmc_2chips_pins, |
181 | .npins = ARRAY_SIZE(fsmc_2chips_pins), |
182 | .modemuxs = fsmc_2chips_modemux, |
183 | .nmodemuxs = ARRAY_SIZE(fsmc_2chips_modemux), |
184 | }; |
185 | |
186 | /* fsmc_4chips_pins */ |
187 | static const unsigned fsmc_4chips_pins[] = { 1, 2, 3, 97 }; |
188 | static struct spear_muxreg fsmc_4chips_muxreg[] = { |
189 | { |
190 | .reg = PMX_CONFIG_REG, |
191 | .mask = PMX_FIRDA_MASK | PMX_UART0_MASK, |
192 | .val = 0, |
193 | }, |
194 | }; |
195 | |
196 | static struct spear_modemux fsmc_4chips_modemux[] = { |
197 | { |
198 | .modes = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE | |
199 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE, |
200 | .muxregs = fsmc_4chips_muxreg, |
201 | .nmuxregs = ARRAY_SIZE(fsmc_4chips_muxreg), |
202 | }, |
203 | }; |
204 | |
205 | static struct spear_pingroup fsmc_4chips_pingroup = { |
206 | .name = "fsmc_4chips_grp" , |
207 | .pins = fsmc_4chips_pins, |
208 | .npins = ARRAY_SIZE(fsmc_4chips_pins), |
209 | .modemuxs = fsmc_4chips_modemux, |
210 | .nmodemuxs = ARRAY_SIZE(fsmc_4chips_modemux), |
211 | }; |
212 | |
213 | static const char *const fsmc_grps[] = { "fsmc_2chips_grp" , "fsmc_4chips_grp" |
214 | }; |
215 | static struct spear_function fsmc_function = { |
216 | .name = "fsmc" , |
217 | .groups = fsmc_grps, |
218 | .ngroups = ARRAY_SIZE(fsmc_grps), |
219 | }; |
220 | |
221 | /* clcd_lcdmode_pins */ |
222 | static const unsigned clcd_lcdmode_pins[] = { 49, 50 }; |
223 | static struct spear_muxreg clcd_lcdmode_muxreg[] = { |
224 | { |
225 | .reg = PMX_CONFIG_REG, |
226 | .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, |
227 | .val = 0, |
228 | }, |
229 | }; |
230 | |
231 | static struct spear_modemux clcd_lcdmode_modemux[] = { |
232 | { |
233 | .modes = HEND_IP_PHONE_MODE | HEND_WIFI_PHONE_MODE | |
234 | CAMU_LCD_MODE | CAML_LCD_MODE, |
235 | .muxregs = clcd_lcdmode_muxreg, |
236 | .nmuxregs = ARRAY_SIZE(clcd_lcdmode_muxreg), |
237 | }, |
238 | }; |
239 | |
240 | static struct spear_pingroup clcd_lcdmode_pingroup = { |
241 | .name = "clcd_lcdmode_grp" , |
242 | .pins = clcd_lcdmode_pins, |
243 | .npins = ARRAY_SIZE(clcd_lcdmode_pins), |
244 | .modemuxs = clcd_lcdmode_modemux, |
245 | .nmodemuxs = ARRAY_SIZE(clcd_lcdmode_modemux), |
246 | }; |
247 | |
248 | /* clcd_pfmode_pins */ |
249 | static const unsigned clcd_pfmode_pins[] = { 47, 48, 49, 50 }; |
250 | static struct spear_muxreg clcd_pfmode_muxreg[] = { |
251 | { |
252 | .reg = PMX_CONFIG_REG, |
253 | .mask = PMX_TIMER_2_3_MASK, |
254 | .val = 0, |
255 | }, |
256 | }; |
257 | |
258 | static struct spear_modemux clcd_pfmode_modemux[] = { |
259 | { |
260 | .modes = PHOTO_FRAME_MODE, |
261 | .muxregs = clcd_pfmode_muxreg, |
262 | .nmuxregs = ARRAY_SIZE(clcd_pfmode_muxreg), |
263 | }, |
264 | }; |
265 | |
266 | static struct spear_pingroup clcd_pfmode_pingroup = { |
267 | .name = "clcd_pfmode_grp" , |
268 | .pins = clcd_pfmode_pins, |
269 | .npins = ARRAY_SIZE(clcd_pfmode_pins), |
270 | .modemuxs = clcd_pfmode_modemux, |
271 | .nmodemuxs = ARRAY_SIZE(clcd_pfmode_modemux), |
272 | }; |
273 | |
274 | static const char *const clcd_grps[] = { "clcd_lcdmode_grp" , "clcd_pfmode_grp" |
275 | }; |
276 | static struct spear_function clcd_function = { |
277 | .name = "clcd" , |
278 | .groups = clcd_grps, |
279 | .ngroups = ARRAY_SIZE(clcd_grps), |
280 | }; |
281 | |
282 | /* tdm_pins */ |
283 | static const unsigned tdm_pins[] = { 34, 35, 36, 37, 38 }; |
284 | static struct spear_muxreg tdm_muxreg[] = { |
285 | { |
286 | .reg = PMX_CONFIG_REG, |
287 | .mask = PMX_UART0_MODEM_MASK | PMX_SSP_CS_MASK, |
288 | .val = 0, |
289 | }, |
290 | }; |
291 | |
292 | static struct spear_modemux tdm_modemux[] = { |
293 | { |
294 | .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | |
295 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
296 | | HEND_WIFI_PHONE_MODE | ATA_PABX_WI2S_MODE |
297 | | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
298 | | CAMU_WLCD_MODE | CAML_LCD_MODE, |
299 | .muxregs = tdm_muxreg, |
300 | .nmuxregs = ARRAY_SIZE(tdm_muxreg), |
301 | }, |
302 | }; |
303 | |
304 | static struct spear_pingroup tdm_pingroup = { |
305 | .name = "tdm_grp" , |
306 | .pins = tdm_pins, |
307 | .npins = ARRAY_SIZE(tdm_pins), |
308 | .modemuxs = tdm_modemux, |
309 | .nmodemuxs = ARRAY_SIZE(tdm_modemux), |
310 | }; |
311 | |
312 | static const char *const tdm_grps[] = { "tdm_grp" }; |
313 | static struct spear_function tdm_function = { |
314 | .name = "tdm" , |
315 | .groups = tdm_grps, |
316 | .ngroups = ARRAY_SIZE(tdm_grps), |
317 | }; |
318 | |
319 | /* i2c_clk_pins */ |
320 | static const unsigned i2c_clk_pins[] = { 45, 46, 47, 48 }; |
321 | static struct spear_muxreg i2c_clk_muxreg[] = { |
322 | { |
323 | .reg = PMX_CONFIG_REG, |
324 | .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, |
325 | .val = 0, |
326 | }, |
327 | }; |
328 | |
329 | static struct spear_modemux i2c_clk_modemux[] = { |
330 | { |
331 | .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | |
332 | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | |
333 | ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE | CAML_LCDW_MODE |
334 | | CAML_LCD_MODE, |
335 | .muxregs = i2c_clk_muxreg, |
336 | .nmuxregs = ARRAY_SIZE(i2c_clk_muxreg), |
337 | }, |
338 | }; |
339 | |
340 | static struct spear_pingroup i2c_clk_pingroup = { |
341 | .name = "i2c_clk_grp_grp" , |
342 | .pins = i2c_clk_pins, |
343 | .npins = ARRAY_SIZE(i2c_clk_pins), |
344 | .modemuxs = i2c_clk_modemux, |
345 | .nmodemuxs = ARRAY_SIZE(i2c_clk_modemux), |
346 | }; |
347 | |
348 | static const char *const i2c_grps[] = { "i2c_clk_grp" }; |
349 | static struct spear_function i2c_function = { |
350 | .name = "i2c1" , |
351 | .groups = i2c_grps, |
352 | .ngroups = ARRAY_SIZE(i2c_grps), |
353 | }; |
354 | |
355 | /* caml_pins */ |
356 | static const unsigned caml_pins[] = { 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 }; |
357 | static struct spear_muxreg caml_muxreg[] = { |
358 | { |
359 | .reg = PMX_CONFIG_REG, |
360 | .mask = PMX_MII_MASK, |
361 | .val = 0, |
362 | }, |
363 | }; |
364 | |
365 | static struct spear_modemux caml_modemux[] = { |
366 | { |
367 | .modes = CAML_LCDW_MODE | CAML_LCD_MODE, |
368 | .muxregs = caml_muxreg, |
369 | .nmuxregs = ARRAY_SIZE(caml_muxreg), |
370 | }, |
371 | }; |
372 | |
373 | static struct spear_pingroup caml_pingroup = { |
374 | .name = "caml_grp" , |
375 | .pins = caml_pins, |
376 | .npins = ARRAY_SIZE(caml_pins), |
377 | .modemuxs = caml_modemux, |
378 | .nmodemuxs = ARRAY_SIZE(caml_modemux), |
379 | }; |
380 | |
381 | /* camu_pins */ |
382 | static const unsigned camu_pins[] = { 16, 17, 18, 19, 20, 21, 45, 46, 47, 48 }; |
383 | static struct spear_muxreg camu_muxreg[] = { |
384 | { |
385 | .reg = PMX_CONFIG_REG, |
386 | .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK | PMX_MII_MASK, |
387 | .val = 0, |
388 | }, |
389 | }; |
390 | |
391 | static struct spear_modemux camu_modemux[] = { |
392 | { |
393 | .modes = CAMU_LCD_MODE | CAMU_WLCD_MODE, |
394 | .muxregs = camu_muxreg, |
395 | .nmuxregs = ARRAY_SIZE(camu_muxreg), |
396 | }, |
397 | }; |
398 | |
399 | static struct spear_pingroup camu_pingroup = { |
400 | .name = "camu_grp" , |
401 | .pins = camu_pins, |
402 | .npins = ARRAY_SIZE(camu_pins), |
403 | .modemuxs = camu_modemux, |
404 | .nmodemuxs = ARRAY_SIZE(camu_modemux), |
405 | }; |
406 | |
407 | static const char *const cam_grps[] = { "caml_grp" , "camu_grp" }; |
408 | static struct spear_function cam_function = { |
409 | .name = "cam" , |
410 | .groups = cam_grps, |
411 | .ngroups = ARRAY_SIZE(cam_grps), |
412 | }; |
413 | |
414 | /* dac_pins */ |
415 | static const unsigned dac_pins[] = { 43, 44 }; |
416 | static struct spear_muxreg dac_muxreg[] = { |
417 | { |
418 | .reg = PMX_CONFIG_REG, |
419 | .mask = PMX_TIMER_0_1_MASK, |
420 | .val = 0, |
421 | }, |
422 | }; |
423 | |
424 | static struct spear_modemux dac_modemux[] = { |
425 | { |
426 | .modes = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
427 | | CAMU_WLCD_MODE | CAML_LCD_MODE, |
428 | .muxregs = dac_muxreg, |
429 | .nmuxregs = ARRAY_SIZE(dac_muxreg), |
430 | }, |
431 | }; |
432 | |
433 | static struct spear_pingroup dac_pingroup = { |
434 | .name = "dac_grp" , |
435 | .pins = dac_pins, |
436 | .npins = ARRAY_SIZE(dac_pins), |
437 | .modemuxs = dac_modemux, |
438 | .nmodemuxs = ARRAY_SIZE(dac_modemux), |
439 | }; |
440 | |
441 | static const char *const dac_grps[] = { "dac_grp" }; |
442 | static struct spear_function dac_function = { |
443 | .name = "dac" , |
444 | .groups = dac_grps, |
445 | .ngroups = ARRAY_SIZE(dac_grps), |
446 | }; |
447 | |
448 | /* i2s_pins */ |
449 | static const unsigned i2s_pins[] = { 39, 40, 41, 42 }; |
450 | static struct spear_muxreg i2s_muxreg[] = { |
451 | { |
452 | .reg = PMX_CONFIG_REG, |
453 | .mask = PMX_UART0_MODEM_MASK, |
454 | .val = 0, |
455 | }, |
456 | }; |
457 | |
458 | static struct spear_modemux i2s_modemux[] = { |
459 | { |
460 | .modes = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
461 | | LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE | |
462 | ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE |
463 | | CAMU_WLCD_MODE | CAML_LCD_MODE, |
464 | .muxregs = i2s_muxreg, |
465 | .nmuxregs = ARRAY_SIZE(i2s_muxreg), |
466 | }, |
467 | }; |
468 | |
469 | static struct spear_pingroup i2s_pingroup = { |
470 | .name = "i2s_grp" , |
471 | .pins = i2s_pins, |
472 | .npins = ARRAY_SIZE(i2s_pins), |
473 | .modemuxs = i2s_modemux, |
474 | .nmodemuxs = ARRAY_SIZE(i2s_modemux), |
475 | }; |
476 | |
477 | static const char *const i2s_grps[] = { "i2s_grp" }; |
478 | static struct spear_function i2s_function = { |
479 | .name = "i2s" , |
480 | .groups = i2s_grps, |
481 | .ngroups = ARRAY_SIZE(i2s_grps), |
482 | }; |
483 | |
484 | /* sdhci_4bit_pins */ |
485 | static const unsigned sdhci_4bit_pins[] = { 28, 29, 30, 31, 32, 33 }; |
486 | static struct spear_muxreg sdhci_4bit_muxreg[] = { |
487 | { |
488 | .reg = PMX_CONFIG_REG, |
489 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | |
490 | PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | |
491 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK, |
492 | .val = 0, |
493 | }, |
494 | }; |
495 | |
496 | static struct spear_modemux sdhci_4bit_modemux[] = { |
497 | { |
498 | .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | |
499 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | |
500 | HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | |
501 | CAMU_WLCD_MODE | CAML_LCD_MODE | ATA_PABX_WI2S_MODE, |
502 | .muxregs = sdhci_4bit_muxreg, |
503 | .nmuxregs = ARRAY_SIZE(sdhci_4bit_muxreg), |
504 | }, |
505 | }; |
506 | |
507 | static struct spear_pingroup sdhci_4bit_pingroup = { |
508 | .name = "sdhci_4bit_grp" , |
509 | .pins = sdhci_4bit_pins, |
510 | .npins = ARRAY_SIZE(sdhci_4bit_pins), |
511 | .modemuxs = sdhci_4bit_modemux, |
512 | .nmodemuxs = ARRAY_SIZE(sdhci_4bit_modemux), |
513 | }; |
514 | |
515 | /* sdhci_8bit_pins */ |
516 | static const unsigned sdhci_8bit_pins[] = { 24, 25, 26, 27, 28, 29, 30, 31, 32, |
517 | 33 }; |
518 | static struct spear_muxreg sdhci_8bit_muxreg[] = { |
519 | { |
520 | .reg = PMX_CONFIG_REG, |
521 | .mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK | |
522 | PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK | |
523 | PMX_GPIO_PIN4_MASK | PMX_GPIO_PIN5_MASK | PMX_MII_MASK, |
524 | .val = 0, |
525 | }, |
526 | }; |
527 | |
528 | static struct spear_modemux sdhci_8bit_modemux[] = { |
529 | { |
530 | .modes = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | |
531 | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | |
532 | HEND_WIFI_PHONE_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE | |
533 | CAMU_WLCD_MODE | CAML_LCD_MODE, |
534 | .muxregs = sdhci_8bit_muxreg, |
535 | .nmuxregs = ARRAY_SIZE(sdhci_8bit_muxreg), |
536 | }, |
537 | }; |
538 | |
539 | static struct spear_pingroup sdhci_8bit_pingroup = { |
540 | .name = "sdhci_8bit_grp" , |
541 | .pins = sdhci_8bit_pins, |
542 | .npins = ARRAY_SIZE(sdhci_8bit_pins), |
543 | .modemuxs = sdhci_8bit_modemux, |
544 | .nmodemuxs = ARRAY_SIZE(sdhci_8bit_modemux), |
545 | }; |
546 | |
547 | static const char *const sdhci_grps[] = { "sdhci_4bit_grp" , "sdhci_8bit_grp" }; |
548 | static struct spear_function sdhci_function = { |
549 | .name = "sdhci" , |
550 | .groups = sdhci_grps, |
551 | .ngroups = ARRAY_SIZE(sdhci_grps), |
552 | }; |
553 | |
554 | /* gpio1_0_to_3_pins */ |
555 | static const unsigned gpio1_0_to_3_pins[] = { 39, 40, 41, 42 }; |
556 | static struct spear_muxreg gpio1_0_to_3_muxreg[] = { |
557 | { |
558 | .reg = PMX_CONFIG_REG, |
559 | .mask = PMX_UART0_MODEM_MASK, |
560 | .val = 0, |
561 | }, |
562 | }; |
563 | |
564 | static struct spear_modemux gpio1_0_to_3_modemux[] = { |
565 | { |
566 | .modes = PHOTO_FRAME_MODE, |
567 | .muxregs = gpio1_0_to_3_muxreg, |
568 | .nmuxregs = ARRAY_SIZE(gpio1_0_to_3_muxreg), |
569 | }, |
570 | }; |
571 | |
572 | static struct spear_pingroup gpio1_0_to_3_pingroup = { |
573 | .name = "gpio1_0_to_3_grp" , |
574 | .pins = gpio1_0_to_3_pins, |
575 | .npins = ARRAY_SIZE(gpio1_0_to_3_pins), |
576 | .modemuxs = gpio1_0_to_3_modemux, |
577 | .nmodemuxs = ARRAY_SIZE(gpio1_0_to_3_modemux), |
578 | }; |
579 | |
580 | /* gpio1_4_to_7_pins */ |
581 | static const unsigned gpio1_4_to_7_pins[] = { 43, 44, 45, 46 }; |
582 | |
583 | static struct spear_muxreg gpio1_4_to_7_muxreg[] = { |
584 | { |
585 | .reg = PMX_CONFIG_REG, |
586 | .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK, |
587 | .val = 0, |
588 | }, |
589 | }; |
590 | |
591 | static struct spear_modemux gpio1_4_to_7_modemux[] = { |
592 | { |
593 | .modes = PHOTO_FRAME_MODE, |
594 | .muxregs = gpio1_4_to_7_muxreg, |
595 | .nmuxregs = ARRAY_SIZE(gpio1_4_to_7_muxreg), |
596 | }, |
597 | }; |
598 | |
599 | static struct spear_pingroup gpio1_4_to_7_pingroup = { |
600 | .name = "gpio1_4_to_7_grp" , |
601 | .pins = gpio1_4_to_7_pins, |
602 | .npins = ARRAY_SIZE(gpio1_4_to_7_pins), |
603 | .modemuxs = gpio1_4_to_7_modemux, |
604 | .nmodemuxs = ARRAY_SIZE(gpio1_4_to_7_modemux), |
605 | }; |
606 | |
607 | static const char *const gpio1_grps[] = { "gpio1_0_to_3_grp" , "gpio1_4_to_7_grp" |
608 | }; |
609 | static struct spear_function gpio1_function = { |
610 | .name = "gpio1" , |
611 | .groups = gpio1_grps, |
612 | .ngroups = ARRAY_SIZE(gpio1_grps), |
613 | }; |
614 | |
615 | /* pingroups */ |
616 | static struct spear_pingroup *spear300_pingroups[] = { |
617 | SPEAR3XX_COMMON_PINGROUPS, |
618 | &fsmc_2chips_pingroup, |
619 | &fsmc_4chips_pingroup, |
620 | &clcd_lcdmode_pingroup, |
621 | &clcd_pfmode_pingroup, |
622 | &tdm_pingroup, |
623 | &i2c_clk_pingroup, |
624 | &caml_pingroup, |
625 | &camu_pingroup, |
626 | &dac_pingroup, |
627 | &i2s_pingroup, |
628 | &sdhci_4bit_pingroup, |
629 | &sdhci_8bit_pingroup, |
630 | &gpio1_0_to_3_pingroup, |
631 | &gpio1_4_to_7_pingroup, |
632 | }; |
633 | |
634 | /* functions */ |
635 | static struct spear_function *spear300_functions[] = { |
636 | SPEAR3XX_COMMON_FUNCTIONS, |
637 | &fsmc_function, |
638 | &clcd_function, |
639 | &tdm_function, |
640 | &i2c_function, |
641 | &cam_function, |
642 | &dac_function, |
643 | &i2s_function, |
644 | &sdhci_function, |
645 | &gpio1_function, |
646 | }; |
647 | |
648 | static const struct of_device_id spear300_pinctrl_of_match[] = { |
649 | { |
650 | .compatible = "st,spear300-pinmux" , |
651 | }, |
652 | {}, |
653 | }; |
654 | |
655 | static int spear300_pinctrl_probe(struct platform_device *pdev) |
656 | { |
657 | spear3xx_machdata.groups = spear300_pingroups; |
658 | spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); |
659 | spear3xx_machdata.functions = spear300_functions; |
660 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); |
661 | spear3xx_machdata.gpio_pingroups = NULL; |
662 | spear3xx_machdata.ngpio_pingroups = 0; |
663 | |
664 | spear3xx_machdata.modes_supported = true; |
665 | spear3xx_machdata.pmx_modes = spear300_pmx_modes; |
666 | spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear300_pmx_modes); |
667 | |
668 | pmx_init_addr(machdata: &spear3xx_machdata, PMX_CONFIG_REG); |
669 | |
670 | return spear_pinctrl_probe(pdev, machdata: &spear3xx_machdata); |
671 | } |
672 | |
673 | static struct platform_driver spear300_pinctrl_driver = { |
674 | .driver = { |
675 | .name = DRIVER_NAME, |
676 | .of_match_table = spear300_pinctrl_of_match, |
677 | }, |
678 | .probe = spear300_pinctrl_probe, |
679 | }; |
680 | |
681 | static int __init spear300_pinctrl_init(void) |
682 | { |
683 | return platform_driver_register(&spear300_pinctrl_driver); |
684 | } |
685 | arch_initcall(spear300_pinctrl_init); |
686 | |