linux/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// Copyright (C) 2015-2017 Socionext Inc.
   4//   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
   5
   6#include <linux/list.h>
   7#include <linux/mfd/syscon.h>
   8#include <linux/of.h>
   9#include <linux/pinctrl/pinconf.h>
  10#include <linux/pinctrl/pinconf-generic.h>
  11#include <linux/pinctrl/pinctrl.h>
  12#include <linux/pinctrl/pinmux.h>
  13#include <linux/platform_device.h>
  14#include <linux/regmap.h>
  15
  16#include "../core.h"
  17#include "../pinctrl-utils.h"
  18#include "pinctrl-uniphier.h"
  19
  20#define UNIPHIER_PINCTRL_PINMUX_BASE    0x1000
  21#define UNIPHIER_PINCTRL_LOAD_PINMUX    0x1700
  22#define UNIPHIER_PINCTRL_DRVCTRL_BASE   0x1800
  23#define UNIPHIER_PINCTRL_DRV2CTRL_BASE  0x1900
  24#define UNIPHIER_PINCTRL_DRV3CTRL_BASE  0x1980
  25#define UNIPHIER_PINCTRL_PUPDCTRL_BASE  0x1a00
  26#define UNIPHIER_PINCTRL_IECTRL_BASE    0x1d00
  27
  28struct uniphier_pinctrl_reg_region {
  29        struct list_head node;
  30        unsigned int base;
  31        unsigned int nregs;
  32        u32 vals[];
  33};
  34
  35struct uniphier_pinctrl_priv {
  36        struct pinctrl_desc pctldesc;
  37        struct pinctrl_dev *pctldev;
  38        struct regmap *regmap;
  39        const struct uniphier_pinctrl_socdata *socdata;
  40        struct list_head reg_regions;
  41};
  42
  43static int uniphier_pctl_get_groups_count(struct pinctrl_dev *pctldev)
  44{
  45        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  46
  47        return priv->socdata->groups_count;
  48}
  49
  50static const char *uniphier_pctl_get_group_name(struct pinctrl_dev *pctldev,
  51                                                unsigned selector)
  52{
  53        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  54
  55        return priv->socdata->groups[selector].name;
  56}
  57
  58static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev,
  59                                        unsigned selector,
  60                                        const unsigned **pins,
  61                                        unsigned *num_pins)
  62{
  63        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
  64
  65        *pins = priv->socdata->groups[selector].pins;
  66        *num_pins = priv->socdata->groups[selector].num_pins;
  67
  68        return 0;
  69}
  70
  71#ifdef CONFIG_DEBUG_FS
  72static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
  73                                       struct seq_file *s, unsigned offset)
  74{
  75        const struct pin_desc *desc = pin_desc_get(pctldev, offset);
  76        const char *pull_dir, *drv_type;
  77
  78        switch (uniphier_pin_get_pull_dir(desc->drv_data)) {
  79        case UNIPHIER_PIN_PULL_UP:
  80                pull_dir = "UP";
  81                break;
  82        case UNIPHIER_PIN_PULL_DOWN:
  83                pull_dir = "DOWN";
  84                break;
  85        case UNIPHIER_PIN_PULL_UP_FIXED:
  86                pull_dir = "UP(FIXED)";
  87                break;
  88        case UNIPHIER_PIN_PULL_DOWN_FIXED:
  89                pull_dir = "DOWN(FIXED)";
  90                break;
  91        case UNIPHIER_PIN_PULL_NONE:
  92                pull_dir = "NONE";
  93                break;
  94        default:
  95                BUG();
  96        }
  97
  98        switch (uniphier_pin_get_drv_type(desc->drv_data)) {
  99        case UNIPHIER_PIN_DRV_1BIT:
 100                drv_type = "4/8(mA)";
 101                break;
 102        case UNIPHIER_PIN_DRV_2BIT:
 103                drv_type = "8/12/16/20(mA)";
 104                break;
 105        case UNIPHIER_PIN_DRV_3BIT:
 106                drv_type = "4/5/7/9/11/12/14/16(mA)";
 107                break;
 108        case UNIPHIER_PIN_DRV_FIXED4:
 109                drv_type = "4(mA)";
 110                break;
 111        case UNIPHIER_PIN_DRV_FIXED5:
 112                drv_type = "5(mA)";
 113                break;
 114        case UNIPHIER_PIN_DRV_FIXED8:
 115                drv_type = "8(mA)";
 116                break;
 117        case UNIPHIER_PIN_DRV_NONE:
 118                drv_type = "NONE";
 119                break;
 120        default:
 121                BUG();
 122        }
 123
 124        seq_printf(s, " PULL_DIR=%s  DRV_TYPE=%s", pull_dir, drv_type);
 125}
 126#endif
 127
 128static const struct pinctrl_ops uniphier_pctlops = {
 129        .get_groups_count = uniphier_pctl_get_groups_count,
 130        .get_group_name = uniphier_pctl_get_group_name,
 131        .get_group_pins = uniphier_pctl_get_group_pins,
 132#ifdef CONFIG_DEBUG_FS
 133        .pin_dbg_show = uniphier_pctl_pin_dbg_show,
 134#endif
 135        .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
 136        .dt_free_map = pinctrl_utils_free_map,
 137};
 138
 139static const unsigned int uniphier_conf_drv_strengths_1bit[] = {4, 8};
 140static const unsigned int uniphier_conf_drv_strengths_2bit[] = {8, 12, 16, 20};
 141static const unsigned int uniphier_conf_drv_strengths_3bit[] = {4, 5, 7, 9, 11,
 142                                                                12, 14, 16};
 143static const unsigned int uniphier_conf_drv_strengths_fixed4[] = {4};
 144static const unsigned int uniphier_conf_drv_strengths_fixed5[] = {5};
 145static const unsigned int uniphier_conf_drv_strengths_fixed8[] = {8};
 146
 147static int uniphier_conf_get_drvctrl_data(struct pinctrl_dev *pctldev,
 148                                          unsigned int pin, unsigned int *reg,
 149                                          unsigned int *shift,
 150                                          unsigned int *mask,
 151                                          const unsigned int **strengths)
 152{
 153        const struct pin_desc *desc = pin_desc_get(pctldev, pin);
 154        enum uniphier_pin_drv_type type =
 155                                uniphier_pin_get_drv_type(desc->drv_data);
 156        unsigned int base = 0;
 157        unsigned int stride = 0;
 158        unsigned int width = 0;
 159        unsigned int drvctrl;
 160
 161        switch (type) {
 162        case UNIPHIER_PIN_DRV_1BIT:
 163                *strengths = uniphier_conf_drv_strengths_1bit;
 164                base = UNIPHIER_PINCTRL_DRVCTRL_BASE;
 165                stride = 1;
 166                width = 1;
 167                break;
 168        case UNIPHIER_PIN_DRV_2BIT:
 169                *strengths = uniphier_conf_drv_strengths_2bit;
 170                base = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
 171                stride = 2;
 172                width = 2;
 173                break;
 174        case UNIPHIER_PIN_DRV_3BIT:
 175                *strengths = uniphier_conf_drv_strengths_3bit;
 176                base = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
 177                stride = 4;
 178                width = 3;
 179                break;
 180        case UNIPHIER_PIN_DRV_FIXED4:
 181                *strengths = uniphier_conf_drv_strengths_fixed4;
 182                break;
 183        case UNIPHIER_PIN_DRV_FIXED5:
 184                *strengths = uniphier_conf_drv_strengths_fixed5;
 185                break;
 186        case UNIPHIER_PIN_DRV_FIXED8:
 187                *strengths = uniphier_conf_drv_strengths_fixed8;
 188                break;
 189        default:
 190                /* drive strength control is not supported for this pin */
 191                return -EINVAL;
 192        }
 193
 194        drvctrl = uniphier_pin_get_drvctrl(desc->drv_data);
 195        drvctrl *= stride;
 196
 197        *reg = base + drvctrl / 32 * 4;
 198        *shift = drvctrl % 32;
 199        *mask = (1U << width) - 1;
 200
 201        return 0;
 202}
 203
 204static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
 205                                      unsigned int pin,
 206                                      enum pin_config_param param)
 207{
 208        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 209        const struct pin_desc *desc = pin_desc_get(pctldev, pin);
 210        enum uniphier_pin_pull_dir pull_dir =
 211                                uniphier_pin_get_pull_dir(desc->drv_data);
 212        unsigned int pupdctrl, reg, shift, val;
 213        unsigned int expected = 1;
 214        int ret;
 215
 216        switch (param) {
 217        case PIN_CONFIG_BIAS_DISABLE:
 218                if (pull_dir == UNIPHIER_PIN_PULL_NONE)
 219                        return 0;
 220                if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
 221                    pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
 222                        return -EINVAL;
 223                expected = 0;
 224                break;
 225        case PIN_CONFIG_BIAS_PULL_UP:
 226                if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED)
 227                        return 0;
 228                if (pull_dir != UNIPHIER_PIN_PULL_UP)
 229                        return -EINVAL;
 230                break;
 231        case PIN_CONFIG_BIAS_PULL_DOWN:
 232                if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
 233                        return 0;
 234                if (pull_dir != UNIPHIER_PIN_PULL_DOWN)
 235                        return -EINVAL;
 236                break;
 237        default:
 238                BUG();
 239        }
 240
 241        pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data);
 242
 243        reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
 244        shift = pupdctrl % 32;
 245
 246        ret = regmap_read(priv->regmap, reg, &val);
 247        if (ret)
 248                return ret;
 249
 250        val = (val >> shift) & 1;
 251
 252        return (val == expected) ? 0 : -EINVAL;
 253}
 254
 255static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
 256                                       unsigned int pin, u32 *strength)
 257{
 258        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 259        unsigned int reg, shift, mask, val;
 260        const unsigned int *strengths;
 261        int ret;
 262
 263        ret = uniphier_conf_get_drvctrl_data(pctldev, pin, &reg, &shift,
 264                                             &mask, &strengths);
 265        if (ret)
 266                return ret;
 267
 268        if (mask) {
 269                ret = regmap_read(priv->regmap, reg, &val);
 270                if (ret)
 271                        return ret;
 272        } else {
 273                val = 0;
 274        }
 275
 276        *strength = strengths[(val >> shift) & mask];
 277
 278        return 0;
 279}
 280
 281static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
 282                                              unsigned int pin)
 283{
 284        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 285        const struct pin_desc *desc = pin_desc_get(pctldev, pin);
 286        unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data);
 287        unsigned int reg, mask, val;
 288        int ret;
 289
 290        if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
 291                /* This pin is always input-enabled. */
 292                return 0;
 293
 294        if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
 295                iectrl = pin;
 296
 297        reg = UNIPHIER_PINCTRL_IECTRL_BASE + iectrl / 32 * 4;
 298        mask = BIT(iectrl % 32);
 299
 300        ret = regmap_read(priv->regmap, reg, &val);
 301        if (ret)
 302                return ret;
 303
 304        return val & mask ? 0 : -EINVAL;
 305}
 306
 307static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev,
 308                                        unsigned pin,
 309                                        unsigned long *configs)
 310{
 311        enum pin_config_param param = pinconf_to_config_param(*configs);
 312        bool has_arg = false;
 313        u32 arg;
 314        int ret;
 315
 316        switch (param) {
 317        case PIN_CONFIG_BIAS_DISABLE:
 318        case PIN_CONFIG_BIAS_PULL_UP:
 319        case PIN_CONFIG_BIAS_PULL_DOWN:
 320                ret = uniphier_conf_pin_bias_get(pctldev, pin, param);
 321                break;
 322        case PIN_CONFIG_DRIVE_STRENGTH:
 323                ret = uniphier_conf_pin_drive_get(pctldev, pin, &arg);
 324                has_arg = true;
 325                break;
 326        case PIN_CONFIG_INPUT_ENABLE:
 327                ret = uniphier_conf_pin_input_enable_get(pctldev, pin);
 328                break;
 329        default:
 330                /* unsupported parameter */
 331                ret = -EINVAL;
 332                break;
 333        }
 334
 335        if (ret == 0 && has_arg)
 336                *configs = pinconf_to_config_packed(param, arg);
 337
 338        return ret;
 339}
 340
 341static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
 342                                      unsigned int pin,
 343                                      enum pin_config_param param, u32 arg)
 344{
 345        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 346        const struct pin_desc *desc = pin_desc_get(pctldev, pin);
 347        enum uniphier_pin_pull_dir pull_dir =
 348                                uniphier_pin_get_pull_dir(desc->drv_data);
 349        unsigned int pupdctrl, reg, shift;
 350        unsigned int val = 1;
 351
 352        switch (param) {
 353        case PIN_CONFIG_BIAS_DISABLE:
 354                if (pull_dir == UNIPHIER_PIN_PULL_NONE)
 355                        return 0;
 356                if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
 357                    pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) {
 358                        dev_err(pctldev->dev,
 359                                "can not disable pull register for pin %s\n",
 360                                desc->name);
 361                        return -EINVAL;
 362                }
 363                val = 0;
 364                break;
 365        case PIN_CONFIG_BIAS_PULL_UP:
 366                if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED && arg != 0)
 367                        return 0;
 368                if (pull_dir != UNIPHIER_PIN_PULL_UP) {
 369                        dev_err(pctldev->dev,
 370                                "pull-up is unsupported for pin %s\n",
 371                                desc->name);
 372                        return -EINVAL;
 373                }
 374                if (arg == 0) {
 375                        dev_err(pctldev->dev, "pull-up can not be total\n");
 376                        return -EINVAL;
 377                }
 378                break;
 379        case PIN_CONFIG_BIAS_PULL_DOWN:
 380                if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED && arg != 0)
 381                        return 0;
 382                if (pull_dir != UNIPHIER_PIN_PULL_DOWN) {
 383                        dev_err(pctldev->dev,
 384                                "pull-down is unsupported for pin %s\n",
 385                                desc->name);
 386                        return -EINVAL;
 387                }
 388                if (arg == 0) {
 389                        dev_err(pctldev->dev, "pull-down can not be total\n");
 390                        return -EINVAL;
 391                }
 392                break;
 393        case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
 394                if (pull_dir == UNIPHIER_PIN_PULL_NONE) {
 395                        dev_err(pctldev->dev,
 396                                "pull-up/down is unsupported for pin %s\n",
 397                                desc->name);
 398                        return -EINVAL;
 399                }
 400
 401                if (arg == 0)
 402                        return 0; /* configuration ingored */
 403                break;
 404        default:
 405                BUG();
 406        }
 407
 408        pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data);
 409
 410        reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
 411        shift = pupdctrl % 32;
 412
 413        return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift);
 414}
 415
 416static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
 417                                       unsigned int pin, u32 strength)
 418{
 419        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 420        const struct pin_desc *desc = pin_desc_get(pctldev, pin);
 421        unsigned int reg, shift, mask, val;
 422        const unsigned int *strengths;
 423        int ret;
 424
 425        ret = uniphier_conf_get_drvctrl_data(pctldev, pin, &reg, &shift,
 426                                             &mask, &strengths);
 427        if (ret) {
 428                dev_err(pctldev->dev, "cannot set drive strength for pin %s\n",
 429                        desc->name);
 430                return ret;
 431        }
 432
 433        for (val = 0; val <= mask; val++) {
 434                if (strengths[val] > strength)
 435                        break;
 436        }
 437
 438        if (val == 0) {
 439                dev_err(pctldev->dev,
 440                        "unsupported drive strength %u mA for pin %s\n",
 441                        strength, desc->name);
 442                return -EINVAL;
 443        }
 444
 445        if (!mask)
 446                return 0;
 447
 448        val--;
 449
 450        return regmap_update_bits(priv->regmap, reg,
 451                                  mask << shift, val << shift);
 452}
 453
 454static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
 455                                          unsigned int pin, u32 enable)
 456{
 457        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 458        const struct pin_desc *desc = pin_desc_get(pctldev, pin);
 459        unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data);
 460        unsigned int reg, mask;
 461
 462        /*
 463         * Multiple pins share one input enable, per-pin disabling is
 464         * impossible.
 465         */
 466        if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL) &&
 467            !enable)
 468                return -EINVAL;
 469
 470        /* UNIPHIER_PIN_IECTRL_NONE means the pin is always input-enabled */
 471        if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
 472                return enable ? 0 : -EINVAL;
 473
 474        if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
 475                iectrl = pin;
 476
 477        reg = UNIPHIER_PINCTRL_IECTRL_BASE + iectrl / 32 * 4;
 478        mask = BIT(iectrl % 32);
 479
 480        return regmap_update_bits(priv->regmap, reg, mask, enable ? mask : 0);
 481}
 482
 483static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev,
 484                                        unsigned pin,
 485                                        unsigned long *configs,
 486                                        unsigned num_configs)
 487{
 488        int i, ret;
 489
 490        for (i = 0; i < num_configs; i++) {
 491                enum pin_config_param param =
 492                                        pinconf_to_config_param(configs[i]);
 493                u32 arg = pinconf_to_config_argument(configs[i]);
 494
 495                switch (param) {
 496                case PIN_CONFIG_BIAS_DISABLE:
 497                case PIN_CONFIG_BIAS_PULL_UP:
 498                case PIN_CONFIG_BIAS_PULL_DOWN:
 499                case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
 500                        ret = uniphier_conf_pin_bias_set(pctldev, pin,
 501                                                         param, arg);
 502                        break;
 503                case PIN_CONFIG_DRIVE_STRENGTH:
 504                        ret = uniphier_conf_pin_drive_set(pctldev, pin, arg);
 505                        break;
 506                case PIN_CONFIG_INPUT_ENABLE:
 507                        ret = uniphier_conf_pin_input_enable(pctldev, pin, arg);
 508                        break;
 509                default:
 510                        dev_err(pctldev->dev,
 511                                "unsupported configuration parameter %u\n",
 512                                param);
 513                        return -EINVAL;
 514                }
 515
 516                if (ret)
 517                        return ret;
 518        }
 519
 520        return 0;
 521}
 522
 523static int uniphier_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
 524                                              unsigned selector,
 525                                              unsigned long *configs,
 526                                              unsigned num_configs)
 527{
 528        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 529        const unsigned *pins = priv->socdata->groups[selector].pins;
 530        unsigned num_pins = priv->socdata->groups[selector].num_pins;
 531        int i, ret;
 532
 533        for (i = 0; i < num_pins; i++) {
 534                ret = uniphier_conf_pin_config_set(pctldev, pins[i],
 535                                                   configs, num_configs);
 536                if (ret)
 537                        return ret;
 538        }
 539
 540        return 0;
 541}
 542
 543static const struct pinconf_ops uniphier_confops = {
 544        .is_generic = true,
 545        .pin_config_get = uniphier_conf_pin_config_get,
 546        .pin_config_set = uniphier_conf_pin_config_set,
 547        .pin_config_group_set = uniphier_conf_pin_config_group_set,
 548};
 549
 550static int uniphier_pmx_get_functions_count(struct pinctrl_dev *pctldev)
 551{
 552        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 553
 554        return priv->socdata->functions_count;
 555}
 556
 557static const char *uniphier_pmx_get_function_name(struct pinctrl_dev *pctldev,
 558                                                  unsigned selector)
 559{
 560        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 561
 562        return priv->socdata->functions[selector].name;
 563}
 564
 565static int uniphier_pmx_get_function_groups(struct pinctrl_dev *pctldev,
 566                                            unsigned selector,
 567                                            const char * const **groups,
 568                                            unsigned *num_groups)
 569{
 570        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 571
 572        *groups = priv->socdata->functions[selector].groups;
 573        *num_groups = priv->socdata->functions[selector].num_groups;
 574
 575        return 0;
 576}
 577
 578static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
 579                                    int muxval)
 580{
 581        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 582        unsigned int mux_bits, reg_stride, reg, reg_end, shift, mask;
 583        bool load_pinctrl;
 584        int ret;
 585
 586        /* some pins need input-enabling */
 587        ret = uniphier_conf_pin_input_enable(pctldev, pin, 1);
 588        if (ret)
 589                return ret;
 590
 591        if (muxval < 0)
 592                return 0;       /* dedicated pin; nothing to do for pin-mux */
 593
 594        if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
 595                /*
 596                 *  Mode     reg_offset     bit_position
 597                 *  Normal    4 * n        shift+3:shift
 598                 *  Debug     4 * n        shift+7:shift+4
 599                 */
 600                mux_bits = 4;
 601                reg_stride = 8;
 602                load_pinctrl = true;
 603        } else {
 604                /*
 605                 *  Mode     reg_offset     bit_position
 606                 *  Normal    8 * n        shift+3:shift
 607                 *  Debug     8 * n + 4    shift+3:shift
 608                 */
 609                mux_bits = 8;
 610                reg_stride = 4;
 611                load_pinctrl = false;
 612        }
 613
 614        reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
 615        reg_end = reg + reg_stride;
 616        shift = pin * mux_bits % 32;
 617        mask = (1U << mux_bits) - 1;
 618
 619        /*
 620         * If reg_stride is greater than 4, the MSB of each pinsel shall be
 621         * stored in the offset+4.
 622         */
 623        for (; reg < reg_end; reg += 4) {
 624                ret = regmap_update_bits(priv->regmap, reg,
 625                                         mask << shift, muxval << shift);
 626                if (ret)
 627                        return ret;
 628                muxval >>= mux_bits;
 629        }
 630
 631        if (load_pinctrl) {
 632                ret = regmap_write(priv->regmap,
 633                                   UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
 634                if (ret)
 635                        return ret;
 636        }
 637
 638        return 0;
 639}
 640
 641static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
 642                                unsigned func_selector,
 643                                unsigned group_selector)
 644{
 645        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 646        const struct uniphier_pinctrl_group *grp =
 647                                        &priv->socdata->groups[group_selector];
 648        int i;
 649        int ret;
 650
 651        for (i = 0; i < grp->num_pins; i++) {
 652                ret = uniphier_pmx_set_one_mux(pctldev, grp->pins[i],
 653                                               grp->muxvals[i]);
 654                if (ret)
 655                        return ret;
 656        }
 657
 658        return 0;
 659}
 660
 661static int uniphier_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
 662                                            struct pinctrl_gpio_range *range,
 663                                            unsigned offset)
 664{
 665        struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
 666        unsigned int gpio_offset;
 667        int muxval, i;
 668
 669        if (range->pins) {
 670                for (i = 0; i < range->npins; i++)
 671                        if (range->pins[i] == offset)
 672                                break;
 673
 674                if (WARN_ON(i == range->npins))
 675                        return -EINVAL;
 676
 677                gpio_offset = i;
 678        } else {
 679                gpio_offset = offset - range->pin_base;
 680        }
 681
 682        gpio_offset += range->id;
 683
 684        muxval = priv->socdata->get_gpio_muxval(offset, gpio_offset);
 685
 686        return uniphier_pmx_set_one_mux(pctldev, offset, muxval);
 687}
 688
 689static const struct pinmux_ops uniphier_pmxops = {
 690        .get_functions_count = uniphier_pmx_get_functions_count,
 691        .get_function_name = uniphier_pmx_get_function_name,
 692        .get_function_groups = uniphier_pmx_get_function_groups,
 693        .set_mux = uniphier_pmx_set_mux,
 694        .gpio_request_enable = uniphier_pmx_gpio_request_enable,
 695        .strict = true,
 696};
 697
 698#ifdef CONFIG_PM_SLEEP
 699static int uniphier_pinctrl_suspend(struct device *dev)
 700{
 701        struct uniphier_pinctrl_priv *priv = dev_get_drvdata(dev);
 702        struct uniphier_pinctrl_reg_region *r;
 703        int ret;
 704
 705        list_for_each_entry(r, &priv->reg_regions, node) {
 706                ret = regmap_bulk_read(priv->regmap, r->base, r->vals,
 707                                       r->nregs);
 708                if (ret)
 709                        return ret;
 710        }
 711
 712        return 0;
 713}
 714
 715static int uniphier_pinctrl_resume(struct device *dev)
 716{
 717        struct uniphier_pinctrl_priv *priv = dev_get_drvdata(dev);
 718        struct uniphier_pinctrl_reg_region *r;
 719        int ret;
 720
 721        list_for_each_entry(r, &priv->reg_regions, node) {
 722                ret = regmap_bulk_write(priv->regmap, r->base, r->vals,
 723                                        r->nregs);
 724                if (ret)
 725                        return ret;
 726        }
 727
 728        if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
 729                ret = regmap_write(priv->regmap,
 730                                   UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
 731                if (ret)
 732                        return ret;
 733        }
 734
 735        return 0;
 736}
 737
 738static int uniphier_pinctrl_add_reg_region(struct device *dev,
 739                                           struct uniphier_pinctrl_priv *priv,
 740                                           unsigned int base,
 741                                           unsigned int count,
 742                                           unsigned int width)
 743{
 744        struct uniphier_pinctrl_reg_region *region;
 745        unsigned int nregs;
 746
 747        if (!count)
 748                return 0;
 749
 750        nregs = DIV_ROUND_UP(count * width, 32);
 751
 752        region = devm_kzalloc(dev, struct_size(region, vals, nregs),
 753                              GFP_KERNEL);
 754        if (!region)
 755                return -ENOMEM;
 756
 757        region->base = base;
 758        region->nregs = nregs;
 759
 760        list_add_tail(&region->node, &priv->reg_regions);
 761
 762        return 0;
 763}
 764#endif
 765
 766static int uniphier_pinctrl_pm_init(struct device *dev,
 767                                    struct uniphier_pinctrl_priv *priv)
 768{
 769#ifdef CONFIG_PM_SLEEP
 770        const struct uniphier_pinctrl_socdata *socdata = priv->socdata;
 771        unsigned int num_drvctrl = 0;
 772        unsigned int num_drv2ctrl = 0;
 773        unsigned int num_drv3ctrl = 0;
 774        unsigned int num_pupdctrl = 0;
 775        unsigned int num_iectrl = 0;
 776        unsigned int iectrl, drvctrl, pupdctrl;
 777        enum uniphier_pin_drv_type drv_type;
 778        enum uniphier_pin_pull_dir pull_dir;
 779        int i, ret;
 780
 781        for (i = 0; i < socdata->npins; i++) {
 782                void *drv_data = socdata->pins[i].drv_data;
 783
 784                drvctrl = uniphier_pin_get_drvctrl(drv_data);
 785                drv_type = uniphier_pin_get_drv_type(drv_data);
 786                pupdctrl = uniphier_pin_get_pupdctrl(drv_data);
 787                pull_dir = uniphier_pin_get_pull_dir(drv_data);
 788                iectrl = uniphier_pin_get_iectrl(drv_data);
 789
 790                switch (drv_type) {
 791                case UNIPHIER_PIN_DRV_1BIT:
 792                        num_drvctrl = max(num_drvctrl, drvctrl + 1);
 793                        break;
 794                case UNIPHIER_PIN_DRV_2BIT:
 795                        num_drv2ctrl = max(num_drv2ctrl, drvctrl + 1);
 796                        break;
 797                case UNIPHIER_PIN_DRV_3BIT:
 798                        num_drv3ctrl = max(num_drv3ctrl, drvctrl + 1);
 799                        break;
 800                default:
 801                        break;
 802                }
 803
 804                if (pull_dir == UNIPHIER_PIN_PULL_UP ||
 805                    pull_dir == UNIPHIER_PIN_PULL_DOWN)
 806                        num_pupdctrl = max(num_pupdctrl, pupdctrl + 1);
 807
 808                if (iectrl != UNIPHIER_PIN_IECTRL_NONE) {
 809                        if (socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
 810                                iectrl = i;
 811                        num_iectrl = max(num_iectrl, iectrl + 1);
 812                }
 813        }
 814
 815        INIT_LIST_HEAD(&priv->reg_regions);
 816
 817        ret = uniphier_pinctrl_add_reg_region(dev, priv,
 818                                              UNIPHIER_PINCTRL_PINMUX_BASE,
 819                                              socdata->npins, 8);
 820        if (ret)
 821                return ret;
 822
 823        ret = uniphier_pinctrl_add_reg_region(dev, priv,
 824                                              UNIPHIER_PINCTRL_DRVCTRL_BASE,
 825                                              num_drvctrl, 1);
 826        if (ret)
 827                return ret;
 828
 829        ret = uniphier_pinctrl_add_reg_region(dev, priv,
 830                                              UNIPHIER_PINCTRL_DRV2CTRL_BASE,
 831                                              num_drv2ctrl, 2);
 832        if (ret)
 833                return ret;
 834
 835        ret = uniphier_pinctrl_add_reg_region(dev, priv,
 836                                              UNIPHIER_PINCTRL_DRV3CTRL_BASE,
 837                                              num_drv3ctrl, 3);
 838        if (ret)
 839                return ret;
 840
 841        ret = uniphier_pinctrl_add_reg_region(dev, priv,
 842                                              UNIPHIER_PINCTRL_PUPDCTRL_BASE,
 843                                              num_pupdctrl, 1);
 844        if (ret)
 845                return ret;
 846
 847        ret = uniphier_pinctrl_add_reg_region(dev, priv,
 848                                              UNIPHIER_PINCTRL_IECTRL_BASE,
 849                                              num_iectrl, 1);
 850        if (ret)
 851                return ret;
 852#endif
 853        return 0;
 854}
 855
 856const struct dev_pm_ops uniphier_pinctrl_pm_ops = {
 857        SET_LATE_SYSTEM_SLEEP_PM_OPS(uniphier_pinctrl_suspend,
 858                                     uniphier_pinctrl_resume)
 859};
 860
 861int uniphier_pinctrl_probe(struct platform_device *pdev,
 862                           const struct uniphier_pinctrl_socdata *socdata)
 863{
 864        struct device *dev = &pdev->dev;
 865        struct uniphier_pinctrl_priv *priv;
 866        struct device_node *parent;
 867        int ret;
 868
 869        if (!socdata ||
 870            !socdata->pins || !socdata->npins ||
 871            !socdata->groups || !socdata->groups_count ||
 872            !socdata->functions || !socdata->functions_count) {
 873                dev_err(dev, "pinctrl socdata lacks necessary members\n");
 874                return -EINVAL;
 875        }
 876
 877        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 878        if (!priv)
 879                return -ENOMEM;
 880
 881        parent = of_get_parent(dev->of_node);
 882        priv->regmap = syscon_node_to_regmap(parent);
 883        of_node_put(parent);
 884
 885        if (IS_ERR(priv->regmap)) {
 886                dev_err(dev, "failed to get regmap\n");
 887                return PTR_ERR(priv->regmap);
 888        }
 889
 890        priv->socdata = socdata;
 891        priv->pctldesc.name = dev->driver->name;
 892        priv->pctldesc.pins = socdata->pins;
 893        priv->pctldesc.npins = socdata->npins;
 894        priv->pctldesc.pctlops = &uniphier_pctlops;
 895        priv->pctldesc.pmxops = &uniphier_pmxops;
 896        priv->pctldesc.confops = &uniphier_confops;
 897        priv->pctldesc.owner = dev->driver->owner;
 898
 899        ret = uniphier_pinctrl_pm_init(dev, priv);
 900        if (ret)
 901                return ret;
 902
 903        priv->pctldev = devm_pinctrl_register(dev, &priv->pctldesc, priv);
 904        if (IS_ERR(priv->pctldev)) {
 905                dev_err(dev, "failed to register UniPhier pinctrl driver\n");
 906                return PTR_ERR(priv->pctldev);
 907        }
 908
 909        platform_set_drvdata(pdev, priv);
 910
 911        return 0;
 912}
 913
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.