aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2013-01-18 16:30:34 -0500
committerLinus Walleij <linus.walleij@linaro.org>2013-01-22 07:51:15 -0500
commit0e37f88d9ad800f5dd94c9fc9dc304b4e9cb7d2c (patch)
tree592b7e3812dc6c06db0dc8ecf59e52dbf8984b4f
parent9931faca02c604c22335f5a935a501bb2ace6e20 (diff)
ARM: sunxi: Add pinctrl driver for Allwinner SoCs
The Allwinner SoCs have an IP module that handle both the muxing and the GPIOs. This IP has 8 banks of 32 bits, with a number of pins actually useful for each of these banks varying from one to another, and depending on the SoC used on the board. This driver only implements the pinctrl part, the gpio part will come eventually. Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt60
-rw-r--r--arch/arm/mach-sunxi/Kconfig1
-rw-r--r--drivers/pinctrl/Kconfig5
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.c548
-rw-r--r--drivers/pinctrl/pinctrl-sunxi.h387
6 files changed, 1002 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
new file mode 100644
index 000000000000..dff0e5f995e2
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sunxi-pinctrl.txt
@@ -0,0 +1,60 @@
1* Allwinner A1X Pin Controller
2
3The pins controlled by sunXi pin controller are organized in banks,
4each bank has 32 pins. Each pin has 7 multiplexing functions, with
5the first two functions being GPIO in and out. The configuration on
6the pins includes drive strength and pull-up.
7
8Required properties:
9- compatible: "allwinner,<soc>-pinctrl". Supported SoCs for now are:
10 sun5i-a13.
11- reg: Should contain the register physical address and length for the
12 pin controller.
13
14Please refer to pinctrl-bindings.txt in this directory for details of the
15common pinctrl bindings used by client devices.
16
17A pinctrl node should contain at least one subnodes representing the
18pinctrl groups available on the machine. Each subnode will list the
19pins it needs, and how they should be configured, with regard to muxer
20configuration, drive strength and pullups. If one of these options is
21not set, its actual value will be unspecified.
22
23Required subnode-properties:
24
25- allwinner,pins: List of strings containing the pin name.
26- allwinner,function: Function to mux the pins listed above to.
27
28Optional subnode-properties:
29- allwinner,drive: Integer. Represents the current sent to the pin
30 0: 10 mA
31 1: 20 mA
32 2: 30 mA
33 3: 40 mA
34- allwinner,pull: Integer.
35 0: No resistor
36 1: Pull-up resistor
37 2: Pull-down resistor
38
39Examples:
40
41pinctrl@01c20800 {
42 compatible = "allwinner,sun5i-a13-pinctrl";
43 reg = <0x01c20800 0x400>;
44 #address-cells = <1>;
45 #size-cells = <0>;
46
47 uart1_pins_a: uart1@0 {
48 allwinner,pins = "PE10", "PE11";
49 allwinner,function = "uart1";
50 allwinner,drive = <0>;
51 allwinner,pull = <0>;
52 };
53
54 uart1_pins_b: uart1@1 {
55 allwinner,pins = "PG3", "PG4";
56 allwinner,function = "uart1";
57 allwinner,drive = <0>;
58 allwinner,pull = <0>;
59 };
60};
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 3fdd0085e306..8709a39bd34c 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -7,3 +7,4 @@ config ARCH_SUNXI
7 select PINCTRL 7 select PINCTRL
8 select SPARSE_IRQ 8 select SPARSE_IRQ
9 select SUNXI_TIMER 9 select SUNXI_TIMER
10 select PINCTRL_SUNXI \ No newline at end of file
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index c31aeb01bb00..88840a421c6e 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -151,6 +151,11 @@ config PINCTRL_SIRF
151 depends on ARCH_SIRF 151 depends on ARCH_SIRF
152 select PINMUX 152 select PINMUX
153 153
154config PINCTRL_SUNXI
155 bool
156 select PINMUX
157 select GENERIC_PINCONF
158
154config PINCTRL_TEGRA 159config PINCTRL_TEGRA
155 bool 160 bool
156 select PINMUX 161 select PINMUX
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index fc4606f27dc7..a2427da4d58e 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
30obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o 30obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o
31obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o 31obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
32obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o 32obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
33obj-$(CONFIG_PINCTRL_SUNXI) += pinctrl-sunxi.o
33obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o 34obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
34obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o 35obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
35obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o 36obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
diff --git a/drivers/pinctrl/pinctrl-sunxi.c b/drivers/pinctrl/pinctrl-sunxi.c
new file mode 100644
index 000000000000..1a81613e8f77
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-sunxi.c
@@ -0,0 +1,548 @@
1/*
2 * Allwinner A1X SoCs pinctrl driver.
3 *
4 * Copyright (C) 2012 Maxime Ripard
5 *
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/of_device.h>
18#include <linux/pinctrl/consumer.h>
19#include <linux/pinctrl/machine.h>
20#include <linux/pinctrl/pinctrl.h>
21#include <linux/pinctrl/pinconf-generic.h>
22#include <linux/pinctrl/pinmux.h>
23#include <linux/platform_device.h>
24#include <linux/slab.h>
25
26#include "core.h"
27#include "pinctrl-sunxi.h"
28
29static struct sunxi_pinctrl_group *
30sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
31{
32 int i;
33
34 for (i = 0; i < pctl->ngroups; i++) {
35 struct sunxi_pinctrl_group *grp = pctl->groups + i;
36
37 if (!strcmp(grp->name, group))
38 return grp;
39 }
40
41 return NULL;
42}
43
44static struct sunxi_pinctrl_function *
45sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
46 const char *name)
47{
48 struct sunxi_pinctrl_function *func = pctl->functions;
49 int i;
50
51 for (i = 0; i < pctl->nfunctions; i++) {
52 if (!func[i].name)
53 break;
54
55 if (!strcmp(func[i].name, name))
56 return func + i;
57 }
58
59 return NULL;
60}
61
62static struct sunxi_desc_function *
63sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
64 const char *pin_name,
65 const char *func_name)
66{
67 int i;
68
69 for (i = 0; i < pctl->desc->npins; i++) {
70 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
71
72 if (!strcmp(pin->pin.name, pin_name)) {
73 struct sunxi_desc_function *func = pin->functions;
74
75 while (func->name) {
76 if (!strcmp(func->name, func_name))
77 return func;
78
79 func++;
80 }
81 }
82 }
83
84 return NULL;
85}
86
87static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
88{
89 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
90
91 return pctl->ngroups;
92}
93
94static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
95 unsigned group)
96{
97 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
98
99 return pctl->groups[group].name;
100}
101
102static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
103 unsigned group,
104 const unsigned **pins,
105 unsigned *num_pins)
106{
107 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
108
109 *pins = (unsigned *)&pctl->groups[group].pin;
110 *num_pins = 1;
111
112 return 0;
113}
114
115static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
116 struct device_node *node,
117 struct pinctrl_map **map,
118 unsigned *num_maps)
119{
120 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
121 unsigned long *pinconfig;
122 struct property *prop;
123 const char *function;
124 const char *group;
125 int ret, nmaps, i = 0;
126 u32 val;
127
128 *map = NULL;
129 *num_maps = 0;
130
131 ret = of_property_read_string(node, "allwinner,function", &function);
132 if (ret) {
133 dev_err(pctl->dev,
134 "missing allwinner,function property in node %s\n",
135 node->name);
136 return -EINVAL;
137 }
138
139 nmaps = of_property_count_strings(node, "allwinner,pins") * 2;
140 if (nmaps < 0) {
141 dev_err(pctl->dev,
142 "missing allwinner,pins property in node %s\n",
143 node->name);
144 return -EINVAL;
145 }
146
147 *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
148 if (!map)
149 return -ENOMEM;
150
151 of_property_for_each_string(node, "allwinner,pins", prop, group) {
152 struct sunxi_pinctrl_group *grp =
153 sunxi_pinctrl_find_group_by_name(pctl, group);
154 int j = 0, configlen = 0;
155
156 if (!grp) {
157 dev_err(pctl->dev, "unknown pin %s", group);
158 continue;
159 }
160
161 if (!sunxi_pinctrl_desc_find_function_by_name(pctl,
162 grp->name,
163 function)) {
164 dev_err(pctl->dev, "unsupported function %s on pin %s",
165 function, group);
166 continue;
167 }
168
169 (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
170 (*map)[i].data.mux.group = group;
171 (*map)[i].data.mux.function = function;
172
173 i++;
174
175 (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
176 (*map)[i].data.configs.group_or_pin = group;
177
178 if (of_find_property(node, "allwinner,drive", NULL))
179 configlen++;
180 if (of_find_property(node, "allwinner,pull", NULL))
181 configlen++;
182
183 pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
184
185 if (!of_property_read_u32(node, "allwinner,drive", &val)) {
186 u16 strength = (val + 1) * 10;
187 pinconfig[j++] =
188 pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
189 strength);
190 }
191
192 if (!of_property_read_u32(node, "allwinner,pull", &val)) {
193 enum pin_config_param pull = PIN_CONFIG_END;
194 if (val == 1)
195 pull = PIN_CONFIG_BIAS_PULL_UP;
196 else if (val == 2)
197 pull = PIN_CONFIG_BIAS_PULL_DOWN;
198 pinconfig[j++] = pinconf_to_config_packed(pull, 0);
199 }
200
201 (*map)[i].data.configs.configs = pinconfig;
202 (*map)[i].data.configs.num_configs = configlen;
203
204 i++;
205 }
206
207 *num_maps = nmaps;
208
209 return 0;
210}
211
212static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
213 struct pinctrl_map *map,
214 unsigned num_maps)
215{
216 int i;
217
218 for (i = 0; i < num_maps; i++) {
219 if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
220 kfree(map[i].data.configs.configs);
221 }
222
223 kfree(map);
224}
225
226static struct pinctrl_ops sunxi_pctrl_ops = {
227 .dt_node_to_map = sunxi_pctrl_dt_node_to_map,
228 .dt_free_map = sunxi_pctrl_dt_free_map,
229 .get_groups_count = sunxi_pctrl_get_groups_count,
230 .get_group_name = sunxi_pctrl_get_group_name,
231 .get_group_pins = sunxi_pctrl_get_group_pins,
232};
233
234static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
235 unsigned group,
236 unsigned long *config)
237{
238 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
239
240 *config = pctl->groups[group].config;
241
242 return 0;
243}
244
245static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
246 unsigned group,
247 unsigned long config)
248{
249 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
250 struct sunxi_pinctrl_group *g = &pctl->groups[group];
251 u32 val, mask;
252 u16 strength;
253 u8 dlevel;
254
255 switch (pinconf_to_config_param(config)) {
256 case PIN_CONFIG_DRIVE_STRENGTH:
257 strength = pinconf_to_config_argument(config);
258 if (strength > 40)
259 return -EINVAL;
260 /*
261 * We convert from mA to what the register expects:
262 * 0: 10mA
263 * 1: 20mA
264 * 2: 30mA
265 * 3: 40mA
266 */
267 dlevel = strength / 10 - 1;
268 val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
269 mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
270 writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin),
271 pctl->membase + sunxi_dlevel_reg(g->pin));
272 break;
273 case PIN_CONFIG_BIAS_PULL_UP:
274 val = readl(pctl->membase + sunxi_pull_reg(g->pin));
275 mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
276 writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin),
277 pctl->membase + sunxi_pull_reg(g->pin));
278 break;
279 case PIN_CONFIG_BIAS_PULL_DOWN:
280 val = readl(pctl->membase + sunxi_pull_reg(g->pin));
281 mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
282 writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin),
283 pctl->membase + sunxi_pull_reg(g->pin));
284 break;
285 default:
286 break;
287 }
288
289 /* cache the config value */
290 g->config = config;
291
292 return 0;
293}
294
295static struct pinconf_ops sunxi_pconf_ops = {
296 .pin_config_group_get = sunxi_pconf_group_get,
297 .pin_config_group_set = sunxi_pconf_group_set,
298};
299
300static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
301{
302 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
303
304 return pctl->nfunctions;
305}
306
307static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev,
308 unsigned function)
309{
310 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
311
312 return pctl->functions[function].name;
313}
314
315static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev,
316 unsigned function,
317 const char * const **groups,
318 unsigned * const num_groups)
319{
320 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
321
322 *groups = pctl->functions[function].groups;
323 *num_groups = pctl->functions[function].ngroups;
324
325 return 0;
326}
327
328static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
329 unsigned pin,
330 u8 config)
331{
332 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
333
334 u32 val = readl(pctl->membase + sunxi_mux_reg(pin));
335 u32 mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
336 writel((val & ~mask) | config << sunxi_mux_offset(pin),
337 pctl->membase + sunxi_mux_reg(pin));
338}
339
340static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
341 unsigned function,
342 unsigned group)
343{
344 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
345 struct sunxi_pinctrl_group *g = pctl->groups + group;
346 struct sunxi_pinctrl_function *func = pctl->functions + function;
347 struct sunxi_desc_function *desc =
348 sunxi_pinctrl_desc_find_function_by_name(pctl,
349 g->name,
350 func->name);
351
352 if (!desc)
353 return -EINVAL;
354
355 sunxi_pmx_set(pctldev, g->pin, desc->muxval);
356
357 return 0;
358}
359
360static struct pinmux_ops sunxi_pmx_ops = {
361 .get_functions_count = sunxi_pmx_get_funcs_cnt,
362 .get_function_name = sunxi_pmx_get_func_name,
363 .get_function_groups = sunxi_pmx_get_func_groups,
364 .enable = sunxi_pmx_enable,
365};
366
367static struct pinctrl_desc sunxi_pctrl_desc = {
368 .confops = &sunxi_pconf_ops,
369 .pctlops = &sunxi_pctrl_ops,
370 .pmxops = &sunxi_pmx_ops,
371};
372
373static struct of_device_id sunxi_pinctrl_match[] = {
374 {}
375};
376MODULE_DEVICE_TABLE(of, sunxi_pinctrl_match);
377
378static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
379 const char *name)
380{
381 struct sunxi_pinctrl_function *func = pctl->functions;
382
383 while (func->name) {
384 /* function already there */
385 if (strcmp(func->name, name) == 0) {
386 func->ngroups++;
387 return -EEXIST;
388 }
389 func++;
390 }
391
392 func->name = name;
393 func->ngroups = 1;
394
395 pctl->nfunctions++;
396
397 return 0;
398}
399
400static int sunxi_pinctrl_build_state(struct platform_device *pdev)
401{
402 struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
403 int i;
404
405 pctl->ngroups = pctl->desc->npins;
406
407 /* Allocate groups */
408 pctl->groups = devm_kzalloc(&pdev->dev,
409 pctl->ngroups * sizeof(*pctl->groups),
410 GFP_KERNEL);
411 if (!pctl->groups)
412 return -ENOMEM;
413
414 for (i = 0; i < pctl->desc->npins; i++) {
415 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
416 struct sunxi_pinctrl_group *group = pctl->groups + i;
417
418 group->name = pin->pin.name;
419 group->pin = pin->pin.number;
420 }
421
422 /*
423 * We suppose that we won't have any more functions than pins,
424 * we'll reallocate that later anyway
425 */
426 pctl->functions = devm_kzalloc(&pdev->dev,
427 pctl->desc->npins * sizeof(*pctl->functions),
428 GFP_KERNEL);
429 if (!pctl->functions)
430 return -ENOMEM;
431
432 /* Count functions and their associated groups */
433 for (i = 0; i < pctl->desc->npins; i++) {
434 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
435 struct sunxi_desc_function *func = pin->functions;
436
437 while (func->name) {
438 sunxi_pinctrl_add_function(pctl, func->name);
439 func++;
440 }
441 }
442
443 pctl->functions = krealloc(pctl->functions,
444 pctl->nfunctions * sizeof(*pctl->functions),
445 GFP_KERNEL);
446
447 for (i = 0; i < pctl->desc->npins; i++) {
448 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
449 struct sunxi_desc_function *func = pin->functions;
450
451 while (func->name) {
452 struct sunxi_pinctrl_function *func_item;
453 const char **func_grp;
454
455 func_item = sunxi_pinctrl_find_function_by_name(pctl,
456 func->name);
457 if (!func_item)
458 return -EINVAL;
459
460 if (!func_item->groups) {
461 func_item->groups =
462 devm_kzalloc(&pdev->dev,
463 func_item->ngroups * sizeof(*func_item->groups),
464 GFP_KERNEL);
465 if (!func_item->groups)
466 return -ENOMEM;
467 }
468
469 func_grp = func_item->groups;
470 while (*func_grp)
471 func_grp++;
472
473 *func_grp = pin->pin.name;
474 func++;
475 }
476 }
477
478 return 0;
479}
480
481static int sunxi_pinctrl_probe(struct platform_device *pdev)
482{
483 struct device_node *node = pdev->dev.of_node;
484 const struct of_device_id *device;
485 struct pinctrl_pin_desc *pins;
486 struct sunxi_pinctrl *pctl;
487 int i, ret;
488
489 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
490 if (!pctl)
491 return -ENOMEM;
492 platform_set_drvdata(pdev, pctl);
493
494 pctl->membase = of_iomap(node, 0);
495 if (!pctl->membase)
496 return -ENOMEM;
497
498 device = of_match_device(sunxi_pinctrl_match, &pdev->dev);
499 if (!device)
500 return -ENODEV;
501
502 pctl->desc = (struct sunxi_pinctrl_desc *)device->data;
503
504 ret = sunxi_pinctrl_build_state(pdev);
505 if (ret) {
506 dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
507 return ret;
508 }
509
510 pins = devm_kzalloc(&pdev->dev,
511 pctl->desc->npins * sizeof(*pins),
512 GFP_KERNEL);
513 if (!pins)
514 return -ENOMEM;
515
516 for (i = 0; i < pctl->desc->npins; i++)
517 pins[i] = pctl->desc->pins[i].pin;
518
519 sunxi_pctrl_desc.name = dev_name(&pdev->dev);
520 sunxi_pctrl_desc.owner = THIS_MODULE;
521 sunxi_pctrl_desc.pins = pins;
522 sunxi_pctrl_desc.npins = pctl->desc->npins;
523 pctl->dev = &pdev->dev;
524 pctl->pctl_dev = pinctrl_register(&sunxi_pctrl_desc,
525 &pdev->dev, pctl);
526 if (!pctl->pctl_dev) {
527 dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
528 return -EINVAL;
529 }
530
531 dev_info(&pdev->dev, "initialized sunXi pin control driver\n");
532
533 return 0;
534}
535
536static struct platform_driver sunxi_pinctrl_driver = {
537 .probe = sunxi_pinctrl_probe,
538 .driver = {
539 .name = "sunxi-pinctrl",
540 .owner = THIS_MODULE,
541 .of_match_table = sunxi_pinctrl_match,
542 },
543};
544module_platform_driver(sunxi_pinctrl_driver);
545
546MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
547MODULE_DESCRIPTION("Allwinner A1X pinctrl driver");
548MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/pinctrl-sunxi.h b/drivers/pinctrl/pinctrl-sunxi.h
new file mode 100644
index 000000000000..0dc3b9d5321b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-sunxi.h
@@ -0,0 +1,387 @@
1/*
2 * Allwinner A1X SoCs pinctrl driver.
3 *
4 * Copyright (C) 2012 Maxime Ripard
5 *
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#ifndef __PINCTRL_SUNXI_H
14#define __PINCTRL_SUNXI_H
15
16#include <linux/kernel.h>
17
18#define PA_BASE 0
19#define PB_BASE 32
20#define PC_BASE 64
21#define PD_BASE 96
22#define PE_BASE 128
23#define PF_BASE 160
24#define PG_BASE 192
25
26#define SUNXI_PINCTRL_PIN_PA0 PINCTRL_PIN(PA_BASE + 0, "PA0")
27#define SUNXI_PINCTRL_PIN_PA1 PINCTRL_PIN(PA_BASE + 1, "PA1")
28#define SUNXI_PINCTRL_PIN_PA2 PINCTRL_PIN(PA_BASE + 2, "PA2")
29#define SUNXI_PINCTRL_PIN_PA3 PINCTRL_PIN(PA_BASE + 3, "PA3")
30#define SUNXI_PINCTRL_PIN_PA4 PINCTRL_PIN(PA_BASE + 4, "PA4")
31#define SUNXI_PINCTRL_PIN_PA5 PINCTRL_PIN(PA_BASE + 5, "PA5")
32#define SUNXI_PINCTRL_PIN_PA6 PINCTRL_PIN(PA_BASE + 6, "PA6")
33#define SUNXI_PINCTRL_PIN_PA7 PINCTRL_PIN(PA_BASE + 7, "PA7")
34#define SUNXI_PINCTRL_PIN_PA8 PINCTRL_PIN(PA_BASE + 8, "PA8")
35#define SUNXI_PINCTRL_PIN_PA9 PINCTRL_PIN(PA_BASE + 9, "PA9")
36#define SUNXI_PINCTRL_PIN_PA10 PINCTRL_PIN(PA_BASE + 10, "PA10")
37#define SUNXI_PINCTRL_PIN_PA11 PINCTRL_PIN(PA_BASE + 11, "PA11")
38#define SUNXI_PINCTRL_PIN_PA12 PINCTRL_PIN(PA_BASE + 12, "PA12")
39#define SUNXI_PINCTRL_PIN_PA13 PINCTRL_PIN(PA_BASE + 13, "PA13")
40#define SUNXI_PINCTRL_PIN_PA14 PINCTRL_PIN(PA_BASE + 14, "PA14")
41#define SUNXI_PINCTRL_PIN_PA15 PINCTRL_PIN(PA_BASE + 15, "PA15")
42#define SUNXI_PINCTRL_PIN_PA16 PINCTRL_PIN(PA_BASE + 16, "PA16")
43#define SUNXI_PINCTRL_PIN_PA17 PINCTRL_PIN(PA_BASE + 17, "PA17")
44#define SUNXI_PINCTRL_PIN_PA18 PINCTRL_PIN(PA_BASE + 18, "PA18")
45#define SUNXI_PINCTRL_PIN_PA19 PINCTRL_PIN(PA_BASE + 19, "PA19")
46#define SUNXI_PINCTRL_PIN_PA20 PINCTRL_PIN(PA_BASE + 20, "PA20")
47#define SUNXI_PINCTRL_PIN_PA21 PINCTRL_PIN(PA_BASE + 21, "PA21")
48#define SUNXI_PINCTRL_PIN_PA22 PINCTRL_PIN(PA_BASE + 22, "PA22")
49#define SUNXI_PINCTRL_PIN_PA23 PINCTRL_PIN(PA_BASE + 23, "PA23")
50#define SUNXI_PINCTRL_PIN_PA24 PINCTRL_PIN(PA_BASE + 24, "PA24")
51#define SUNXI_PINCTRL_PIN_PA25 PINCTRL_PIN(PA_BASE + 25, "PA25")
52#define SUNXI_PINCTRL_PIN_PA26 PINCTRL_PIN(PA_BASE + 26, "PA26")
53#define SUNXI_PINCTRL_PIN_PA27 PINCTRL_PIN(PA_BASE + 27, "PA27")
54#define SUNXI_PINCTRL_PIN_PA28 PINCTRL_PIN(PA_BASE + 28, "PA28")
55#define SUNXI_PINCTRL_PIN_PA29 PINCTRL_PIN(PA_BASE + 29, "PA29")
56#define SUNXI_PINCTRL_PIN_PA30 PINCTRL_PIN(PA_BASE + 30, "PA30")
57#define SUNXI_PINCTRL_PIN_PA31 PINCTRL_PIN(PA_BASE + 31, "PA31")
58
59#define SUNXI_PINCTRL_PIN_PB0 PINCTRL_PIN(PB_BASE + 0, "PB0")
60#define SUNXI_PINCTRL_PIN_PB1 PINCTRL_PIN(PB_BASE + 1, "PB1")
61#define SUNXI_PINCTRL_PIN_PB2 PINCTRL_PIN(PB_BASE + 2, "PB2")
62#define SUNXI_PINCTRL_PIN_PB3 PINCTRL_PIN(PB_BASE + 3, "PB3")
63#define SUNXI_PINCTRL_PIN_PB4 PINCTRL_PIN(PB_BASE + 4, "PB4")
64#define SUNXI_PINCTRL_PIN_PB5 PINCTRL_PIN(PB_BASE + 5, "PB5")
65#define SUNXI_PINCTRL_PIN_PB6 PINCTRL_PIN(PB_BASE + 6, "PB6")
66#define SUNXI_PINCTRL_PIN_PB7 PINCTRL_PIN(PB_BASE + 7, "PB7")
67#define SUNXI_PINCTRL_PIN_PB8 PINCTRL_PIN(PB_BASE + 8, "PB8")
68#define SUNXI_PINCTRL_PIN_PB9 PINCTRL_PIN(PB_BASE + 9, "PB9")
69#define SUNXI_PINCTRL_PIN_PB10 PINCTRL_PIN(PB_BASE + 10, "PB10")
70#define SUNXI_PINCTRL_PIN_PB11 PINCTRL_PIN(PB_BASE + 11, "PB11")
71#define SUNXI_PINCTRL_PIN_PB12 PINCTRL_PIN(PB_BASE + 12, "PB12")
72#define SUNXI_PINCTRL_PIN_PB13 PINCTRL_PIN(PB_BASE + 13, "PB13")
73#define SUNXI_PINCTRL_PIN_PB14 PINCTRL_PIN(PB_BASE + 14, "PB14")
74#define SUNXI_PINCTRL_PIN_PB15 PINCTRL_PIN(PB_BASE + 15, "PB15")
75#define SUNXI_PINCTRL_PIN_PB16 PINCTRL_PIN(PB_BASE + 16, "PB16")
76#define SUNXI_PINCTRL_PIN_PB17 PINCTRL_PIN(PB_BASE + 17, "PB17")
77#define SUNXI_PINCTRL_PIN_PB18 PINCTRL_PIN(PB_BASE + 18, "PB18")
78#define SUNXI_PINCTRL_PIN_PB19 PINCTRL_PIN(PB_BASE + 19, "PB19")
79#define SUNXI_PINCTRL_PIN_PB20 PINCTRL_PIN(PB_BASE + 20, "PB20")
80#define SUNXI_PINCTRL_PIN_PB21 PINCTRL_PIN(PB_BASE + 21, "PB21")
81#define SUNXI_PINCTRL_PIN_PB22 PINCTRL_PIN(PB_BASE + 22, "PB22")
82#define SUNXI_PINCTRL_PIN_PB23 PINCTRL_PIN(PB_BASE + 23, "PB23")
83#define SUNXI_PINCTRL_PIN_PB24 PINCTRL_PIN(PB_BASE + 24, "PB24")
84#define SUNXI_PINCTRL_PIN_PB25 PINCTRL_PIN(PB_BASE + 25, "PB25")
85#define SUNXI_PINCTRL_PIN_PB26 PINCTRL_PIN(PB_BASE + 26, "PB26")
86#define SUNXI_PINCTRL_PIN_PB27 PINCTRL_PIN(PB_BASE + 27, "PB27")
87#define SUNXI_PINCTRL_PIN_PB28 PINCTRL_PIN(PB_BASE + 28, "PB28")
88#define SUNXI_PINCTRL_PIN_PB29 PINCTRL_PIN(PB_BASE + 29, "PB29")
89#define SUNXI_PINCTRL_PIN_PB30 PINCTRL_PIN(PB_BASE + 30, "PB30")
90#define SUNXI_PINCTRL_PIN_PB31 PINCTRL_PIN(PB_BASE + 31, "PB31")
91
92#define SUNXI_PINCTRL_PIN_PC0 PINCTRL_PIN(PC_BASE + 0, "PC0")
93#define SUNXI_PINCTRL_PIN_PC1 PINCTRL_PIN(PC_BASE + 1, "PC1")
94#define SUNXI_PINCTRL_PIN_PC2 PINCTRL_PIN(PC_BASE + 2, "PC2")
95#define SUNXI_PINCTRL_PIN_PC3 PINCTRL_PIN(PC_BASE + 3, "PC3")
96#define SUNXI_PINCTRL_PIN_PC4 PINCTRL_PIN(PC_BASE + 4, "PC4")
97#define SUNXI_PINCTRL_PIN_PC5 PINCTRL_PIN(PC_BASE + 5, "PC5")
98#define SUNXI_PINCTRL_PIN_PC6 PINCTRL_PIN(PC_BASE + 6, "PC6")
99#define SUNXI_PINCTRL_PIN_PC7 PINCTRL_PIN(PC_BASE + 7, "PC7")
100#define SUNXI_PINCTRL_PIN_PC8 PINCTRL_PIN(PC_BASE + 8, "PC8")
101#define SUNXI_PINCTRL_PIN_PC9 PINCTRL_PIN(PC_BASE + 9, "PC9")
102#define SUNXI_PINCTRL_PIN_PC10 PINCTRL_PIN(PC_BASE + 10, "PC10")
103#define SUNXI_PINCTRL_PIN_PC11 PINCTRL_PIN(PC_BASE + 11, "PC11")
104#define SUNXI_PINCTRL_PIN_PC12 PINCTRL_PIN(PC_BASE + 12, "PC12")
105#define SUNXI_PINCTRL_PIN_PC13 PINCTRL_PIN(PC_BASE + 13, "PC13")
106#define SUNXI_PINCTRL_PIN_PC14 PINCTRL_PIN(PC_BASE + 14, "PC14")
107#define SUNXI_PINCTRL_PIN_PC15 PINCTRL_PIN(PC_BASE + 15, "PC15")
108#define SUNXI_PINCTRL_PIN_PC16 PINCTRL_PIN(PC_BASE + 16, "PC16")
109#define SUNXI_PINCTRL_PIN_PC17 PINCTRL_PIN(PC_BASE + 17, "PC17")
110#define SUNXI_PINCTRL_PIN_PC18 PINCTRL_PIN(PC_BASE + 18, "PC18")
111#define SUNXI_PINCTRL_PIN_PC19 PINCTRL_PIN(PC_BASE + 19, "PC19")
112#define SUNXI_PINCTRL_PIN_PC20 PINCTRL_PIN(PC_BASE + 20, "PC20")
113#define SUNXI_PINCTRL_PIN_PC21 PINCTRL_PIN(PC_BASE + 21, "PC21")
114#define SUNXI_PINCTRL_PIN_PC22 PINCTRL_PIN(PC_BASE + 22, "PC22")
115#define SUNXI_PINCTRL_PIN_PC23 PINCTRL_PIN(PC_BASE + 23, "PC23")
116#define SUNXI_PINCTRL_PIN_PC24 PINCTRL_PIN(PC_BASE + 24, "PC24")
117#define SUNXI_PINCTRL_PIN_PC25 PINCTRL_PIN(PC_BASE + 25, "PC25")
118#define SUNXI_PINCTRL_PIN_PC26 PINCTRL_PIN(PC_BASE + 26, "PC26")
119#define SUNXI_PINCTRL_PIN_PC27 PINCTRL_PIN(PC_BASE + 27, "PC27")
120#define SUNXI_PINCTRL_PIN_PC28 PINCTRL_PIN(PC_BASE + 28, "PC28")
121#define SUNXI_PINCTRL_PIN_PC29 PINCTRL_PIN(PC_BASE + 29, "PC29")
122#define SUNXI_PINCTRL_PIN_PC30 PINCTRL_PIN(PC_BASE + 30, "PC30")
123#define SUNXI_PINCTRL_PIN_PC31 PINCTRL_PIN(PC_BASE + 31, "PC31")
124
125#define SUNXI_PINCTRL_PIN_PD0 PINCTRL_PIN(PD_BASE + 0, "PD0")
126#define SUNXI_PINCTRL_PIN_PD1 PINCTRL_PIN(PD_BASE + 1, "PD1")
127#define SUNXI_PINCTRL_PIN_PD2 PINCTRL_PIN(PD_BASE + 2, "PD2")
128#define SUNXI_PINCTRL_PIN_PD3 PINCTRL_PIN(PD_BASE + 3, "PD3")
129#define SUNXI_PINCTRL_PIN_PD4 PINCTRL_PIN(PD_BASE + 4, "PD4")
130#define SUNXI_PINCTRL_PIN_PD5 PINCTRL_PIN(PD_BASE + 5, "PD5")
131#define SUNXI_PINCTRL_PIN_PD6 PINCTRL_PIN(PD_BASE + 6, "PD6")
132#define SUNXI_PINCTRL_PIN_PD7 PINCTRL_PIN(PD_BASE + 7, "PD7")
133#define SUNXI_PINCTRL_PIN_PD8 PINCTRL_PIN(PD_BASE + 8, "PD8")
134#define SUNXI_PINCTRL_PIN_PD9 PINCTRL_PIN(PD_BASE + 9, "PD9")
135#define SUNXI_PINCTRL_PIN_PD10 PINCTRL_PIN(PD_BASE + 10, "PD10")
136#define SUNXI_PINCTRL_PIN_PD11 PINCTRL_PIN(PD_BASE + 11, "PD11")
137#define SUNXI_PINCTRL_PIN_PD12 PINCTRL_PIN(PD_BASE + 12, "PD12")
138#define SUNXI_PINCTRL_PIN_PD13 PINCTRL_PIN(PD_BASE + 13, "PD13")
139#define SUNXI_PINCTRL_PIN_PD14 PINCTRL_PIN(PD_BASE + 14, "PD14")
140#define SUNXI_PINCTRL_PIN_PD15 PINCTRL_PIN(PD_BASE + 15, "PD15")
141#define SUNXI_PINCTRL_PIN_PD16 PINCTRL_PIN(PD_BASE + 16, "PD16")
142#define SUNXI_PINCTRL_PIN_PD17 PINCTRL_PIN(PD_BASE + 17, "PD17")
143#define SUNXI_PINCTRL_PIN_PD18 PINCTRL_PIN(PD_BASE + 18, "PD18")
144#define SUNXI_PINCTRL_PIN_PD19 PINCTRL_PIN(PD_BASE + 19, "PD19")
145#define SUNXI_PINCTRL_PIN_PD20 PINCTRL_PIN(PD_BASE + 20, "PD20")
146#define SUNXI_PINCTRL_PIN_PD21 PINCTRL_PIN(PD_BASE + 21, "PD21")
147#define SUNXI_PINCTRL_PIN_PD22 PINCTRL_PIN(PD_BASE + 22, "PD22")
148#define SUNXI_PINCTRL_PIN_PD23 PINCTRL_PIN(PD_BASE + 23, "PD23")
149#define SUNXI_PINCTRL_PIN_PD24 PINCTRL_PIN(PD_BASE + 24, "PD24")
150#define SUNXI_PINCTRL_PIN_PD25 PINCTRL_PIN(PD_BASE + 25, "PD25")
151#define SUNXI_PINCTRL_PIN_PD26 PINCTRL_PIN(PD_BASE + 26, "PD26")
152#define SUNXI_PINCTRL_PIN_PD27 PINCTRL_PIN(PD_BASE + 27, "PD27")
153#define SUNXI_PINCTRL_PIN_PD28 PINCTRL_PIN(PD_BASE + 28, "PD28")
154#define SUNXI_PINCTRL_PIN_PD29 PINCTRL_PIN(PD_BASE + 29, "PD29")
155#define SUNXI_PINCTRL_PIN_PD30 PINCTRL_PIN(PD_BASE + 30, "PD30")
156#define SUNXI_PINCTRL_PIN_PD31 PINCTRL_PIN(PD_BASE + 31, "PD31")
157
158#define SUNXI_PINCTRL_PIN_PE0 PINCTRL_PIN(PE_BASE + 0, "PE0")
159#define SUNXI_PINCTRL_PIN_PE1 PINCTRL_PIN(PE_BASE + 1, "PE1")
160#define SUNXI_PINCTRL_PIN_PE2 PINCTRL_PIN(PE_BASE + 2, "PE2")
161#define SUNXI_PINCTRL_PIN_PE3 PINCTRL_PIN(PE_BASE + 3, "PE3")
162#define SUNXI_PINCTRL_PIN_PE4 PINCTRL_PIN(PE_BASE + 4, "PE4")
163#define SUNXI_PINCTRL_PIN_PE5 PINCTRL_PIN(PE_BASE + 5, "PE5")
164#define SUNXI_PINCTRL_PIN_PE6 PINCTRL_PIN(PE_BASE + 6, "PE6")
165#define SUNXI_PINCTRL_PIN_PE7 PINCTRL_PIN(PE_BASE + 7, "PE7")
166#define SUNXI_PINCTRL_PIN_PE8 PINCTRL_PIN(PE_BASE + 8, "PE8")
167#define SUNXI_PINCTRL_PIN_PE9 PINCTRL_PIN(PE_BASE + 9, "PE9")
168#define SUNXI_PINCTRL_PIN_PE10 PINCTRL_PIN(PE_BASE + 10, "PE10")
169#define SUNXI_PINCTRL_PIN_PE11 PINCTRL_PIN(PE_BASE + 11, "PE11")
170#define SUNXI_PINCTRL_PIN_PE12 PINCTRL_PIN(PE_BASE + 12, "PE12")
171#define SUNXI_PINCTRL_PIN_PE13 PINCTRL_PIN(PE_BASE + 13, "PE13")
172#define SUNXI_PINCTRL_PIN_PE14 PINCTRL_PIN(PE_BASE + 14, "PE14")
173#define SUNXI_PINCTRL_PIN_PE15 PINCTRL_PIN(PE_BASE + 15, "PE15")
174#define SUNXI_PINCTRL_PIN_PE16 PINCTRL_PIN(PE_BASE + 16, "PE16")
175#define SUNXI_PINCTRL_PIN_PE17 PINCTRL_PIN(PE_BASE + 17, "PE17")
176#define SUNXI_PINCTRL_PIN_PE18 PINCTRL_PIN(PE_BASE + 18, "PE18")
177#define SUNXI_PINCTRL_PIN_PE19 PINCTRL_PIN(PE_BASE + 19, "PE19")
178#define SUNXI_PINCTRL_PIN_PE20 PINCTRL_PIN(PE_BASE + 20, "PE20")
179#define SUNXI_PINCTRL_PIN_PE21 PINCTRL_PIN(PE_BASE + 21, "PE21")
180#define SUNXI_PINCTRL_PIN_PE22 PINCTRL_PIN(PE_BASE + 22, "PE22")
181#define SUNXI_PINCTRL_PIN_PE23 PINCTRL_PIN(PE_BASE + 23, "PE23")
182#define SUNXI_PINCTRL_PIN_PE24 PINCTRL_PIN(PE_BASE + 24, "PE24")
183#define SUNXI_PINCTRL_PIN_PE25 PINCTRL_PIN(PE_BASE + 25, "PE25")
184#define SUNXI_PINCTRL_PIN_PE26 PINCTRL_PIN(PE_BASE + 26, "PE26")
185#define SUNXI_PINCTRL_PIN_PE27 PINCTRL_PIN(PE_BASE + 27, "PE27")
186#define SUNXI_PINCTRL_PIN_PE28 PINCTRL_PIN(PE_BASE + 28, "PE28")
187#define SUNXI_PINCTRL_PIN_PE29 PINCTRL_PIN(PE_BASE + 29, "PE29")
188#define SUNXI_PINCTRL_PIN_PE30 PINCTRL_PIN(PE_BASE + 30, "PE30")
189#define SUNXI_PINCTRL_PIN_PE31 PINCTRL_PIN(PE_BASE + 31, "PE31")
190
191#define SUNXI_PINCTRL_PIN_PF0 PINCTRL_PIN(PF_BASE + 0, "PF0")
192#define SUNXI_PINCTRL_PIN_PF1 PINCTRL_PIN(PF_BASE + 1, "PF1")
193#define SUNXI_PINCTRL_PIN_PF2 PINCTRL_PIN(PF_BASE + 2, "PF2")
194#define SUNXI_PINCTRL_PIN_PF3 PINCTRL_PIN(PF_BASE + 3, "PF3")
195#define SUNXI_PINCTRL_PIN_PF4 PINCTRL_PIN(PF_BASE + 4, "PF4")
196#define SUNXI_PINCTRL_PIN_PF5 PINCTRL_PIN(PF_BASE + 5, "PF5")
197#define SUNXI_PINCTRL_PIN_PF6 PINCTRL_PIN(PF_BASE + 6, "PF6")
198#define SUNXI_PINCTRL_PIN_PF7 PINCTRL_PIN(PF_BASE + 7, "PF7")
199#define SUNXI_PINCTRL_PIN_PF8 PINCTRL_PIN(PF_BASE + 8, "PF8")
200#define SUNXI_PINCTRL_PIN_PF9 PINCTRL_PIN(PF_BASE + 9, "PF9")
201#define SUNXI_PINCTRL_PIN_PF10 PINCTRL_PIN(PF_BASE + 10, "PF10")
202#define SUNXI_PINCTRL_PIN_PF11 PINCTRL_PIN(PF_BASE + 11, "PF11")
203#define SUNXI_PINCTRL_PIN_PF12 PINCTRL_PIN(PF_BASE + 12, "PF12")
204#define SUNXI_PINCTRL_PIN_PF13 PINCTRL_PIN(PF_BASE + 13, "PF13")
205#define SUNXI_PINCTRL_PIN_PF14 PINCTRL_PIN(PF_BASE + 14, "PF14")
206#define SUNXI_PINCTRL_PIN_PF15 PINCTRL_PIN(PF_BASE + 15, "PF15")
207#define SUNXI_PINCTRL_PIN_PF16 PINCTRL_PIN(PF_BASE + 16, "PF16")
208#define SUNXI_PINCTRL_PIN_PF17 PINCTRL_PIN(PF_BASE + 17, "PF17")
209#define SUNXI_PINCTRL_PIN_PF18 PINCTRL_PIN(PF_BASE + 18, "PF18")
210#define SUNXI_PINCTRL_PIN_PF19 PINCTRL_PIN(PF_BASE + 19, "PF19")
211#define SUNXI_PINCTRL_PIN_PF20 PINCTRL_PIN(PF_BASE + 20, "PF20")
212#define SUNXI_PINCTRL_PIN_PF21 PINCTRL_PIN(PF_BASE + 21, "PF21")
213#define SUNXI_PINCTRL_PIN_PF22 PINCTRL_PIN(PF_BASE + 22, "PF22")
214#define SUNXI_PINCTRL_PIN_PF23 PINCTRL_PIN(PF_BASE + 23, "PF23")
215#define SUNXI_PINCTRL_PIN_PF24 PINCTRL_PIN(PF_BASE + 24, "PF24")
216#define SUNXI_PINCTRL_PIN_PF25 PINCTRL_PIN(PF_BASE + 25, "PF25")
217#define SUNXI_PINCTRL_PIN_PF26 PINCTRL_PIN(PF_BASE + 26, "PF26")
218#define SUNXI_PINCTRL_PIN_PF27 PINCTRL_PIN(PF_BASE + 27, "PF27")
219#define SUNXI_PINCTRL_PIN_PF28 PINCTRL_PIN(PF_BASE + 28, "PF28")
220#define SUNXI_PINCTRL_PIN_PF29 PINCTRL_PIN(PF_BASE + 29, "PF29")
221#define SUNXI_PINCTRL_PIN_PF30 PINCTRL_PIN(PF_BASE + 30, "PF30")
222#define SUNXI_PINCTRL_PIN_PF31 PINCTRL_PIN(PF_BASE + 31, "PF31")
223
224#define SUNXI_PINCTRL_PIN_PG0 PINCTRL_PIN(PG_BASE + 0, "PG0")
225#define SUNXI_PINCTRL_PIN_PG1 PINCTRL_PIN(PG_BASE + 1, "PG1")
226#define SUNXI_PINCTRL_PIN_PG2 PINCTRL_PIN(PG_BASE + 2, "PG2")
227#define SUNXI_PINCTRL_PIN_PG3 PINCTRL_PIN(PG_BASE + 3, "PG3")
228#define SUNXI_PINCTRL_PIN_PG4 PINCTRL_PIN(PG_BASE + 4, "PG4")
229#define SUNXI_PINCTRL_PIN_PG5 PINCTRL_PIN(PG_BASE + 5, "PG5")
230#define SUNXI_PINCTRL_PIN_PG6 PINCTRL_PIN(PG_BASE + 6, "PG6")
231#define SUNXI_PINCTRL_PIN_PG7 PINCTRL_PIN(PG_BASE + 7, "PG7")
232#define SUNXI_PINCTRL_PIN_PG8 PINCTRL_PIN(PG_BASE + 8, "PG8")
233#define SUNXI_PINCTRL_PIN_PG9 PINCTRL_PIN(PG_BASE + 9, "PG9")
234#define SUNXI_PINCTRL_PIN_PG10 PINCTRL_PIN(PG_BASE + 10, "PG10")
235#define SUNXI_PINCTRL_PIN_PG11 PINCTRL_PIN(PG_BASE + 11, "PG11")
236#define SUNXI_PINCTRL_PIN_PG12 PINCTRL_PIN(PG_BASE + 12, "PG12")
237#define SUNXI_PINCTRL_PIN_PG13 PINCTRL_PIN(PG_BASE + 13, "PG13")
238#define SUNXI_PINCTRL_PIN_PG14 PINCTRL_PIN(PG_BASE + 14, "PG14")
239#define SUNXI_PINCTRL_PIN_PG15 PINCTRL_PIN(PG_BASE + 15, "PG15")
240#define SUNXI_PINCTRL_PIN_PG16 PINCTRL_PIN(PG_BASE + 16, "PG16")
241#define SUNXI_PINCTRL_PIN_PG17 PINCTRL_PIN(PG_BASE + 17, "PG17")
242#define SUNXI_PINCTRL_PIN_PG18 PINCTRL_PIN(PG_BASE + 18, "PG18")
243#define SUNXI_PINCTRL_PIN_PG19 PINCTRL_PIN(PG_BASE + 19, "PG19")
244#define SUNXI_PINCTRL_PIN_PG20 PINCTRL_PIN(PG_BASE + 20, "PG20")
245#define SUNXI_PINCTRL_PIN_PG21 PINCTRL_PIN(PG_BASE + 21, "PG21")
246#define SUNXI_PINCTRL_PIN_PG22 PINCTRL_PIN(PG_BASE + 22, "PG22")
247#define SUNXI_PINCTRL_PIN_PG23 PINCTRL_PIN(PG_BASE + 23, "PG23")
248#define SUNXI_PINCTRL_PIN_PG24 PINCTRL_PIN(PG_BASE + 24, "PG24")
249#define SUNXI_PINCTRL_PIN_PG25 PINCTRL_PIN(PG_BASE + 25, "PG25")
250#define SUNXI_PINCTRL_PIN_PG26 PINCTRL_PIN(PG_BASE + 26, "PG26")
251#define SUNXI_PINCTRL_PIN_PG27 PINCTRL_PIN(PG_BASE + 27, "PG27")
252#define SUNXI_PINCTRL_PIN_PG28 PINCTRL_PIN(PG_BASE + 28, "PG28")
253#define SUNXI_PINCTRL_PIN_PG29 PINCTRL_PIN(PG_BASE + 29, "PG29")
254#define SUNXI_PINCTRL_PIN_PG30 PINCTRL_PIN(PG_BASE + 30, "PG30")
255#define SUNXI_PINCTRL_PIN_PG31 PINCTRL_PIN(PG_BASE + 31, "PG31")
256
257#define BANK_MEM_SIZE 0x24
258#define MUX_REGS_OFFSET 0x0
259#define DLEVEL_REGS_OFFSET 0x14
260#define PULL_REGS_OFFSET 0x1c
261
262#define PINS_PER_BANK 32
263#define MUX_PINS_PER_REG 8
264#define MUX_PINS_BITS 4
265#define MUX_PINS_MASK 0x0f
266#define DLEVEL_PINS_PER_REG 16
267#define DLEVEL_PINS_BITS 2
268#define DLEVEL_PINS_MASK 0x03
269#define PULL_PINS_PER_REG 16
270#define PULL_PINS_BITS 2
271#define PULL_PINS_MASK 0x03
272
273struct sunxi_desc_function {
274 const char *name;
275 u8 muxval;
276};
277
278struct sunxi_desc_pin {
279 struct pinctrl_pin_desc pin;
280 struct sunxi_desc_function *functions;
281};
282
283struct sunxi_pinctrl_desc {
284 const struct sunxi_desc_pin *pins;
285 int npins;
286};
287
288struct sunxi_pinctrl_function {
289 const char *name;
290 const char **groups;
291 unsigned ngroups;
292};
293
294struct sunxi_pinctrl_group {
295 const char *name;
296 unsigned long config;
297 unsigned pin;
298};
299
300struct sunxi_pinctrl {
301 void __iomem *membase;
302 struct sunxi_pinctrl_desc *desc;
303 struct device *dev;
304 struct sunxi_pinctrl_function *functions;
305 unsigned nfunctions;
306 struct sunxi_pinctrl_group *groups;
307 unsigned ngroups;
308 struct pinctrl_dev *pctl_dev;
309};
310
311#define SUNXI_PIN(_pin, ...) \
312 { \
313 .pin = _pin, \
314 .functions = (struct sunxi_desc_function[]){ \
315 __VA_ARGS__, { } }, \
316 }
317
318#define SUNXI_FUNCTION(_val, _name) \
319 { \
320 .name = _name, \
321 .muxval = _val, \
322 }
323
324
325/*
326 * The sunXi PIO registers are organized as is:
327 * 0x00 - 0x0c Muxing values.
328 * 8 pins per register, each pin having a 4bits value
329 * 0x10 Pin values
330 * 32 bits per register, each pin corresponding to one bit
331 * 0x14 - 0x18 Drive level
332 * 16 pins per register, each pin having a 2bits value
333 * 0x1c - 0x20 Pull-Up values
334 * 16 pins per register, each pin having a 2bits value
335 *
336 * This is for the first bank. Each bank will have the same layout,
337 * with an offset being a multiple of 0x24.
338 *
339 * The following functions calculate from the pin number the register
340 * and the bit offset that we should access.
341 */
342static inline u32 sunxi_mux_reg(u16 pin)
343{
344 u8 bank = pin / PINS_PER_BANK;
345 u32 offset = bank * BANK_MEM_SIZE;
346 offset += MUX_REGS_OFFSET;
347 offset += pin % PINS_PER_BANK / MUX_PINS_PER_REG * 0x04;
348 return round_down(offset, 4);
349}
350
351static inline u32 sunxi_mux_offset(u16 pin)
352{
353 u32 pin_num = pin % MUX_PINS_PER_REG;
354 return pin_num * MUX_PINS_BITS;
355}
356
357static inline u32 sunxi_dlevel_reg(u16 pin)
358{
359 u8 bank = pin / PINS_PER_BANK;
360 u32 offset = bank * BANK_MEM_SIZE;
361 offset += DLEVEL_REGS_OFFSET;
362 offset += pin % PINS_PER_BANK / DLEVEL_PINS_PER_REG * 0x04;
363 return round_down(offset, 4);
364}
365
366static inline u32 sunxi_dlevel_offset(u16 pin)
367{
368 u32 pin_num = pin % DLEVEL_PINS_PER_REG;
369 return pin_num * DLEVEL_PINS_BITS;
370}
371
372static inline u32 sunxi_pull_reg(u16 pin)
373{
374 u8 bank = pin / PINS_PER_BANK;
375 u32 offset = bank * BANK_MEM_SIZE;
376 offset += PULL_REGS_OFFSET;
377 offset += pin % PINS_PER_BANK / PULL_PINS_PER_REG * 0x04;
378 return round_down(offset, 4);
379}
380
381static inline u32 sunxi_pull_offset(u16 pin)
382{
383 u32 pin_num = pin % PULL_PINS_PER_REG;
384 return pin_num * PULL_PINS_BITS;
385}
386
387#endif /* __PINCTRL_SUNXI_H */