linux/drivers/pinctrl/aspeed/pinctrl-aspeed.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 IBM Corp.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 */
   9
  10#include <linux/mfd/syscon.h>
  11#include <linux/platform_device.h>
  12#include <linux/slab.h>
  13#include <linux/string.h>
  14#include "../core.h"
  15#include "pinctrl-aspeed.h"
  16
  17static const char *const aspeed_pinmux_ips[] = {
  18        [ASPEED_IP_SCU] = "SCU",
  19        [ASPEED_IP_GFX] = "GFX",
  20        [ASPEED_IP_LPC] = "LPC",
  21};
  22
  23int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
  24{
  25        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
  26
  27        return pdata->ngroups;
  28}
  29
  30const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
  31                unsigned int group)
  32{
  33        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
  34
  35        return pdata->groups[group].name;
  36}
  37
  38int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
  39                                  unsigned int group, const unsigned int **pins,
  40                                  unsigned int *npins)
  41{
  42        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
  43
  44        *pins = &pdata->groups[group].pins[0];
  45        *npins = pdata->groups[group].npins;
  46
  47        return 0;
  48}
  49
  50void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
  51                                 struct seq_file *s, unsigned int offset)
  52{
  53        seq_printf(s, " %s", dev_name(pctldev->dev));
  54}
  55
  56int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev)
  57{
  58        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
  59
  60        return pdata->nfunctions;
  61}
  62
  63const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev,
  64                                      unsigned int function)
  65{
  66        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
  67
  68        return pdata->functions[function].name;
  69}
  70
  71int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
  72                                unsigned int function,
  73                                const char * const **groups,
  74                                unsigned int * const num_groups)
  75{
  76        struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
  77
  78        *groups = pdata->functions[function].groups;
  79        *num_groups = pdata->functions[function].ngroups;
  80
  81        return 0;
  82}
  83
  84static inline void aspeed_sig_desc_print_val(
  85                const struct aspeed_sig_desc *desc, bool enable, u32 rv)
  86{
  87        pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n",
  88                        aspeed_pinmux_ips[desc->ip], desc->reg,
  89                        desc->mask, enable ? desc->enable : desc->disable,
  90                        (rv & desc->mask) >> __ffs(desc->mask), rv);
  91}
  92
  93/**
  94 * Query the enabled or disabled state of a signal descriptor
  95 *
  96 * @desc: The signal descriptor of interest
  97 * @enabled: True to query the enabled state, false to query disabled state
  98 * @regmap: The IP block's regmap instance
  99 *
 100 * Return: 1 if the descriptor's bitfield is configured to the state
 101 * selected by @enabled, 0 if not, and less than zero if an unrecoverable
 102 * failure occurred
 103 *
 104 * Evaluation of descriptor state is non-trivial in that it is not a binary
 105 * outcome: The bitfields can be greater than one bit in size and thus can take
 106 * a value that is neither the enabled nor disabled state recorded in the
 107 * descriptor (typically this means a different function to the one of interest
 108 * is enabled). Thus we must explicitly test for either condition as required.
 109 */
 110static int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
 111                                 bool enabled, struct regmap *map)
 112{
 113        int ret;
 114        unsigned int raw;
 115        u32 want;
 116
 117        if (!map)
 118                return -ENODEV;
 119
 120        ret = regmap_read(map, desc->reg, &raw);
 121        if (ret)
 122                return ret;
 123
 124        aspeed_sig_desc_print_val(desc, enabled, raw);
 125        want = enabled ? desc->enable : desc->disable;
 126
 127        return ((raw & desc->mask) >> __ffs(desc->mask)) == want;
 128}
 129
 130/**
 131 * Query the enabled or disabled state for a mux function's signal on a pin
 132 *
 133 * @expr: An expression controlling the signal for a mux function on a pin
 134 * @enabled: True to query the enabled state, false to query disabled state
 135 * @maps: The list of regmap instances
 136 *
 137 * Return: 1 if the expression composed by @enabled evaluates true, 0 if not,
 138 * and less than zero if an unrecoverable failure occurred.
 139 *
 140 * A mux function is enabled or disabled if the function's signal expression
 141 * for each pin in the function's pin group evaluates true for the desired
 142 * state. An signal expression evaluates true if all of its associated signal
 143 * descriptors evaluate true for the desired state.
 144 *
 145 * If an expression's state is described by more than one bit, either through
 146 * multi-bit bitfields in a single signal descriptor or through multiple signal
 147 * descriptors of a single bit then it is possible for the expression to be in
 148 * neither the enabled nor disabled state. Thus we must explicitly test for
 149 * either condition as required.
 150 */
 151static int aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr,
 152                                 bool enabled, struct regmap * const *maps)
 153{
 154        int i;
 155        int ret;
 156
 157        for (i = 0; i < expr->ndescs; i++) {
 158                const struct aspeed_sig_desc *desc = &expr->descs[i];
 159
 160                ret = aspeed_sig_desc_eval(desc, enabled, maps[desc->ip]);
 161                if (ret <= 0)
 162                        return ret;
 163        }
 164
 165        return 1;
 166}
 167
 168/**
 169 * Configure a pin's signal by applying an expression's descriptor state for
 170 * all descriptors in the expression.
 171 *
 172 * @expr: The expression associated with the function whose signal is to be
 173 *        configured
 174 * @enable: true to enable an function's signal through a pin's signal
 175 *          expression, false to disable the function's signal
 176 * @maps: The list of regmap instances for pinmux register access.
 177 *
 178 * Return: 0 if the expression is configured as requested and a negative error
 179 * code otherwise
 180 */
 181static int aspeed_sig_expr_set(const struct aspeed_sig_expr *expr,
 182                                bool enable, struct regmap * const *maps)
 183{
 184        int ret;
 185        int i;
 186
 187        for (i = 0; i < expr->ndescs; i++) {
 188                const struct aspeed_sig_desc *desc = &expr->descs[i];
 189                u32 pattern = enable ? desc->enable : desc->disable;
 190                u32 val = (pattern << __ffs(desc->mask));
 191
 192                if (!maps[desc->ip])
 193                        return -ENODEV;
 194
 195                /*
 196                 * Strap registers are configured in hardware or by early-boot
 197                 * firmware. Treat them as read-only despite that we can write
 198                 * them. This may mean that certain functions cannot be
 199                 * deconfigured and is the reason we re-evaluate after writing
 200                 * all descriptor bits.
 201                 *
 202                 * Port D and port E GPIO loopback modes are the only exception
 203                 * as those are commonly used with front-panel buttons to allow
 204                 * normal operation of the host when the BMC is powered off or
 205                 * fails to boot. Once the BMC has booted, the loopback mode
 206                 * must be disabled for the BMC to control host power-on and
 207                 * reset.
 208                 */
 209                if (desc->ip == ASPEED_IP_SCU && desc->reg == HW_STRAP1 &&
 210                    !(desc->mask & (BIT(21) | BIT(22))))
 211                        continue;
 212
 213                if (desc->ip == ASPEED_IP_SCU && desc->reg == HW_STRAP2)
 214                        continue;
 215
 216                /* On AST2500, Set bits in SCU7C are cleared from SCU70 */
 217                if (desc->ip == ASPEED_IP_SCU && desc->reg == HW_STRAP1) {
 218                        unsigned int rev_id;
 219
 220                        ret = regmap_read(maps[ASPEED_IP_SCU],
 221                                HW_REVISION_ID, &rev_id);
 222                        if (ret < 0)
 223                                return ret;
 224
 225                        if (0x04 == (rev_id >> 24)) {
 226                                u32 value = ~val & desc->mask;
 227
 228                                if (value) {
 229                                        ret = regmap_write(maps[desc->ip],
 230                                                HW_REVISION_ID, value);
 231                                        if (ret < 0)
 232                                                return ret;
 233                                }
 234                        }
 235                }
 236
 237                ret = regmap_update_bits(maps[desc->ip], desc->reg,
 238                                         desc->mask, val);
 239
 240                if (ret)
 241                        return ret;
 242        }
 243
 244        ret = aspeed_sig_expr_eval(expr, enable, maps);
 245        if (ret < 0)
 246                return ret;
 247
 248        if (!ret)
 249                return -EPERM;
 250
 251        return 0;
 252}
 253
 254static int aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr,
 255                                   struct regmap * const *maps)
 256{
 257        int ret;
 258
 259        ret = aspeed_sig_expr_eval(expr, true, maps);
 260        if (ret < 0)
 261                return ret;
 262
 263        if (!ret)
 264                return aspeed_sig_expr_set(expr, true, maps);
 265
 266        return 0;
 267}
 268
 269static int aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr,
 270                                    struct regmap * const *maps)
 271{
 272        int ret;
 273
 274        ret = aspeed_sig_expr_eval(expr, true, maps);
 275        if (ret < 0)
 276                return ret;
 277
 278        if (ret)
 279                return aspeed_sig_expr_set(expr, false, maps);
 280
 281        return 0;
 282}
 283
 284/**
 285 * Disable a signal on a pin by disabling all provided signal expressions.
 286 *
 287 * @exprs: The list of signal expressions (from a priority level on a pin)
 288 * @maps: The list of regmap instances for pinmux register access.
 289 *
 290 * Return: 0 if all expressions are disabled, otherwise a negative error code
 291 */
 292static int aspeed_disable_sig(const struct aspeed_sig_expr **exprs,
 293                               struct regmap * const *maps)
 294{
 295        int ret = 0;
 296
 297        if (!exprs)
 298                return true;
 299
 300        while (*exprs && !ret) {
 301                ret = aspeed_sig_expr_disable(*exprs, maps);
 302                exprs++;
 303        }
 304
 305        return ret;
 306}
 307
 308/**
 309 * Search for the signal expression needed to enable the pin's signal for the
 310 * requested function.
 311 *
 312 * @exprs: List of signal expressions (haystack)
 313 * @name: The name of the requested function (needle)
 314 *
 315 * Return: A pointer to the signal expression whose function tag matches the
 316 * provided name, otherwise NULL.
 317 *
 318 */
 319static const struct aspeed_sig_expr *aspeed_find_expr_by_name(
 320                const struct aspeed_sig_expr **exprs, const char *name)
 321{
 322        while (*exprs) {
 323                if (strcmp((*exprs)->function, name) == 0)
 324                        return *exprs;
 325                exprs++;
 326        }
 327
 328        return NULL;
 329}
 330
 331static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc,
 332                                   const char *(*get)(
 333                                           const struct aspeed_sig_expr *))
 334{
 335        char *found = NULL;
 336        size_t len = 0;
 337        const struct aspeed_sig_expr ***prios, **funcs, *expr;
 338
 339        prios = pdesc->prios;
 340
 341        while ((funcs = *prios)) {
 342                while ((expr = *funcs)) {
 343                        const char *str = get(expr);
 344                        size_t delta = strlen(str) + 2;
 345                        char *expanded;
 346
 347                        expanded = krealloc(found, len + delta + 1, GFP_KERNEL);
 348                        if (!expanded) {
 349                                kfree(found);
 350                                return expanded;
 351                        }
 352
 353                        found = expanded;
 354                        found[len] = '\0';
 355                        len += delta;
 356
 357                        strcat(found, str);
 358                        strcat(found, ", ");
 359
 360                        funcs++;
 361                }
 362                prios++;
 363        }
 364
 365        if (len < 2) {
 366                kfree(found);
 367                return NULL;
 368        }
 369
 370        found[len - 2] = '\0';
 371
 372        return found;
 373}
 374
 375static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr)
 376{
 377        return expr->function;
 378}
 379
 380static char *get_defined_functions(const struct aspeed_pin_desc *pdesc)
 381{
 382        return get_defined_attribute(pdesc, aspeed_sig_expr_function);
 383}
 384
 385static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr)
 386{
 387        return expr->signal;
 388}
 389
 390static char *get_defined_signals(const struct aspeed_pin_desc *pdesc)
 391{
 392        return get_defined_attribute(pdesc, aspeed_sig_expr_signal);
 393}
 394
 395int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
 396                          unsigned int group)
 397{
 398        int i;
 399        int ret;
 400        const struct aspeed_pinctrl_data *pdata =
 401                pinctrl_dev_get_drvdata(pctldev);
 402        const struct aspeed_pin_group *pgroup = &pdata->groups[group];
 403        const struct aspeed_pin_function *pfunc =
 404                &pdata->functions[function];
 405
 406        for (i = 0; i < pgroup->npins; i++) {
 407                int pin = pgroup->pins[i];
 408                const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data;
 409                const struct aspeed_sig_expr *expr = NULL;
 410                const struct aspeed_sig_expr **funcs;
 411                const struct aspeed_sig_expr ***prios;
 412
 413                pr_debug("Muxing pin %d for %s\n", pin, pfunc->name);
 414
 415                if (!pdesc)
 416                        return -EINVAL;
 417
 418                prios = pdesc->prios;
 419
 420                if (!prios)
 421                        continue;
 422
 423                /* Disable functions at a higher priority than that requested */
 424                while ((funcs = *prios)) {
 425                        expr = aspeed_find_expr_by_name(funcs, pfunc->name);
 426
 427                        if (expr)
 428                                break;
 429
 430                        ret = aspeed_disable_sig(funcs, pdata->maps);
 431                        if (ret)
 432                                return ret;
 433
 434                        prios++;
 435                }
 436
 437                if (!expr) {
 438                        char *functions = get_defined_functions(pdesc);
 439                        char *signals = get_defined_signals(pdesc);
 440
 441                        pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n",
 442                                pfunc->name, pdesc->name, pin, signals,
 443                                functions);
 444                        kfree(signals);
 445                        kfree(functions);
 446
 447                        return -ENXIO;
 448                }
 449
 450                ret = aspeed_sig_expr_enable(expr, pdata->maps);
 451                if (ret)
 452                        return ret;
 453        }
 454
 455        return 0;
 456}
 457
 458static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
 459{
 460        /*
 461         * The signal type is GPIO if the signal name has "GPIO" as a prefix.
 462         * strncmp (rather than strcmp) is used to implement the prefix
 463         * requirement.
 464         *
 465         * expr->signal might look like "GPIOT3" in the GPIO case.
 466         */
 467        return strncmp(expr->signal, "GPIO", 4) == 0;
 468}
 469
 470static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
 471{
 472        if (!exprs)
 473                return false;
 474
 475        while (*exprs) {
 476                if (aspeed_expr_is_gpio(*exprs))
 477                        return true;
 478                exprs++;
 479        }
 480
 481        return false;
 482}
 483
 484int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
 485                               struct pinctrl_gpio_range *range,
 486                               unsigned int offset)
 487{
 488        int ret;
 489        const struct aspeed_pinctrl_data *pdata =
 490                pinctrl_dev_get_drvdata(pctldev);
 491        const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data;
 492        const struct aspeed_sig_expr ***prios, **funcs, *expr;
 493
 494        if (!pdesc)
 495                return -EINVAL;
 496
 497        prios = pdesc->prios;
 498
 499        if (!prios)
 500                return -ENXIO;
 501
 502        /* Disable any functions of higher priority than GPIO */
 503        while ((funcs = *prios)) {
 504                if (aspeed_gpio_in_exprs(funcs))
 505                        break;
 506
 507                ret = aspeed_disable_sig(funcs, pdata->maps);
 508                if (ret)
 509                        return ret;
 510
 511                prios++;
 512        }
 513
 514        if (!funcs) {
 515                char *signals = get_defined_signals(pdesc);
 516
 517                pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n",
 518                        pdesc->name, offset, signals);
 519                kfree(signals);
 520
 521                return -ENXIO;
 522        }
 523
 524        expr = *funcs;
 525
 526        /*
 527         * Disabling all higher-priority expressions is enough to enable the
 528         * lowest-priority signal type. As such it has no associated
 529         * expression.
 530         */
 531        if (!expr)
 532                return 0;
 533
 534        /*
 535         * If GPIO is not the lowest priority signal type, assume there is only
 536         * one expression defined to enable the GPIO function
 537         */
 538        return aspeed_sig_expr_enable(expr, pdata->maps);
 539}
 540
 541int aspeed_pinctrl_probe(struct platform_device *pdev,
 542                         struct pinctrl_desc *pdesc,
 543                         struct aspeed_pinctrl_data *pdata)
 544{
 545        struct device *parent;
 546        struct pinctrl_dev *pctl;
 547
 548        parent = pdev->dev.parent;
 549        if (!parent) {
 550                dev_err(&pdev->dev, "No parent for syscon pincontroller\n");
 551                return -ENODEV;
 552        }
 553
 554        pdata->maps[ASPEED_IP_SCU] = syscon_node_to_regmap(parent->of_node);
 555        if (IS_ERR(pdata->maps[ASPEED_IP_SCU])) {
 556                dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
 557                return PTR_ERR(pdata->maps[ASPEED_IP_SCU]);
 558        }
 559
 560        pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
 561
 562        if (IS_ERR(pctl)) {
 563                dev_err(&pdev->dev, "Failed to register pinctrl\n");
 564                return PTR_ERR(pctl);
 565        }
 566
 567        platform_set_drvdata(pdev, pdata);
 568
 569        return 0;
 570}
 571
 572static inline bool pin_in_config_range(unsigned int offset,
 573                const struct aspeed_pin_config *config)
 574{
 575        return offset >= config->pins[0] && offset <= config->pins[1];
 576}
 577
 578static inline const struct aspeed_pin_config *find_pinconf_config(
 579                const struct aspeed_pinctrl_data *pdata,
 580                unsigned int offset,
 581                enum pin_config_param param)
 582{
 583        unsigned int i;
 584
 585        for (i = 0; i < pdata->nconfigs; i++) {
 586                if (param == pdata->configs[i].param &&
 587                                pin_in_config_range(offset, &pdata->configs[i]))
 588                        return &pdata->configs[i];
 589        }
 590
 591        return NULL;
 592}
 593
 594/**
 595 * @param: pinconf configuration parameter
 596 * @arg: The supported argument for @param, or -1 if any value is supported
 597 * @value: The register value to write to configure @arg for @param
 598 *
 599 * The map is to be used in conjunction with the configuration array supplied
 600 * by the driver implementation.
 601 */
 602struct aspeed_pin_config_map {
 603        enum pin_config_param param;
 604        s32 arg;
 605        u32 val;
 606};
 607
 608enum aspeed_pin_config_map_type { MAP_TYPE_ARG, MAP_TYPE_VAL };
 609
 610/* Aspeed consistently both:
 611 *
 612 * 1. Defines "disable bits" for internal pull-downs
 613 * 2. Uses 8mA or 16mA drive strengths
 614 */
 615static const struct aspeed_pin_config_map pin_config_map[] = {
 616        { PIN_CONFIG_BIAS_PULL_DOWN,  0, 1 },
 617        { PIN_CONFIG_BIAS_PULL_DOWN, -1, 0 },
 618        { PIN_CONFIG_BIAS_DISABLE,   -1, 1 },
 619        { PIN_CONFIG_DRIVE_STRENGTH,  8, 0 },
 620        { PIN_CONFIG_DRIVE_STRENGTH, 16, 1 },
 621};
 622
 623static const struct aspeed_pin_config_map *find_pinconf_map(
 624                enum pin_config_param param,
 625                enum aspeed_pin_config_map_type type,
 626                s64 value)
 627{
 628        int i;
 629
 630        for (i = 0; i < ARRAY_SIZE(pin_config_map); i++) {
 631                const struct aspeed_pin_config_map *elem;
 632                bool match;
 633
 634                elem = &pin_config_map[i];
 635
 636                switch (type) {
 637                case MAP_TYPE_ARG:
 638                        match = (elem->arg == -1 || elem->arg == value);
 639                        break;
 640                case MAP_TYPE_VAL:
 641                        match = (elem->val == value);
 642                        break;
 643                }
 644
 645                if (param == elem->param && match)
 646                        return elem;
 647        }
 648
 649        return NULL;
 650}
 651
 652int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
 653                unsigned long *config)
 654{
 655        const enum pin_config_param param = pinconf_to_config_param(*config);
 656        const struct aspeed_pin_config_map *pmap;
 657        const struct aspeed_pinctrl_data *pdata;
 658        const struct aspeed_pin_config *pconf;
 659        unsigned int val;
 660        int rc = 0;
 661        u32 arg;
 662
 663        pdata = pinctrl_dev_get_drvdata(pctldev);
 664        pconf = find_pinconf_config(pdata, offset, param);
 665        if (!pconf)
 666                return -ENOTSUPP;
 667
 668        rc = regmap_read(pdata->maps[ASPEED_IP_SCU], pconf->reg, &val);
 669        if (rc < 0)
 670                return rc;
 671
 672        pmap = find_pinconf_map(param, MAP_TYPE_VAL,
 673                        (val & BIT(pconf->bit)) >> pconf->bit);
 674
 675        if (!pmap)
 676                return -EINVAL;
 677
 678        if (param == PIN_CONFIG_DRIVE_STRENGTH)
 679                arg = (u32) pmap->arg;
 680        else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
 681                arg = !!pmap->arg;
 682        else
 683                arg = 1;
 684
 685        if (!arg)
 686                return -EINVAL;
 687
 688        *config = pinconf_to_config_packed(param, arg);
 689
 690        return 0;
 691}
 692
 693int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
 694                unsigned long *configs, unsigned int num_configs)
 695{
 696        const struct aspeed_pinctrl_data *pdata;
 697        unsigned int i;
 698        int rc = 0;
 699
 700        pdata = pinctrl_dev_get_drvdata(pctldev);
 701
 702        for (i = 0; i < num_configs; i++) {
 703                const struct aspeed_pin_config_map *pmap;
 704                const struct aspeed_pin_config *pconf;
 705                enum pin_config_param param;
 706                unsigned int val;
 707                u32 arg;
 708
 709                param = pinconf_to_config_param(configs[i]);
 710                arg = pinconf_to_config_argument(configs[i]);
 711
 712                pconf = find_pinconf_config(pdata, offset, param);
 713                if (!pconf)
 714                        return -ENOTSUPP;
 715
 716                pmap = find_pinconf_map(param, MAP_TYPE_ARG, arg);
 717
 718                if (unlikely(WARN_ON(!pmap)))
 719                        return -EINVAL;
 720
 721                val = pmap->val << pconf->bit;
 722
 723                rc = regmap_update_bits(pdata->maps[ASPEED_IP_SCU], pconf->reg,
 724                                BIT(pconf->bit), val);
 725
 726                if (rc < 0)
 727                        return rc;
 728
 729                pr_debug("%s: Set SCU%02X[%d]=%d for param %d(=%d) on pin %d\n",
 730                                __func__, pconf->reg, pconf->bit, pmap->val,
 731                                param, arg, offset);
 732        }
 733
 734        return 0;
 735}
 736
 737int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
 738                unsigned int selector,
 739                unsigned long *config)
 740{
 741        const unsigned int *pins;
 742        unsigned int npins;
 743        int rc;
 744
 745        rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
 746        if (rc < 0)
 747                return rc;
 748
 749        if (!npins)
 750                return -ENODEV;
 751
 752        rc = aspeed_pin_config_get(pctldev, pins[0], config);
 753
 754        return rc;
 755}
 756
 757int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
 758                unsigned int selector,
 759                unsigned long *configs,
 760                unsigned int num_configs)
 761{
 762        const unsigned int *pins;
 763        unsigned int npins;
 764        int rc;
 765        int i;
 766
 767        pr_debug("%s: Fetching pins for group selector %d\n",
 768                        __func__, selector);
 769        rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
 770        if (rc < 0)
 771                return rc;
 772
 773        for (i = 0; i < npins; i++) {
 774                rc = aspeed_pin_config_set(pctldev, pins[i], configs,
 775                                num_configs);
 776                if (rc < 0)
 777                        return rc;
 778        }
 779
 780        return 0;
 781}
 782