root/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uniphier_pctl_get_groups_count
  2. uniphier_pctl_get_group_name
  3. uniphier_pctl_get_group_pins
  4. uniphier_pctl_pin_dbg_show
  5. uniphier_conf_get_drvctrl_data
  6. uniphier_conf_pin_bias_get
  7. uniphier_conf_pin_drive_get
  8. uniphier_conf_pin_input_enable_get
  9. uniphier_conf_pin_config_get
  10. uniphier_conf_pin_bias_set
  11. uniphier_conf_pin_drive_set
  12. uniphier_conf_pin_input_enable
  13. uniphier_conf_pin_config_set
  14. uniphier_conf_pin_config_group_set
  15. uniphier_pmx_get_functions_count
  16. uniphier_pmx_get_function_name
  17. uniphier_pmx_get_function_groups
  18. uniphier_pmx_set_one_mux
  19. uniphier_pmx_set_mux
  20. uniphier_pmx_gpio_request_enable
  21. uniphier_pinctrl_suspend
  22. uniphier_pinctrl_resume
  23. uniphier_pinctrl_add_reg_region
  24. uniphier_pinctrl_pm_init
  25. uniphier_pinctrl_probe

   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 
  28 struct uniphier_pinctrl_reg_region {
  29         struct list_head node;
  30         unsigned int base;
  31         unsigned int nregs;
  32         u32 vals[0];
  33 };
  34 
  35 struct 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 
  43 static 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 
  50 static 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 
  58 static 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
  72 static 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 
 128 static 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 
 139 static const unsigned int uniphier_conf_drv_strengths_1bit[] = {4, 8};
 140 static const unsigned int uniphier_conf_drv_strengths_2bit[] = {8, 12, 16, 20};
 141 static const unsigned int uniphier_conf_drv_strengths_3bit[] = {4, 5, 7, 9, 11,
 142                                                                 12, 14, 16};
 143 static const unsigned int uniphier_conf_drv_strengths_fixed4[] = {4};
 144 static const unsigned int uniphier_conf_drv_strengths_fixed5[] = {5};
 145 static const unsigned int uniphier_conf_drv_strengths_fixed8[] = {8};
 146 
 147 static 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 
 204 static 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 
 255 static 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 
 281 static 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 
 307 static 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 
 341 static 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 
 416 static 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 
 454 static 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 
 483 static 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 
 523 static 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 
 543 static 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 
 550 static 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 
 557 static 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 
 565 static 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 
 578 static 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 
 641 static 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 
 661 static 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 
 689 static 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
 699 static 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 
 715 static 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 
 738 static 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 
 766 static 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 
 856 const struct dev_pm_ops uniphier_pinctrl_pm_ops = {
 857         SET_LATE_SYSTEM_SLEEP_PM_OPS(uniphier_pinctrl_suspend,
 858                                      uniphier_pinctrl_resume)
 859 };
 860 
 861 int 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 }

/* [<][>][^][v][top][bottom][index][help] */