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 * aspeed_disable_sig() - Disable a signal on a pin by disabling all provided
 112 * signal expressions.
 113 *
 114 * @ctx: The pinmux context
 115 * @exprs: The list of signal expressions (from a priority level on a pin)
 116 *
 117 * Return: 0 if all expressions are disabled, otherwise a negative error code
 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 * aspeed_find_expr_by_name - Search for the signal expression needed to
 137 * enable the pin's signal for the requested function.
 138 *
 139 * @exprs: List of signal expressions (haystack)
 140 * @name: The name of the requested function (needle)
 141 *
 142 * Return: A pointer to the signal expression whose function tag matches the
 143 * provided name, otherwise NULL.
 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                pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
 240
 241                if (!pdesc)
 242                        return -EINVAL;
 243
 244                prios = pdesc->prios;
 245
 246                if (!prios)
 247                        continue;
 248
 249                /* Disable functions at a higher priority than that requested */
 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         * We need to differentiate between GPIO and non-GPIO signals to
 291         * implement the gpio_request_enable() interface. For better or worse
 292         * the ASPEED pinctrl driver uses the expression names to determine
 293         * whether an expression will mux a pin for GPIO.
 294         *
 295         * Generally we have the following - A GPIO such as B1 has:
 296         *
 297         *    - expr->signal set to "GPIOB1"
 298         *    - expr->function set to "GPIOB1"
 299         *
 300         * Using this fact we can determine whether the provided expression is
 301         * a GPIO expression by testing the signal name for the string prefix
 302         * "GPIO".
 303         *
 304         * However, some GPIOs are input-only, and the ASPEED datasheets name
 305         * them differently. An input-only GPIO such as T0 has:
 306         *
 307         *    - expr->signal set to "GPIT0"
 308         *    - expr->function set to "GPIT0"
 309         *
 310         * It's tempting to generalise the prefix test from "GPIO" to "GPI" to
 311         * account for both GPIOs and GPIs, but in doing so we run aground on
 312         * another feature:
 313         *
 314         * Some pins in the ASPEED BMC SoCs have a "pass-through" GPIO
 315         * function where the input state of one pin is replicated as the
 316         * output state of another (as if they were shorted together - a mux
 317         * configuration that is typically enabled by hardware strapping).
 318         * This feature allows the BMC to pass e.g. power button state through
 319         * to the host while the BMC is yet to boot, but take control of the
 320         * button state once the BMC has booted by muxing each pin as a
 321         * separate, pin-specific GPIO.
 322         *
 323         * Conceptually this pass-through mode is a form of GPIO and is named
 324         * as such in the datasheets, e.g. "GPID0". This naming similarity
 325         * trips us up with the simple GPI-prefixed-signal-name scheme
 326         * discussed above, as the pass-through configuration is not what we
 327         * want when muxing a pin as GPIO for the GPIO subsystem.
 328         *
 329         * On e.g. the AST2400, a pass-through function "GPID0" is grouped on
 330         * balls A18 and D16, where we have:
 331         *
 332         *    For ball A18:
 333         *    - expr->signal set to "GPID0IN"
 334         *    - expr->function set to "GPID0"
 335         *
 336         *    For ball D16:
 337         *    - expr->signal set to "GPID0OUT"
 338         *    - expr->function set to "GPID0"
 339         *
 340         * By contrast, the pin-specific GPIO expressions for the same pins are
 341         * as follows:
 342         *
 343         *    For ball A18:
 344         *    - expr->signal looks like "GPIOD0"
 345         *    - expr->function looks like "GPIOD0"
 346         *
 347         *    For ball D16:
 348         *    - expr->signal looks like "GPIOD1"
 349         *    - expr->function looks like "GPIOD1"
 350         *
 351         * Testing both the signal _and_ function names gives us the means
 352         * differentiate the pass-through GPIO pinmux configuration from the
 353         * pin-specific configuration that the GPIO subsystem is after: An
 354         * expression is a pin-specific (non-pass-through) GPIO configuration
 355         * if the signal prefix is "GPI" and the signal name matches the
 356         * function name.
 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        /* Disable any functions of higher priority than GPIO */
 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         * Disabling all higher-priority expressions is enough to enable the
 421         * lowest-priority signal type. As such it has no associated
 422         * expression.
 423         */
 424        if (!expr) {
 425                pr_debug("Muxed pin %s as GPIO\n", pdesc->name);
 426                return 0;
 427        }
 428
 429        /*
 430         * If GPIO is not the lowest priority signal type, assume there is only
 431         * one expression defined to enable the GPIO function
 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