0001
0002
0003
0004
0005
0006 #include <linux/mfd/syscon.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/slab.h>
0009 #include <linux/string.h>
0010 #include "../core.h"
0011 #include "pinctrl-aspeed.h"
0012
0013 int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
0014 {
0015 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0016
0017 return pdata->pinmux.ngroups;
0018 }
0019
0020 const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
0021 unsigned int group)
0022 {
0023 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0024
0025 return pdata->pinmux.groups[group].name;
0026 }
0027
0028 int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
0029 unsigned int group, const unsigned int **pins,
0030 unsigned int *npins)
0031 {
0032 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0033
0034 *pins = &pdata->pinmux.groups[group].pins[0];
0035 *npins = pdata->pinmux.groups[group].npins;
0036
0037 return 0;
0038 }
0039
0040 void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
0041 struct seq_file *s, unsigned int offset)
0042 {
0043 seq_printf(s, " %s", dev_name(pctldev->dev));
0044 }
0045
0046 int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev)
0047 {
0048 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0049
0050 return pdata->pinmux.nfunctions;
0051 }
0052
0053 const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev,
0054 unsigned int function)
0055 {
0056 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0057
0058 return pdata->pinmux.functions[function].name;
0059 }
0060
0061 int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
0062 unsigned int function,
0063 const char * const **groups,
0064 unsigned int * const num_groups)
0065 {
0066 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0067
0068 *groups = pdata->pinmux.functions[function].groups;
0069 *num_groups = pdata->pinmux.functions[function].ngroups;
0070
0071 return 0;
0072 }
0073
0074 static int aspeed_sig_expr_enable(struct aspeed_pinmux_data *ctx,
0075 const struct aspeed_sig_expr *expr)
0076 {
0077 int ret;
0078
0079 pr_debug("Enabling signal %s for %s\n", expr->signal,
0080 expr->function);
0081
0082 ret = aspeed_sig_expr_eval(ctx, expr, true);
0083 if (ret < 0)
0084 return ret;
0085
0086 if (!ret)
0087 return aspeed_sig_expr_set(ctx, expr, true);
0088
0089 return 0;
0090 }
0091
0092 static int aspeed_sig_expr_disable(struct aspeed_pinmux_data *ctx,
0093 const struct aspeed_sig_expr *expr)
0094 {
0095 int ret;
0096
0097 pr_debug("Disabling signal %s for %s\n", expr->signal,
0098 expr->function);
0099
0100 ret = aspeed_sig_expr_eval(ctx, expr, true);
0101 if (ret < 0)
0102 return ret;
0103
0104 if (ret)
0105 return aspeed_sig_expr_set(ctx, expr, false);
0106
0107 return 0;
0108 }
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 static int aspeed_disable_sig(struct aspeed_pinmux_data *ctx,
0120 const struct aspeed_sig_expr **exprs)
0121 {
0122 int ret = 0;
0123
0124 if (!exprs)
0125 return true;
0126
0127 while (*exprs && !ret) {
0128 ret = aspeed_sig_expr_disable(ctx, *exprs);
0129 exprs++;
0130 }
0131
0132 return ret;
0133 }
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 static const struct aspeed_sig_expr *aspeed_find_expr_by_name(
0147 const struct aspeed_sig_expr **exprs, const char *name)
0148 {
0149 while (*exprs) {
0150 if (strcmp((*exprs)->function, name) == 0)
0151 return *exprs;
0152 exprs++;
0153 }
0154
0155 return NULL;
0156 }
0157
0158 static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc,
0159 const char *(*get)(
0160 const struct aspeed_sig_expr *))
0161 {
0162 char *found = NULL;
0163 size_t len = 0;
0164 const struct aspeed_sig_expr ***prios, **funcs, *expr;
0165
0166 prios = pdesc->prios;
0167
0168 while ((funcs = *prios)) {
0169 while ((expr = *funcs)) {
0170 const char *str = get(expr);
0171 size_t delta = strlen(str) + 2;
0172 char *expanded;
0173
0174 expanded = krealloc(found, len + delta + 1, GFP_KERNEL);
0175 if (!expanded) {
0176 kfree(found);
0177 return expanded;
0178 }
0179
0180 found = expanded;
0181 found[len] = '\0';
0182 len += delta;
0183
0184 strcat(found, str);
0185 strcat(found, ", ");
0186
0187 funcs++;
0188 }
0189 prios++;
0190 }
0191
0192 if (len < 2) {
0193 kfree(found);
0194 return NULL;
0195 }
0196
0197 found[len - 2] = '\0';
0198
0199 return found;
0200 }
0201
0202 static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr)
0203 {
0204 return expr->function;
0205 }
0206
0207 static char *get_defined_functions(const struct aspeed_pin_desc *pdesc)
0208 {
0209 return get_defined_attribute(pdesc, aspeed_sig_expr_function);
0210 }
0211
0212 static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr)
0213 {
0214 return expr->signal;
0215 }
0216
0217 static char *get_defined_signals(const struct aspeed_pin_desc *pdesc)
0218 {
0219 return get_defined_attribute(pdesc, aspeed_sig_expr_signal);
0220 }
0221
0222 int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
0223 unsigned int group)
0224 {
0225 int i;
0226 int ret;
0227 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0228 const struct aspeed_pin_group *pgroup = &pdata->pinmux.groups[group];
0229 const struct aspeed_pin_function *pfunc =
0230 &pdata->pinmux.functions[function];
0231
0232 for (i = 0; i < pgroup->npins; i++) {
0233 int pin = pgroup->pins[i];
0234 const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data;
0235 const struct aspeed_sig_expr *expr = NULL;
0236 const struct aspeed_sig_expr **funcs;
0237 const struct aspeed_sig_expr ***prios;
0238
0239 if (!pdesc)
0240 return -EINVAL;
0241
0242 pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
0243
0244 prios = pdesc->prios;
0245
0246 if (!prios)
0247 continue;
0248
0249
0250 while ((funcs = *prios)) {
0251 expr = aspeed_find_expr_by_name(funcs, pfunc->name);
0252
0253 if (expr)
0254 break;
0255
0256 ret = aspeed_disable_sig(&pdata->pinmux, funcs);
0257 if (ret)
0258 return ret;
0259
0260 prios++;
0261 }
0262
0263 if (!expr) {
0264 char *functions = get_defined_functions(pdesc);
0265 char *signals = get_defined_signals(pdesc);
0266
0267 pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n",
0268 pfunc->name, pdesc->name, pin, signals,
0269 functions);
0270 kfree(signals);
0271 kfree(functions);
0272
0273 return -ENXIO;
0274 }
0275
0276 ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
0277 if (ret)
0278 return ret;
0279
0280 pr_debug("Muxed pin %s as %s for %s\n", pdesc->name, expr->signal,
0281 expr->function);
0282 }
0283
0284 return 0;
0285 }
0286
0287 static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
0288 {
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 return !strncmp(expr->signal, "GPI", 3) &&
0359 !strcmp(expr->signal, expr->function);
0360 }
0361
0362 static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
0363 {
0364 if (!exprs)
0365 return false;
0366
0367 while (*exprs) {
0368 if (aspeed_expr_is_gpio(*exprs))
0369 return true;
0370 exprs++;
0371 }
0372
0373 return false;
0374 }
0375
0376 int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
0377 struct pinctrl_gpio_range *range,
0378 unsigned int offset)
0379 {
0380 int ret;
0381 struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
0382 const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data;
0383 const struct aspeed_sig_expr ***prios, **funcs, *expr;
0384
0385 if (!pdesc)
0386 return -EINVAL;
0387
0388 prios = pdesc->prios;
0389
0390 if (!prios)
0391 return -ENXIO;
0392
0393 pr_debug("Muxing pin %s for GPIO\n", pdesc->name);
0394
0395
0396 while ((funcs = *prios)) {
0397 if (aspeed_gpio_in_exprs(funcs))
0398 break;
0399
0400 ret = aspeed_disable_sig(&pdata->pinmux, funcs);
0401 if (ret)
0402 return ret;
0403
0404 prios++;
0405 }
0406
0407 if (!funcs) {
0408 char *signals = get_defined_signals(pdesc);
0409
0410 pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n",
0411 pdesc->name, offset, signals);
0412 kfree(signals);
0413
0414 return -ENXIO;
0415 }
0416
0417 expr = *funcs;
0418
0419
0420
0421
0422
0423
0424 if (!expr) {
0425 pr_debug("Muxed pin %s as GPIO\n", pdesc->name);
0426 return 0;
0427 }
0428
0429
0430
0431
0432
0433 ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
0434 if (ret)
0435 return ret;
0436
0437 pr_debug("Muxed pin %s as %s\n", pdesc->name, expr->signal);
0438
0439 return 0;
0440 }
0441
0442 int aspeed_pinctrl_probe(struct platform_device *pdev,
0443 struct pinctrl_desc *pdesc,
0444 struct aspeed_pinctrl_data *pdata)
0445 {
0446 struct device *parent;
0447 struct pinctrl_dev *pctl;
0448
0449 parent = pdev->dev.parent;
0450 if (!parent) {
0451 dev_err(&pdev->dev, "No parent for syscon pincontroller\n");
0452 return -ENODEV;
0453 }
0454
0455 pdata->scu = syscon_node_to_regmap(parent->of_node);
0456 if (IS_ERR(pdata->scu)) {
0457 dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
0458 return PTR_ERR(pdata->scu);
0459 }
0460
0461 pdata->pinmux.maps[ASPEED_IP_SCU] = pdata->scu;
0462
0463 pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
0464
0465 if (IS_ERR(pctl)) {
0466 dev_err(&pdev->dev, "Failed to register pinctrl\n");
0467 return PTR_ERR(pctl);
0468 }
0469
0470 platform_set_drvdata(pdev, pdata);
0471
0472 return 0;
0473 }
0474
0475 static inline bool pin_in_config_range(unsigned int offset,
0476 const struct aspeed_pin_config *config)
0477 {
0478 return offset >= config->pins[0] && offset <= config->pins[1];
0479 }
0480
0481 static inline const struct aspeed_pin_config *find_pinconf_config(
0482 const struct aspeed_pinctrl_data *pdata,
0483 unsigned int offset,
0484 enum pin_config_param param)
0485 {
0486 unsigned int i;
0487
0488 for (i = 0; i < pdata->nconfigs; i++) {
0489 if (param == pdata->configs[i].param &&
0490 pin_in_config_range(offset, &pdata->configs[i]))
0491 return &pdata->configs[i];
0492 }
0493
0494 return NULL;
0495 }
0496
0497 enum aspeed_pin_config_map_type { MAP_TYPE_ARG, MAP_TYPE_VAL };
0498
0499 static const struct aspeed_pin_config_map *find_pinconf_map(
0500 const struct aspeed_pinctrl_data *pdata,
0501 enum pin_config_param param,
0502 enum aspeed_pin_config_map_type type,
0503 s64 value)
0504 {
0505 int i;
0506
0507 for (i = 0; i < pdata->nconfmaps; i++) {
0508 const struct aspeed_pin_config_map *elem;
0509 bool match;
0510
0511 elem = &pdata->confmaps[i];
0512
0513 switch (type) {
0514 case MAP_TYPE_ARG:
0515 match = (elem->arg == -1 || elem->arg == value);
0516 break;
0517 case MAP_TYPE_VAL:
0518 match = (elem->val == value);
0519 break;
0520 }
0521
0522 if (param == elem->param && match)
0523 return elem;
0524 }
0525
0526 return NULL;
0527 }
0528
0529 int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
0530 unsigned long *config)
0531 {
0532 const enum pin_config_param param = pinconf_to_config_param(*config);
0533 const struct aspeed_pin_config_map *pmap;
0534 const struct aspeed_pinctrl_data *pdata;
0535 const struct aspeed_pin_config *pconf;
0536 unsigned int val;
0537 int rc = 0;
0538 u32 arg;
0539
0540 pdata = pinctrl_dev_get_drvdata(pctldev);
0541 pconf = find_pinconf_config(pdata, offset, param);
0542 if (!pconf)
0543 return -ENOTSUPP;
0544
0545 rc = regmap_read(pdata->scu, pconf->reg, &val);
0546 if (rc < 0)
0547 return rc;
0548
0549 pmap = find_pinconf_map(pdata, param, MAP_TYPE_VAL,
0550 (val & pconf->mask) >> __ffs(pconf->mask));
0551
0552 if (!pmap)
0553 return -EINVAL;
0554
0555 if (param == PIN_CONFIG_DRIVE_STRENGTH)
0556 arg = (u32) pmap->arg;
0557 else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
0558 arg = !!pmap->arg;
0559 else
0560 arg = 1;
0561
0562 if (!arg)
0563 return -EINVAL;
0564
0565 *config = pinconf_to_config_packed(param, arg);
0566
0567 return 0;
0568 }
0569
0570 int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
0571 unsigned long *configs, unsigned int num_configs)
0572 {
0573 const struct aspeed_pinctrl_data *pdata;
0574 unsigned int i;
0575 int rc = 0;
0576
0577 pdata = pinctrl_dev_get_drvdata(pctldev);
0578
0579 for (i = 0; i < num_configs; i++) {
0580 const struct aspeed_pin_config_map *pmap;
0581 const struct aspeed_pin_config *pconf;
0582 enum pin_config_param param;
0583 unsigned int val;
0584 u32 arg;
0585
0586 param = pinconf_to_config_param(configs[i]);
0587 arg = pinconf_to_config_argument(configs[i]);
0588
0589 pconf = find_pinconf_config(pdata, offset, param);
0590 if (!pconf)
0591 return -ENOTSUPP;
0592
0593 pmap = find_pinconf_map(pdata, param, MAP_TYPE_ARG, arg);
0594
0595 if (WARN_ON(!pmap))
0596 return -EINVAL;
0597
0598 val = pmap->val << __ffs(pconf->mask);
0599
0600 rc = regmap_update_bits(pdata->scu, pconf->reg,
0601 pconf->mask, val);
0602
0603 if (rc < 0)
0604 return rc;
0605
0606 pr_debug("%s: Set SCU%02X[0x%08X]=0x%X for param %d(=%d) on pin %d\n",
0607 __func__, pconf->reg, pconf->mask,
0608 val, param, arg, offset);
0609 }
0610
0611 return 0;
0612 }
0613
0614 int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
0615 unsigned int selector,
0616 unsigned long *config)
0617 {
0618 const unsigned int *pins;
0619 unsigned int npins;
0620 int rc;
0621
0622 rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
0623 if (rc < 0)
0624 return rc;
0625
0626 if (!npins)
0627 return -ENODEV;
0628
0629 rc = aspeed_pin_config_get(pctldev, pins[0], config);
0630
0631 return rc;
0632 }
0633
0634 int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
0635 unsigned int selector,
0636 unsigned long *configs,
0637 unsigned int num_configs)
0638 {
0639 const unsigned int *pins;
0640 unsigned int npins;
0641 int rc;
0642 int i;
0643
0644 pr_debug("%s: Fetching pins for group selector %d\n",
0645 __func__, selector);
0646 rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
0647 if (rc < 0)
0648 return rc;
0649
0650 for (i = 0; i < npins; i++) {
0651 rc = aspeed_pin_config_set(pctldev, pins[i], configs,
0652 num_configs);
0653 if (rc < 0)
0654 return rc;
0655 }
0656
0657 return 0;
0658 }