Lines Matching +full:custom +full:- +full:output +full:- +full:range +full:- +full:config

1 // SPDX-License-Identifier: GPL-2.0
3 * MediaTek Pinctrl Paris Driver, which implement the vendor per-pin
18 #include <dt-bindings/pinctrl/mt65xx.h>
20 #include "pinctrl-paris.h"
24 /* Custom pinconf parameters */
34 {"mediatek,pull-up-adv", MTK_PIN_CONFIG_PU_ADV, 1},
35 {"mediatek,pull-down-adv", MTK_PIN_CONFIG_PD_ADV, 1},
36 {"mediatek,drive-strength-adv", MTK_PIN_CONFIG_DRV_ADV, 2},
43 PCONFDUMP(MTK_PIN_CONFIG_PU_ADV, "pu-adv", NULL, true),
44 PCONFDUMP(MTK_PIN_CONFIG_PD_ADV, "pd-adv", NULL, true),
45 PCONFDUMP(MTK_PIN_CONFIG_DRV_ADV, "drive-strength-adv", NULL, true),
57 * This section supports converting to/from custom MTK_PIN_CONFIG_DRV_ADV
60 * The custom value encodes three hardware bits as follows:
64 * ------------------------------------------------
66 * -------------------------------------
78 return -EINVAL; in mtk_drv_adv_to_uA()
82 return -EINVAL; in mtk_drv_adv_to_uA()
100 return -EINVAL; in mtk_drv_uA_to_adv()
104 struct pinctrl_gpio_range *range, in mtk_pinmux_gpio_request_enable() argument
110 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; in mtk_pinmux_gpio_request_enable()
113 hw->soc->gpio_m); in mtk_pinmux_gpio_request_enable()
117 struct pinctrl_gpio_range *range, in mtk_pinmux_gpio_set_direction() argument
123 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; in mtk_pinmux_gpio_set_direction()
130 unsigned int pin, unsigned long *config) in mtk_pinconf_get() argument
133 u32 param = pinconf_to_config_param(*config); in mtk_pinconf_get()
134 int pullup, reg, err = -ENOTSUPP, ret = 1; in mtk_pinconf_get()
137 if (pin >= hw->soc->npins) in mtk_pinconf_get()
138 return -EINVAL; in mtk_pinconf_get()
140 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; in mtk_pinconf_get()
146 if (!hw->soc->bias_get_combo) in mtk_pinconf_get()
148 err = hw->soc->bias_get_combo(hw, desc, &pullup, &ret); in mtk_pinconf_get()
155 err = -EINVAL; in mtk_pinconf_get()
158 err = -EINVAL; in mtk_pinconf_get()
161 err = -EINVAL; in mtk_pinconf_get()
170 err = -EINVAL; in mtk_pinconf_get()
178 err = -EINVAL; in mtk_pinconf_get()
188 /* return error when in output mode in mtk_pinconf_get()
192 err = -EINVAL; in mtk_pinconf_get()
198 err = -EINVAL; in mtk_pinconf_get()
201 if (!hw->soc->drive_get) in mtk_pinconf_get()
204 if (hw->soc->adv_drive_get) { in mtk_pinconf_get()
205 err = hw->soc->adv_drive_get(hw, desc, &ret); in mtk_pinconf_get()
210 err = -EINVAL; in mtk_pinconf_get()
216 err = hw->soc->drive_get(hw, desc, &ret); in mtk_pinconf_get()
219 if (!hw->soc->adv_drive_get) in mtk_pinconf_get()
222 err = hw->soc->adv_drive_get(hw, desc, &ret); in mtk_pinconf_get()
240 if (!hw->soc->adv_pull_get) in mtk_pinconf_get()
243 err = hw->soc->adv_pull_get(hw, desc, pullup, &ret); in mtk_pinconf_get()
246 if (!hw->soc->adv_drive_get) in mtk_pinconf_get()
248 err = hw->soc->adv_drive_get(hw, desc, &ret); in mtk_pinconf_get()
253 *config = pinconf_to_config_packed(param, ret); in mtk_pinconf_get()
263 int err = -ENOTSUPP; in mtk_pinconf_set()
266 if (pin >= hw->soc->npins) in mtk_pinconf_set()
267 return -EINVAL; in mtk_pinconf_set()
269 desc = (const struct mtk_pin_desc *)&hw->soc->pins[pin]; in mtk_pinconf_set()
273 if (!hw->soc->bias_set_combo) in mtk_pinconf_set()
275 err = hw->soc->bias_set_combo(hw, desc, 0, MTK_DISABLE); in mtk_pinconf_set()
278 if (!hw->soc->bias_set_combo) in mtk_pinconf_set()
280 err = hw->soc->bias_set_combo(hw, desc, 1, arg); in mtk_pinconf_set()
283 if (!hw->soc->bias_set_combo) in mtk_pinconf_set()
285 err = hw->soc->bias_set_combo(hw, desc, 0, arg); in mtk_pinconf_set()
288 /* regard all non-zero value as enable */ in mtk_pinconf_set()
292 /* regard all non-zero value as enable */ in mtk_pinconf_set()
307 * arg = 0: Output mode & SMT disable in mtk_pinconf_set()
316 if (!hw->soc->drive_set) in mtk_pinconf_set()
318 err = hw->soc->drive_set(hw, desc, arg); in mtk_pinconf_set()
321 if (!hw->soc->adv_drive_set) in mtk_pinconf_set()
327 err = hw->soc->adv_drive_set(hw, desc, err); in mtk_pinconf_set()
337 if (!hw->soc->adv_pull_set) in mtk_pinconf_set()
339 err = hw->soc->adv_pull_set(hw, desc, in mtk_pinconf_set()
344 if (!hw->soc->adv_drive_set) in mtk_pinconf_set()
346 err = hw->soc->adv_drive_set(hw, desc, arg); in mtk_pinconf_set()
358 for (i = 0; i < hw->soc->ngrps; i++) { in mtk_pctrl_find_group_by_pin()
359 struct mtk_pinctrl_group *grp = hw->groups + i; in mtk_pctrl_find_group_by_pin()
361 if (grp->pin == pin) in mtk_pctrl_find_group_by_pin()
371 const struct mtk_pin_desc *pin = hw->soc->pins + pin_num; in mtk_pctrl_find_function_by_pin()
372 const struct mtk_func_desc *func = pin->funcs; in mtk_pctrl_find_function_by_pin()
374 while (func && func->name) { in mtk_pctrl_find_function_by_pin()
375 if (func->muxval == fnum) in mtk_pctrl_find_function_by_pin()
388 for (i = 0; i < hw->soc->npins; i++) { in mtk_pctrl_is_function_valid()
389 const struct mtk_pin_desc *pin = hw->soc->pins + i; in mtk_pctrl_is_function_valid()
391 if (pin->number == pin_num) { in mtk_pctrl_is_function_valid()
392 const struct mtk_func_desc *func = pin->funcs; in mtk_pctrl_is_function_valid()
394 while (func && func->name) { in mtk_pctrl_is_function_valid()
395 if (func->muxval == fnum) in mtk_pctrl_is_function_valid()
417 return -ENOSPC; in mtk_pctrl_dt_node_to_map_func()
420 (*map)[*num_maps].data.mux.group = grp->name; in mtk_pctrl_dt_node_to_map_func()
424 dev_err(pctl->dev, "invalid function %d on pin %d .\n", in mtk_pctrl_dt_node_to_map_func()
426 return -EINVAL; in mtk_pctrl_dt_node_to_map_func()
453 dev_err(hw->dev, "missing pins property in node %pOFn .\n", in mtk_pctrl_dt_subnode_to_map()
455 return -EINVAL; in mtk_pctrl_dt_subnode_to_map()
466 num_pins = pins->length / sizeof(u32); in mtk_pctrl_dt_subnode_to_map()
475 err = -EINVAL; in mtk_pctrl_dt_subnode_to_map()
494 if (pin >= hw->soc->npins || in mtk_pctrl_dt_subnode_to_map()
496 dev_err(hw->dev, "invalid pins value.\n"); in mtk_pctrl_dt_subnode_to_map()
497 err = -EINVAL; in mtk_pctrl_dt_subnode_to_map()
503 dev_err(hw->dev, "unable to match pin %d to group\n", in mtk_pctrl_dt_subnode_to_map()
505 err = -EINVAL; in mtk_pctrl_dt_subnode_to_map()
518 grp->name, in mtk_pctrl_dt_subnode_to_map()
563 return hw->soc->ngrps; in mtk_pctrl_get_groups_count()
571 return hw->groups[group].name; in mtk_pctrl_get_group_name()
580 *pins = (unsigned *)&hw->groups[group].pin; in mtk_pctrl_get_group_pins()
591 if (gpio >= hw->soc->npins) in mtk_hw_get_value_wrap()
592 return -EINVAL; in mtk_hw_get_value_wrap()
594 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; in mtk_hw_get_value_wrap()
627 int pinmux, pullup = 0, pullen = 0, len = 0, r1 = -1, r0 = -1, rsel = -1; in mtk_pctrl_show_one_pin()
631 if (gpio >= hw->soc->npins) in mtk_pctrl_show_one_pin()
632 return -EINVAL; in mtk_pctrl_show_one_pin()
635 return -EINVAL; in mtk_pctrl_show_one_pin()
637 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; in mtk_pctrl_show_one_pin()
639 if (pinmux >= hw->soc->nfuncs) in mtk_pctrl_show_one_pin()
640 pinmux -= hw->soc->nfuncs; in mtk_pctrl_show_one_pin()
644 if (hw->soc->pull_type) in mtk_pctrl_show_one_pin()
645 try_all_type = hw->soc->pull_type[desc->number]; in mtk_pctrl_show_one_pin()
647 if (hw->rsel_si_unit && (try_all_type & MTK_PULL_RSEL_TYPE)) { in mtk_pctrl_show_one_pin()
673 rsel = pullen - MTK_PULL_SET_RSEL_000; in mtk_pctrl_show_one_pin()
677 len += scnprintf(buf + len, buf_len - len, in mtk_pctrl_show_one_pin()
690 if (r1 != -1) in mtk_pctrl_show_one_pin()
691 len += scnprintf(buf + len, buf_len - len, " (%1d %1d)", r1, r0); in mtk_pctrl_show_one_pin()
692 else if (rsel != -1) in mtk_pctrl_show_one_pin()
693 len += scnprintf(buf + len, buf_len - len, " (%1d)", rsel); in mtk_pctrl_show_one_pin()
738 *groups = hw->grp_names; in mtk_pmx_get_func_groups()
739 *num_groups = hw->soc->ngrps; in mtk_pmx_get_func_groups()
749 struct mtk_pinctrl_group *grp = hw->groups + group; in mtk_pmx_set_mux()
754 ret = mtk_pctrl_is_function_valid(hw, grp->pin, function); in mtk_pmx_set_mux()
756 dev_err(hw->dev, "invalid function %d on group %d .\n", in mtk_pmx_set_mux()
758 return -EINVAL; in mtk_pmx_set_mux()
761 desc_func = mtk_pctrl_find_function_by_pin(hw, grp->pin, function); in mtk_pmx_set_mux()
763 return -EINVAL; in mtk_pmx_set_mux()
765 desc = (const struct mtk_pin_desc *)&hw->soc->pins[grp->pin]; in mtk_pmx_set_mux()
766 return mtk_hw_set_value(hw, desc, PINCTRL_PIN_REG_MODE, desc_func->muxval); in mtk_pmx_set_mux()
779 unsigned long *config) in mtk_pconf_group_get() argument
782 struct mtk_pinctrl_group *grp = &hw->groups[group]; in mtk_pconf_group_get()
785 return mtk_pinconf_get(pctldev, grp->pin, config); in mtk_pconf_group_get()
792 struct mtk_pinctrl_group *grp = &hw->groups[group]; in mtk_pconf_group_set()
798 ret = mtk_pinconf_set(pctldev, grp->pin, in mtk_pconf_group_set()
811 * Disable advanced drive strength mode if drive-strength-microamp in mtk_pconf_group_set()
812 * is not set. However, mediatek,drive-strength-adv takes precedence in mtk_pconf_group_set()
815 if (hw->soc->adv_drive_set && !drive_strength_uA_found && in mtk_pconf_group_set()
817 hw->soc->adv_drive_set(hw, &hw->soc->pins[grp->pin], 0); in mtk_pconf_group_set()
843 if (gpio >= hw->soc->npins) in mtk_gpio_get_direction()
844 return -EINVAL; in mtk_gpio_get_direction()
853 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; in mtk_gpio_get_direction()
871 if (gpio >= hw->soc->npins) in mtk_gpio_get()
872 return -EINVAL; in mtk_gpio_get()
874 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; in mtk_gpio_get()
888 if (gpio >= hw->soc->npins) in mtk_gpio_set()
891 desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio]; in mtk_gpio_set()
900 if (gpio >= hw->soc->npins) in mtk_gpio_direction_input()
901 return -EINVAL; in mtk_gpio_direction_input()
911 if (gpio >= hw->soc->npins) in mtk_gpio_direction_output()
912 return -EINVAL; in mtk_gpio_direction_output()
924 if (!hw->eint) in mtk_gpio_to_irq()
925 return -ENOTSUPP; in mtk_gpio_to_irq()
927 desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset]; in mtk_gpio_to_irq()
929 if (desc->eint.eint_n == EINT_NA) in mtk_gpio_to_irq()
930 return -ENOTSUPP; in mtk_gpio_to_irq()
932 return mtk_eint_find_irq(hw->eint, desc->eint.eint_n); in mtk_gpio_to_irq()
936 unsigned long config) in mtk_gpio_set_config() argument
942 desc = (const struct mtk_pin_desc *)&hw->soc->pins[offset]; in mtk_gpio_set_config()
944 if (!hw->eint || in mtk_gpio_set_config()
945 pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE || in mtk_gpio_set_config()
946 desc->eint.eint_n == EINT_NA) in mtk_gpio_set_config()
947 return -ENOTSUPP; in mtk_gpio_set_config()
949 debounce = pinconf_to_config_argument(config); in mtk_gpio_set_config()
951 return mtk_eint_set_debounce(hw->eint, desc->eint.eint_n, debounce); in mtk_gpio_set_config()
956 struct gpio_chip *chip = &hw->chip; in mtk_build_gpiochip()
959 chip->label = PINCTRL_PINCTRL_DEV; in mtk_build_gpiochip()
960 chip->parent = hw->dev; in mtk_build_gpiochip()
961 chip->request = gpiochip_generic_request; in mtk_build_gpiochip()
962 chip->free = gpiochip_generic_free; in mtk_build_gpiochip()
963 chip->get_direction = mtk_gpio_get_direction; in mtk_build_gpiochip()
964 chip->direction_input = mtk_gpio_direction_input; in mtk_build_gpiochip()
965 chip->direction_output = mtk_gpio_direction_output; in mtk_build_gpiochip()
966 chip->get = mtk_gpio_get; in mtk_build_gpiochip()
967 chip->set = mtk_gpio_set; in mtk_build_gpiochip()
968 chip->to_irq = mtk_gpio_to_irq; in mtk_build_gpiochip()
969 chip->set_config = mtk_gpio_set_config; in mtk_build_gpiochip()
970 chip->base = -1; in mtk_build_gpiochip()
971 chip->ngpio = hw->soc->npins; in mtk_build_gpiochip()
986 hw->groups = devm_kmalloc_array(&pdev->dev, hw->soc->ngrps, in mtk_pctrl_build_state()
987 sizeof(*hw->groups), GFP_KERNEL); in mtk_pctrl_build_state()
988 if (!hw->groups) in mtk_pctrl_build_state()
989 return -ENOMEM; in mtk_pctrl_build_state()
992 hw->grp_names = devm_kmalloc_array(&pdev->dev, hw->soc->ngrps, in mtk_pctrl_build_state()
993 sizeof(*hw->grp_names), GFP_KERNEL); in mtk_pctrl_build_state()
994 if (!hw->grp_names) in mtk_pctrl_build_state()
995 return -ENOMEM; in mtk_pctrl_build_state()
997 for (i = 0; i < hw->soc->npins; i++) { in mtk_pctrl_build_state()
998 const struct mtk_pin_desc *pin = hw->soc->pins + i; in mtk_pctrl_build_state()
999 struct mtk_pinctrl_group *group = hw->groups + i; in mtk_pctrl_build_state()
1001 group->name = pin->name; in mtk_pctrl_build_state()
1002 group->pin = pin->number; in mtk_pctrl_build_state()
1004 hw->grp_names[i] = pin->name; in mtk_pctrl_build_state()
1012 struct device *dev = &pdev->dev; in mtk_paris_pinctrl_probe()
1017 hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); in mtk_paris_pinctrl_probe()
1019 return -ENOMEM; in mtk_paris_pinctrl_probe()
1023 hw->soc = device_get_match_data(dev); in mtk_paris_pinctrl_probe()
1024 if (!hw->soc) in mtk_paris_pinctrl_probe()
1025 return -ENOENT; in mtk_paris_pinctrl_probe()
1027 hw->dev = &pdev->dev; in mtk_paris_pinctrl_probe()
1029 if (!hw->soc->nbase_names) in mtk_paris_pinctrl_probe()
1030 return dev_err_probe(dev, -EINVAL, in mtk_paris_pinctrl_probe()
1033 hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names, in mtk_paris_pinctrl_probe()
1034 sizeof(*hw->base), GFP_KERNEL); in mtk_paris_pinctrl_probe()
1035 if (!hw->base) in mtk_paris_pinctrl_probe()
1036 return -ENOMEM; in mtk_paris_pinctrl_probe()
1038 for (i = 0; i < hw->soc->nbase_names; i++) { in mtk_paris_pinctrl_probe()
1039 hw->base[i] = devm_platform_ioremap_resource_byname(pdev, in mtk_paris_pinctrl_probe()
1040 hw->soc->base_names[i]); in mtk_paris_pinctrl_probe()
1041 if (IS_ERR(hw->base[i])) in mtk_paris_pinctrl_probe()
1042 return PTR_ERR(hw->base[i]); in mtk_paris_pinctrl_probe()
1045 hw->nbase = hw->soc->nbase_names; in mtk_paris_pinctrl_probe()
1047 hw->rsel_si_unit = of_property_read_bool(hw->dev->of_node, in mtk_paris_pinctrl_probe()
1048 "mediatek,rsel-resistance-in-si-unit"); in mtk_paris_pinctrl_probe()
1050 spin_lock_init(&hw->lock); in mtk_paris_pinctrl_probe()
1057 pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins), in mtk_paris_pinctrl_probe()
1060 return -ENOMEM; in mtk_paris_pinctrl_probe()
1062 for (i = 0; i < hw->soc->npins; i++) { in mtk_paris_pinctrl_probe()
1063 pins[i].number = hw->soc->pins[i].number; in mtk_paris_pinctrl_probe()
1064 pins[i].name = hw->soc->pins[i].name; in mtk_paris_pinctrl_probe()
1069 mtk_desc.npins = hw->soc->npins; in mtk_paris_pinctrl_probe()
1076 err = devm_pinctrl_register_and_init(&pdev->dev, &mtk_desc, hw, in mtk_paris_pinctrl_probe()
1077 &hw->pctrl); in mtk_paris_pinctrl_probe()
1081 err = pinctrl_enable(hw->pctrl); in mtk_paris_pinctrl_probe()
1087 dev_warn(&pdev->dev, in mtk_paris_pinctrl_probe()
1105 return mtk_eint_do_suspend(pctl->eint); in mtk_paris_pinctrl_suspend()
1112 return mtk_eint_do_resume(pctl->eint); in mtk_paris_pinctrl_resume()