linux/drivers/pinctrl/aspeed/pinctrl-aspeed.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2016 IBM Corp.
   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 * Disable a signal on a pin by disabling all provided signal expressions.
 112 *
 113 * @ctx: The pinmux context
 114 * @exprs: The list of signal expressions (from a priority level on a pin)
 115 *
 116 * Return: 0 if all expressions are disabled, otherwise a negative error code
 117 */
 118static int aspeed_disable_sig(struct aspeed_pinmux_data *ctx,
 119                              const struct aspeed_sig_expr **exprs)
 120{
 121        int ret = 0;
 122
 123        if (!exprs)
 124                return true;
 125
 126        while (*exprs && !ret) {
 127                ret = aspeed_sig_expr_disable(ctx, *exprs);
 128                exprs++;
 129        }
 130
 131        return ret;
 132}
 133
 134/**
 135 * Search for the signal expression needed to enable the pin's signal for the
 136 * requested function.
 137 *
 138 * @exprs: List of signal expressions (haystack)
 139 * @name: The name of the requested function (needle)
 140 *
 141 * Return: A pointer to the signal expression whose function tag matches the
 142 * provided name, otherwise NULL.
 143 *
 144 */
 145static const struct aspeed_sig_expr *aspeed_find_expr_by_name(
 146                const struct aspeed_sig_expr **exprs, const char *name)
 147{
 148        while (*exprs) {
 149                if (strcmp((*exprs)->function, name) == 0)
 150                        return *exprs;
 151                exprs++;
 152        }
 153
 154        return NULL;
 155}
 156
 157static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc,
 158                                   const char *(*get)(
 159                                           const struct aspeed_sig_expr *))
 160{
 161        char *found = NULL;
 162        size_t len = 0;
 163        const struct aspeed_sig_expr ***prios, **funcs, *expr;
 164
 165        prios = pdesc->prios;
 166
 167        while ((funcs = *prios)) {
 168                while ((expr = *funcs)) {
 169                        const char *str = get(expr);
 170                        size_t delta = strlen(str) + 2;
 171                        char *expanded;
 172
 173                        expanded = krealloc(found, len + delta + 1, GFP_KERNEL);
 174                        if (!expanded) {
 175                                kfree(found);
 176                                return expanded;
 177                        }
 178
 179                        found = expanded;
 180                        found[len] = '\0';
 181                        len += delta;
 182
 183                        strcat(found, str);
 184                        strcat(found, ", ");
 185
 186                        funcs++;
 187                }
 188                prios++;
 189        }
 190
 191        if (len < 2) {
 192                kfree(found);
 193                return NULL;
 194        }
 195
 196        found[len - 2] = '\0';
 197
 198        return found;
 199}
 200
 201static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr)
 202{
 203        return expr->function;
 204}
 205
 206static char *get_defined_functions(const struct aspeed_pin_desc *pdesc)
 207{
 208        return get_defined_attribute(pdesc, aspeed_sig_expr_function);
 209}
 210
 211static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr)
 212{
 213        return expr->signal;
 214}
 215
 216static char *get_defined_signals(const struct aspeed_pin_desc *pdesc)
 217{
 218        return get_defined_attribute(pdesc, aspeed_sig_expr_signal);
 219}
 220
 221int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
 222                          unsigned int group)
 223{
 224        int i;
 225        int ret;
 226        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 227        const struct aspeed_pin_group *pgroup = &pdata->pinmux.groups[group];
 228        const struct aspeed_pin_function *pfunc =
 229                &pdata->pinmux.functions[function];
 230
 231        for (i = 0; i < pgroup->npins; i++) {
 232                int pin = pgroup->pins[i];
 233                const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data;
 234                const struct aspeed_sig_expr *expr = NULL;
 235                const struct aspeed_sig_expr **funcs;
 236                const struct aspeed_sig_expr ***prios;
 237
 238                pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
 239
 240                if (!pdesc)
 241                        return -EINVAL;
 242
 243                prios = pdesc->prios;
 244
 245                if (!prios)
 246                        continue;
 247
 248                /* Disable functions at a higher priority than that requested */
 249                while ((funcs = *prios)) {
 250                        expr = aspeed_find_expr_by_name(funcs, pfunc->name);
 251
 252                        if (expr)
 253                                break;
 254
 255                        ret = aspeed_disable_sig(&pdata->pinmux, funcs);
 256                        if (ret)
 257                                return ret;
 258
 259                        prios++;
 260                }
 261
 262                if (!expr) {
 263                        char *functions = get_defined_functions(pdesc);
 264                        char *signals = get_defined_signals(pdesc);
 265
 266                        pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n",
 267                                pfunc->name, pdesc->name, pin, signals,
 268                                functions);
 269                        kfree(signals);
 270                        kfree(functions);
 271
 272                        return -ENXIO;
 273                }
 274
 275                ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
 276                if (ret)
 277                        return ret;
 278
 279                pr_debug("Muxed pin %s as %s for %s\n", pdesc->name, expr->signal,
 280                         expr->function);
 281        }
 282
 283        return 0;
 284}
 285
 286static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
 287{
 288        /*
 289         * The signal type is GPIO if the signal name has "GPIO" as a prefix.
 290         * strncmp (rather than strcmp) is used to implement the prefix
 291         * requirement.
 292         *
 293         * expr->signal might look like "GPIOT3" in the GPIO case.
 294         */
 295        return strncmp(expr->signal, "GPIO", 4) == 0;
 296}
 297
 298static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
 299{
 300        if (!exprs)
 301                return false;
 302
 303        while (*exprs) {
 304                if (aspeed_expr_is_gpio(*exprs))
 305                        return true;
 306                exprs++;
 307        }
 308
 309        return false;
 310}
 311
 312int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
 313                               struct pinctrl_gpio_range *range,
 314                               unsigned int offset)
 315{
 316        int ret;
 317        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
 318        const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data;
 319        const struct aspeed_sig_expr ***prios, **funcs, *expr;
 320
 321        if (!pdesc)
 322                return -EINVAL;
 323
 324        prios = pdesc->prios;
 325
 326        if (!prios)
 327                return -ENXIO;
 328
 329        pr_debug("Muxing pin %s for GPIO\n", pdesc->name);
 330
 331        /* Disable any functions of higher priority than GPIO */
 332        while ((funcs = *prios)) {
 333                if (aspeed_gpio_in_exprs(funcs))
 334                        break;
 335
 336                ret = aspeed_disable_sig(&pdata->pinmux, funcs);
 337                if (ret)
 338                        return ret;
 339
 340                prios++;
 341        }
 342
 343        if (!funcs) {
 344                char *signals = get_defined_signals(pdesc);
 345
 346                pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n",
 347                        pdesc->name, offset, signals);
 348                kfree(signals);
 349
 350                return -ENXIO;
 351        }
 352
 353        expr = *funcs;
 354
 355        /*
 356         * Disabling all higher-priority expressions is enough to enable the
 357         * lowest-priority signal type. As such it has no associated
 358         * expression.
 359         */
 360        if (!expr) {
 361                pr_debug("Muxed pin %s as GPIO\n", pdesc->name);
 362                return 0;
 363        }
 364
 365        /*
 366         * If GPIO is not the lowest priority signal type, assume there is only
 367         * one expression defined to enable the GPIO function
 368         */
 369        ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
 370        if (ret)
 371                return ret;
 372
 373        pr_debug("Muxed pin %s as %s\n", pdesc->name, expr->signal);
 374
 375        return 0;
 376}
 377
 378int aspeed_pinctrl_probe(struct platform_device *pdev,
 379                         struct pinctrl_desc *pdesc,
 380                         struct aspeed_pinctrl_data *pdata)
 381{
 382        struct device *parent;
 383        struct pinctrl_dev *pctl;
 384
 385        parent = pdev->dev.parent;
 386        if (!parent) {
 387                dev_err(&pdev->dev, "No parent for syscon pincontroller\n");
 388                return -ENODEV;
 389        }
 390
 391        pdata->scu = syscon_node_to_regmap(parent->of_node);
 392        if (IS_ERR(pdata->scu)) {
 393                dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
 394                return PTR_ERR(pdata->scu);
 395        }
 396
 397        pdata->pinmux.maps[ASPEED_IP_SCU] = pdata->scu;
 398
 399        pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
 400
 401        if (IS_ERR(pctl)) {
 402                dev_err(&pdev->dev, "Failed to register pinctrl\n");
 403                return PTR_ERR(pctl);
 404        }
 405
 406        platform_set_drvdata(pdev, pdata);
 407
 408        return 0;
 409}
 410
 411static inline bool pin_in_config_range(unsigned int offset,
 412                const struct aspeed_pin_config *config)
 413{
 414        return offset >= config->pins[0] && offset <= config->pins[1];
 415}
 416
 417static inline const struct aspeed_pin_config *find_pinconf_config(
 418                const struct aspeed_pinctrl_data *pdata,
 419                unsigned int offset,
 420                enum pin_config_param param)
 421{
 422        unsigned int i;
 423
 424        for (i = 0; i < pdata->nconfigs; i++) {
 425                if (param == pdata->configs[i].param &&
 426                                pin_in_config_range(offset, &pdata->configs[i]))
 427                        return &pdata->configs[i];
 428        }
 429
 430        return NULL;
 431}
 432
 433enum aspeed_pin_config_map_type { MAP_TYPE_ARG, MAP_TYPE_VAL };
 434
 435static const struct aspeed_pin_config_map *find_pinconf_map(
 436                const struct aspeed_pinctrl_data *pdata,
 437                enum pin_config_param param,
 438                enum aspeed_pin_config_map_type type,
 439                s64 value)
 440{
 441        int i;
 442
 443        for (i = 0; i < pdata->nconfmaps; i++) {
 444                const struct aspeed_pin_config_map *elem;
 445                bool match;
 446
 447                elem = &pdata->confmaps[i];
 448
 449                switch (type) {
 450                case MAP_TYPE_ARG:
 451                        match = (elem->arg == -1 || elem->arg == value);
 452                        break;
 453                case MAP_TYPE_VAL:
 454                        match = (elem->val == value);
 455                        break;
 456                }
 457
 458                if (param == elem->param && match)
 459                        return elem;
 460        }
 461
 462        return NULL;
 463}
 464
 465int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
 466                unsigned long *config)
 467{
 468        const enum pin_config_param param = pinconf_to_config_param(*config);
 469        const struct aspeed_pin_config_map *pmap;
 470        const struct aspeed_pinctrl_data *pdata;
 471        const struct aspeed_pin_config *pconf;
 472        unsigned int val;
 473        int rc = 0;
 474        u32 arg;
 475
 476        pdata = pinctrl_dev_get_drvdata(pctldev);
 477        pconf = find_pinconf_config(pdata, offset, param);
 478        if (!pconf)
 479                return -ENOTSUPP;
 480
 481        rc = regmap_read(pdata->scu, pconf->reg, &val);
 482        if (rc < 0)
 483                return rc;
 484
 485        pmap = find_pinconf_map(pdata, param, MAP_TYPE_VAL,
 486                        (val & pconf->mask) >> __ffs(pconf->mask));
 487
 488        if (!pmap)
 489                return -EINVAL;
 490
 491        if (param == PIN_CONFIG_DRIVE_STRENGTH)
 492                arg = (u32) pmap->arg;
 493        else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
 494                arg = !!pmap->arg;
 495        else
 496                arg = 1;
 497
 498        if (!arg)
 499                return -EINVAL;
 500
 501        *config = pinconf_to_config_packed(param, arg);
 502
 503        return 0;
 504}
 505
 506int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
 507                unsigned long *configs, unsigned int num_configs)
 508{
 509        const struct aspeed_pinctrl_data *pdata;
 510        unsigned int i;
 511        int rc = 0;
 512
 513        pdata = pinctrl_dev_get_drvdata(pctldev);
 514
 515        for (i = 0; i < num_configs; i++) {
 516                const struct aspeed_pin_config_map *pmap;
 517                const struct aspeed_pin_config *pconf;
 518                enum pin_config_param param;
 519                unsigned int val;
 520                u32 arg;
 521
 522                param = pinconf_to_config_param(configs[i]);
 523                arg = pinconf_to_config_argument(configs[i]);
 524
 525                pconf = find_pinconf_config(pdata, offset, param);
 526                if (!pconf)
 527                        return -ENOTSUPP;
 528
 529                pmap = find_pinconf_map(pdata, param, MAP_TYPE_ARG, arg);
 530
 531                if (WARN_ON(!pmap))
 532                        return -EINVAL;
 533
 534                val = pmap->val << __ffs(pconf->mask);
 535
 536                rc = regmap_update_bits(pdata->scu, pconf->reg,
 537                                        pmap->mask, val);
 538
 539                if (rc < 0)
 540                        return rc;
 541
 542                pr_debug("%s: Set SCU%02X[%lu]=%d for param %d(=%d) on pin %d\n",
 543                                __func__, pconf->reg, __ffs(pconf->mask),
 544                                pmap->val, param, arg, offset);
 545        }
 546
 547        return 0;
 548}
 549
 550int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
 551                unsigned int selector,
 552                unsigned long *config)
 553{
 554        const unsigned int *pins;
 555        unsigned int npins;
 556        int rc;
 557
 558        rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
 559        if (rc < 0)
 560                return rc;
 561
 562        if (!npins)
 563                return -ENODEV;
 564
 565        rc = aspeed_pin_config_get(pctldev, pins[0], config);
 566
 567        return rc;
 568}
 569
 570int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
 571                unsigned int selector,
 572                unsigned long *configs,
 573                unsigned int num_configs)
 574{
 575        const unsigned int *pins;
 576        unsigned int npins;
 577        int rc;
 578        int i;
 579
 580        pr_debug("%s: Fetching pins for group selector %d\n",
 581                        __func__, selector);
 582        rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
 583        if (rc < 0)
 584                return rc;
 585
 586        for (i = 0; i < npins; i++) {
 587                rc = aspeed_pin_config_set(pctldev, pins[i], configs,
 588                                num_configs);
 589                if (rc < 0)
 590                        return rc;
 591        }
 592
 593        return 0;
 594}
 595