Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

pinctrl: rk805: Add rk806 pinctrl support

Add support for rk806 dvs pinctrl to the existing rk805
driver.

This has been implemented using shengfei Xu's rk806
specific driver from the vendor tree as reference.

Co-developed-by: shengfei Xu <xsf@rock-chips.com>
Signed-off-by: shengfei Xu <xsf@rock-chips.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Diederik de Haas <didi.debian@cknow.org> # Rock64, Quartz64 Model A + B
Tested-by: Vincent Legoll <vincent.legoll@gmail.com> # Pine64 QuartzPro64
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://lore.kernel.org/r/20230504173618.142075-10-sebastian.reichel@collabora.com
Signed-off-by: Lee Jones <lee@kernel.org>

authored by

Sebastian Reichel and committed by
Lee Jones
924764aa 210f418f

+168 -21
+168 -21
drivers/pinctrl/pinctrl-rk805.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * Pinctrl driver for Rockchip RK805 PMIC 3 + * Pinctrl driver for Rockchip RK805/RK806 PMIC 4 4 * 5 5 * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd 6 + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. 6 7 * 7 8 * Author: Joseph Chen <chenjh@rock-chips.com> 9 + * Author: Xu Shengfei <xsf@rock-chips.com> 8 10 * 9 11 * Based on the pinctrl-as3722 driver 10 12 */ ··· 46 44 47 45 /* 48 46 * @reg: gpio setting register; 47 + * @fun_reg: functions select register; 49 48 * @fun_mask: functions select mask value, when set is gpio; 50 49 * @dir_mask: input or output mask value, when set is output, otherwise input; 51 50 * @val_mask: gpio set value, when set is level high, otherwise low; ··· 59 56 */ 60 57 struct rk805_pin_config { 61 58 u8 reg; 59 + u8 fun_reg; 62 60 u8 fun_msk; 63 61 u8 dir_msk; 64 62 u8 val_msk; ··· 84 80 RK805_PINMUX_GPIO, 85 81 }; 86 82 83 + enum rk806_pinmux_option { 84 + RK806_PINMUX_FUN0 = 0, 85 + RK806_PINMUX_FUN1, 86 + RK806_PINMUX_FUN2, 87 + RK806_PINMUX_FUN3, 88 + RK806_PINMUX_FUN4, 89 + RK806_PINMUX_FUN5, 90 + }; 91 + 87 92 enum { 88 93 RK805_GPIO0, 89 94 RK805_GPIO1, 90 95 }; 91 96 97 + enum { 98 + RK806_GPIO_DVS1, 99 + RK806_GPIO_DVS2, 100 + RK806_GPIO_DVS3 101 + }; 102 + 92 103 static const char *const rk805_gpio_groups[] = { 93 104 "gpio0", 94 105 "gpio1", 106 + }; 107 + 108 + static const char *const rk806_gpio_groups[] = { 109 + "gpio_pwrctrl1", 110 + "gpio_pwrctrl2", 111 + "gpio_pwrctrl3", 95 112 }; 96 113 97 114 /* RK805: 2 output only GPIOs */ ··· 121 96 PINCTRL_PIN(RK805_GPIO1, "gpio1"), 122 97 }; 123 98 99 + /* RK806 */ 100 + static const struct pinctrl_pin_desc rk806_pins_desc[] = { 101 + PINCTRL_PIN(RK806_GPIO_DVS1, "gpio_pwrctrl1"), 102 + PINCTRL_PIN(RK806_GPIO_DVS2, "gpio_pwrctrl2"), 103 + PINCTRL_PIN(RK806_GPIO_DVS3, "gpio_pwrctrl3"), 104 + }; 105 + 124 106 static const struct rk805_pin_function rk805_pin_functions[] = { 125 107 { 126 108 .name = "gpio", 127 109 .groups = rk805_gpio_groups, 128 110 .ngroups = ARRAY_SIZE(rk805_gpio_groups), 129 111 .mux_option = RK805_PINMUX_GPIO, 112 + }, 113 + }; 114 + 115 + static const struct rk805_pin_function rk806_pin_functions[] = { 116 + { 117 + .name = "pin_fun0", 118 + .groups = rk806_gpio_groups, 119 + .ngroups = ARRAY_SIZE(rk806_gpio_groups), 120 + .mux_option = RK806_PINMUX_FUN0, 121 + }, 122 + { 123 + .name = "pin_fun1", 124 + .groups = rk806_gpio_groups, 125 + .ngroups = ARRAY_SIZE(rk806_gpio_groups), 126 + .mux_option = RK806_PINMUX_FUN1, 127 + }, 128 + { 129 + .name = "pin_fun2", 130 + .groups = rk806_gpio_groups, 131 + .ngroups = ARRAY_SIZE(rk806_gpio_groups), 132 + .mux_option = RK806_PINMUX_FUN2, 133 + }, 134 + { 135 + .name = "pin_fun3", 136 + .groups = rk806_gpio_groups, 137 + .ngroups = ARRAY_SIZE(rk806_gpio_groups), 138 + .mux_option = RK806_PINMUX_FUN3, 139 + }, 140 + { 141 + .name = "pin_fun4", 142 + .groups = rk806_gpio_groups, 143 + .ngroups = ARRAY_SIZE(rk806_gpio_groups), 144 + .mux_option = RK806_PINMUX_FUN4, 145 + }, 146 + { 147 + .name = "pin_fun5", 148 + .groups = rk806_gpio_groups, 149 + .ngroups = ARRAY_SIZE(rk806_gpio_groups), 150 + .mux_option = RK806_PINMUX_FUN5, 130 151 }, 131 152 }; 132 153 ··· 189 118 }, 190 119 }; 191 120 121 + static const struct rk805_pin_group rk806_pin_groups[] = { 122 + { 123 + .name = "gpio_pwrctrl1", 124 + .pins = { RK806_GPIO_DVS1 }, 125 + .npins = 1, 126 + }, 127 + { 128 + .name = "gpio_pwrctrl2", 129 + .pins = { RK806_GPIO_DVS2 }, 130 + .npins = 1, 131 + }, 132 + { 133 + .name = "gpio_pwrctrl3", 134 + .pins = { RK806_GPIO_DVS3 }, 135 + .npins = 1, 136 + } 137 + }; 138 + 192 139 #define RK805_GPIO0_VAL_MSK BIT(0) 193 140 #define RK805_GPIO1_VAL_MSK BIT(1) 194 141 ··· 219 130 .reg = RK805_OUT_REG, 220 131 .val_msk = RK805_GPIO1_VAL_MSK, 221 132 }, 133 + }; 134 + 135 + #define RK806_PWRCTRL1_DR BIT(0) 136 + #define RK806_PWRCTRL2_DR BIT(1) 137 + #define RK806_PWRCTRL3_DR BIT(2) 138 + #define RK806_PWRCTRL1_DATA BIT(4) 139 + #define RK806_PWRCTRL2_DATA BIT(5) 140 + #define RK806_PWRCTRL3_DATA BIT(6) 141 + #define RK806_PWRCTRL1_FUN GENMASK(2, 0) 142 + #define RK806_PWRCTRL2_FUN GENMASK(6, 4) 143 + #define RK806_PWRCTRL3_FUN GENMASK(2, 0) 144 + 145 + static struct rk805_pin_config rk806_gpio_cfgs[] = { 146 + { 147 + .fun_reg = RK806_SLEEP_CONFIG0, 148 + .fun_msk = RK806_PWRCTRL1_FUN, 149 + .reg = RK806_SLEEP_GPIO, 150 + .val_msk = RK806_PWRCTRL1_DATA, 151 + .dir_msk = RK806_PWRCTRL1_DR, 152 + }, 153 + { 154 + .fun_reg = RK806_SLEEP_CONFIG0, 155 + .fun_msk = RK806_PWRCTRL2_FUN, 156 + .reg = RK806_SLEEP_GPIO, 157 + .val_msk = RK806_PWRCTRL2_DATA, 158 + .dir_msk = RK806_PWRCTRL2_DR, 159 + }, 160 + { 161 + .fun_reg = RK806_SLEEP_CONFIG1, 162 + .fun_msk = RK806_PWRCTRL3_FUN, 163 + .reg = RK806_SLEEP_GPIO, 164 + .val_msk = RK806_PWRCTRL3_DATA, 165 + .dir_msk = RK806_PWRCTRL3_DR, 166 + } 222 167 }; 223 168 224 169 /* generic gpio chip */ ··· 412 289 if (!pci->pin_cfg[offset].fun_msk) 413 290 return 0; 414 291 415 - if (mux == RK805_PINMUX_GPIO) { 416 - ret = regmap_update_bits(pci->rk808->regmap, 417 - pci->pin_cfg[offset].reg, 418 - pci->pin_cfg[offset].fun_msk, 419 - pci->pin_cfg[offset].fun_msk); 420 - if (ret) { 421 - dev_err(pci->dev, "set gpio%d GPIO failed\n", offset); 422 - return ret; 423 - } 424 - } else { 425 - dev_err(pci->dev, "Couldn't find function mux %d\n", mux); 426 - return -EINVAL; 427 - } 292 + mux <<= ffs(pci->pin_cfg[offset].fun_msk) - 1; 293 + ret = regmap_update_bits(pci->rk808->regmap, 294 + pci->pin_cfg[offset].fun_reg, 295 + pci->pin_cfg[offset].fun_msk, mux); 296 + 297 + if (ret) 298 + dev_err(pci->dev, "set gpio%d func%d failed\n", offset, mux); 428 299 429 300 return 0; 430 301 } ··· 434 317 return _rk805_pinctrl_set_mux(pctldev, offset, mux); 435 318 } 436 319 320 + static int rk805_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev, 321 + struct pinctrl_gpio_range *range, 322 + unsigned int offset) 323 + { 324 + struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 325 + 326 + switch (pci->rk808->variant) { 327 + case RK805_ID: 328 + return _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO); 329 + case RK806_ID: 330 + return _rk805_pinctrl_set_mux(pctldev, offset, RK806_PINMUX_FUN5); 331 + } 332 + 333 + return -ENOTSUPP; 334 + } 335 + 437 336 static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, 438 337 struct pinctrl_gpio_range *range, 439 338 unsigned int offset, bool input) 440 339 { 441 340 struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev); 442 341 int ret; 443 - 444 - /* switch to gpio function */ 445 - ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO); 446 - if (ret) { 447 - dev_err(pci->dev, "set gpio%d mux failed\n", offset); 448 - return ret; 449 - } 450 342 451 343 /* set direction */ 452 344 if (!pci->pin_cfg[offset].dir_msk) ··· 478 352 .get_function_name = rk805_pinctrl_get_func_name, 479 353 .get_function_groups = rk805_pinctrl_get_func_groups, 480 354 .set_mux = rk805_pinctrl_set_mux, 355 + .gpio_request_enable = rk805_pinctrl_gpio_request_enable, 481 356 .gpio_set_direction = rk805_pmx_gpio_set_direction, 482 357 }; 483 358 ··· 491 364 492 365 switch (param) { 493 366 case PIN_CONFIG_OUTPUT: 367 + case PIN_CONFIG_INPUT_ENABLE: 494 368 arg = rk805_gpio_get(&pci->gpio_chip, pin); 495 369 break; 496 370 default: ··· 521 393 rk805_gpio_set(&pci->gpio_chip, pin, arg); 522 394 rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false); 523 395 break; 396 + case PIN_CONFIG_INPUT_ENABLE: 397 + if (pci->rk808->variant != RK805_ID && arg) { 398 + rk805_pmx_gpio_set_direction(pctldev, NULL, pin, true); 399 + break; 400 + } 401 + fallthrough; 524 402 default: 525 403 dev_err(pci->dev, "Properties not supported\n"); 526 404 return -ENOTSUPP; ··· 582 448 pci->pin_cfg = rk805_gpio_cfgs; 583 449 pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs); 584 450 break; 451 + case RK806_ID: 452 + pci->pins = rk806_pins_desc; 453 + pci->num_pins = ARRAY_SIZE(rk806_pins_desc); 454 + pci->functions = rk806_pin_functions; 455 + pci->num_functions = ARRAY_SIZE(rk806_pin_functions); 456 + pci->groups = rk806_pin_groups; 457 + pci->num_pin_groups = ARRAY_SIZE(rk806_pin_groups); 458 + pci->pinctrl_desc.pins = rk806_pins_desc; 459 + pci->pinctrl_desc.npins = ARRAY_SIZE(rk806_pins_desc); 460 + pci->pin_cfg = rk806_gpio_cfgs; 461 + pci->gpio_chip.ngpio = ARRAY_SIZE(rk806_gpio_cfgs); 462 + break; 585 463 default: 586 464 dev_err(&pdev->dev, "unsupported RK805 ID %lu\n", 587 465 pci->rk808->variant); ··· 634 488 module_platform_driver(rk805_pinctrl_driver); 635 489 636 490 MODULE_DESCRIPTION("RK805 pin control and GPIO driver"); 491 + MODULE_AUTHOR("Xu Shengfei <xsf@rock-chips.com>"); 637 492 MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>"); 638 493 MODULE_LICENSE("GPL v2");