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