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/clk.h> |
14 | #include <linux/export.h> |
15 | #include <linux/gpio/driver.h> |
16 | #include <linux/interrupt.h> |
17 | #include <linux/io.h> |
18 | #include <linux/irqchip/chained_irq.h> |
19 | #include <linux/irqdomain.h> |
20 | #include <linux/of.h> |
21 | #include <linux/of_clk.h> |
22 | #include <linux/platform_device.h> |
23 | #include <linux/regulator/consumer.h> |
24 | #include <linux/slab.h> |
25 | |
26 | #include <linux/pinctrl/consumer.h> |
27 | #include <linux/pinctrl/machine.h> |
28 | #include <linux/pinctrl/pinconf-generic.h> |
29 | #include <linux/pinctrl/pinconf.h> |
30 | #include <linux/pinctrl/pinctrl.h> |
31 | #include <linux/pinctrl/pinmux.h> |
32 | |
33 | #include <dt-bindings/pinctrl/sun4i-a10.h> |
34 | |
35 | #include "../core.h" |
36 | #include "pinctrl-sunxi.h" |
37 | |
38 | /* |
39 | * These lock classes tell lockdep that GPIO IRQs are in a different |
40 | * category than their parents, so it won't report false recursion. |
41 | */ |
42 | static struct lock_class_key sunxi_pinctrl_irq_lock_class; |
43 | static struct lock_class_key sunxi_pinctrl_irq_request_class; |
44 | |
45 | static struct irq_chip sunxi_pinctrl_edge_irq_chip; |
46 | static struct irq_chip sunxi_pinctrl_level_irq_chip; |
47 | |
48 | /* |
49 | * The sunXi PIO registers are organized as a series of banks, with registers |
50 | * for each bank in the following order: |
51 | * - Mux config |
52 | * - Data value |
53 | * - Drive level |
54 | * - Pull direction |
55 | * |
56 | * Multiple consecutive registers are used for fields wider than one bit. |
57 | * |
58 | * The following functions calculate the register and the bit offset to access. |
59 | * They take a pin number which is relative to the start of the current device. |
60 | */ |
61 | static void sunxi_mux_reg(const struct sunxi_pinctrl *pctl, |
62 | u32 pin, u32 *reg, u32 *shift, u32 *mask) |
63 | { |
64 | u32 bank = pin / PINS_PER_BANK; |
65 | u32 offset = pin % PINS_PER_BANK * MUX_FIELD_WIDTH; |
66 | |
67 | *reg = bank * pctl->bank_mem_size + MUX_REGS_OFFSET + |
68 | offset / BITS_PER_TYPE(u32) * sizeof(u32); |
69 | *shift = offset % BITS_PER_TYPE(u32); |
70 | *mask = (BIT(MUX_FIELD_WIDTH) - 1) << *shift; |
71 | } |
72 | |
73 | static void sunxi_data_reg(const struct sunxi_pinctrl *pctl, |
74 | u32 pin, u32 *reg, u32 *shift, u32 *mask) |
75 | { |
76 | u32 bank = pin / PINS_PER_BANK; |
77 | u32 offset = pin % PINS_PER_BANK * DATA_FIELD_WIDTH; |
78 | |
79 | *reg = bank * pctl->bank_mem_size + DATA_REGS_OFFSET + |
80 | offset / BITS_PER_TYPE(u32) * sizeof(u32); |
81 | *shift = offset % BITS_PER_TYPE(u32); |
82 | *mask = (BIT(DATA_FIELD_WIDTH) - 1) << *shift; |
83 | } |
84 | |
85 | static void sunxi_dlevel_reg(const struct sunxi_pinctrl *pctl, |
86 | u32 pin, u32 *reg, u32 *shift, u32 *mask) |
87 | { |
88 | u32 bank = pin / PINS_PER_BANK; |
89 | u32 offset = pin % PINS_PER_BANK * pctl->dlevel_field_width; |
90 | |
91 | *reg = bank * pctl->bank_mem_size + DLEVEL_REGS_OFFSET + |
92 | offset / BITS_PER_TYPE(u32) * sizeof(u32); |
93 | *shift = offset % BITS_PER_TYPE(u32); |
94 | *mask = (BIT(pctl->dlevel_field_width) - 1) << *shift; |
95 | } |
96 | |
97 | static void sunxi_pull_reg(const struct sunxi_pinctrl *pctl, |
98 | u32 pin, u32 *reg, u32 *shift, u32 *mask) |
99 | { |
100 | u32 bank = pin / PINS_PER_BANK; |
101 | u32 offset = pin % PINS_PER_BANK * PULL_FIELD_WIDTH; |
102 | |
103 | *reg = bank * pctl->bank_mem_size + pctl->pull_regs_offset + |
104 | offset / BITS_PER_TYPE(u32) * sizeof(u32); |
105 | *shift = offset % BITS_PER_TYPE(u32); |
106 | *mask = (BIT(PULL_FIELD_WIDTH) - 1) << *shift; |
107 | } |
108 | |
109 | static struct sunxi_pinctrl_group * |
110 | sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group) |
111 | { |
112 | int i; |
113 | |
114 | for (i = 0; i < pctl->ngroups; i++) { |
115 | struct sunxi_pinctrl_group *grp = pctl->groups + i; |
116 | |
117 | if (!strcmp(grp->name, group)) |
118 | return grp; |
119 | } |
120 | |
121 | return NULL; |
122 | } |
123 | |
124 | static struct sunxi_pinctrl_function * |
125 | sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl, |
126 | const char *name) |
127 | { |
128 | struct sunxi_pinctrl_function *func = pctl->functions; |
129 | int i; |
130 | |
131 | for (i = 0; i < pctl->nfunctions; i++) { |
132 | if (!func[i].name) |
133 | break; |
134 | |
135 | if (!strcmp(func[i].name, name)) |
136 | return func + i; |
137 | } |
138 | |
139 | return NULL; |
140 | } |
141 | |
142 | static struct sunxi_desc_function * |
143 | sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl, |
144 | const char *pin_name, |
145 | const char *func_name) |
146 | { |
147 | int i; |
148 | |
149 | for (i = 0; i < pctl->desc->npins; i++) { |
150 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
151 | |
152 | if (!strcmp(pin->pin.name, pin_name)) { |
153 | struct sunxi_desc_function *func = pin->functions; |
154 | |
155 | while (func->name) { |
156 | if (!strcmp(func->name, func_name) && |
157 | (!func->variant || |
158 | func->variant & pctl->variant)) |
159 | return func; |
160 | |
161 | func++; |
162 | } |
163 | } |
164 | } |
165 | |
166 | return NULL; |
167 | } |
168 | |
169 | static struct sunxi_desc_function * |
170 | sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl, |
171 | const u16 pin_num, |
172 | const char *func_name) |
173 | { |
174 | int i; |
175 | |
176 | for (i = 0; i < pctl->desc->npins; i++) { |
177 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
178 | |
179 | if (pin->pin.number == pin_num) { |
180 | struct sunxi_desc_function *func = pin->functions; |
181 | |
182 | while (func->name) { |
183 | if (!strcmp(func->name, func_name)) |
184 | return func; |
185 | |
186 | func++; |
187 | } |
188 | } |
189 | } |
190 | |
191 | return NULL; |
192 | } |
193 | |
194 | static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev) |
195 | { |
196 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
197 | |
198 | return pctl->ngroups; |
199 | } |
200 | |
201 | static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev, |
202 | unsigned group) |
203 | { |
204 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
205 | |
206 | return pctl->groups[group].name; |
207 | } |
208 | |
209 | static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev, |
210 | unsigned group, |
211 | const unsigned **pins, |
212 | unsigned *num_pins) |
213 | { |
214 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
215 | |
216 | *pins = (unsigned *)&pctl->groups[group].pin; |
217 | *num_pins = 1; |
218 | |
219 | return 0; |
220 | } |
221 | |
222 | static bool sunxi_pctrl_has_bias_prop(struct device_node *node) |
223 | { |
224 | return of_property_present(np: node, propname: "bias-pull-up" ) || |
225 | of_property_present(np: node, propname: "bias-pull-down" ) || |
226 | of_property_present(np: node, propname: "bias-disable" ) || |
227 | of_property_present(np: node, propname: "allwinner,pull" ); |
228 | } |
229 | |
230 | static bool sunxi_pctrl_has_drive_prop(struct device_node *node) |
231 | { |
232 | return of_property_present(np: node, propname: "drive-strength" ) || |
233 | of_property_present(np: node, propname: "allwinner,drive" ); |
234 | } |
235 | |
236 | static int sunxi_pctrl_parse_bias_prop(struct device_node *node) |
237 | { |
238 | u32 val; |
239 | |
240 | /* Try the new style binding */ |
241 | if (of_property_present(np: node, propname: "bias-pull-up" )) |
242 | return PIN_CONFIG_BIAS_PULL_UP; |
243 | |
244 | if (of_property_present(np: node, propname: "bias-pull-down" )) |
245 | return PIN_CONFIG_BIAS_PULL_DOWN; |
246 | |
247 | if (of_property_present(np: node, propname: "bias-disable" )) |
248 | return PIN_CONFIG_BIAS_DISABLE; |
249 | |
250 | /* And fall back to the old binding */ |
251 | if (of_property_read_u32(np: node, propname: "allwinner,pull" , out_value: &val)) |
252 | return -EINVAL; |
253 | |
254 | switch (val) { |
255 | case SUN4I_PINCTRL_NO_PULL: |
256 | return PIN_CONFIG_BIAS_DISABLE; |
257 | case SUN4I_PINCTRL_PULL_UP: |
258 | return PIN_CONFIG_BIAS_PULL_UP; |
259 | case SUN4I_PINCTRL_PULL_DOWN: |
260 | return PIN_CONFIG_BIAS_PULL_DOWN; |
261 | } |
262 | |
263 | return -EINVAL; |
264 | } |
265 | |
266 | static int sunxi_pctrl_parse_drive_prop(struct device_node *node) |
267 | { |
268 | u32 val; |
269 | |
270 | /* Try the new style binding */ |
271 | if (!of_property_read_u32(np: node, propname: "drive-strength" , out_value: &val)) { |
272 | /* We can't go below 10mA ... */ |
273 | if (val < 10) |
274 | return -EINVAL; |
275 | |
276 | /* ... and only up to 40 mA ... */ |
277 | if (val > 40) |
278 | val = 40; |
279 | |
280 | /* by steps of 10 mA */ |
281 | return rounddown(val, 10); |
282 | } |
283 | |
284 | /* And then fall back to the old binding */ |
285 | if (of_property_read_u32(np: node, propname: "allwinner,drive" , out_value: &val)) |
286 | return -EINVAL; |
287 | |
288 | return (val + 1) * 10; |
289 | } |
290 | |
291 | static const char *sunxi_pctrl_parse_function_prop(struct device_node *node) |
292 | { |
293 | const char *function; |
294 | int ret; |
295 | |
296 | /* Try the generic binding */ |
297 | ret = of_property_read_string(np: node, propname: "function" , out_string: &function); |
298 | if (!ret) |
299 | return function; |
300 | |
301 | /* And fall back to our legacy one */ |
302 | ret = of_property_read_string(np: node, propname: "allwinner,function" , out_string: &function); |
303 | if (!ret) |
304 | return function; |
305 | |
306 | return NULL; |
307 | } |
308 | |
309 | static const char *sunxi_pctrl_find_pins_prop(struct device_node *node, |
310 | int *npins) |
311 | { |
312 | int count; |
313 | |
314 | /* Try the generic binding */ |
315 | count = of_property_count_strings(np: node, propname: "pins" ); |
316 | if (count > 0) { |
317 | *npins = count; |
318 | return "pins" ; |
319 | } |
320 | |
321 | /* And fall back to our legacy one */ |
322 | count = of_property_count_strings(np: node, propname: "allwinner,pins" ); |
323 | if (count > 0) { |
324 | *npins = count; |
325 | return "allwinner,pins" ; |
326 | } |
327 | |
328 | return NULL; |
329 | } |
330 | |
331 | static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node, |
332 | unsigned int *len) |
333 | { |
334 | unsigned long *pinconfig; |
335 | unsigned int configlen = 0, idx = 0; |
336 | int ret; |
337 | |
338 | if (sunxi_pctrl_has_drive_prop(node)) |
339 | configlen++; |
340 | if (sunxi_pctrl_has_bias_prop(node)) |
341 | configlen++; |
342 | |
343 | /* |
344 | * If we don't have any configuration, bail out |
345 | */ |
346 | if (!configlen) |
347 | return NULL; |
348 | |
349 | pinconfig = kcalloc(n: configlen, size: sizeof(*pinconfig), GFP_KERNEL); |
350 | if (!pinconfig) |
351 | return ERR_PTR(error: -ENOMEM); |
352 | |
353 | if (sunxi_pctrl_has_drive_prop(node)) { |
354 | int drive = sunxi_pctrl_parse_drive_prop(node); |
355 | if (drive < 0) { |
356 | ret = drive; |
357 | goto err_free; |
358 | } |
359 | |
360 | pinconfig[idx++] = pinconf_to_config_packed(param: PIN_CONFIG_DRIVE_STRENGTH, |
361 | argument: drive); |
362 | } |
363 | |
364 | if (sunxi_pctrl_has_bias_prop(node)) { |
365 | int pull = sunxi_pctrl_parse_bias_prop(node); |
366 | int arg = 0; |
367 | if (pull < 0) { |
368 | ret = pull; |
369 | goto err_free; |
370 | } |
371 | |
372 | if (pull != PIN_CONFIG_BIAS_DISABLE) |
373 | arg = 1; /* hardware uses weak pull resistors */ |
374 | |
375 | pinconfig[idx++] = pinconf_to_config_packed(param: pull, argument: arg); |
376 | } |
377 | |
378 | |
379 | *len = configlen; |
380 | return pinconfig; |
381 | |
382 | err_free: |
383 | kfree(objp: pinconfig); |
384 | return ERR_PTR(error: ret); |
385 | } |
386 | |
387 | static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, |
388 | struct device_node *node, |
389 | struct pinctrl_map **map, |
390 | unsigned *num_maps) |
391 | { |
392 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
393 | unsigned long *pinconfig; |
394 | struct property *prop; |
395 | const char *function, *pin_prop; |
396 | const char *group; |
397 | int ret, npins, nmaps, configlen = 0, i = 0; |
398 | |
399 | *map = NULL; |
400 | *num_maps = 0; |
401 | |
402 | function = sunxi_pctrl_parse_function_prop(node); |
403 | if (!function) { |
404 | dev_err(pctl->dev, "missing function property in node %pOFn\n" , |
405 | node); |
406 | return -EINVAL; |
407 | } |
408 | |
409 | pin_prop = sunxi_pctrl_find_pins_prop(node, npins: &npins); |
410 | if (!pin_prop) { |
411 | dev_err(pctl->dev, "missing pins property in node %pOFn\n" , |
412 | node); |
413 | return -EINVAL; |
414 | } |
415 | |
416 | /* |
417 | * We have two maps for each pin: one for the function, one |
418 | * for the configuration (bias, strength, etc). |
419 | * |
420 | * We might be slightly overshooting, since we might not have |
421 | * any configuration. |
422 | */ |
423 | nmaps = npins * 2; |
424 | *map = kmalloc_array(n: nmaps, size: sizeof(struct pinctrl_map), GFP_KERNEL); |
425 | if (!*map) |
426 | return -ENOMEM; |
427 | |
428 | pinconfig = sunxi_pctrl_build_pin_config(node, len: &configlen); |
429 | if (IS_ERR(ptr: pinconfig)) { |
430 | ret = PTR_ERR(ptr: pinconfig); |
431 | goto err_free_map; |
432 | } |
433 | |
434 | of_property_for_each_string(node, pin_prop, prop, group) { |
435 | struct sunxi_pinctrl_group *grp = |
436 | sunxi_pinctrl_find_group_by_name(pctl, group); |
437 | |
438 | if (!grp) { |
439 | dev_err(pctl->dev, "unknown pin %s" , group); |
440 | continue; |
441 | } |
442 | |
443 | if (!sunxi_pinctrl_desc_find_function_by_name(pctl, |
444 | pin_name: grp->name, |
445 | func_name: function)) { |
446 | dev_err(pctl->dev, "unsupported function %s on pin %s" , |
447 | function, group); |
448 | continue; |
449 | } |
450 | |
451 | (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP; |
452 | (*map)[i].data.mux.group = group; |
453 | (*map)[i].data.mux.function = function; |
454 | |
455 | i++; |
456 | |
457 | if (pinconfig) { |
458 | (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; |
459 | (*map)[i].data.configs.group_or_pin = group; |
460 | (*map)[i].data.configs.configs = pinconfig; |
461 | (*map)[i].data.configs.num_configs = configlen; |
462 | i++; |
463 | } |
464 | } |
465 | |
466 | *num_maps = i; |
467 | |
468 | /* |
469 | * We know have the number of maps we need, we can resize our |
470 | * map array |
471 | */ |
472 | *map = krealloc(objp: *map, new_size: i * sizeof(struct pinctrl_map), GFP_KERNEL); |
473 | if (!*map) |
474 | return -ENOMEM; |
475 | |
476 | return 0; |
477 | |
478 | err_free_map: |
479 | kfree(objp: *map); |
480 | *map = NULL; |
481 | return ret; |
482 | } |
483 | |
484 | static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev, |
485 | struct pinctrl_map *map, |
486 | unsigned num_maps) |
487 | { |
488 | int i; |
489 | |
490 | /* pin config is never in the first map */ |
491 | for (i = 1; i < num_maps; i++) { |
492 | if (map[i].type != PIN_MAP_TYPE_CONFIGS_GROUP) |
493 | continue; |
494 | |
495 | /* |
496 | * All the maps share the same pin config, |
497 | * free only the first one we find. |
498 | */ |
499 | kfree(objp: map[i].data.configs.configs); |
500 | break; |
501 | } |
502 | |
503 | kfree(objp: map); |
504 | } |
505 | |
506 | static const struct pinctrl_ops sunxi_pctrl_ops = { |
507 | .dt_node_to_map = sunxi_pctrl_dt_node_to_map, |
508 | .dt_free_map = sunxi_pctrl_dt_free_map, |
509 | .get_groups_count = sunxi_pctrl_get_groups_count, |
510 | .get_group_name = sunxi_pctrl_get_group_name, |
511 | .get_group_pins = sunxi_pctrl_get_group_pins, |
512 | }; |
513 | |
514 | static int sunxi_pconf_reg(const struct sunxi_pinctrl *pctl, |
515 | u32 pin, enum pin_config_param param, |
516 | u32 *reg, u32 *shift, u32 *mask) |
517 | { |
518 | switch (param) { |
519 | case PIN_CONFIG_DRIVE_STRENGTH: |
520 | sunxi_dlevel_reg(pctl, pin, reg, shift, mask); |
521 | break; |
522 | |
523 | case PIN_CONFIG_BIAS_PULL_UP: |
524 | case PIN_CONFIG_BIAS_PULL_DOWN: |
525 | case PIN_CONFIG_BIAS_DISABLE: |
526 | sunxi_pull_reg(pctl, pin, reg, shift, mask); |
527 | break; |
528 | |
529 | default: |
530 | return -ENOTSUPP; |
531 | } |
532 | |
533 | return 0; |
534 | } |
535 | |
536 | static int sunxi_pconf_get(struct pinctrl_dev *pctldev, unsigned pin, |
537 | unsigned long *config) |
538 | { |
539 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
540 | enum pin_config_param param = pinconf_to_config_param(config: *config); |
541 | u32 reg, shift, mask, val; |
542 | u16 arg; |
543 | int ret; |
544 | |
545 | pin -= pctl->desc->pin_base; |
546 | |
547 | ret = sunxi_pconf_reg(pctl, pin, param, reg: ®, shift: &shift, mask: &mask); |
548 | if (ret < 0) |
549 | return ret; |
550 | |
551 | val = (readl(addr: pctl->membase + reg) & mask) >> shift; |
552 | |
553 | switch (pinconf_to_config_param(config: *config)) { |
554 | case PIN_CONFIG_DRIVE_STRENGTH: |
555 | arg = (val + 1) * 10; |
556 | break; |
557 | |
558 | case PIN_CONFIG_BIAS_PULL_UP: |
559 | if (val != SUN4I_PINCTRL_PULL_UP) |
560 | return -EINVAL; |
561 | arg = 1; /* hardware is weak pull-up */ |
562 | break; |
563 | |
564 | case PIN_CONFIG_BIAS_PULL_DOWN: |
565 | if (val != SUN4I_PINCTRL_PULL_DOWN) |
566 | return -EINVAL; |
567 | arg = 1; /* hardware is weak pull-down */ |
568 | break; |
569 | |
570 | case PIN_CONFIG_BIAS_DISABLE: |
571 | if (val != SUN4I_PINCTRL_NO_PULL) |
572 | return -EINVAL; |
573 | arg = 0; |
574 | break; |
575 | |
576 | default: |
577 | /* sunxi_pconf_reg should catch anything unsupported */ |
578 | WARN_ON(1); |
579 | return -ENOTSUPP; |
580 | } |
581 | |
582 | *config = pinconf_to_config_packed(param, argument: arg); |
583 | |
584 | return 0; |
585 | } |
586 | |
587 | static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev, |
588 | unsigned group, |
589 | unsigned long *config) |
590 | { |
591 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
592 | struct sunxi_pinctrl_group *g = &pctl->groups[group]; |
593 | |
594 | /* We only support 1 pin per group. Chain it to the pin callback */ |
595 | return sunxi_pconf_get(pctldev, pin: g->pin, config); |
596 | } |
597 | |
598 | static int sunxi_pconf_set(struct pinctrl_dev *pctldev, unsigned pin, |
599 | unsigned long *configs, unsigned num_configs) |
600 | { |
601 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
602 | int i; |
603 | |
604 | pin -= pctl->desc->pin_base; |
605 | |
606 | for (i = 0; i < num_configs; i++) { |
607 | u32 arg, reg, shift, mask, val; |
608 | enum pin_config_param param; |
609 | unsigned long flags; |
610 | int ret; |
611 | |
612 | param = pinconf_to_config_param(config: configs[i]); |
613 | arg = pinconf_to_config_argument(config: configs[i]); |
614 | |
615 | ret = sunxi_pconf_reg(pctl, pin, param, reg: ®, shift: &shift, mask: &mask); |
616 | if (ret < 0) |
617 | return ret; |
618 | |
619 | switch (param) { |
620 | case PIN_CONFIG_DRIVE_STRENGTH: |
621 | if (arg < 10 || arg > 40) |
622 | return -EINVAL; |
623 | /* |
624 | * We convert from mA to what the register expects: |
625 | * 0: 10mA |
626 | * 1: 20mA |
627 | * 2: 30mA |
628 | * 3: 40mA |
629 | */ |
630 | val = arg / 10 - 1; |
631 | break; |
632 | case PIN_CONFIG_BIAS_DISABLE: |
633 | val = 0; |
634 | break; |
635 | case PIN_CONFIG_BIAS_PULL_UP: |
636 | if (arg == 0) |
637 | return -EINVAL; |
638 | val = 1; |
639 | break; |
640 | case PIN_CONFIG_BIAS_PULL_DOWN: |
641 | if (arg == 0) |
642 | return -EINVAL; |
643 | val = 2; |
644 | break; |
645 | default: |
646 | /* sunxi_pconf_reg should catch anything unsupported */ |
647 | WARN_ON(1); |
648 | return -ENOTSUPP; |
649 | } |
650 | |
651 | raw_spin_lock_irqsave(&pctl->lock, flags); |
652 | writel(val: (readl(addr: pctl->membase + reg) & ~mask) | val << shift, |
653 | addr: pctl->membase + reg); |
654 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
655 | } /* for each config */ |
656 | |
657 | return 0; |
658 | } |
659 | |
660 | static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, |
661 | unsigned long *configs, unsigned num_configs) |
662 | { |
663 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
664 | struct sunxi_pinctrl_group *g = &pctl->groups[group]; |
665 | |
666 | /* We only support 1 pin per group. Chain it to the pin callback */ |
667 | return sunxi_pconf_set(pctldev, pin: g->pin, configs, num_configs); |
668 | } |
669 | |
670 | static const struct pinconf_ops sunxi_pconf_ops = { |
671 | .is_generic = true, |
672 | .pin_config_get = sunxi_pconf_get, |
673 | .pin_config_set = sunxi_pconf_set, |
674 | .pin_config_group_get = sunxi_pconf_group_get, |
675 | .pin_config_group_set = sunxi_pconf_group_set, |
676 | }; |
677 | |
678 | static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl, |
679 | unsigned pin, |
680 | struct regulator *supply) |
681 | { |
682 | unsigned short bank; |
683 | unsigned long flags; |
684 | u32 val, reg; |
685 | int uV; |
686 | |
687 | if (!pctl->desc->io_bias_cfg_variant) |
688 | return 0; |
689 | |
690 | uV = regulator_get_voltage(regulator: supply); |
691 | if (uV < 0) |
692 | return uV; |
693 | |
694 | /* Might be dummy regulator with no voltage set */ |
695 | if (uV == 0) |
696 | return 0; |
697 | |
698 | pin -= pctl->desc->pin_base; |
699 | bank = pin / PINS_PER_BANK; |
700 | |
701 | switch (pctl->desc->io_bias_cfg_variant) { |
702 | case BIAS_VOLTAGE_GRP_CONFIG: |
703 | /* |
704 | * Configured value must be equal or greater to actual |
705 | * voltage. |
706 | */ |
707 | if (uV <= 1800000) |
708 | val = 0x0; /* 1.8V */ |
709 | else if (uV <= 2500000) |
710 | val = 0x6; /* 2.5V */ |
711 | else if (uV <= 2800000) |
712 | val = 0x9; /* 2.8V */ |
713 | else if (uV <= 3000000) |
714 | val = 0xA; /* 3.0V */ |
715 | else |
716 | val = 0xD; /* 3.3V */ |
717 | |
718 | reg = readl(addr: pctl->membase + sunxi_grp_config_reg(pin)); |
719 | reg &= ~IO_BIAS_MASK; |
720 | writel(val: reg | val, addr: pctl->membase + sunxi_grp_config_reg(pin)); |
721 | return 0; |
722 | case BIAS_VOLTAGE_PIO_POW_MODE_CTL: |
723 | val = uV > 1800000 && uV <= 2500000 ? BIT(bank) : 0; |
724 | |
725 | raw_spin_lock_irqsave(&pctl->lock, flags); |
726 | reg = readl(addr: pctl->membase + PIO_POW_MOD_CTL_REG); |
727 | reg &= ~BIT(bank); |
728 | writel(val: reg | val, addr: pctl->membase + PIO_POW_MOD_CTL_REG); |
729 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
730 | |
731 | fallthrough; |
732 | case BIAS_VOLTAGE_PIO_POW_MODE_SEL: |
733 | val = uV <= 1800000 ? 1 : 0; |
734 | |
735 | raw_spin_lock_irqsave(&pctl->lock, flags); |
736 | reg = readl(addr: pctl->membase + PIO_POW_MOD_SEL_REG); |
737 | reg &= ~(1 << bank); |
738 | writel(val: reg | val << bank, addr: pctl->membase + PIO_POW_MOD_SEL_REG); |
739 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
740 | return 0; |
741 | default: |
742 | return -EINVAL; |
743 | } |
744 | } |
745 | |
746 | static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev) |
747 | { |
748 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
749 | |
750 | return pctl->nfunctions; |
751 | } |
752 | |
753 | static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev, |
754 | unsigned function) |
755 | { |
756 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
757 | |
758 | return pctl->functions[function].name; |
759 | } |
760 | |
761 | static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev, |
762 | unsigned function, |
763 | const char * const **groups, |
764 | unsigned * const num_groups) |
765 | { |
766 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
767 | |
768 | *groups = pctl->functions[function].groups; |
769 | *num_groups = pctl->functions[function].ngroups; |
770 | |
771 | return 0; |
772 | } |
773 | |
774 | static void sunxi_pmx_set(struct pinctrl_dev *pctldev, |
775 | unsigned pin, |
776 | u8 config) |
777 | { |
778 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
779 | u32 reg, shift, mask; |
780 | unsigned long flags; |
781 | |
782 | pin -= pctl->desc->pin_base; |
783 | sunxi_mux_reg(pctl, pin, reg: ®, shift: &shift, mask: &mask); |
784 | |
785 | raw_spin_lock_irqsave(&pctl->lock, flags); |
786 | |
787 | writel(val: (readl(addr: pctl->membase + reg) & ~mask) | config << shift, |
788 | addr: pctl->membase + reg); |
789 | |
790 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
791 | } |
792 | |
793 | static int sunxi_pmx_set_mux(struct pinctrl_dev *pctldev, |
794 | unsigned function, |
795 | unsigned group) |
796 | { |
797 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
798 | struct sunxi_pinctrl_group *g = pctl->groups + group; |
799 | struct sunxi_pinctrl_function *func = pctl->functions + function; |
800 | struct sunxi_desc_function *desc = |
801 | sunxi_pinctrl_desc_find_function_by_name(pctl, |
802 | pin_name: g->name, |
803 | func_name: func->name); |
804 | |
805 | if (!desc) |
806 | return -EINVAL; |
807 | |
808 | sunxi_pmx_set(pctldev, pin: g->pin, config: desc->muxval); |
809 | |
810 | return 0; |
811 | } |
812 | |
813 | static int |
814 | sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, |
815 | struct pinctrl_gpio_range *range, |
816 | unsigned offset, |
817 | bool input) |
818 | { |
819 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
820 | struct sunxi_desc_function *desc; |
821 | const char *func; |
822 | |
823 | if (input) |
824 | func = "gpio_in" ; |
825 | else |
826 | func = "gpio_out" ; |
827 | |
828 | desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin_num: offset, func_name: func); |
829 | if (!desc) |
830 | return -EINVAL; |
831 | |
832 | sunxi_pmx_set(pctldev, pin: offset, config: desc->muxval); |
833 | |
834 | return 0; |
835 | } |
836 | |
837 | static int sunxi_pmx_request(struct pinctrl_dev *pctldev, unsigned offset) |
838 | { |
839 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
840 | unsigned short bank = offset / PINS_PER_BANK; |
841 | unsigned short bank_offset = bank - pctl->desc->pin_base / |
842 | PINS_PER_BANK; |
843 | struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset]; |
844 | struct regulator *reg = s_reg->regulator; |
845 | char supply[16]; |
846 | int ret; |
847 | |
848 | if (WARN_ON_ONCE(bank_offset >= ARRAY_SIZE(pctl->regulators))) |
849 | return -EINVAL; |
850 | |
851 | if (reg) { |
852 | refcount_inc(r: &s_reg->refcount); |
853 | return 0; |
854 | } |
855 | |
856 | snprintf(buf: supply, size: sizeof(supply), fmt: "vcc-p%c" , 'a' + bank); |
857 | reg = regulator_get(dev: pctl->dev, id: supply); |
858 | if (IS_ERR(ptr: reg)) |
859 | return dev_err_probe(dev: pctl->dev, err: PTR_ERR(ptr: reg), |
860 | fmt: "Couldn't get bank P%c regulator\n" , |
861 | 'A' + bank); |
862 | |
863 | ret = regulator_enable(regulator: reg); |
864 | if (ret) { |
865 | dev_err(pctl->dev, |
866 | "Couldn't enable bank P%c regulator\n" , 'A' + bank); |
867 | goto out; |
868 | } |
869 | |
870 | sunxi_pinctrl_set_io_bias_cfg(pctl, pin: offset, supply: reg); |
871 | |
872 | s_reg->regulator = reg; |
873 | refcount_set(r: &s_reg->refcount, n: 1); |
874 | |
875 | return 0; |
876 | |
877 | out: |
878 | regulator_put(regulator: s_reg->regulator); |
879 | |
880 | return ret; |
881 | } |
882 | |
883 | static int sunxi_pmx_free(struct pinctrl_dev *pctldev, unsigned offset) |
884 | { |
885 | struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
886 | unsigned short bank = offset / PINS_PER_BANK; |
887 | unsigned short bank_offset = bank - pctl->desc->pin_base / |
888 | PINS_PER_BANK; |
889 | struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset]; |
890 | |
891 | if (!refcount_dec_and_test(r: &s_reg->refcount)) |
892 | return 0; |
893 | |
894 | regulator_disable(regulator: s_reg->regulator); |
895 | regulator_put(regulator: s_reg->regulator); |
896 | s_reg->regulator = NULL; |
897 | |
898 | return 0; |
899 | } |
900 | |
901 | static const struct pinmux_ops sunxi_pmx_ops = { |
902 | .get_functions_count = sunxi_pmx_get_funcs_cnt, |
903 | .get_function_name = sunxi_pmx_get_func_name, |
904 | .get_function_groups = sunxi_pmx_get_func_groups, |
905 | .set_mux = sunxi_pmx_set_mux, |
906 | .gpio_set_direction = sunxi_pmx_gpio_set_direction, |
907 | .request = sunxi_pmx_request, |
908 | .free = sunxi_pmx_free, |
909 | .strict = true, |
910 | }; |
911 | |
912 | static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip, |
913 | unsigned offset) |
914 | { |
915 | struct sunxi_pinctrl *pctl = gpiochip_get_data(gc: chip); |
916 | |
917 | return sunxi_pmx_gpio_set_direction(pctldev: pctl->pctl_dev, NULL, |
918 | offset: chip->base + offset, input: true); |
919 | } |
920 | |
921 | static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset) |
922 | { |
923 | struct sunxi_pinctrl *pctl = gpiochip_get_data(gc: chip); |
924 | bool set_mux = pctl->desc->irq_read_needs_mux && |
925 | gpiochip_line_is_irq(gc: chip, offset); |
926 | u32 pin = offset + chip->base; |
927 | u32 reg, shift, mask, val; |
928 | |
929 | sunxi_data_reg(pctl, pin: offset, reg: ®, shift: &shift, mask: &mask); |
930 | |
931 | if (set_mux) |
932 | sunxi_pmx_set(pctldev: pctl->pctl_dev, pin, SUN4I_FUNC_INPUT); |
933 | |
934 | val = (readl(addr: pctl->membase + reg) & mask) >> shift; |
935 | |
936 | if (set_mux) |
937 | sunxi_pmx_set(pctldev: pctl->pctl_dev, pin, SUN4I_FUNC_IRQ); |
938 | |
939 | return val; |
940 | } |
941 | |
942 | static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip, |
943 | unsigned offset, int value) |
944 | { |
945 | struct sunxi_pinctrl *pctl = gpiochip_get_data(gc: chip); |
946 | u32 reg, shift, mask, val; |
947 | unsigned long flags; |
948 | |
949 | sunxi_data_reg(pctl, pin: offset, reg: ®, shift: &shift, mask: &mask); |
950 | |
951 | raw_spin_lock_irqsave(&pctl->lock, flags); |
952 | |
953 | val = readl(addr: pctl->membase + reg); |
954 | |
955 | if (value) |
956 | val |= mask; |
957 | else |
958 | val &= ~mask; |
959 | |
960 | writel(val, addr: pctl->membase + reg); |
961 | |
962 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
963 | } |
964 | |
965 | static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip, |
966 | unsigned offset, int value) |
967 | { |
968 | struct sunxi_pinctrl *pctl = gpiochip_get_data(gc: chip); |
969 | |
970 | sunxi_pinctrl_gpio_set(chip, offset, value); |
971 | return sunxi_pmx_gpio_set_direction(pctldev: pctl->pctl_dev, NULL, |
972 | offset: chip->base + offset, input: false); |
973 | } |
974 | |
975 | static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc, |
976 | const struct of_phandle_args *gpiospec, |
977 | u32 *flags) |
978 | { |
979 | int pin, base; |
980 | |
981 | base = PINS_PER_BANK * gpiospec->args[0]; |
982 | pin = base + gpiospec->args[1]; |
983 | |
984 | if (pin > gc->ngpio) |
985 | return -EINVAL; |
986 | |
987 | if (flags) |
988 | *flags = gpiospec->args[2]; |
989 | |
990 | return pin; |
991 | } |
992 | |
993 | static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
994 | { |
995 | struct sunxi_pinctrl *pctl = gpiochip_get_data(gc: chip); |
996 | struct sunxi_desc_function *desc; |
997 | unsigned pinnum = pctl->desc->pin_base + offset; |
998 | unsigned irqnum; |
999 | |
1000 | if (offset >= chip->ngpio) |
1001 | return -ENXIO; |
1002 | |
1003 | desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin_num: pinnum, func_name: "irq" ); |
1004 | if (!desc) |
1005 | return -EINVAL; |
1006 | |
1007 | irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum; |
1008 | |
1009 | dev_dbg(chip->parent, "%s: request IRQ for GPIO %d, return %d\n" , |
1010 | chip->label, offset + chip->base, irqnum); |
1011 | |
1012 | return irq_find_mapping(domain: pctl->domain, hwirq: irqnum); |
1013 | } |
1014 | |
1015 | static int sunxi_pinctrl_irq_request_resources(struct irq_data *d) |
1016 | { |
1017 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1018 | struct sunxi_desc_function *func; |
1019 | int ret; |
1020 | |
1021 | func = sunxi_pinctrl_desc_find_function_by_pin(pctl, |
1022 | pin_num: pctl->irq_array[d->hwirq], func_name: "irq" ); |
1023 | if (!func) |
1024 | return -EINVAL; |
1025 | |
1026 | ret = gpiochip_lock_as_irq(gc: pctl->chip, |
1027 | offset: pctl->irq_array[d->hwirq] - pctl->desc->pin_base); |
1028 | if (ret) { |
1029 | dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n" , |
1030 | irqd_to_hwirq(d)); |
1031 | return ret; |
1032 | } |
1033 | |
1034 | /* Change muxing to INT mode */ |
1035 | sunxi_pmx_set(pctldev: pctl->pctl_dev, pin: pctl->irq_array[d->hwirq], config: func->muxval); |
1036 | |
1037 | return 0; |
1038 | } |
1039 | |
1040 | static void sunxi_pinctrl_irq_release_resources(struct irq_data *d) |
1041 | { |
1042 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1043 | |
1044 | gpiochip_unlock_as_irq(gc: pctl->chip, |
1045 | offset: pctl->irq_array[d->hwirq] - pctl->desc->pin_base); |
1046 | } |
1047 | |
1048 | static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type) |
1049 | { |
1050 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1051 | u32 reg = sunxi_irq_cfg_reg(desc: pctl->desc, irq: d->hwirq); |
1052 | u8 index = sunxi_irq_cfg_offset(irq: d->hwirq); |
1053 | unsigned long flags; |
1054 | u32 regval; |
1055 | u8 mode; |
1056 | |
1057 | switch (type) { |
1058 | case IRQ_TYPE_EDGE_RISING: |
1059 | mode = IRQ_EDGE_RISING; |
1060 | break; |
1061 | case IRQ_TYPE_EDGE_FALLING: |
1062 | mode = IRQ_EDGE_FALLING; |
1063 | break; |
1064 | case IRQ_TYPE_EDGE_BOTH: |
1065 | mode = IRQ_EDGE_BOTH; |
1066 | break; |
1067 | case IRQ_TYPE_LEVEL_HIGH: |
1068 | mode = IRQ_LEVEL_HIGH; |
1069 | break; |
1070 | case IRQ_TYPE_LEVEL_LOW: |
1071 | mode = IRQ_LEVEL_LOW; |
1072 | break; |
1073 | default: |
1074 | return -EINVAL; |
1075 | } |
1076 | |
1077 | raw_spin_lock_irqsave(&pctl->lock, flags); |
1078 | |
1079 | if (type & IRQ_TYPE_LEVEL_MASK) |
1080 | irq_set_chip_handler_name_locked(data: d, chip: &sunxi_pinctrl_level_irq_chip, |
1081 | handler: handle_fasteoi_irq, NULL); |
1082 | else |
1083 | irq_set_chip_handler_name_locked(data: d, chip: &sunxi_pinctrl_edge_irq_chip, |
1084 | handler: handle_edge_irq, NULL); |
1085 | |
1086 | regval = readl(addr: pctl->membase + reg); |
1087 | regval &= ~(IRQ_CFG_IRQ_MASK << index); |
1088 | writel(val: regval | (mode << index), addr: pctl->membase + reg); |
1089 | |
1090 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
1091 | |
1092 | return 0; |
1093 | } |
1094 | |
1095 | static void sunxi_pinctrl_irq_ack(struct irq_data *d) |
1096 | { |
1097 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1098 | u32 status_reg = sunxi_irq_status_reg(desc: pctl->desc, irq: d->hwirq); |
1099 | u8 status_idx = sunxi_irq_status_offset(irq: d->hwirq); |
1100 | |
1101 | /* Clear the IRQ */ |
1102 | writel(val: 1 << status_idx, addr: pctl->membase + status_reg); |
1103 | } |
1104 | |
1105 | static void sunxi_pinctrl_irq_mask(struct irq_data *d) |
1106 | { |
1107 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1108 | u32 reg = sunxi_irq_ctrl_reg(desc: pctl->desc, irq: d->hwirq); |
1109 | u8 idx = sunxi_irq_ctrl_offset(irq: d->hwirq); |
1110 | unsigned long flags; |
1111 | u32 val; |
1112 | |
1113 | raw_spin_lock_irqsave(&pctl->lock, flags); |
1114 | |
1115 | /* Mask the IRQ */ |
1116 | val = readl(addr: pctl->membase + reg); |
1117 | writel(val: val & ~(1 << idx), addr: pctl->membase + reg); |
1118 | |
1119 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
1120 | } |
1121 | |
1122 | static void sunxi_pinctrl_irq_unmask(struct irq_data *d) |
1123 | { |
1124 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1125 | u32 reg = sunxi_irq_ctrl_reg(desc: pctl->desc, irq: d->hwirq); |
1126 | u8 idx = sunxi_irq_ctrl_offset(irq: d->hwirq); |
1127 | unsigned long flags; |
1128 | u32 val; |
1129 | |
1130 | raw_spin_lock_irqsave(&pctl->lock, flags); |
1131 | |
1132 | /* Unmask the IRQ */ |
1133 | val = readl(addr: pctl->membase + reg); |
1134 | writel(val: val | (1 << idx), addr: pctl->membase + reg); |
1135 | |
1136 | raw_spin_unlock_irqrestore(&pctl->lock, flags); |
1137 | } |
1138 | |
1139 | static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d) |
1140 | { |
1141 | sunxi_pinctrl_irq_ack(d); |
1142 | sunxi_pinctrl_irq_unmask(d); |
1143 | } |
1144 | |
1145 | static int sunxi_pinctrl_irq_set_wake(struct irq_data *d, unsigned int on) |
1146 | { |
1147 | struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d); |
1148 | u8 bank = d->hwirq / IRQ_PER_BANK; |
1149 | |
1150 | return irq_set_irq_wake(irq: pctl->irq[bank], on); |
1151 | } |
1152 | |
1153 | static struct irq_chip sunxi_pinctrl_edge_irq_chip = { |
1154 | .name = "sunxi_pio_edge" , |
1155 | .irq_ack = sunxi_pinctrl_irq_ack, |
1156 | .irq_mask = sunxi_pinctrl_irq_mask, |
1157 | .irq_unmask = sunxi_pinctrl_irq_unmask, |
1158 | .irq_request_resources = sunxi_pinctrl_irq_request_resources, |
1159 | .irq_release_resources = sunxi_pinctrl_irq_release_resources, |
1160 | .irq_set_type = sunxi_pinctrl_irq_set_type, |
1161 | .irq_set_wake = sunxi_pinctrl_irq_set_wake, |
1162 | .flags = IRQCHIP_MASK_ON_SUSPEND, |
1163 | }; |
1164 | |
1165 | static struct irq_chip sunxi_pinctrl_level_irq_chip = { |
1166 | .name = "sunxi_pio_level" , |
1167 | .irq_eoi = sunxi_pinctrl_irq_ack, |
1168 | .irq_mask = sunxi_pinctrl_irq_mask, |
1169 | .irq_unmask = sunxi_pinctrl_irq_unmask, |
1170 | /* Define irq_enable / disable to avoid spurious irqs for drivers |
1171 | * using these to suppress irqs while they clear the irq source */ |
1172 | .irq_enable = sunxi_pinctrl_irq_ack_unmask, |
1173 | .irq_disable = sunxi_pinctrl_irq_mask, |
1174 | .irq_request_resources = sunxi_pinctrl_irq_request_resources, |
1175 | .irq_release_resources = sunxi_pinctrl_irq_release_resources, |
1176 | .irq_set_type = sunxi_pinctrl_irq_set_type, |
1177 | .irq_set_wake = sunxi_pinctrl_irq_set_wake, |
1178 | .flags = IRQCHIP_EOI_THREADED | |
1179 | IRQCHIP_MASK_ON_SUSPEND | |
1180 | IRQCHIP_EOI_IF_HANDLED, |
1181 | }; |
1182 | |
1183 | static int sunxi_pinctrl_irq_of_xlate(struct irq_domain *d, |
1184 | struct device_node *node, |
1185 | const u32 *intspec, |
1186 | unsigned int intsize, |
1187 | unsigned long *out_hwirq, |
1188 | unsigned int *out_type) |
1189 | { |
1190 | struct sunxi_pinctrl *pctl = d->host_data; |
1191 | struct sunxi_desc_function *desc; |
1192 | int pin, base; |
1193 | |
1194 | if (intsize < 3) |
1195 | return -EINVAL; |
1196 | |
1197 | base = PINS_PER_BANK * intspec[0]; |
1198 | pin = pctl->desc->pin_base + base + intspec[1]; |
1199 | |
1200 | desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin_num: pin, func_name: "irq" ); |
1201 | if (!desc) |
1202 | return -EINVAL; |
1203 | |
1204 | *out_hwirq = desc->irqbank * PINS_PER_BANK + desc->irqnum; |
1205 | *out_type = intspec[2]; |
1206 | |
1207 | return 0; |
1208 | } |
1209 | |
1210 | static const struct irq_domain_ops sunxi_pinctrl_irq_domain_ops = { |
1211 | .xlate = sunxi_pinctrl_irq_of_xlate, |
1212 | }; |
1213 | |
1214 | static void sunxi_pinctrl_irq_handler(struct irq_desc *desc) |
1215 | { |
1216 | unsigned int irq = irq_desc_get_irq(desc); |
1217 | struct irq_chip *chip = irq_desc_get_chip(desc); |
1218 | struct sunxi_pinctrl *pctl = irq_desc_get_handler_data(desc); |
1219 | unsigned long bank, reg, val; |
1220 | |
1221 | for (bank = 0; bank < pctl->desc->irq_banks; bank++) |
1222 | if (irq == pctl->irq[bank]) |
1223 | break; |
1224 | |
1225 | WARN_ON(bank == pctl->desc->irq_banks); |
1226 | |
1227 | chained_irq_enter(chip, desc); |
1228 | |
1229 | reg = sunxi_irq_status_reg_from_bank(desc: pctl->desc, bank); |
1230 | val = readl(addr: pctl->membase + reg); |
1231 | |
1232 | if (val) { |
1233 | int irqoffset; |
1234 | |
1235 | for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) |
1236 | generic_handle_domain_irq(domain: pctl->domain, |
1237 | hwirq: bank * IRQ_PER_BANK + irqoffset); |
1238 | } |
1239 | |
1240 | chained_irq_exit(chip, desc); |
1241 | } |
1242 | |
1243 | static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl, |
1244 | const char *name) |
1245 | { |
1246 | struct sunxi_pinctrl_function *func = pctl->functions; |
1247 | |
1248 | while (func->name) { |
1249 | /* function already there */ |
1250 | if (strcmp(func->name, name) == 0) { |
1251 | func->ngroups++; |
1252 | return -EEXIST; |
1253 | } |
1254 | func++; |
1255 | } |
1256 | |
1257 | func->name = name; |
1258 | func->ngroups = 1; |
1259 | |
1260 | pctl->nfunctions++; |
1261 | |
1262 | return 0; |
1263 | } |
1264 | |
1265 | static int sunxi_pinctrl_build_state(struct platform_device *pdev) |
1266 | { |
1267 | struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev); |
1268 | void *ptr; |
1269 | int i; |
1270 | |
1271 | /* |
1272 | * Allocate groups |
1273 | * |
1274 | * We assume that the number of groups is the number of pins |
1275 | * given in the data array. |
1276 | |
1277 | * This will not always be true, since some pins might not be |
1278 | * available in the current variant, but fortunately for us, |
1279 | * this means that the number of pins is the maximum group |
1280 | * number we will ever see. |
1281 | */ |
1282 | pctl->groups = devm_kcalloc(dev: &pdev->dev, |
1283 | n: pctl->desc->npins, size: sizeof(*pctl->groups), |
1284 | GFP_KERNEL); |
1285 | if (!pctl->groups) |
1286 | return -ENOMEM; |
1287 | |
1288 | for (i = 0; i < pctl->desc->npins; i++) { |
1289 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
1290 | struct sunxi_pinctrl_group *group = pctl->groups + pctl->ngroups; |
1291 | |
1292 | if (pin->variant && !(pctl->variant & pin->variant)) |
1293 | continue; |
1294 | |
1295 | group->name = pin->pin.name; |
1296 | group->pin = pin->pin.number; |
1297 | |
1298 | /* And now we count the actual number of pins / groups */ |
1299 | pctl->ngroups++; |
1300 | } |
1301 | |
1302 | /* |
1303 | * Find an upper bound for the maximum number of functions: in |
1304 | * the worst case we have gpio_in, gpio_out, irq and up to seven |
1305 | * special functions per pin, plus one entry for the sentinel. |
1306 | * We'll reallocate that later anyway. |
1307 | */ |
1308 | pctl->functions = kcalloc(n: 7 * pctl->ngroups + 4, |
1309 | size: sizeof(*pctl->functions), |
1310 | GFP_KERNEL); |
1311 | if (!pctl->functions) |
1312 | return -ENOMEM; |
1313 | |
1314 | /* Count functions and their associated groups */ |
1315 | for (i = 0; i < pctl->desc->npins; i++) { |
1316 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
1317 | struct sunxi_desc_function *func; |
1318 | |
1319 | if (pin->variant && !(pctl->variant & pin->variant)) |
1320 | continue; |
1321 | |
1322 | for (func = pin->functions; func->name; func++) { |
1323 | if (func->variant && !(pctl->variant & func->variant)) |
1324 | continue; |
1325 | |
1326 | /* Create interrupt mapping while we're at it */ |
1327 | if (!strcmp(func->name, "irq" )) { |
1328 | int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK; |
1329 | pctl->irq_array[irqnum] = pin->pin.number; |
1330 | } |
1331 | |
1332 | sunxi_pinctrl_add_function(pctl, name: func->name); |
1333 | } |
1334 | } |
1335 | |
1336 | /* And now allocated and fill the array for real */ |
1337 | ptr = krealloc(objp: pctl->functions, |
1338 | new_size: pctl->nfunctions * sizeof(*pctl->functions), |
1339 | GFP_KERNEL); |
1340 | if (!ptr) { |
1341 | kfree(objp: pctl->functions); |
1342 | pctl->functions = NULL; |
1343 | return -ENOMEM; |
1344 | } |
1345 | pctl->functions = ptr; |
1346 | |
1347 | for (i = 0; i < pctl->desc->npins; i++) { |
1348 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
1349 | struct sunxi_desc_function *func; |
1350 | |
1351 | if (pin->variant && !(pctl->variant & pin->variant)) |
1352 | continue; |
1353 | |
1354 | for (func = pin->functions; func->name; func++) { |
1355 | struct sunxi_pinctrl_function *func_item; |
1356 | const char **func_grp; |
1357 | |
1358 | if (func->variant && !(pctl->variant & func->variant)) |
1359 | continue; |
1360 | |
1361 | func_item = sunxi_pinctrl_find_function_by_name(pctl, |
1362 | name: func->name); |
1363 | if (!func_item) { |
1364 | kfree(objp: pctl->functions); |
1365 | return -EINVAL; |
1366 | } |
1367 | |
1368 | if (!func_item->groups) { |
1369 | func_item->groups = |
1370 | devm_kcalloc(dev: &pdev->dev, |
1371 | n: func_item->ngroups, |
1372 | size: sizeof(*func_item->groups), |
1373 | GFP_KERNEL); |
1374 | if (!func_item->groups) { |
1375 | kfree(objp: pctl->functions); |
1376 | return -ENOMEM; |
1377 | } |
1378 | } |
1379 | |
1380 | func_grp = func_item->groups; |
1381 | while (*func_grp) |
1382 | func_grp++; |
1383 | |
1384 | *func_grp = pin->pin.name; |
1385 | } |
1386 | } |
1387 | |
1388 | return 0; |
1389 | } |
1390 | |
1391 | static int sunxi_pinctrl_get_debounce_div(struct clk *clk, int freq, int *diff) |
1392 | { |
1393 | unsigned long clock = clk_get_rate(clk); |
1394 | unsigned int best_diff, best_div; |
1395 | int i; |
1396 | |
1397 | best_diff = abs(freq - clock); |
1398 | best_div = 0; |
1399 | |
1400 | for (i = 1; i < 8; i++) { |
1401 | int cur_diff = abs(freq - (clock >> i)); |
1402 | |
1403 | if (cur_diff < best_diff) { |
1404 | best_diff = cur_diff; |
1405 | best_div = i; |
1406 | } |
1407 | } |
1408 | |
1409 | *diff = best_diff; |
1410 | return best_div; |
1411 | } |
1412 | |
1413 | static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl, |
1414 | struct device_node *node) |
1415 | { |
1416 | unsigned int hosc_diff, losc_diff; |
1417 | unsigned int hosc_div, losc_div; |
1418 | struct clk *hosc, *losc; |
1419 | u8 div, src; |
1420 | int i, ret; |
1421 | |
1422 | /* Deal with old DTs that didn't have the oscillators */ |
1423 | if (of_clk_get_parent_count(np: node) != 3) |
1424 | return 0; |
1425 | |
1426 | /* If we don't have any setup, bail out */ |
1427 | if (!of_property_present(np: node, propname: "input-debounce" )) |
1428 | return 0; |
1429 | |
1430 | losc = devm_clk_get(dev: pctl->dev, id: "losc" ); |
1431 | if (IS_ERR(ptr: losc)) |
1432 | return PTR_ERR(ptr: losc); |
1433 | |
1434 | hosc = devm_clk_get(dev: pctl->dev, id: "hosc" ); |
1435 | if (IS_ERR(ptr: hosc)) |
1436 | return PTR_ERR(ptr: hosc); |
1437 | |
1438 | for (i = 0; i < pctl->desc->irq_banks; i++) { |
1439 | unsigned long debounce_freq; |
1440 | u32 debounce; |
1441 | |
1442 | ret = of_property_read_u32_index(np: node, propname: "input-debounce" , |
1443 | index: i, out_value: &debounce); |
1444 | if (ret) |
1445 | return ret; |
1446 | |
1447 | if (!debounce) |
1448 | continue; |
1449 | |
1450 | debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce); |
1451 | losc_div = sunxi_pinctrl_get_debounce_div(clk: losc, |
1452 | freq: debounce_freq, |
1453 | diff: &losc_diff); |
1454 | |
1455 | hosc_div = sunxi_pinctrl_get_debounce_div(clk: hosc, |
1456 | freq: debounce_freq, |
1457 | diff: &hosc_diff); |
1458 | |
1459 | if (hosc_diff < losc_diff) { |
1460 | div = hosc_div; |
1461 | src = 1; |
1462 | } else { |
1463 | div = losc_div; |
1464 | src = 0; |
1465 | } |
1466 | |
1467 | writel(val: src | div << 4, |
1468 | addr: pctl->membase + |
1469 | sunxi_irq_debounce_reg_from_bank(desc: pctl->desc, bank: i)); |
1470 | } |
1471 | |
1472 | return 0; |
1473 | } |
1474 | |
1475 | int sunxi_pinctrl_init_with_variant(struct platform_device *pdev, |
1476 | const struct sunxi_pinctrl_desc *desc, |
1477 | unsigned long variant) |
1478 | { |
1479 | struct device_node *node = pdev->dev.of_node; |
1480 | struct pinctrl_desc *pctrl_desc; |
1481 | struct pinctrl_pin_desc *pins; |
1482 | struct sunxi_pinctrl *pctl; |
1483 | struct pinmux_ops *pmxops; |
1484 | int i, ret, last_pin, pin_idx; |
1485 | struct clk *clk; |
1486 | |
1487 | pctl = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pctl), GFP_KERNEL); |
1488 | if (!pctl) |
1489 | return -ENOMEM; |
1490 | platform_set_drvdata(pdev, data: pctl); |
1491 | |
1492 | raw_spin_lock_init(&pctl->lock); |
1493 | |
1494 | pctl->membase = devm_platform_ioremap_resource(pdev, index: 0); |
1495 | if (IS_ERR(ptr: pctl->membase)) |
1496 | return PTR_ERR(ptr: pctl->membase); |
1497 | |
1498 | pctl->dev = &pdev->dev; |
1499 | pctl->desc = desc; |
1500 | pctl->variant = variant; |
1501 | if (pctl->variant >= PINCTRL_SUN20I_D1) { |
1502 | pctl->bank_mem_size = D1_BANK_MEM_SIZE; |
1503 | pctl->pull_regs_offset = D1_PULL_REGS_OFFSET; |
1504 | pctl->dlevel_field_width = D1_DLEVEL_FIELD_WIDTH; |
1505 | } else { |
1506 | pctl->bank_mem_size = BANK_MEM_SIZE; |
1507 | pctl->pull_regs_offset = PULL_REGS_OFFSET; |
1508 | pctl->dlevel_field_width = DLEVEL_FIELD_WIDTH; |
1509 | } |
1510 | |
1511 | pctl->irq_array = devm_kcalloc(dev: &pdev->dev, |
1512 | IRQ_PER_BANK * pctl->desc->irq_banks, |
1513 | size: sizeof(*pctl->irq_array), |
1514 | GFP_KERNEL); |
1515 | if (!pctl->irq_array) |
1516 | return -ENOMEM; |
1517 | |
1518 | ret = sunxi_pinctrl_build_state(pdev); |
1519 | if (ret) { |
1520 | dev_err(&pdev->dev, "dt probe failed: %d\n" , ret); |
1521 | return ret; |
1522 | } |
1523 | |
1524 | pins = devm_kcalloc(dev: &pdev->dev, |
1525 | n: pctl->desc->npins, size: sizeof(*pins), |
1526 | GFP_KERNEL); |
1527 | if (!pins) |
1528 | return -ENOMEM; |
1529 | |
1530 | for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) { |
1531 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
1532 | |
1533 | if (pin->variant && !(pctl->variant & pin->variant)) |
1534 | continue; |
1535 | |
1536 | pins[pin_idx++] = pin->pin; |
1537 | } |
1538 | |
1539 | pctrl_desc = devm_kzalloc(dev: &pdev->dev, |
1540 | size: sizeof(*pctrl_desc), |
1541 | GFP_KERNEL); |
1542 | if (!pctrl_desc) |
1543 | return -ENOMEM; |
1544 | |
1545 | pctrl_desc->name = dev_name(dev: &pdev->dev); |
1546 | pctrl_desc->owner = THIS_MODULE; |
1547 | pctrl_desc->pins = pins; |
1548 | pctrl_desc->npins = pctl->ngroups; |
1549 | pctrl_desc->confops = &sunxi_pconf_ops; |
1550 | pctrl_desc->pctlops = &sunxi_pctrl_ops; |
1551 | |
1552 | pmxops = devm_kmemdup(dev: &pdev->dev, src: &sunxi_pmx_ops, len: sizeof(sunxi_pmx_ops), |
1553 | GFP_KERNEL); |
1554 | if (!pmxops) |
1555 | return -ENOMEM; |
1556 | |
1557 | if (desc->disable_strict_mode) |
1558 | pmxops->strict = false; |
1559 | |
1560 | pctrl_desc->pmxops = pmxops; |
1561 | |
1562 | pctl->pctl_dev = devm_pinctrl_register(dev: &pdev->dev, pctldesc: pctrl_desc, driver_data: pctl); |
1563 | if (IS_ERR(ptr: pctl->pctl_dev)) { |
1564 | dev_err(&pdev->dev, "couldn't register pinctrl driver\n" ); |
1565 | return PTR_ERR(ptr: pctl->pctl_dev); |
1566 | } |
1567 | |
1568 | pctl->chip = devm_kzalloc(dev: &pdev->dev, size: sizeof(*pctl->chip), GFP_KERNEL); |
1569 | if (!pctl->chip) |
1570 | return -ENOMEM; |
1571 | |
1572 | last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number; |
1573 | pctl->chip->owner = THIS_MODULE; |
1574 | pctl->chip->request = gpiochip_generic_request; |
1575 | pctl->chip->free = gpiochip_generic_free; |
1576 | pctl->chip->set_config = gpiochip_generic_config; |
1577 | pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; |
1578 | pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; |
1579 | pctl->chip->get = sunxi_pinctrl_gpio_get; |
1580 | pctl->chip->set = sunxi_pinctrl_gpio_set; |
1581 | pctl->chip->of_xlate = sunxi_pinctrl_gpio_of_xlate; |
1582 | pctl->chip->to_irq = sunxi_pinctrl_gpio_to_irq; |
1583 | pctl->chip->of_gpio_n_cells = 3; |
1584 | pctl->chip->can_sleep = false; |
1585 | pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK) - |
1586 | pctl->desc->pin_base; |
1587 | pctl->chip->label = dev_name(dev: &pdev->dev); |
1588 | pctl->chip->parent = &pdev->dev; |
1589 | pctl->chip->base = pctl->desc->pin_base; |
1590 | |
1591 | ret = gpiochip_add_data(pctl->chip, pctl); |
1592 | if (ret) |
1593 | return ret; |
1594 | |
1595 | for (i = 0; i < pctl->desc->npins; i++) { |
1596 | const struct sunxi_desc_pin *pin = pctl->desc->pins + i; |
1597 | |
1598 | ret = gpiochip_add_pin_range(gc: pctl->chip, pinctl_name: dev_name(dev: &pdev->dev), |
1599 | gpio_offset: pin->pin.number - pctl->desc->pin_base, |
1600 | pin_offset: pin->pin.number, npins: 1); |
1601 | if (ret) |
1602 | goto gpiochip_error; |
1603 | } |
1604 | |
1605 | ret = of_clk_get_parent_count(np: node); |
1606 | clk = devm_clk_get(dev: &pdev->dev, id: ret == 1 ? NULL : "apb" ); |
1607 | if (IS_ERR(ptr: clk)) { |
1608 | ret = PTR_ERR(ptr: clk); |
1609 | goto gpiochip_error; |
1610 | } |
1611 | |
1612 | ret = clk_prepare_enable(clk); |
1613 | if (ret) |
1614 | goto gpiochip_error; |
1615 | |
1616 | pctl->irq = devm_kcalloc(dev: &pdev->dev, |
1617 | n: pctl->desc->irq_banks, |
1618 | size: sizeof(*pctl->irq), |
1619 | GFP_KERNEL); |
1620 | if (!pctl->irq) { |
1621 | ret = -ENOMEM; |
1622 | goto clk_error; |
1623 | } |
1624 | |
1625 | for (i = 0; i < pctl->desc->irq_banks; i++) { |
1626 | pctl->irq[i] = platform_get_irq(pdev, i); |
1627 | if (pctl->irq[i] < 0) { |
1628 | ret = pctl->irq[i]; |
1629 | goto clk_error; |
1630 | } |
1631 | } |
1632 | |
1633 | pctl->domain = irq_domain_add_linear(of_node: node, |
1634 | size: pctl->desc->irq_banks * IRQ_PER_BANK, |
1635 | ops: &sunxi_pinctrl_irq_domain_ops, |
1636 | host_data: pctl); |
1637 | if (!pctl->domain) { |
1638 | dev_err(&pdev->dev, "Couldn't register IRQ domain\n" ); |
1639 | ret = -ENOMEM; |
1640 | goto clk_error; |
1641 | } |
1642 | |
1643 | for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) { |
1644 | int irqno = irq_create_mapping(host: pctl->domain, hwirq: i); |
1645 | |
1646 | irq_set_lockdep_class(irq: irqno, lock_class: &sunxi_pinctrl_irq_lock_class, |
1647 | request_class: &sunxi_pinctrl_irq_request_class); |
1648 | irq_set_chip_and_handler(irq: irqno, chip: &sunxi_pinctrl_edge_irq_chip, |
1649 | handle: handle_edge_irq); |
1650 | irq_set_chip_data(irq: irqno, data: pctl); |
1651 | } |
1652 | |
1653 | for (i = 0; i < pctl->desc->irq_banks; i++) { |
1654 | /* Mask and clear all IRQs before registering a handler */ |
1655 | writel(val: 0, addr: pctl->membase + |
1656 | sunxi_irq_ctrl_reg_from_bank(desc: pctl->desc, bank: i)); |
1657 | writel(val: 0xffffffff, |
1658 | addr: pctl->membase + |
1659 | sunxi_irq_status_reg_from_bank(desc: pctl->desc, bank: i)); |
1660 | |
1661 | irq_set_chained_handler_and_data(irq: pctl->irq[i], |
1662 | handle: sunxi_pinctrl_irq_handler, |
1663 | data: pctl); |
1664 | } |
1665 | |
1666 | sunxi_pinctrl_setup_debounce(pctl, node); |
1667 | |
1668 | dev_info(&pdev->dev, "initialized sunXi PIO driver\n" ); |
1669 | |
1670 | return 0; |
1671 | |
1672 | clk_error: |
1673 | clk_disable_unprepare(clk); |
1674 | gpiochip_error: |
1675 | gpiochip_remove(gc: pctl->chip); |
1676 | return ret; |
1677 | } |
1678 | |