2 * linux/drivers/pinctrl/pinmux-falcon.c
3 * based on linux/drivers/pinctrl/pinmux-pxa910.c
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation.
9 * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
10 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
13 #include <linux/gpio.h>
14 #include <linux/interrupt.h>
15 #include <linux/slab.h>
16 #include <linux/export.h>
17 #include <linux/err.h>
18 #include <linux/module.h>
20 #include <linux/of_platform.h>
21 #include <linux/of_address.h>
22 #include <linux/of_gpio.h>
23 #include <linux/platform_device.h>
25 #include "pinctrl-lantiq.h"
27 #include <lantiq_soc.h>
29 /* Multiplexer Control Register */
30 #define LTQ_PADC_MUX(x) (x * 0x4)
31 /* Pull Up Enable Register */
32 #define LTQ_PADC_PUEN 0x80
33 /* Pull Down Enable Register */
34 #define LTQ_PADC_PDEN 0x84
35 /* Slew Rate Control Register */
36 #define LTQ_PADC_SRC 0x88
37 /* Drive Current Control Register */
38 #define LTQ_PADC_DCC 0x8C
39 /* Pad Control Availability Register */
40 #define LTQ_PADC_AVAIL 0xF0
42 #define pad_r32(p, reg) ltq_r32(p + reg)
43 #define pad_w32(p, val, reg) ltq_w32(val, p + reg)
44 #define pad_w32_mask(c, clear, set, reg) \
45 pad_w32(c, (pad_r32(c, reg) & ~(clear)) | (set), reg)
47 #define pad_getbit(m, r, p) (!!(ltq_r32(m + r) & (1 << p)))
51 #define PORT(x) (x / PINS)
52 #define PORT_PIN(x) (x % PINS)
54 #define MFP_FALCON(a, f0, f1, f2, f3) \
66 #define GRP_MUX(a, m, p) \
69 .mux = FALCON_MUX_##m, \
71 .npins = ARRAY_SIZE(p), \
90 FALCON_MUX_NONE
= 0xffff,
93 static struct pinctrl_pin_desc falcon_pads
[PORTS
* PINS
];
94 static int pad_count
[PORTS
];
96 static void lantiq_load_pin_desc(struct pinctrl_pin_desc
*d
, int bank
, int len
)
98 int base
= bank
* PINS
;
101 for (i
= 0; i
< len
; i
++) {
102 /* strlen("ioXYZ") + 1 = 6 */
103 char *name
= kzalloc(6, GFP_KERNEL
);
105 snprintf(name
, 6, "io%d", base
+ i
);
106 d
[i
].number
= base
+ i
;
109 pad_count
[bank
] = len
;
112 static struct ltq_mfp_pin falcon_mfp
[] = {
113 /* pin f0 f1 f2 f3 */
114 MFP_FALCON(GPIO0
, RST
, GPIO
, NONE
, NONE
),
115 MFP_FALCON(GPIO1
, GPIO
, GPIO
, NONE
, NONE
),
116 MFP_FALCON(GPIO2
, GPIO
, GPIO
, NONE
, NONE
),
117 MFP_FALCON(GPIO3
, GPIO
, GPIO
, NONE
, NONE
),
118 MFP_FALCON(GPIO4
, NTR
, GPIO
, NONE
, NONE
),
119 MFP_FALCON(GPIO5
, NTR
, GPIO
, PPS
, NONE
),
120 MFP_FALCON(GPIO6
, RST
, GPIO
, NONE
, NONE
),
121 MFP_FALCON(GPIO7
, MDIO
, GPIO
, NONE
, NONE
),
122 MFP_FALCON(GPIO8
, MDIO
, GPIO
, NONE
, NONE
),
123 MFP_FALCON(GPIO9
, LED
, GPIO
, NONE
, NONE
),
124 MFP_FALCON(GPIO10
, LED
, GPIO
, NONE
, NONE
),
125 MFP_FALCON(GPIO11
, LED
, GPIO
, NONE
, NONE
),
126 MFP_FALCON(GPIO12
, LED
, GPIO
, NONE
, NONE
),
127 MFP_FALCON(GPIO13
, LED
, GPIO
, NONE
, NONE
),
128 MFP_FALCON(GPIO14
, LED
, GPIO
, NONE
, NONE
),
129 MFP_FALCON(GPIO32
, ASC
, GPIO
, NONE
, NONE
),
130 MFP_FALCON(GPIO33
, ASC
, GPIO
, NONE
, NONE
),
131 MFP_FALCON(GPIO34
, SPI
, GPIO
, NONE
, NONE
),
132 MFP_FALCON(GPIO35
, SPI
, GPIO
, NONE
, NONE
),
133 MFP_FALCON(GPIO36
, SPI
, GPIO
, NONE
, NONE
),
134 MFP_FALCON(GPIO37
, SPI
, GPIO
, NONE
, NONE
),
135 MFP_FALCON(GPIO38
, SPI
, GPIO
, NONE
, NONE
),
136 MFP_FALCON(GPIO39
, I2C
, GPIO
, NONE
, NONE
),
137 MFP_FALCON(GPIO40
, I2C
, GPIO
, NONE
, NONE
),
138 MFP_FALCON(GPIO41
, HOSTIF
, GPIO
, HOSTIF
, JTAG
),
139 MFP_FALCON(GPIO42
, HOSTIF
, GPIO
, HOSTIF
, NONE
),
140 MFP_FALCON(GPIO43
, SLIC
, GPIO
, NONE
, NONE
),
141 MFP_FALCON(GPIO44
, SLIC
, GPIO
, PCM
, ASC
),
142 MFP_FALCON(GPIO45
, SLIC
, GPIO
, PCM
, ASC
),
143 MFP_FALCON(GPIO64
, MII
, GPIO
, NONE
, NONE
),
144 MFP_FALCON(GPIO65
, MII
, GPIO
, NONE
, NONE
),
145 MFP_FALCON(GPIO66
, MII
, GPIO
, NONE
, NONE
),
146 MFP_FALCON(GPIO67
, MII
, GPIO
, NONE
, NONE
),
147 MFP_FALCON(GPIO68
, MII
, GPIO
, NONE
, NONE
),
148 MFP_FALCON(GPIO69
, MII
, GPIO
, NONE
, NONE
),
149 MFP_FALCON(GPIO70
, MII
, GPIO
, NONE
, NONE
),
150 MFP_FALCON(GPIO71
, MII
, GPIO
, NONE
, NONE
),
151 MFP_FALCON(GPIO72
, MII
, GPIO
, NONE
, NONE
),
152 MFP_FALCON(GPIO73
, MII
, GPIO
, NONE
, NONE
),
153 MFP_FALCON(GPIO74
, MII
, GPIO
, NONE
, NONE
),
154 MFP_FALCON(GPIO75
, MII
, GPIO
, NONE
, NONE
),
155 MFP_FALCON(GPIO76
, MII
, GPIO
, NONE
, NONE
),
156 MFP_FALCON(GPIO77
, MII
, GPIO
, NONE
, NONE
),
157 MFP_FALCON(GPIO78
, MII
, GPIO
, NONE
, NONE
),
158 MFP_FALCON(GPIO79
, MII
, GPIO
, NONE
, NONE
),
159 MFP_FALCON(GPIO80
, MII
, GPIO
, NONE
, NONE
),
160 MFP_FALCON(GPIO81
, MII
, GPIO
, NONE
, NONE
),
161 MFP_FALCON(GPIO82
, MII
, GPIO
, NONE
, NONE
),
162 MFP_FALCON(GPIO83
, MII
, GPIO
, NONE
, NONE
),
163 MFP_FALCON(GPIO84
, MII
, GPIO
, NONE
, NONE
),
164 MFP_FALCON(GPIO85
, MII
, GPIO
, NONE
, NONE
),
165 MFP_FALCON(GPIO86
, MII
, GPIO
, NONE
, NONE
),
166 MFP_FALCON(GPIO87
, MII
, GPIO
, NONE
, NONE
),
167 MFP_FALCON(GPIO88
, PHY
, GPIO
, NONE
, NONE
),
170 static const unsigned pins_por
[] = {GPIO0
};
171 static const unsigned pins_ntr
[] = {GPIO4
};
172 static const unsigned pins_ntr8k
[] = {GPIO5
};
173 static const unsigned pins_pps
[] = {GPIO5
};
174 static const unsigned pins_hrst
[] = {GPIO6
};
175 static const unsigned pins_mdio
[] = {GPIO7
, GPIO8
};
176 static const unsigned pins_bled
[] = {GPIO9
, GPIO10
, GPIO11
,
177 GPIO12
, GPIO13
, GPIO14
};
178 static const unsigned pins_asc0
[] = {GPIO32
, GPIO33
};
179 static const unsigned pins_spi
[] = {GPIO34
, GPIO35
, GPIO36
};
180 static const unsigned pins_spi_cs0
[] = {GPIO37
};
181 static const unsigned pins_spi_cs1
[] = {GPIO38
};
182 static const unsigned pins_i2c
[] = {GPIO39
, GPIO40
};
183 static const unsigned pins_jtag
[] = {GPIO41
};
184 static const unsigned pins_slic
[] = {GPIO43
, GPIO44
, GPIO45
};
185 static const unsigned pins_pcm
[] = {GPIO44
, GPIO45
};
186 static const unsigned pins_asc1
[] = {GPIO44
, GPIO45
};
188 static struct ltq_pin_group falcon_grps
[] = {
189 GRP_MUX("por", RST
, pins_por
),
190 GRP_MUX("ntr", NTR
, pins_ntr
),
191 GRP_MUX("ntr8k", NTR
, pins_ntr8k
),
192 GRP_MUX("pps", PPS
, pins_pps
),
193 GRP_MUX("hrst", RST
, pins_hrst
),
194 GRP_MUX("mdio", MDIO
, pins_mdio
),
195 GRP_MUX("bootled", LED
, pins_bled
),
196 GRP_MUX("asc0", ASC
, pins_asc0
),
197 GRP_MUX("spi", SPI
, pins_spi
),
198 GRP_MUX("spi cs0", SPI
, pins_spi_cs0
),
199 GRP_MUX("spi cs1", SPI
, pins_spi_cs1
),
200 GRP_MUX("i2c", I2C
, pins_i2c
),
201 GRP_MUX("jtag", JTAG
, pins_jtag
),
202 GRP_MUX("slic", SLIC
, pins_slic
),
203 GRP_MUX("pcm", PCM
, pins_pcm
),
204 GRP_MUX("asc1", ASC
, pins_asc1
),
207 static const char * const ltq_rst_grps
[] = {"por", "hrst"};
208 static const char * const ltq_ntr_grps
[] = {"ntr", "ntr8k", "pps"};
209 static const char * const ltq_mdio_grps
[] = {"mdio"};
210 static const char * const ltq_bled_grps
[] = {"bootled"};
211 static const char * const ltq_asc_grps
[] = {"asc0", "asc1"};
212 static const char * const ltq_spi_grps
[] = {"spi", "spi cs0", "spi cs1"};
213 static const char * const ltq_i2c_grps
[] = {"i2c"};
214 static const char * const ltq_jtag_grps
[] = {"jtag"};
215 static const char * const ltq_slic_grps
[] = {"slic"};
216 static const char * const ltq_pcm_grps
[] = {"pcm"};
218 static struct ltq_pmx_func falcon_funcs
[] = {
219 {"rst", ARRAY_AND_SIZE(ltq_rst_grps
)},
220 {"ntr", ARRAY_AND_SIZE(ltq_ntr_grps
)},
221 {"mdio", ARRAY_AND_SIZE(ltq_mdio_grps
)},
222 {"led", ARRAY_AND_SIZE(ltq_bled_grps
)},
223 {"asc", ARRAY_AND_SIZE(ltq_asc_grps
)},
224 {"spi", ARRAY_AND_SIZE(ltq_spi_grps
)},
225 {"i2c", ARRAY_AND_SIZE(ltq_i2c_grps
)},
226 {"jtag", ARRAY_AND_SIZE(ltq_jtag_grps
)},
227 {"slic", ARRAY_AND_SIZE(ltq_slic_grps
)},
228 {"pcm", ARRAY_AND_SIZE(ltq_pcm_grps
)},
234 /* --------- pinconf related code --------- */
235 static int falcon_pinconf_group_get(struct pinctrl_dev
*pctrldev
,
236 unsigned group
, unsigned long *config
)
241 static int falcon_pinconf_group_set(struct pinctrl_dev
*pctrldev
,
242 unsigned group
, unsigned long *configs
,
243 unsigned num_configs
)
248 static int falcon_pinconf_get(struct pinctrl_dev
*pctrldev
,
249 unsigned pin
, unsigned long *config
)
251 struct ltq_pinmux_info
*info
= pinctrl_dev_get_drvdata(pctrldev
);
252 enum ltq_pinconf_param param
= LTQ_PINCONF_UNPACK_PARAM(*config
);
253 void __iomem
*mem
= info
->membase
[PORT(pin
)];
256 case LTQ_PINCONF_PARAM_DRIVE_CURRENT
:
257 *config
= LTQ_PINCONF_PACK(param
,
258 !!pad_getbit(mem
, LTQ_PADC_DCC
, PORT_PIN(pin
)));
261 case LTQ_PINCONF_PARAM_SLEW_RATE
:
262 *config
= LTQ_PINCONF_PACK(param
,
263 !!pad_getbit(mem
, LTQ_PADC_SRC
, PORT_PIN(pin
)));
266 case LTQ_PINCONF_PARAM_PULL
:
267 if (pad_getbit(mem
, LTQ_PADC_PDEN
, PORT_PIN(pin
)))
268 *config
= LTQ_PINCONF_PACK(param
, 1);
269 else if (pad_getbit(mem
, LTQ_PADC_PUEN
, PORT_PIN(pin
)))
270 *config
= LTQ_PINCONF_PACK(param
, 2);
272 *config
= LTQ_PINCONF_PACK(param
, 0);
283 static int falcon_pinconf_set(struct pinctrl_dev
*pctrldev
,
284 unsigned pin
, unsigned long *configs
,
285 unsigned num_configs
)
287 enum ltq_pinconf_param param
;
289 struct ltq_pinmux_info
*info
= pinctrl_dev_get_drvdata(pctrldev
);
290 void __iomem
*mem
= info
->membase
[PORT(pin
)];
294 for (i
= 0; i
< num_configs
; i
++) {
295 param
= LTQ_PINCONF_UNPACK_PARAM(configs
[i
]);
296 arg
= LTQ_PINCONF_UNPACK_ARG(configs
[i
]);
299 case LTQ_PINCONF_PARAM_DRIVE_CURRENT
:
303 case LTQ_PINCONF_PARAM_SLEW_RATE
:
307 case LTQ_PINCONF_PARAM_PULL
:
315 pr_err("%s: Invalid config param %04x\n",
316 pinctrl_dev_get_name(pctrldev
), param
);
320 pad_w32(mem
, BIT(PORT_PIN(pin
)), reg
);
321 if (!(pad_r32(mem
, reg
) & BIT(PORT_PIN(pin
))))
323 } /* for each config */
328 static void falcon_pinconf_dbg_show(struct pinctrl_dev
*pctrldev
,
329 struct seq_file
*s
, unsigned offset
)
331 unsigned long config
;
332 struct pin_desc
*desc
;
334 struct ltq_pinmux_info
*info
= pinctrl_dev_get_drvdata(pctrldev
);
335 int port
= PORT(offset
);
337 seq_printf(s
, " (port %d) mux %d -- ", port
,
338 pad_r32(info
->membase
[port
], LTQ_PADC_MUX(PORT_PIN(offset
))));
340 config
= LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_PULL
, 0);
341 if (!falcon_pinconf_get(pctrldev
, offset
, &config
))
342 seq_printf(s
, "pull %d ",
343 (int)LTQ_PINCONF_UNPACK_ARG(config
));
345 config
= LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_DRIVE_CURRENT
, 0);
346 if (!falcon_pinconf_get(pctrldev
, offset
, &config
))
347 seq_printf(s
, "drive-current %d ",
348 (int)LTQ_PINCONF_UNPACK_ARG(config
));
350 config
= LTQ_PINCONF_PACK(LTQ_PINCONF_PARAM_SLEW_RATE
, 0);
351 if (!falcon_pinconf_get(pctrldev
, offset
, &config
))
352 seq_printf(s
, "slew-rate %d ",
353 (int)LTQ_PINCONF_UNPACK_ARG(config
));
355 desc
= pin_desc_get(pctrldev
, offset
);
357 if (desc
->gpio_owner
)
358 seq_printf(s
, " owner: %s", desc
->gpio_owner
);
360 seq_printf(s
, " not registered");
364 static void falcon_pinconf_group_dbg_show(struct pinctrl_dev
*pctrldev
,
365 struct seq_file
*s
, unsigned selector
)
369 static const struct pinconf_ops falcon_pinconf_ops
= {
370 .pin_config_get
= falcon_pinconf_get
,
371 .pin_config_set
= falcon_pinconf_set
,
372 .pin_config_group_get
= falcon_pinconf_group_get
,
373 .pin_config_group_set
= falcon_pinconf_group_set
,
374 .pin_config_dbg_show
= falcon_pinconf_dbg_show
,
375 .pin_config_group_dbg_show
= falcon_pinconf_group_dbg_show
,
378 static struct pinctrl_desc falcon_pctrl_desc
= {
379 .owner
= THIS_MODULE
,
381 .confops
= &falcon_pinconf_ops
,
384 static inline int falcon_mux_apply(struct pinctrl_dev
*pctrldev
,
387 struct ltq_pinmux_info
*info
= pinctrl_dev_get_drvdata(pctrldev
);
388 int port
= PORT(info
->mfp
[mfp
].pin
);
390 if ((port
>= PORTS
) || (!info
->membase
[port
]))
393 pad_w32(info
->membase
[port
], mux
,
394 LTQ_PADC_MUX(PORT_PIN(info
->mfp
[mfp
].pin
)));
398 static const struct ltq_cfg_param falcon_cfg_params
[] = {
399 {"lantiq,pull", LTQ_PINCONF_PARAM_PULL
},
400 {"lantiq,drive-current", LTQ_PINCONF_PARAM_DRIVE_CURRENT
},
401 {"lantiq,slew-rate", LTQ_PINCONF_PARAM_SLEW_RATE
},
404 static struct ltq_pinmux_info falcon_info
= {
405 .desc
= &falcon_pctrl_desc
,
406 .apply_mux
= falcon_mux_apply
,
407 .params
= falcon_cfg_params
,
408 .num_params
= ARRAY_SIZE(falcon_cfg_params
),
414 /* --------- register the pinctrl layer --------- */
416 int pinctrl_falcon_get_range_size(int id
)
420 if ((id
>= PORTS
) || (!falcon_info
.membase
[id
]))
423 avail
= pad_r32(falcon_info
.membase
[id
], LTQ_PADC_AVAIL
);
428 void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range
*range
)
430 pinctrl_add_gpio_range(falcon_info
.pctrl
, range
);
433 static int pinctrl_falcon_probe(struct platform_device
*pdev
)
435 struct device_node
*np
;
439 /* load and remap the pad resources of the different banks */
440 for_each_compatible_node(np
, NULL
, "lantiq,pad-falcon") {
441 struct platform_device
*ppdev
= of_find_device_by_node(np
);
442 const __be32
*bank
= of_get_property(np
, "lantiq,bank", NULL
);
447 if (!of_device_is_available(np
))
451 dev_err(&pdev
->dev
, "failed to find pad pdev\n");
454 if (!bank
|| *bank
>= PORTS
)
456 if (of_address_to_resource(np
, 0, &res
))
458 falcon_info
.clk
[*bank
] = clk_get(&ppdev
->dev
, NULL
);
459 if (IS_ERR(falcon_info
.clk
[*bank
])) {
460 dev_err(&ppdev
->dev
, "failed to get clock\n");
461 return PTR_ERR(falcon_info
.clk
[*bank
]);
463 falcon_info
.membase
[*bank
] = devm_ioremap_resource(&pdev
->dev
,
465 if (IS_ERR(falcon_info
.membase
[*bank
]))
466 return PTR_ERR(falcon_info
.membase
[*bank
]);
468 avail
= pad_r32(falcon_info
.membase
[*bank
],
471 lantiq_load_pin_desc(&falcon_pads
[pad_count
], *bank
, pins
);
473 clk_enable(falcon_info
.clk
[*bank
]);
474 dev_dbg(&pdev
->dev
, "found %s with %d pads\n",
477 dev_dbg(&pdev
->dev
, "found a total of %d pads\n", pad_count
);
478 falcon_pctrl_desc
.name
= dev_name(&pdev
->dev
);
479 falcon_pctrl_desc
.npins
= pad_count
;
481 falcon_info
.mfp
= falcon_mfp
;
482 falcon_info
.num_mfp
= ARRAY_SIZE(falcon_mfp
);
483 falcon_info
.grps
= falcon_grps
;
484 falcon_info
.num_grps
= ARRAY_SIZE(falcon_grps
);
485 falcon_info
.funcs
= falcon_funcs
;
486 falcon_info
.num_funcs
= ARRAY_SIZE(falcon_funcs
);
488 ret
= ltq_pinctrl_register(pdev
, &falcon_info
);
490 dev_info(&pdev
->dev
, "Init done\n");
494 static const struct of_device_id falcon_match
[] = {
495 { .compatible
= "lantiq,pinctrl-falcon" },
498 MODULE_DEVICE_TABLE(of
, falcon_match
);
500 static struct platform_driver pinctrl_falcon_driver
= {
501 .probe
= pinctrl_falcon_probe
,
503 .name
= "pinctrl-falcon",
504 .of_match_table
= falcon_match
,
508 int __init
pinctrl_falcon_init(void)
510 return platform_driver_register(&pinctrl_falcon_driver
);
513 core_initcall_sync(pinctrl_falcon_init
);