1
2
3
4
5
6#include <linux/mfd/syscon.h>
7#include <linux/platform_device.h>
8#include <linux/slab.h>
9#include <linux/string.h>
10#include "../core.h"
11#include "pinctrl-aspeed.h"
12
13int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
14{
15 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
16
17 return pdata->pinmux.ngroups;
18}
19
20const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
21 unsigned int group)
22{
23 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
24
25 return pdata->pinmux.groups[group].name;
26}
27
28int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
29 unsigned int group, const unsigned int **pins,
30 unsigned int *npins)
31{
32 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
33
34 *pins = &pdata->pinmux.groups[group].pins[0];
35 *npins = pdata->pinmux.groups[group].npins;
36
37 return 0;
38}
39
40void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
41 struct seq_file *s, unsigned int offset)
42{
43 seq_printf(s, " %s", dev_name(pctldev->dev));
44}
45
46int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev)
47{
48 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
49
50 return pdata->pinmux.nfunctions;
51}
52
53const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev,
54 unsigned int function)
55{
56 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
57
58 return pdata->pinmux.functions[function].name;
59}
60
61int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
62 unsigned int function,
63 const char * const **groups,
64 unsigned int * const num_groups)
65{
66 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
67
68 *groups = pdata->pinmux.functions[function].groups;
69 *num_groups = pdata->pinmux.functions[function].ngroups;
70
71 return 0;
72}
73
74static int aspeed_sig_expr_enable(struct aspeed_pinmux_data *ctx,
75 const struct aspeed_sig_expr *expr)
76{
77 int ret;
78
79 pr_debug("Enabling signal %s for %s\n", expr->signal,
80 expr->function);
81
82 ret = aspeed_sig_expr_eval(ctx, expr, true);
83 if (ret < 0)
84 return ret;
85
86 if (!ret)
87 return aspeed_sig_expr_set(ctx, expr, true);
88
89 return 0;
90}
91
92static int aspeed_sig_expr_disable(struct aspeed_pinmux_data *ctx,
93 const struct aspeed_sig_expr *expr)
94{
95 int ret;
96
97 pr_debug("Disabling signal %s for %s\n", expr->signal,
98 expr->function);
99
100 ret = aspeed_sig_expr_eval(ctx, expr, true);
101 if (ret < 0)
102 return ret;
103
104 if (ret)
105 return aspeed_sig_expr_set(ctx, expr, false);
106
107 return 0;
108}
109
110
111
112
113
114
115
116
117
118
119static int aspeed_disable_sig(struct aspeed_pinmux_data *ctx,
120 const struct aspeed_sig_expr **exprs)
121{
122 int ret = 0;
123
124 if (!exprs)
125 return true;
126
127 while (*exprs && !ret) {
128 ret = aspeed_sig_expr_disable(ctx, *exprs);
129 exprs++;
130 }
131
132 return ret;
133}
134
135
136
137
138
139
140
141
142
143
144
145
146static const struct aspeed_sig_expr *aspeed_find_expr_by_name(
147 const struct aspeed_sig_expr **exprs, const char *name)
148{
149 while (*exprs) {
150 if (strcmp((*exprs)->function, name) == 0)
151 return *exprs;
152 exprs++;
153 }
154
155 return NULL;
156}
157
158static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc,
159 const char *(*get)(
160 const struct aspeed_sig_expr *))
161{
162 char *found = NULL;
163 size_t len = 0;
164 const struct aspeed_sig_expr ***prios, **funcs, *expr;
165
166 prios = pdesc->prios;
167
168 while ((funcs = *prios)) {
169 while ((expr = *funcs)) {
170 const char *str = get(expr);
171 size_t delta = strlen(str) + 2;
172 char *expanded;
173
174 expanded = krealloc(found, len + delta + 1, GFP_KERNEL);
175 if (!expanded) {
176 kfree(found);
177 return expanded;
178 }
179
180 found = expanded;
181 found[len] = '\0';
182 len += delta;
183
184 strcat(found, str);
185 strcat(found, ", ");
186
187 funcs++;
188 }
189 prios++;
190 }
191
192 if (len < 2) {
193 kfree(found);
194 return NULL;
195 }
196
197 found[len - 2] = '\0';
198
199 return found;
200}
201
202static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr)
203{
204 return expr->function;
205}
206
207static char *get_defined_functions(const struct aspeed_pin_desc *pdesc)
208{
209 return get_defined_attribute(pdesc, aspeed_sig_expr_function);
210}
211
212static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr)
213{
214 return expr->signal;
215}
216
217static char *get_defined_signals(const struct aspeed_pin_desc *pdesc)
218{
219 return get_defined_attribute(pdesc, aspeed_sig_expr_signal);
220}
221
222int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
223 unsigned int group)
224{
225 int i;
226 int ret;
227 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
228 const struct aspeed_pin_group *pgroup = &pdata->pinmux.groups[group];
229 const struct aspeed_pin_function *pfunc =
230 &pdata->pinmux.functions[function];
231
232 for (i = 0; i < pgroup->npins; i++) {
233 int pin = pgroup->pins[i];
234 const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data;
235 const struct aspeed_sig_expr *expr = NULL;
236 const struct aspeed_sig_expr **funcs;
237 const struct aspeed_sig_expr ***prios;
238
239 if (!pdesc)
240 return -EINVAL;
241
242 pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
243
244 prios = pdesc->prios;
245
246 if (!prios)
247 continue;
248
249
250 while ((funcs = *prios)) {
251 expr = aspeed_find_expr_by_name(funcs, pfunc->name);
252
253 if (expr)
254 break;
255
256 ret = aspeed_disable_sig(&pdata->pinmux, funcs);
257 if (ret)
258 return ret;
259
260 prios++;
261 }
262
263 if (!expr) {
264 char *functions = get_defined_functions(pdesc);
265 char *signals = get_defined_signals(pdesc);
266
267 pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n",
268 pfunc->name, pdesc->name, pin, signals,
269 functions);
270 kfree(signals);
271 kfree(functions);
272
273 return -ENXIO;
274 }
275
276 ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
277 if (ret)
278 return ret;
279
280 pr_debug("Muxed pin %s as %s for %s\n", pdesc->name, expr->signal,
281 expr->function);
282 }
283
284 return 0;
285}
286
287static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
288{
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358 return !strncmp(expr->signal, "GPI", 3) &&
359 !strcmp(expr->signal, expr->function);
360}
361
362static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
363{
364 if (!exprs)
365 return false;
366
367 while (*exprs) {
368 if (aspeed_expr_is_gpio(*exprs))
369 return true;
370 exprs++;
371 }
372
373 return false;
374}
375
376int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
377 struct pinctrl_gpio_range *range,
378 unsigned int offset)
379{
380 int ret;
381 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
382 const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data;
383 const struct aspeed_sig_expr ***prios, **funcs, *expr;
384
385 if (!pdesc)
386 return -EINVAL;
387
388 prios = pdesc->prios;
389
390 if (!prios)
391 return -ENXIO;
392
393 pr_debug("Muxing pin %s for GPIO\n", pdesc->name);
394
395
396 while ((funcs = *prios)) {
397 if (aspeed_gpio_in_exprs(funcs))
398 break;
399
400 ret = aspeed_disable_sig(&pdata->pinmux, funcs);
401 if (ret)
402 return ret;
403
404 prios++;
405 }
406
407 if (!funcs) {
408 char *signals = get_defined_signals(pdesc);
409
410 pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n",
411 pdesc->name, offset, signals);
412 kfree(signals);
413
414 return -ENXIO;
415 }
416
417 expr = *funcs;
418
419
420
421
422
423
424 if (!expr) {
425 pr_debug("Muxed pin %s as GPIO\n", pdesc->name);
426 return 0;
427 }
428
429
430
431
432
433 ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
434 if (ret)
435 return ret;
436
437 pr_debug("Muxed pin %s as %s\n", pdesc->name, expr->signal);
438
439 return 0;
440}
441
442int aspeed_pinctrl_probe(struct platform_device *pdev,
443 struct pinctrl_desc *pdesc,
444 struct aspeed_pinctrl_data *pdata)
445{
446 struct device *parent;
447 struct pinctrl_dev *pctl;
448
449 parent = pdev->dev.parent;
450 if (!parent) {
451 dev_err(&pdev->dev, "No parent for syscon pincontroller\n");
452 return -ENODEV;
453 }
454
455 pdata->scu = syscon_node_to_regmap(parent->of_node);
456 if (IS_ERR(pdata->scu)) {
457 dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
458 return PTR_ERR(pdata->scu);
459 }
460
461 pdata->pinmux.maps[ASPEED_IP_SCU] = pdata->scu;
462
463 pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
464
465 if (IS_ERR(pctl)) {
466 dev_err(&pdev->dev, "Failed to register pinctrl\n");
467 return PTR_ERR(pctl);
468 }
469
470 platform_set_drvdata(pdev, pdata);
471
472 return 0;
473}
474
475static inline bool pin_in_config_range(unsigned int offset,
476 const struct aspeed_pin_config *config)
477{
478 return offset >= config->pins[0] && offset <= config->pins[1];
479}
480
481static inline const struct aspeed_pin_config *find_pinconf_config(
482 const struct aspeed_pinctrl_data *pdata,
483 unsigned int offset,
484 enum pin_config_param param)
485{
486 unsigned int i;
487
488 for (i = 0; i < pdata->nconfigs; i++) {
489 if (param == pdata->configs[i].param &&
490 pin_in_config_range(offset, &pdata->configs[i]))
491 return &pdata->configs[i];
492 }
493
494 return NULL;
495}
496
497enum aspeed_pin_config_map_type { MAP_TYPE_ARG, MAP_TYPE_VAL };
498
499static const struct aspeed_pin_config_map *find_pinconf_map(
500 const struct aspeed_pinctrl_data *pdata,
501 enum pin_config_param param,
502 enum aspeed_pin_config_map_type type,
503 s64 value)
504{
505 int i;
506
507 for (i = 0; i < pdata->nconfmaps; i++) {
508 const struct aspeed_pin_config_map *elem;
509 bool match;
510
511 elem = &pdata->confmaps[i];
512
513 switch (type) {
514 case MAP_TYPE_ARG:
515 match = (elem->arg == -1 || elem->arg == value);
516 break;
517 case MAP_TYPE_VAL:
518 match = (elem->val == value);
519 break;
520 }
521
522 if (param == elem->param && match)
523 return elem;
524 }
525
526 return NULL;
527}
528
529int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
530 unsigned long *config)
531{
532 const enum pin_config_param param = pinconf_to_config_param(*config);
533 const struct aspeed_pin_config_map *pmap;
534 const struct aspeed_pinctrl_data *pdata;
535 const struct aspeed_pin_config *pconf;
536 unsigned int val;
537 int rc = 0;
538 u32 arg;
539
540 pdata = pinctrl_dev_get_drvdata(pctldev);
541 pconf = find_pinconf_config(pdata, offset, param);
542 if (!pconf)
543 return -ENOTSUPP;
544
545 rc = regmap_read(pdata->scu, pconf->reg, &val);
546 if (rc < 0)
547 return rc;
548
549 pmap = find_pinconf_map(pdata, param, MAP_TYPE_VAL,
550 (val & pconf->mask) >> __ffs(pconf->mask));
551
552 if (!pmap)
553 return -EINVAL;
554
555 if (param == PIN_CONFIG_DRIVE_STRENGTH)
556 arg = (u32) pmap->arg;
557 else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
558 arg = !!pmap->arg;
559 else
560 arg = 1;
561
562 if (!arg)
563 return -EINVAL;
564
565 *config = pinconf_to_config_packed(param, arg);
566
567 return 0;
568}
569
570int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
571 unsigned long *configs, unsigned int num_configs)
572{
573 const struct aspeed_pinctrl_data *pdata;
574 unsigned int i;
575 int rc = 0;
576
577 pdata = pinctrl_dev_get_drvdata(pctldev);
578
579 for (i = 0; i < num_configs; i++) {
580 const struct aspeed_pin_config_map *pmap;
581 const struct aspeed_pin_config *pconf;
582 enum pin_config_param param;
583 unsigned int val;
584 u32 arg;
585
586 param = pinconf_to_config_param(configs[i]);
587 arg = pinconf_to_config_argument(configs[i]);
588
589 pconf = find_pinconf_config(pdata, offset, param);
590 if (!pconf)
591 return -ENOTSUPP;
592
593 pmap = find_pinconf_map(pdata, param, MAP_TYPE_ARG, arg);
594
595 if (WARN_ON(!pmap))
596 return -EINVAL;
597
598 val = pmap->val << __ffs(pconf->mask);
599
600 rc = regmap_update_bits(pdata->scu, pconf->reg,
601 pconf->mask, val);
602
603 if (rc < 0)
604 return rc;
605
606 pr_debug("%s: Set SCU%02X[0x%08X]=0x%X for param %d(=%d) on pin %d\n",
607 __func__, pconf->reg, pconf->mask,
608 val, param, arg, offset);
609 }
610
611 return 0;
612}
613
614int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
615 unsigned int selector,
616 unsigned long *config)
617{
618 const unsigned int *pins;
619 unsigned int npins;
620 int rc;
621
622 rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
623 if (rc < 0)
624 return rc;
625
626 if (!npins)
627 return -ENODEV;
628
629 rc = aspeed_pin_config_get(pctldev, pins[0], config);
630
631 return rc;
632}
633
634int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
635 unsigned int selector,
636 unsigned long *configs,
637 unsigned int num_configs)
638{
639 const unsigned int *pins;
640 unsigned int npins;
641 int rc;
642 int i;
643
644 pr_debug("%s: Fetching pins for group selector %d\n",
645 __func__, selector);
646 rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
647 if (rc < 0)
648 return rc;
649
650 for (i = 0; i < npins; i++) {
651 rc = aspeed_pin_config_set(pctldev, pins[i], configs,
652 num_configs);
653 if (rc < 0)
654 return rc;
655 }
656
657 return 0;
658}
659