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

pinctrl: realtek: Add common pinctrl driver for Realtek DHC RTD SoCs

The RTD SoCs share a similar design for pinmux and pinconfig.
This common pinctrl driver supports different variants within the RTD
SoCs.

Signed-off-by: Tzuyi Chang <tychang@realtek.com>
Link: https://lore.kernel.org/r/20230919101117.4097-2-tychang@realtek.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Tzuyi Chang and committed by
Linus Walleij
e99ce780 f3244b65

+717
+1
drivers/pinctrl/Kconfig
··· 520 520 source "drivers/pinctrl/nxp/Kconfig" 521 521 source "drivers/pinctrl/pxa/Kconfig" 522 522 source "drivers/pinctrl/qcom/Kconfig" 523 + source "drivers/pinctrl/realtek/Kconfig" 523 524 source "drivers/pinctrl/renesas/Kconfig" 524 525 source "drivers/pinctrl/samsung/Kconfig" 525 526 source "drivers/pinctrl/spear/Kconfig"
+1
drivers/pinctrl/Makefile
··· 66 66 obj-y += nxp/ 67 67 obj-$(CONFIG_PINCTRL_PXA) += pxa/ 68 68 obj-y += qcom/ 69 + obj-$(CONFIG_ARCH_REALTEK) += realtek/ 69 70 obj-$(CONFIG_PINCTRL_RENESAS) += renesas/ 70 71 obj-$(CONFIG_PINCTRL_SAMSUNG) += samsung/ 71 72 obj-$(CONFIG_PINCTRL_SPEAR) += spear/
+8
drivers/pinctrl/realtek/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + config PINCTRL_RTD 4 + tristate "Realtek DHC core pin controller driver" 5 + depends on ARCH_REALTEK 6 + default y 7 + select PINMUX 8 + select GENERIC_PINCONF
+3
drivers/pinctrl/realtek/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-or-later 2 + # Realtek DHC pin control drivers 3 + obj-$(CONFIG_PINCTRL_RTD) += pinctrl-rtd.o
+580
drivers/pinctrl/realtek/pinctrl-rtd.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Realtek DHC pin controller driver 4 + * 5 + * Copyright (c) 2023 Realtek Semiconductor Corp. 6 + */ 7 + 8 + #include <linux/bitops.h> 9 + #include <linux/io.h> 10 + #include <linux/module.h> 11 + #include <linux/of.h> 12 + #include <linux/of_address.h> 13 + #include <linux/pinctrl/machine.h> 14 + #include <linux/pinctrl/pinconf.h> 15 + #include <linux/pinctrl/pinconf-generic.h> 16 + #include <linux/pinctrl/pinctrl.h> 17 + #include <linux/pinctrl/pinmux.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/seq_file.h> 20 + #include <linux/regmap.h> 21 + #include <linux/slab.h> 22 + #include "../core.h" 23 + #include "../pinctrl-utils.h" 24 + #include "pinctrl-rtd.h" 25 + 26 + struct rtd_pinctrl { 27 + struct device *dev; 28 + struct pinctrl_dev *pcdev; 29 + void __iomem *base; 30 + struct pinctrl_desc desc; 31 + const struct rtd_pinctrl_desc *info; 32 + struct regmap *regmap_pinctrl; 33 + }; 34 + 35 + /* custom pinconf parameters */ 36 + #define RTD_DRIVE_STRENGH_P (PIN_CONFIG_END + 1) 37 + #define RTD_DRIVE_STRENGH_N (PIN_CONFIG_END + 2) 38 + #define RTD_DUTY_CYCLE (PIN_CONFIG_END + 3) 39 + 40 + static const struct pinconf_generic_params rtd_custom_bindings[] = { 41 + {"realtek,drive-strength-p", RTD_DRIVE_STRENGH_P, 0}, 42 + {"realtek,drive-strength-n", RTD_DRIVE_STRENGH_N, 0}, 43 + {"realtek,duty-cycle", RTD_DUTY_CYCLE, 0}, 44 + }; 45 + 46 + static int rtd_pinctrl_get_groups_count(struct pinctrl_dev *pcdev) 47 + { 48 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 49 + 50 + return data->info->num_groups; 51 + } 52 + 53 + static const char *rtd_pinctrl_get_group_name(struct pinctrl_dev *pcdev, 54 + unsigned int selector) 55 + { 56 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 57 + 58 + return data->info->groups[selector].name; 59 + } 60 + 61 + static int rtd_pinctrl_get_group_pins(struct pinctrl_dev *pcdev, 62 + unsigned int selector, 63 + const unsigned int **pins, 64 + unsigned int *num_pins) 65 + { 66 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 67 + 68 + *pins = data->info->groups[selector].pins; 69 + *num_pins = data->info->groups[selector].num_pins; 70 + 71 + return 0; 72 + } 73 + 74 + static void rtd_pinctrl_dbg_show(struct pinctrl_dev *pcdev, 75 + struct seq_file *s, 76 + unsigned int offset) 77 + { 78 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 79 + const struct rtd_pin_desc *mux = &data->info->muxes[offset]; 80 + const struct rtd_pin_mux_desc *func; 81 + u32 val; 82 + u32 mask; 83 + u32 pin_val; 84 + int is_map; 85 + 86 + if (!mux->name) { 87 + seq_puts(s, "[not defined]"); 88 + return; 89 + } 90 + val = readl_relaxed(data->base + mux->mux_offset); 91 + mask = mux->mux_mask; 92 + pin_val = val & mask; 93 + 94 + is_map = 0; 95 + func = &mux->functions[0]; 96 + seq_puts(s, "function: "); 97 + while (func->name) { 98 + if (func->mux_value == pin_val) { 99 + is_map = 1; 100 + seq_printf(s, "[%s] ", func->name); 101 + } else { 102 + seq_printf(s, "%s ", func->name); 103 + } 104 + func++; 105 + } 106 + if (!is_map) 107 + seq_puts(s, "[not defined]"); 108 + } 109 + 110 + static const struct pinctrl_ops rtd_pinctrl_ops = { 111 + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, 112 + .dt_free_map = pinctrl_utils_free_map, 113 + .get_groups_count = rtd_pinctrl_get_groups_count, 114 + .get_group_name = rtd_pinctrl_get_group_name, 115 + .get_group_pins = rtd_pinctrl_get_group_pins, 116 + .pin_dbg_show = rtd_pinctrl_dbg_show, 117 + }; 118 + 119 + static int rtd_pinctrl_get_functions_count(struct pinctrl_dev *pcdev) 120 + { 121 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 122 + 123 + return data->info->num_functions; 124 + } 125 + 126 + static const char *rtd_pinctrl_get_function_name(struct pinctrl_dev *pcdev, 127 + unsigned int selector) 128 + { 129 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 130 + 131 + return data->info->functions[selector].name; 132 + } 133 + 134 + static int rtd_pinctrl_get_function_groups(struct pinctrl_dev *pcdev, 135 + unsigned int selector, 136 + const char * const **groups, 137 + unsigned int * const num_groups) 138 + { 139 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 140 + 141 + *groups = data->info->functions[selector].groups; 142 + *num_groups = data->info->functions[selector].num_groups; 143 + 144 + return 0; 145 + } 146 + 147 + static const struct rtd_pin_desc *rtd_pinctrl_find_mux(struct rtd_pinctrl *data, unsigned int pin) 148 + { 149 + if (!data->info->muxes[pin].name) 150 + return &data->info->muxes[pin]; 151 + 152 + return NULL; 153 + } 154 + 155 + static int rtd_pinctrl_set_one_mux(struct pinctrl_dev *pcdev, 156 + unsigned int pin, const char *func_name) 157 + { 158 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 159 + const struct rtd_pin_desc *mux; 160 + int ret = 0; 161 + int i; 162 + 163 + mux = rtd_pinctrl_find_mux(data, pin); 164 + if (!mux) 165 + return 0; 166 + 167 + if (!mux->functions) { 168 + dev_err(pcdev->dev, "No functions available for pin %s\n", mux->name); 169 + return -ENOTSUPP; 170 + } 171 + 172 + for (i = 0; mux->functions[i].name; i++) { 173 + if (strcmp(mux->functions[i].name, func_name) != 0) 174 + continue; 175 + ret = regmap_update_bits(data->regmap_pinctrl, mux->mux_offset, mux->mux_mask, 176 + mux->functions[i].mux_value); 177 + return ret; 178 + } 179 + 180 + dev_err(pcdev->dev, "No function %s available for pin %s\n", func_name, mux->name); 181 + 182 + return -EINVAL; 183 + } 184 + 185 + static int rtd_pinctrl_set_mux(struct pinctrl_dev *pcdev, 186 + unsigned int function, unsigned int group) 187 + { 188 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 189 + const unsigned int *pins; 190 + unsigned int num_pins; 191 + const char *func_name; 192 + const char *group_name; 193 + int i, ret; 194 + 195 + func_name = data->info->functions[function].name; 196 + group_name = data->info->groups[group].name; 197 + 198 + ret = rtd_pinctrl_get_group_pins(pcdev, group, &pins, &num_pins); 199 + if (ret) { 200 + dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name); 201 + return ret; 202 + } 203 + 204 + for (i = 0; i < num_pins; i++) { 205 + ret = rtd_pinctrl_set_one_mux(pcdev, pins[i], func_name); 206 + if (ret) 207 + return ret; 208 + } 209 + 210 + return 0; 211 + } 212 + 213 + static int rtd_pinctrl_gpio_request_enable(struct pinctrl_dev *pcdev, 214 + struct pinctrl_gpio_range *range, 215 + unsigned int offset) 216 + { 217 + return rtd_pinctrl_set_one_mux(pcdev, offset, "gpio"); 218 + } 219 + 220 + static const struct pinmux_ops rtd_pinmux_ops = { 221 + .get_functions_count = rtd_pinctrl_get_functions_count, 222 + .get_function_name = rtd_pinctrl_get_function_name, 223 + .get_function_groups = rtd_pinctrl_get_function_groups, 224 + .set_mux = rtd_pinctrl_set_mux, 225 + .gpio_request_enable = rtd_pinctrl_gpio_request_enable, 226 + }; 227 + 228 + static const struct pinctrl_pin_desc 229 + *rtd_pinctrl_get_pin_by_number(struct rtd_pinctrl *data, int number) 230 + { 231 + int i; 232 + 233 + for (i = 0; i < data->info->num_pins; i++) { 234 + if (data->info->pins[i].number == number) 235 + return &data->info->pins[i]; 236 + } 237 + 238 + return NULL; 239 + } 240 + 241 + static const struct rtd_pin_config_desc 242 + *rtd_pinctrl_find_config(struct rtd_pinctrl *data, unsigned int pin) 243 + { 244 + if (!data->info->configs[pin].name) 245 + return &data->info->configs[pin]; 246 + 247 + return NULL; 248 + } 249 + 250 + static const struct rtd_pin_sconfig_desc *rtd_pinctrl_find_sconfig(struct rtd_pinctrl *data, 251 + unsigned int pin) 252 + { 253 + int i; 254 + const struct pinctrl_pin_desc *pin_desc; 255 + const char *pin_name; 256 + 257 + pin_desc = rtd_pinctrl_get_pin_by_number(data, pin); 258 + if (!pin_desc) 259 + return NULL; 260 + 261 + pin_name = pin_desc->name; 262 + 263 + for (i = 0; i < data->info->num_sconfigs; i++) { 264 + if (strcmp(data->info->sconfigs[i].name, pin_name) == 0) 265 + return &data->info->sconfigs[i]; 266 + } 267 + 268 + return NULL; 269 + } 270 + 271 + static int rtd_pconf_parse_conf(struct rtd_pinctrl *data, 272 + unsigned int pinnr, 273 + enum pin_config_param param, 274 + enum pin_config_param arg) 275 + { 276 + const struct rtd_pin_config_desc *config_desc; 277 + const struct rtd_pin_sconfig_desc *sconfig_desc; 278 + u8 set_val = 0; 279 + u16 strength; 280 + u32 val; 281 + u32 mask; 282 + u32 pulsel_off, pulen_off, smt_off, curr_off, pow_off, reg_off, p_off, n_off; 283 + const char *name = data->info->pins[pinnr].name; 284 + int ret = 0; 285 + 286 + config_desc = rtd_pinctrl_find_config(data, pinnr); 287 + if (!config_desc) { 288 + dev_err(data->dev, "Not support pin config for pin: %s\n", name); 289 + return -ENOTSUPP; 290 + } 291 + switch ((u32)param) { 292 + case PIN_CONFIG_INPUT_SCHMITT: 293 + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: 294 + if (config_desc->smt_offset == NA) { 295 + dev_err(data->dev, "Not support input schmitt for pin: %s\n", name); 296 + return -ENOTSUPP; 297 + } 298 + smt_off = config_desc->base_bit + config_desc->smt_offset; 299 + reg_off = config_desc->reg_offset; 300 + set_val = arg; 301 + 302 + mask = BIT(smt_off); 303 + val = set_val ? BIT(smt_off) : 0; 304 + break; 305 + 306 + case PIN_CONFIG_DRIVE_PUSH_PULL: 307 + if (config_desc->pud_en_offset == NA) { 308 + dev_err(data->dev, "Not support push pull for pin: %s\n", name); 309 + return -ENOTSUPP; 310 + } 311 + pulen_off = config_desc->base_bit + config_desc->pud_en_offset; 312 + reg_off = config_desc->reg_offset; 313 + 314 + mask = BIT(pulen_off); 315 + val = 0; 316 + break; 317 + 318 + case PIN_CONFIG_BIAS_DISABLE: 319 + if (config_desc->pud_en_offset == NA) { 320 + dev_err(data->dev, "Not support bias disable for pin: %s\n", name); 321 + return -ENOTSUPP; 322 + } 323 + pulen_off = config_desc->base_bit + config_desc->pud_en_offset; 324 + reg_off = config_desc->reg_offset; 325 + 326 + mask = BIT(pulen_off); 327 + val = 0; 328 + break; 329 + 330 + case PIN_CONFIG_BIAS_PULL_UP: 331 + if (config_desc->pud_en_offset == NA) { 332 + dev_err(data->dev, "Not support bias pull up for pin:%s\n", name); 333 + return -ENOTSUPP; 334 + } 335 + pulen_off = config_desc->base_bit + config_desc->pud_en_offset; 336 + pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset; 337 + reg_off = config_desc->reg_offset; 338 + 339 + mask = BIT(pulen_off) | BIT(pulsel_off); 340 + val = mask; 341 + break; 342 + 343 + case PIN_CONFIG_BIAS_PULL_DOWN: 344 + if (config_desc->pud_en_offset == NA) { 345 + dev_err(data->dev, "Not support bias pull down for pin: %s\n", name); 346 + return -ENOTSUPP; 347 + } 348 + pulen_off = config_desc->base_bit + config_desc->pud_en_offset; 349 + pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset; 350 + reg_off = config_desc->reg_offset; 351 + 352 + mask = BIT(pulen_off) | BIT(pulsel_off); 353 + val = BIT(pulen_off); 354 + break; 355 + 356 + case PIN_CONFIG_DRIVE_STRENGTH: 357 + curr_off = config_desc->base_bit + config_desc->curr_offset; 358 + reg_off = config_desc->reg_offset; 359 + strength = arg; 360 + val = 0; 361 + switch (config_desc->curr_type) { 362 + case PADDRI_4_8: 363 + if (strength == 4) 364 + val = 0; 365 + else if (strength == 8) 366 + val = BIT(curr_off); 367 + else 368 + return -EINVAL; 369 + break; 370 + case PADDRI_2_4: 371 + if (strength == 2) 372 + val = 0; 373 + else if (strength == 4) 374 + val = BIT(curr_off); 375 + else 376 + return -EINVAL; 377 + break; 378 + case NA: 379 + dev_err(data->dev, "Not support drive strength for pin: %s\n", name); 380 + return -ENOTSUPP; 381 + default: 382 + return -EINVAL; 383 + } 384 + mask = BIT(curr_off); 385 + break; 386 + 387 + case PIN_CONFIG_POWER_SOURCE: 388 + if (config_desc->power_offset == NA) { 389 + dev_err(data->dev, "Not support power source for pin: %s\n", name); 390 + return -ENOTSUPP; 391 + } 392 + reg_off = config_desc->reg_offset; 393 + pow_off = config_desc->base_bit + config_desc->power_offset; 394 + if (pow_off >= 32) { 395 + reg_off += 0x4; 396 + pow_off -= 32; 397 + } 398 + set_val = arg; 399 + mask = BIT(pow_off); 400 + val = set_val ? mask : 0; 401 + break; 402 + 403 + case RTD_DRIVE_STRENGH_P: 404 + sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr); 405 + if (!sconfig_desc) { 406 + dev_err(data->dev, "Not support P driving for pin: %s\n", name); 407 + return -ENOTSUPP; 408 + } 409 + set_val = arg; 410 + reg_off = sconfig_desc->reg_offset; 411 + p_off = sconfig_desc->pdrive_offset; 412 + if (p_off >= 32) { 413 + reg_off += 0x4; 414 + p_off -= 32; 415 + } 416 + mask = GENMASK(p_off + sconfig_desc->pdrive_maskbits - 1, p_off); 417 + val = set_val << p_off; 418 + break; 419 + 420 + case RTD_DRIVE_STRENGH_N: 421 + sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr); 422 + if (!sconfig_desc) { 423 + dev_err(data->dev, "Not support N driving for pin: %s\n", name); 424 + return -ENOTSUPP; 425 + } 426 + set_val = arg; 427 + reg_off = sconfig_desc->reg_offset; 428 + n_off = sconfig_desc->ndrive_offset; 429 + if (n_off >= 32) { 430 + reg_off += 0x4; 431 + n_off -= 32; 432 + } 433 + mask = GENMASK(n_off + sconfig_desc->ndrive_maskbits - 1, n_off); 434 + val = set_val << n_off; 435 + break; 436 + 437 + case RTD_DUTY_CYCLE: 438 + sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr); 439 + if (!sconfig_desc || sconfig_desc->dcycle_offset == NA) { 440 + dev_err(data->dev, "Not support duty cycle for pin: %s\n", name); 441 + return -ENOTSUPP; 442 + } 443 + set_val = arg; 444 + reg_off = config_desc->reg_offset; 445 + mask = GENMASK(sconfig_desc->dcycle_offset + 446 + sconfig_desc->dcycle_maskbits - 1, sconfig_desc->dcycle_offset); 447 + val = set_val << sconfig_desc->dcycle_offset; 448 + break; 449 + 450 + default: 451 + dev_err(data->dev, "unsupported pinconf: %d\n", (u32)param); 452 + return -EINVAL; 453 + } 454 + 455 + ret = regmap_update_bits(data->regmap_pinctrl, reg_off, mask, val); 456 + if (ret) 457 + dev_err(data->dev, "could not update pinconf(%d) for pin(%s)\n", (u32)param, name); 458 + 459 + return ret; 460 + } 461 + 462 + static int rtd_pin_config_get(struct pinctrl_dev *pcdev, unsigned int pinnr, 463 + unsigned long *config) 464 + { 465 + unsigned int param = pinconf_to_config_param(*config); 466 + unsigned int arg = 0; 467 + 468 + switch (param) { 469 + default: 470 + return -ENOTSUPP; 471 + } 472 + 473 + *config = pinconf_to_config_packed(param, arg); 474 + return 0; 475 + } 476 + 477 + static int rtd_pin_config_set(struct pinctrl_dev *pcdev, unsigned int pinnr, 478 + unsigned long *configs, unsigned int num_configs) 479 + { 480 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 481 + int i; 482 + int ret = 0; 483 + 484 + for (i = 0; i < num_configs; i++) { 485 + ret = rtd_pconf_parse_conf(data, pinnr, 486 + pinconf_to_config_param(configs[i]), 487 + pinconf_to_config_argument(configs[i])); 488 + if (ret < 0) 489 + return ret; 490 + } 491 + 492 + return 0; 493 + } 494 + 495 + static int rtd_pin_config_group_set(struct pinctrl_dev *pcdev, unsigned int group, 496 + unsigned long *configs, unsigned int num_configs) 497 + { 498 + struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev); 499 + const unsigned int *pins; 500 + unsigned int num_pins; 501 + const char *group_name; 502 + int i, ret; 503 + 504 + group_name = data->info->groups[group].name; 505 + 506 + ret = rtd_pinctrl_get_group_pins(pcdev, group, &pins, &num_pins); 507 + if (ret) { 508 + dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name); 509 + return ret; 510 + } 511 + 512 + for (i = 0; i < num_pins; i++) { 513 + ret = rtd_pin_config_set(pcdev, pins[i], configs, num_configs); 514 + if (ret) 515 + return ret; 516 + } 517 + 518 + return 0; 519 + } 520 + 521 + static const struct pinconf_ops rtd_pinconf_ops = { 522 + .is_generic = true, 523 + .pin_config_get = rtd_pin_config_get, 524 + .pin_config_set = rtd_pin_config_set, 525 + .pin_config_group_set = rtd_pin_config_group_set, 526 + }; 527 + 528 + static struct regmap_config rtd_pinctrl_regmap_config = { 529 + .reg_bits = 32, 530 + .val_bits = 32, 531 + .reg_stride = 4, 532 + .use_relaxed_mmio = true, 533 + }; 534 + 535 + int rtd_pinctrl_probe(struct platform_device *pdev, const struct rtd_pinctrl_desc *desc) 536 + { 537 + struct rtd_pinctrl *data; 538 + 539 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 540 + if (!data) 541 + return -ENOMEM; 542 + 543 + data->base = of_iomap(pdev->dev.of_node, 0); 544 + if (IS_ERR(data->base)) 545 + return PTR_ERR(data->base); 546 + 547 + data->dev = &pdev->dev; 548 + data->info = desc; 549 + data->desc.name = dev_name(&pdev->dev); 550 + data->desc.pins = data->info->pins; 551 + data->desc.npins = data->info->num_pins; 552 + data->desc.pctlops = &rtd_pinctrl_ops; 553 + data->desc.pmxops = &rtd_pinmux_ops; 554 + data->desc.confops = &rtd_pinconf_ops; 555 + data->desc.custom_params = rtd_custom_bindings; 556 + data->desc.num_custom_params = ARRAY_SIZE(rtd_custom_bindings); 557 + data->desc.owner = THIS_MODULE; 558 + data->regmap_pinctrl = devm_regmap_init_mmio(data->dev, data->base, 559 + &rtd_pinctrl_regmap_config); 560 + 561 + if (IS_ERR(data->regmap_pinctrl)) { 562 + dev_err(data->dev, "failed to init regmap: %ld\n", 563 + PTR_ERR(data->regmap_pinctrl)); 564 + return PTR_ERR(data->regmap_pinctrl); 565 + } 566 + 567 + data->pcdev = pinctrl_register(&data->desc, &pdev->dev, data); 568 + if (!data->pcdev) 569 + return -ENOMEM; 570 + 571 + platform_set_drvdata(pdev, data); 572 + 573 + dev_dbg(&pdev->dev, "probed\n"); 574 + 575 + return 0; 576 + } 577 + EXPORT_SYMBOL(rtd_pinctrl_probe); 578 + 579 + MODULE_DESCRIPTION("Realtek DHC SoC pinctrl driver"); 580 + MODULE_LICENSE("GPL v2");
+124
drivers/pinctrl/realtek/pinctrl-rtd.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright (c) 2023 Realtek Semiconductor Corp. 4 + */ 5 + 6 + #define NA 0xffffffff 7 + #define PADDRI_4_8 1 8 + #define PADDRI_2_4 0 9 + 10 + struct rtd_pin_group_desc { 11 + const char *name; 12 + const unsigned int *pins; 13 + unsigned int num_pins; 14 + }; 15 + 16 + struct rtd_pin_func_desc { 17 + const char *name; 18 + const char * const *groups; 19 + unsigned int num_groups; 20 + }; 21 + 22 + struct rtd_pin_mux_desc { 23 + const char *name; 24 + u32 mux_value; 25 + }; 26 + 27 + struct rtd_pin_config_desc { 28 + const char *name; 29 + unsigned int reg_offset; 30 + unsigned int base_bit; 31 + unsigned int pud_en_offset; 32 + unsigned int pud_sel_offset; 33 + unsigned int curr_offset; 34 + unsigned int smt_offset; 35 + unsigned int power_offset; 36 + unsigned int curr_type; 37 + }; 38 + 39 + struct rtd_pin_sconfig_desc { 40 + const char *name; 41 + unsigned int reg_offset; 42 + unsigned int dcycle_offset; 43 + unsigned int dcycle_maskbits; 44 + unsigned int ndrive_offset; 45 + unsigned int ndrive_maskbits; 46 + unsigned int pdrive_offset; 47 + unsigned int pdrive_maskbits; 48 + }; 49 + 50 + struct rtd_pin_desc { 51 + const char *name; 52 + unsigned int mux_offset; 53 + u32 mux_mask; 54 + const struct rtd_pin_mux_desc *functions; 55 + }; 56 + 57 + struct rtd_pin_reg_list { 58 + unsigned int reg_offset; 59 + unsigned int val; 60 + }; 61 + 62 + #define SHIFT_LEFT(_val, _shift) ((_val) << (_shift)) 63 + 64 + #define RTK_PIN_MUX(_name, _mux_off, _mux_mask, ...) \ 65 + { \ 66 + .name = # _name, \ 67 + .mux_offset = _mux_off, \ 68 + .mux_mask = _mux_mask, \ 69 + .functions = (const struct rtd_pin_mux_desc []) { \ 70 + __VA_ARGS__, { } \ 71 + }, \ 72 + } 73 + 74 + #define RTK_PIN_CONFIG(_name, _reg_off, _base_bit, _pud_en_off, \ 75 + _pud_sel_off, _curr_off, _smt_off, _pow_off, _curr_type) \ 76 + { \ 77 + .name = # _name, \ 78 + .reg_offset = _reg_off, \ 79 + .base_bit = _base_bit, \ 80 + .pud_en_offset = _pud_en_off, \ 81 + .pud_sel_offset = _pud_sel_off, \ 82 + .curr_offset = _curr_off, \ 83 + .smt_offset = _smt_off, \ 84 + .power_offset = _pow_off, \ 85 + .curr_type = _curr_type, \ 86 + } 87 + 88 + #define RTK_PIN_SCONFIG(_name, _reg_off, _d_offset, _d_mask, \ 89 + _n_offset, _n_mask, _p_offset, _p_mask) \ 90 + { \ 91 + .name = # _name, \ 92 + .reg_offset = _reg_off, \ 93 + .dcycle_offset = _d_offset, \ 94 + .dcycle_maskbits = _d_mask, \ 95 + .ndrive_offset = _n_offset, \ 96 + .ndrive_maskbits = _n_mask, \ 97 + .pdrive_offset = _p_offset, \ 98 + .pdrive_maskbits = _p_mask, \ 99 + } 100 + 101 + #define RTK_PIN_FUNC(_mux_val, _name) \ 102 + { \ 103 + .name = _name, \ 104 + .mux_value = _mux_val, \ 105 + } 106 + 107 + struct rtd_pinctrl_desc { 108 + const struct pinctrl_pin_desc *pins; 109 + unsigned int num_pins; 110 + const struct rtd_pin_group_desc *groups; 111 + unsigned int num_groups; 112 + const struct rtd_pin_func_desc *functions; 113 + unsigned int num_functions; 114 + const struct rtd_pin_desc *muxes; 115 + unsigned int num_muxes; 116 + const struct rtd_pin_config_desc *configs; 117 + unsigned int num_configs; 118 + const struct rtd_pin_sconfig_desc *sconfigs; 119 + unsigned int num_sconfigs; 120 + struct rtd_pin_reg_list *lists; 121 + unsigned int num_regs; 122 + }; 123 + 124 + int rtd_pinctrl_probe(struct platform_device *pdev, const struct rtd_pinctrl_desc *desc);