597 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Realtek DHC pin controller driver4 *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 26struct 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 40static 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 46static 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 53static 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 61static 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 74static 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 110static 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 119static 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 126static 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 134static 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 147static 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 155static 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 if (!mux->name)169 dev_err(pcdev->dev, "NULL pin has no functions\n");170 else171 dev_err(pcdev->dev, "No functions available for pin %s\n", mux->name);172 return -ENOTSUPP;173 }174 175 for (i = 0; mux->functions[i].name; i++) {176 if (strcmp(mux->functions[i].name, func_name) != 0)177 continue;178 ret = regmap_update_bits(data->regmap_pinctrl, mux->mux_offset, mux->mux_mask,179 mux->functions[i].mux_value);180 return ret;181 }182 183 if (!mux->name) {184 dev_err(pcdev->dev, "NULL pin provided for function %s\n", func_name);185 return -EINVAL;186 }187 188 dev_err(pcdev->dev, "No function %s available for pin %s\n", func_name, mux->name);189 190 return -EINVAL;191}192 193static int rtd_pinctrl_set_mux(struct pinctrl_dev *pcdev,194 unsigned int function, unsigned int group)195{196 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);197 const unsigned int *pins;198 unsigned int num_pins;199 const char *func_name;200 const char *group_name;201 int i, ret;202 203 func_name = data->info->functions[function].name;204 group_name = data->info->groups[group].name;205 206 ret = rtd_pinctrl_get_group_pins(pcdev, group, &pins, &num_pins);207 if (ret) {208 dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name);209 return ret;210 }211 212 for (i = 0; i < num_pins; i++) {213 ret = rtd_pinctrl_set_one_mux(pcdev, pins[i], func_name);214 if (ret)215 return ret;216 }217 218 return 0;219}220 221static int rtd_pinctrl_gpio_request_enable(struct pinctrl_dev *pcdev,222 struct pinctrl_gpio_range *range,223 unsigned int offset)224{225 return rtd_pinctrl_set_one_mux(pcdev, offset, "gpio");226}227 228static const struct pinmux_ops rtd_pinmux_ops = {229 .get_functions_count = rtd_pinctrl_get_functions_count,230 .get_function_name = rtd_pinctrl_get_function_name,231 .get_function_groups = rtd_pinctrl_get_function_groups,232 .set_mux = rtd_pinctrl_set_mux,233 .gpio_request_enable = rtd_pinctrl_gpio_request_enable,234};235 236static const struct pinctrl_pin_desc237 *rtd_pinctrl_get_pin_by_number(struct rtd_pinctrl *data, int number)238{239 int i;240 241 for (i = 0; i < data->info->num_pins; i++) {242 if (data->info->pins[i].number == number)243 return &data->info->pins[i];244 }245 246 return NULL;247}248 249static const struct rtd_pin_config_desc250 *rtd_pinctrl_find_config(struct rtd_pinctrl *data, unsigned int pin)251{252 if (data->info->configs[pin].name)253 return &data->info->configs[pin];254 255 return NULL;256}257 258static const struct rtd_pin_sconfig_desc *rtd_pinctrl_find_sconfig(struct rtd_pinctrl *data,259 unsigned int pin)260{261 int i;262 const struct pinctrl_pin_desc *pin_desc;263 const char *pin_name;264 265 pin_desc = rtd_pinctrl_get_pin_by_number(data, pin);266 if (!pin_desc)267 return NULL;268 269 pin_name = pin_desc->name;270 271 for (i = 0; i < data->info->num_sconfigs; i++) {272 if (strcmp(data->info->sconfigs[i].name, pin_name) == 0)273 return &data->info->sconfigs[i];274 }275 276 return NULL;277}278 279static int rtd_pconf_parse_conf(struct rtd_pinctrl *data,280 unsigned int pinnr,281 enum pin_config_param param,282 enum pin_config_param arg)283{284 const struct rtd_pin_config_desc *config_desc;285 const struct rtd_pin_sconfig_desc *sconfig_desc;286 u8 set_val = 0;287 u16 strength;288 u32 val;289 u32 mask;290 u32 pulsel_off, pulen_off, smt_off, curr_off, pow_off, reg_off, p_off, n_off;291 const char *name = data->info->pins[pinnr].name;292 int ret = 0;293 294 config_desc = rtd_pinctrl_find_config(data, pinnr);295 if (!config_desc) {296 dev_err(data->dev, "Not support pin config for pin: %s\n", name);297 return -ENOTSUPP;298 }299 switch ((u32)param) {300 case PIN_CONFIG_INPUT_SCHMITT:301 case PIN_CONFIG_INPUT_SCHMITT_ENABLE:302 if (config_desc->smt_offset == NA) {303 dev_err(data->dev, "Not support input schmitt for pin: %s\n", name);304 return -ENOTSUPP;305 }306 smt_off = config_desc->base_bit + config_desc->smt_offset;307 reg_off = config_desc->reg_offset;308 set_val = arg;309 310 mask = BIT(smt_off);311 val = set_val ? BIT(smt_off) : 0;312 break;313 314 case PIN_CONFIG_DRIVE_PUSH_PULL:315 if (config_desc->pud_en_offset == NA) {316 dev_err(data->dev, "Not support push pull for pin: %s\n", name);317 return -ENOTSUPP;318 }319 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;320 reg_off = config_desc->reg_offset;321 322 mask = BIT(pulen_off);323 val = 0;324 break;325 326 case PIN_CONFIG_BIAS_DISABLE:327 if (config_desc->pud_en_offset == NA) {328 dev_err(data->dev, "Not support bias disable for pin: %s\n", name);329 return -ENOTSUPP;330 }331 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;332 reg_off = config_desc->reg_offset;333 334 mask = BIT(pulen_off);335 val = 0;336 break;337 338 case PIN_CONFIG_BIAS_PULL_UP:339 if (config_desc->pud_en_offset == NA) {340 dev_err(data->dev, "Not support bias pull up for pin:%s\n", name);341 return -ENOTSUPP;342 }343 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;344 pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset;345 reg_off = config_desc->reg_offset;346 347 mask = BIT(pulen_off) | BIT(pulsel_off);348 val = mask;349 break;350 351 case PIN_CONFIG_BIAS_PULL_DOWN:352 if (config_desc->pud_en_offset == NA) {353 dev_err(data->dev, "Not support bias pull down for pin: %s\n", name);354 return -ENOTSUPP;355 }356 pulen_off = config_desc->base_bit + config_desc->pud_en_offset;357 pulsel_off = config_desc->base_bit + config_desc->pud_sel_offset;358 reg_off = config_desc->reg_offset;359 360 mask = BIT(pulen_off) | BIT(pulsel_off);361 val = BIT(pulen_off);362 break;363 364 case PIN_CONFIG_DRIVE_STRENGTH:365 curr_off = config_desc->base_bit + config_desc->curr_offset;366 reg_off = config_desc->reg_offset;367 strength = arg;368 val = 0;369 switch (config_desc->curr_type) {370 case PADDRI_4_8:371 if (strength == 4)372 val = 0;373 else if (strength == 8)374 val = BIT(curr_off);375 else376 return -EINVAL;377 break;378 case PADDRI_2_4:379 if (strength == 2)380 val = 0;381 else if (strength == 4)382 val = BIT(curr_off);383 else384 return -EINVAL;385 break;386 case NA:387 dev_err(data->dev, "Not support drive strength for pin: %s\n", name);388 return -ENOTSUPP;389 default:390 return -EINVAL;391 }392 mask = BIT(curr_off);393 break;394 395 case PIN_CONFIG_POWER_SOURCE:396 if (config_desc->power_offset == NA) {397 dev_err(data->dev, "Not support power source for pin: %s\n", name);398 return -ENOTSUPP;399 }400 reg_off = config_desc->reg_offset;401 pow_off = config_desc->base_bit + config_desc->power_offset;402 if (pow_off >= 32) {403 reg_off += 0x4;404 pow_off -= 32;405 }406 set_val = arg;407 mask = BIT(pow_off);408 val = set_val ? mask : 0;409 break;410 411 case RTD_DRIVE_STRENGH_P:412 sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr);413 if (!sconfig_desc) {414 dev_err(data->dev, "Not support P driving for pin: %s\n", name);415 return -ENOTSUPP;416 }417 set_val = arg;418 reg_off = sconfig_desc->reg_offset;419 p_off = sconfig_desc->pdrive_offset;420 if (p_off >= 32) {421 reg_off += 0x4;422 p_off -= 32;423 }424 mask = GENMASK(p_off + sconfig_desc->pdrive_maskbits - 1, p_off);425 val = set_val << p_off;426 break;427 428 case RTD_DRIVE_STRENGH_N:429 sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr);430 if (!sconfig_desc) {431 dev_err(data->dev, "Not support N driving for pin: %s\n", name);432 return -ENOTSUPP;433 }434 set_val = arg;435 reg_off = sconfig_desc->reg_offset;436 n_off = sconfig_desc->ndrive_offset;437 if (n_off >= 32) {438 reg_off += 0x4;439 n_off -= 32;440 }441 mask = GENMASK(n_off + sconfig_desc->ndrive_maskbits - 1, n_off);442 val = set_val << n_off;443 break;444 445 case RTD_DUTY_CYCLE:446 sconfig_desc = rtd_pinctrl_find_sconfig(data, pinnr);447 if (!sconfig_desc || sconfig_desc->dcycle_offset == NA) {448 dev_err(data->dev, "Not support duty cycle for pin: %s\n", name);449 return -ENOTSUPP;450 }451 set_val = arg;452 reg_off = config_desc->reg_offset;453 mask = GENMASK(sconfig_desc->dcycle_offset +454 sconfig_desc->dcycle_maskbits - 1, sconfig_desc->dcycle_offset);455 val = set_val << sconfig_desc->dcycle_offset;456 break;457 458 default:459 dev_err(data->dev, "unsupported pinconf: %d\n", (u32)param);460 return -EINVAL;461 }462 463 ret = regmap_update_bits(data->regmap_pinctrl, reg_off, mask, val);464 if (ret)465 dev_err(data->dev, "could not update pinconf(%d) for pin(%s)\n", (u32)param, name);466 467 return ret;468}469 470static int rtd_pin_config_get(struct pinctrl_dev *pcdev, unsigned int pinnr,471 unsigned long *config)472{473 unsigned int param = pinconf_to_config_param(*config);474 unsigned int arg = 0;475 476 switch (param) {477 default:478 return -ENOTSUPP;479 }480 481 *config = pinconf_to_config_packed(param, arg);482 return 0;483}484 485static int rtd_pin_config_set(struct pinctrl_dev *pcdev, unsigned int pinnr,486 unsigned long *configs, unsigned int num_configs)487{488 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);489 int i;490 int ret = 0;491 492 for (i = 0; i < num_configs; i++) {493 ret = rtd_pconf_parse_conf(data, pinnr,494 pinconf_to_config_param(configs[i]),495 pinconf_to_config_argument(configs[i]));496 if (ret < 0)497 return ret;498 }499 500 return 0;501}502 503static int rtd_pin_config_group_set(struct pinctrl_dev *pcdev, unsigned int group,504 unsigned long *configs, unsigned int num_configs)505{506 struct rtd_pinctrl *data = pinctrl_dev_get_drvdata(pcdev);507 const unsigned int *pins;508 unsigned int num_pins;509 const char *group_name;510 int i, ret;511 512 group_name = data->info->groups[group].name;513 514 ret = rtd_pinctrl_get_group_pins(pcdev, group, &pins, &num_pins);515 if (ret) {516 dev_err(pcdev->dev, "Getting pins for group %s failed\n", group_name);517 return ret;518 }519 520 for (i = 0; i < num_pins; i++) {521 ret = rtd_pin_config_set(pcdev, pins[i], configs, num_configs);522 if (ret)523 return ret;524 }525 526 return 0;527}528 529static const struct pinconf_ops rtd_pinconf_ops = {530 .is_generic = true,531 .pin_config_get = rtd_pin_config_get,532 .pin_config_set = rtd_pin_config_set,533 .pin_config_group_set = rtd_pin_config_group_set,534};535 536static const struct regmap_config rtd_pinctrl_regmap_config = {537 .reg_bits = 32,538 .val_bits = 32,539 .reg_stride = 4,540 .use_relaxed_mmio = true,541};542 543int rtd_pinctrl_probe(struct platform_device *pdev, const struct rtd_pinctrl_desc *desc)544{545 struct rtd_pinctrl *data;546 int ret;547 548 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);549 if (!data)550 return -ENOMEM;551 552 data->base = of_iomap(pdev->dev.of_node, 0);553 if (!data->base)554 return -ENOMEM;555 556 data->dev = &pdev->dev;557 data->info = desc;558 data->desc.name = dev_name(&pdev->dev);559 data->desc.pins = data->info->pins;560 data->desc.npins = data->info->num_pins;561 data->desc.pctlops = &rtd_pinctrl_ops;562 data->desc.pmxops = &rtd_pinmux_ops;563 data->desc.confops = &rtd_pinconf_ops;564 data->desc.custom_params = rtd_custom_bindings;565 data->desc.num_custom_params = ARRAY_SIZE(rtd_custom_bindings);566 data->desc.owner = THIS_MODULE;567 data->regmap_pinctrl = devm_regmap_init_mmio(data->dev, data->base,568 &rtd_pinctrl_regmap_config);569 570 if (IS_ERR(data->regmap_pinctrl)) {571 dev_err(data->dev, "failed to init regmap: %ld\n",572 PTR_ERR(data->regmap_pinctrl));573 ret = PTR_ERR(data->regmap_pinctrl);574 goto unmap;575 }576 577 data->pcdev = pinctrl_register(&data->desc, &pdev->dev, data);578 if (IS_ERR(data->pcdev)) {579 ret = PTR_ERR(data->pcdev);580 goto unmap;581 }582 583 platform_set_drvdata(pdev, data);584 585 dev_dbg(&pdev->dev, "probed\n");586 587 return 0;588 589unmap:590 iounmap(data->base);591 return ret;592}593EXPORT_SYMBOL(rtd_pinctrl_probe);594 595MODULE_DESCRIPTION("Realtek DHC SoC pinctrl driver");596MODULE_LICENSE("GPL v2");597