blob: 6f02e3422af982740ee3fdb93161f3bae1fb8625 [file] [log] [blame]
Maxime Ripard0e37f882013-01-18 22:30:34 +01001/*
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
Maxime Ripardeaa3d842013-01-18 22:30:35 +010029static const struct sunxi_desc_pin sun5i_a13_pins[] = {
30 /* Hole */
31 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB0,
32 SUNXI_FUNCTION(0x0, "gpio_in"),
33 SUNXI_FUNCTION(0x1, "gpio_out")),
34 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB1,
35 SUNXI_FUNCTION(0x0, "gpio_in"),
36 SUNXI_FUNCTION(0x1, "gpio_out")),
37 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB2,
38 SUNXI_FUNCTION(0x0, "gpio_in"),
39 SUNXI_FUNCTION(0x1, "gpio_out")),
40 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB3,
41 SUNXI_FUNCTION(0x0, "gpio_in"),
42 SUNXI_FUNCTION(0x1, "gpio_out")),
43 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB4,
44 SUNXI_FUNCTION(0x0, "gpio_in"),
45 SUNXI_FUNCTION(0x1, "gpio_out")),
46 /* Hole */
47 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB10,
48 SUNXI_FUNCTION(0x0, "gpio_in"),
49 SUNXI_FUNCTION(0x1, "gpio_out")),
50 /* Hole */
51 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB15,
52 SUNXI_FUNCTION(0x0, "gpio_in"),
53 SUNXI_FUNCTION(0x1, "gpio_out")),
54 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB16,
55 SUNXI_FUNCTION(0x0, "gpio_in"),
56 SUNXI_FUNCTION(0x1, "gpio_out")),
57 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB17,
58 SUNXI_FUNCTION(0x0, "gpio_in"),
59 SUNXI_FUNCTION(0x1, "gpio_out")),
60 SUNXI_PIN(SUNXI_PINCTRL_PIN_PB18,
61 SUNXI_FUNCTION(0x0, "gpio_in"),
62 SUNXI_FUNCTION(0x1, "gpio_out")),
63 /* Hole */
64 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC0,
65 SUNXI_FUNCTION(0x0, "gpio_in"),
66 SUNXI_FUNCTION(0x1, "gpio_out")),
67 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC1,
68 SUNXI_FUNCTION(0x0, "gpio_in"),
69 SUNXI_FUNCTION(0x1, "gpio_out")),
70 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC2,
71 SUNXI_FUNCTION(0x0, "gpio_in"),
72 SUNXI_FUNCTION(0x1, "gpio_out")),
73 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC3,
74 SUNXI_FUNCTION(0x0, "gpio_in"),
75 SUNXI_FUNCTION(0x1, "gpio_out")),
76 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC4,
77 SUNXI_FUNCTION(0x0, "gpio_in"),
78 SUNXI_FUNCTION(0x1, "gpio_out")),
79 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC5,
80 SUNXI_FUNCTION(0x0, "gpio_in"),
81 SUNXI_FUNCTION(0x1, "gpio_out")),
82 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC6,
83 SUNXI_FUNCTION(0x0, "gpio_in"),
84 SUNXI_FUNCTION(0x1, "gpio_out")),
85 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC7,
86 SUNXI_FUNCTION(0x0, "gpio_in"),
87 SUNXI_FUNCTION(0x1, "gpio_out")),
88 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC8,
89 SUNXI_FUNCTION(0x0, "gpio_in"),
90 SUNXI_FUNCTION(0x1, "gpio_out")),
91 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC9,
92 SUNXI_FUNCTION(0x0, "gpio_in"),
93 SUNXI_FUNCTION(0x1, "gpio_out")),
94 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC10,
95 SUNXI_FUNCTION(0x0, "gpio_in"),
96 SUNXI_FUNCTION(0x1, "gpio_out")),
97 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC11,
98 SUNXI_FUNCTION(0x0, "gpio_in"),
99 SUNXI_FUNCTION(0x1, "gpio_out")),
100 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC12,
101 SUNXI_FUNCTION(0x0, "gpio_in"),
102 SUNXI_FUNCTION(0x1, "gpio_out")),
103 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC13,
104 SUNXI_FUNCTION(0x0, "gpio_in"),
105 SUNXI_FUNCTION(0x1, "gpio_out")),
106 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC14,
107 SUNXI_FUNCTION(0x0, "gpio_in"),
108 SUNXI_FUNCTION(0x1, "gpio_out")),
109 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC15,
110 SUNXI_FUNCTION(0x0, "gpio_in"),
111 SUNXI_FUNCTION(0x1, "gpio_out")),
112 /* Hole */
113 SUNXI_PIN(SUNXI_PINCTRL_PIN_PC19,
114 SUNXI_FUNCTION(0x0, "gpio_in"),
115 SUNXI_FUNCTION(0x1, "gpio_out")),
116 /* Hole */
117 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD2,
118 SUNXI_FUNCTION(0x0, "gpio_in"),
119 SUNXI_FUNCTION(0x1, "gpio_out")),
120 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD3,
121 SUNXI_FUNCTION(0x0, "gpio_in"),
122 SUNXI_FUNCTION(0x1, "gpio_out")),
123 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD4,
124 SUNXI_FUNCTION(0x0, "gpio_in"),
125 SUNXI_FUNCTION(0x1, "gpio_out")),
126 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD5,
127 SUNXI_FUNCTION(0x0, "gpio_in"),
128 SUNXI_FUNCTION(0x1, "gpio_out")),
129 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD6,
130 SUNXI_FUNCTION(0x0, "gpio_in"),
131 SUNXI_FUNCTION(0x1, "gpio_out")),
132 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD7,
133 SUNXI_FUNCTION(0x0, "gpio_in"),
134 SUNXI_FUNCTION(0x1, "gpio_out")),
135 /* Hole */
136 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD10,
137 SUNXI_FUNCTION(0x0, "gpio_in"),
138 SUNXI_FUNCTION(0x1, "gpio_out")),
139 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD11,
140 SUNXI_FUNCTION(0x0, "gpio_in"),
141 SUNXI_FUNCTION(0x1, "gpio_out")),
142 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD12,
143 SUNXI_FUNCTION(0x0, "gpio_in"),
144 SUNXI_FUNCTION(0x1, "gpio_out")),
145 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD13,
146 SUNXI_FUNCTION(0x0, "gpio_in"),
147 SUNXI_FUNCTION(0x1, "gpio_out")),
148 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD14,
149 SUNXI_FUNCTION(0x0, "gpio_in"),
150 SUNXI_FUNCTION(0x1, "gpio_out")),
151 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD15,
152 SUNXI_FUNCTION(0x0, "gpio_in"),
153 SUNXI_FUNCTION(0x1, "gpio_out")),
154 /* Hole */
155 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD18,
156 SUNXI_FUNCTION(0x0, "gpio_in"),
157 SUNXI_FUNCTION(0x1, "gpio_out")),
158 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD19,
159 SUNXI_FUNCTION(0x0, "gpio_in"),
160 SUNXI_FUNCTION(0x1, "gpio_out")),
161 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD20,
162 SUNXI_FUNCTION(0x0, "gpio_in"),
163 SUNXI_FUNCTION(0x1, "gpio_out")),
164 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD21,
165 SUNXI_FUNCTION(0x0, "gpio_in"),
166 SUNXI_FUNCTION(0x1, "gpio_out")),
167 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD22,
168 SUNXI_FUNCTION(0x0, "gpio_in"),
169 SUNXI_FUNCTION(0x1, "gpio_out")),
170 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD23,
171 SUNXI_FUNCTION(0x0, "gpio_in"),
172 SUNXI_FUNCTION(0x1, "gpio_out")),
173 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD24,
174 SUNXI_FUNCTION(0x0, "gpio_in"),
175 SUNXI_FUNCTION(0x1, "gpio_out")),
176 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD25,
177 SUNXI_FUNCTION(0x0, "gpio_in"),
178 SUNXI_FUNCTION(0x1, "gpio_out")),
179 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD26,
180 SUNXI_FUNCTION(0x0, "gpio_in"),
181 SUNXI_FUNCTION(0x1, "gpio_out")),
182 SUNXI_PIN(SUNXI_PINCTRL_PIN_PD27,
183 SUNXI_FUNCTION(0x0, "gpio_in"),
184 SUNXI_FUNCTION(0x1, "gpio_out")),
185 /* Hole */
186 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE0,
187 SUNXI_FUNCTION(0x0, "gpio_in"),
188 SUNXI_FUNCTION(0x1, "gpio_out")),
189 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE1,
190 SUNXI_FUNCTION(0x0, "gpio_in"),
191 SUNXI_FUNCTION(0x1, "gpio_out")),
192 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE2,
193 SUNXI_FUNCTION(0x0, "gpio_in"),
194 SUNXI_FUNCTION(0x1, "gpio_out")),
195 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE3,
196 SUNXI_FUNCTION(0x0, "gpio_in"),
197 SUNXI_FUNCTION(0x1, "gpio_out")),
198 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE4,
199 SUNXI_FUNCTION(0x0, "gpio_in"),
200 SUNXI_FUNCTION(0x1, "gpio_out")),
201 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE5,
202 SUNXI_FUNCTION(0x0, "gpio_in"),
203 SUNXI_FUNCTION(0x1, "gpio_out")),
204 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE6,
205 SUNXI_FUNCTION(0x0, "gpio_in"),
206 SUNXI_FUNCTION(0x1, "gpio_out")),
207 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE7,
208 SUNXI_FUNCTION(0x0, "gpio_in"),
209 SUNXI_FUNCTION(0x1, "gpio_out")),
210 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE8,
211 SUNXI_FUNCTION(0x0, "gpio_in"),
212 SUNXI_FUNCTION(0x1, "gpio_out")),
213 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE9,
214 SUNXI_FUNCTION(0x0, "gpio_in"),
215 SUNXI_FUNCTION(0x1, "gpio_out")),
216 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE10,
217 SUNXI_FUNCTION(0x0, "gpio_in"),
218 SUNXI_FUNCTION(0x1, "gpio_out"),
219 SUNXI_FUNCTION(0x4, "uart1")),
220 SUNXI_PIN(SUNXI_PINCTRL_PIN_PE11,
221 SUNXI_FUNCTION(0x0, "gpio_in"),
222 SUNXI_FUNCTION(0x1, "gpio_out"),
223 SUNXI_FUNCTION(0x4, "uart1")),
224 /* Hole */
225 SUNXI_PIN(SUNXI_PINCTRL_PIN_PF0,
226 SUNXI_FUNCTION(0x0, "gpio_in"),
227 SUNXI_FUNCTION(0x1, "gpio_out")),
228 SUNXI_PIN(SUNXI_PINCTRL_PIN_PF1,
229 SUNXI_FUNCTION(0x0, "gpio_in"),
230 SUNXI_FUNCTION(0x1, "gpio_out")),
231 SUNXI_PIN(SUNXI_PINCTRL_PIN_PF2,
232 SUNXI_FUNCTION(0x0, "gpio_in"),
233 SUNXI_FUNCTION(0x1, "gpio_out")),
234 SUNXI_PIN(SUNXI_PINCTRL_PIN_PF3,
235 SUNXI_FUNCTION(0x0, "gpio_in"),
236 SUNXI_FUNCTION(0x1, "gpio_out")),
237 SUNXI_PIN(SUNXI_PINCTRL_PIN_PF4,
238 SUNXI_FUNCTION(0x0, "gpio_in"),
239 SUNXI_FUNCTION(0x1, "gpio_out")),
240 SUNXI_PIN(SUNXI_PINCTRL_PIN_PF5,
241 SUNXI_FUNCTION(0x0, "gpio_in"),
242 SUNXI_FUNCTION(0x1, "gpio_out")),
243 /* Hole */
244 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG0,
245 SUNXI_FUNCTION(0x0, "gpio_in"),
246 SUNXI_FUNCTION(0x1, "gpio_out")),
247 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG1,
248 SUNXI_FUNCTION(0x0, "gpio_in"),
249 SUNXI_FUNCTION(0x1, "gpio_out")),
250 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG2,
251 SUNXI_FUNCTION(0x0, "gpio_in"),
252 SUNXI_FUNCTION(0x1, "gpio_out")),
253 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG3,
254 SUNXI_FUNCTION(0x0, "gpio_in"),
255 SUNXI_FUNCTION(0x1, "gpio_out"),
256 SUNXI_FUNCTION(0x4, "uart1")),
257 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG4,
258 SUNXI_FUNCTION(0x0, "gpio_in"),
259 SUNXI_FUNCTION(0x1, "gpio_out"),
260 SUNXI_FUNCTION(0x4, "uart1")),
261 /* Hole */
262 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG9,
263 SUNXI_FUNCTION(0x0, "gpio_in"),
264 SUNXI_FUNCTION(0x1, "gpio_out")),
265 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG10,
266 SUNXI_FUNCTION(0x0, "gpio_in"),
267 SUNXI_FUNCTION(0x1, "gpio_out")),
268 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG11,
269 SUNXI_FUNCTION(0x0, "gpio_in"),
270 SUNXI_FUNCTION(0x1, "gpio_out")),
271 SUNXI_PIN(SUNXI_PINCTRL_PIN_PG12,
272 SUNXI_FUNCTION(0x0, "gpio_in"),
273 SUNXI_FUNCTION(0x1, "gpio_out")),
274};
275
276static const struct sunxi_pinctrl_desc sun5i_a13_pinctrl_data = {
277 .pins = sun5i_a13_pins,
278 .npins = ARRAY_SIZE(sun5i_a13_pins),
279};
280
Maxime Ripard0e37f882013-01-18 22:30:34 +0100281static struct sunxi_pinctrl_group *
282sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
283{
284 int i;
285
286 for (i = 0; i < pctl->ngroups; i++) {
287 struct sunxi_pinctrl_group *grp = pctl->groups + i;
288
289 if (!strcmp(grp->name, group))
290 return grp;
291 }
292
293 return NULL;
294}
295
296static struct sunxi_pinctrl_function *
297sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
298 const char *name)
299{
300 struct sunxi_pinctrl_function *func = pctl->functions;
301 int i;
302
303 for (i = 0; i < pctl->nfunctions; i++) {
304 if (!func[i].name)
305 break;
306
307 if (!strcmp(func[i].name, name))
308 return func + i;
309 }
310
311 return NULL;
312}
313
314static struct sunxi_desc_function *
315sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
316 const char *pin_name,
317 const char *func_name)
318{
319 int i;
320
321 for (i = 0; i < pctl->desc->npins; i++) {
322 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
323
324 if (!strcmp(pin->pin.name, pin_name)) {
325 struct sunxi_desc_function *func = pin->functions;
326
327 while (func->name) {
328 if (!strcmp(func->name, func_name))
329 return func;
330
331 func++;
332 }
333 }
334 }
335
336 return NULL;
337}
338
339static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
340{
341 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
342
343 return pctl->ngroups;
344}
345
346static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
347 unsigned group)
348{
349 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
350
351 return pctl->groups[group].name;
352}
353
354static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
355 unsigned group,
356 const unsigned **pins,
357 unsigned *num_pins)
358{
359 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
360
361 *pins = (unsigned *)&pctl->groups[group].pin;
362 *num_pins = 1;
363
364 return 0;
365}
366
367static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
368 struct device_node *node,
369 struct pinctrl_map **map,
370 unsigned *num_maps)
371{
372 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
373 unsigned long *pinconfig;
374 struct property *prop;
375 const char *function;
376 const char *group;
377 int ret, nmaps, i = 0;
378 u32 val;
379
380 *map = NULL;
381 *num_maps = 0;
382
383 ret = of_property_read_string(node, "allwinner,function", &function);
384 if (ret) {
385 dev_err(pctl->dev,
386 "missing allwinner,function property in node %s\n",
387 node->name);
388 return -EINVAL;
389 }
390
391 nmaps = of_property_count_strings(node, "allwinner,pins") * 2;
392 if (nmaps < 0) {
393 dev_err(pctl->dev,
394 "missing allwinner,pins property in node %s\n",
395 node->name);
396 return -EINVAL;
397 }
398
399 *map = kmalloc(nmaps * sizeof(struct pinctrl_map), GFP_KERNEL);
400 if (!map)
401 return -ENOMEM;
402
403 of_property_for_each_string(node, "allwinner,pins", prop, group) {
404 struct sunxi_pinctrl_group *grp =
405 sunxi_pinctrl_find_group_by_name(pctl, group);
406 int j = 0, configlen = 0;
407
408 if (!grp) {
409 dev_err(pctl->dev, "unknown pin %s", group);
410 continue;
411 }
412
413 if (!sunxi_pinctrl_desc_find_function_by_name(pctl,
414 grp->name,
415 function)) {
416 dev_err(pctl->dev, "unsupported function %s on pin %s",
417 function, group);
418 continue;
419 }
420
421 (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
422 (*map)[i].data.mux.group = group;
423 (*map)[i].data.mux.function = function;
424
425 i++;
426
427 (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
428 (*map)[i].data.configs.group_or_pin = group;
429
430 if (of_find_property(node, "allwinner,drive", NULL))
431 configlen++;
432 if (of_find_property(node, "allwinner,pull", NULL))
433 configlen++;
434
435 pinconfig = kzalloc(configlen * sizeof(*pinconfig), GFP_KERNEL);
436
437 if (!of_property_read_u32(node, "allwinner,drive", &val)) {
438 u16 strength = (val + 1) * 10;
439 pinconfig[j++] =
440 pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
441 strength);
442 }
443
444 if (!of_property_read_u32(node, "allwinner,pull", &val)) {
445 enum pin_config_param pull = PIN_CONFIG_END;
446 if (val == 1)
447 pull = PIN_CONFIG_BIAS_PULL_UP;
448 else if (val == 2)
449 pull = PIN_CONFIG_BIAS_PULL_DOWN;
450 pinconfig[j++] = pinconf_to_config_packed(pull, 0);
451 }
452
453 (*map)[i].data.configs.configs = pinconfig;
454 (*map)[i].data.configs.num_configs = configlen;
455
456 i++;
457 }
458
459 *num_maps = nmaps;
460
461 return 0;
462}
463
464static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
465 struct pinctrl_map *map,
466 unsigned num_maps)
467{
468 int i;
469
470 for (i = 0; i < num_maps; i++) {
471 if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)
472 kfree(map[i].data.configs.configs);
473 }
474
475 kfree(map);
476}
477
478static struct pinctrl_ops sunxi_pctrl_ops = {
479 .dt_node_to_map = sunxi_pctrl_dt_node_to_map,
480 .dt_free_map = sunxi_pctrl_dt_free_map,
481 .get_groups_count = sunxi_pctrl_get_groups_count,
482 .get_group_name = sunxi_pctrl_get_group_name,
483 .get_group_pins = sunxi_pctrl_get_group_pins,
484};
485
486static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
487 unsigned group,
488 unsigned long *config)
489{
490 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
491
492 *config = pctl->groups[group].config;
493
494 return 0;
495}
496
497static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
498 unsigned group,
499 unsigned long config)
500{
501 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
502 struct sunxi_pinctrl_group *g = &pctl->groups[group];
503 u32 val, mask;
504 u16 strength;
505 u8 dlevel;
506
507 switch (pinconf_to_config_param(config)) {
508 case PIN_CONFIG_DRIVE_STRENGTH:
509 strength = pinconf_to_config_argument(config);
510 if (strength > 40)
511 return -EINVAL;
512 /*
513 * We convert from mA to what the register expects:
514 * 0: 10mA
515 * 1: 20mA
516 * 2: 30mA
517 * 3: 40mA
518 */
519 dlevel = strength / 10 - 1;
520 val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
521 mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
522 writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin),
523 pctl->membase + sunxi_dlevel_reg(g->pin));
524 break;
525 case PIN_CONFIG_BIAS_PULL_UP:
526 val = readl(pctl->membase + sunxi_pull_reg(g->pin));
527 mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
528 writel((val & ~mask) | 1 << sunxi_pull_offset(g->pin),
529 pctl->membase + sunxi_pull_reg(g->pin));
530 break;
531 case PIN_CONFIG_BIAS_PULL_DOWN:
532 val = readl(pctl->membase + sunxi_pull_reg(g->pin));
533 mask = PULL_PINS_MASK << sunxi_pull_offset(g->pin);
534 writel((val & ~mask) | 2 << sunxi_pull_offset(g->pin),
535 pctl->membase + sunxi_pull_reg(g->pin));
536 break;
537 default:
538 break;
539 }
540
541 /* cache the config value */
542 g->config = config;
543
544 return 0;
545}
546
547static struct pinconf_ops sunxi_pconf_ops = {
548 .pin_config_group_get = sunxi_pconf_group_get,
549 .pin_config_group_set = sunxi_pconf_group_set,
550};
551
552static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
553{
554 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
555
556 return pctl->nfunctions;
557}
558
559static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev,
560 unsigned function)
561{
562 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
563
564 return pctl->functions[function].name;
565}
566
567static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev,
568 unsigned function,
569 const char * const **groups,
570 unsigned * const num_groups)
571{
572 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
573
574 *groups = pctl->functions[function].groups;
575 *num_groups = pctl->functions[function].ngroups;
576
577 return 0;
578}
579
580static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
581 unsigned pin,
582 u8 config)
583{
584 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
585
586 u32 val = readl(pctl->membase + sunxi_mux_reg(pin));
587 u32 mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
588 writel((val & ~mask) | config << sunxi_mux_offset(pin),
589 pctl->membase + sunxi_mux_reg(pin));
590}
591
592static int sunxi_pmx_enable(struct pinctrl_dev *pctldev,
593 unsigned function,
594 unsigned group)
595{
596 struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
597 struct sunxi_pinctrl_group *g = pctl->groups + group;
598 struct sunxi_pinctrl_function *func = pctl->functions + function;
599 struct sunxi_desc_function *desc =
600 sunxi_pinctrl_desc_find_function_by_name(pctl,
601 g->name,
602 func->name);
603
604 if (!desc)
605 return -EINVAL;
606
607 sunxi_pmx_set(pctldev, g->pin, desc->muxval);
608
609 return 0;
610}
611
612static struct pinmux_ops sunxi_pmx_ops = {
613 .get_functions_count = sunxi_pmx_get_funcs_cnt,
614 .get_function_name = sunxi_pmx_get_func_name,
615 .get_function_groups = sunxi_pmx_get_func_groups,
616 .enable = sunxi_pmx_enable,
617};
618
619static struct pinctrl_desc sunxi_pctrl_desc = {
620 .confops = &sunxi_pconf_ops,
621 .pctlops = &sunxi_pctrl_ops,
622 .pmxops = &sunxi_pmx_ops,
623};
624
625static struct of_device_id sunxi_pinctrl_match[] = {
Maxime Ripardeaa3d842013-01-18 22:30:35 +0100626 { .compatible = "allwinner,sun5i-a13-pinctrl", .data = (void *)&sun5i_a13_pinctrl_data },
Maxime Ripard0e37f882013-01-18 22:30:34 +0100627 {}
628};
629MODULE_DEVICE_TABLE(of, sunxi_pinctrl_match);
630
631static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
632 const char *name)
633{
634 struct sunxi_pinctrl_function *func = pctl->functions;
635
636 while (func->name) {
637 /* function already there */
638 if (strcmp(func->name, name) == 0) {
639 func->ngroups++;
640 return -EEXIST;
641 }
642 func++;
643 }
644
645 func->name = name;
646 func->ngroups = 1;
647
648 pctl->nfunctions++;
649
650 return 0;
651}
652
653static int sunxi_pinctrl_build_state(struct platform_device *pdev)
654{
655 struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
656 int i;
657
658 pctl->ngroups = pctl->desc->npins;
659
660 /* Allocate groups */
661 pctl->groups = devm_kzalloc(&pdev->dev,
662 pctl->ngroups * sizeof(*pctl->groups),
663 GFP_KERNEL);
664 if (!pctl->groups)
665 return -ENOMEM;
666
667 for (i = 0; i < pctl->desc->npins; i++) {
668 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
669 struct sunxi_pinctrl_group *group = pctl->groups + i;
670
671 group->name = pin->pin.name;
672 group->pin = pin->pin.number;
673 }
674
675 /*
676 * We suppose that we won't have any more functions than pins,
677 * we'll reallocate that later anyway
678 */
679 pctl->functions = devm_kzalloc(&pdev->dev,
680 pctl->desc->npins * sizeof(*pctl->functions),
681 GFP_KERNEL);
682 if (!pctl->functions)
683 return -ENOMEM;
684
685 /* Count functions and their associated groups */
686 for (i = 0; i < pctl->desc->npins; i++) {
687 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
688 struct sunxi_desc_function *func = pin->functions;
689
690 while (func->name) {
691 sunxi_pinctrl_add_function(pctl, func->name);
692 func++;
693 }
694 }
695
696 pctl->functions = krealloc(pctl->functions,
697 pctl->nfunctions * sizeof(*pctl->functions),
698 GFP_KERNEL);
699
700 for (i = 0; i < pctl->desc->npins; i++) {
701 const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
702 struct sunxi_desc_function *func = pin->functions;
703
704 while (func->name) {
705 struct sunxi_pinctrl_function *func_item;
706 const char **func_grp;
707
708 func_item = sunxi_pinctrl_find_function_by_name(pctl,
709 func->name);
710 if (!func_item)
711 return -EINVAL;
712
713 if (!func_item->groups) {
714 func_item->groups =
715 devm_kzalloc(&pdev->dev,
716 func_item->ngroups * sizeof(*func_item->groups),
717 GFP_KERNEL);
718 if (!func_item->groups)
719 return -ENOMEM;
720 }
721
722 func_grp = func_item->groups;
723 while (*func_grp)
724 func_grp++;
725
726 *func_grp = pin->pin.name;
727 func++;
728 }
729 }
730
731 return 0;
732}
733
734static int sunxi_pinctrl_probe(struct platform_device *pdev)
735{
736 struct device_node *node = pdev->dev.of_node;
737 const struct of_device_id *device;
738 struct pinctrl_pin_desc *pins;
739 struct sunxi_pinctrl *pctl;
740 int i, ret;
741
742 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
743 if (!pctl)
744 return -ENOMEM;
745 platform_set_drvdata(pdev, pctl);
746
747 pctl->membase = of_iomap(node, 0);
748 if (!pctl->membase)
749 return -ENOMEM;
750
751 device = of_match_device(sunxi_pinctrl_match, &pdev->dev);
752 if (!device)
753 return -ENODEV;
754
755 pctl->desc = (struct sunxi_pinctrl_desc *)device->data;
756
757 ret = sunxi_pinctrl_build_state(pdev);
758 if (ret) {
759 dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
760 return ret;
761 }
762
763 pins = devm_kzalloc(&pdev->dev,
764 pctl->desc->npins * sizeof(*pins),
765 GFP_KERNEL);
766 if (!pins)
767 return -ENOMEM;
768
769 for (i = 0; i < pctl->desc->npins; i++)
770 pins[i] = pctl->desc->pins[i].pin;
771
772 sunxi_pctrl_desc.name = dev_name(&pdev->dev);
773 sunxi_pctrl_desc.owner = THIS_MODULE;
774 sunxi_pctrl_desc.pins = pins;
775 sunxi_pctrl_desc.npins = pctl->desc->npins;
776 pctl->dev = &pdev->dev;
777 pctl->pctl_dev = pinctrl_register(&sunxi_pctrl_desc,
778 &pdev->dev, pctl);
779 if (!pctl->pctl_dev) {
780 dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
781 return -EINVAL;
782 }
783
784 dev_info(&pdev->dev, "initialized sunXi pin control driver\n");
785
786 return 0;
787}
788
789static struct platform_driver sunxi_pinctrl_driver = {
790 .probe = sunxi_pinctrl_probe,
791 .driver = {
792 .name = "sunxi-pinctrl",
793 .owner = THIS_MODULE,
794 .of_match_table = sunxi_pinctrl_match,
795 },
796};
797module_platform_driver(sunxi_pinctrl_driver);
798
799MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com");
800MODULE_DESCRIPTION("Allwinner A1X pinctrl driver");
801MODULE_LICENSE("GPL");