Lines Matching +full:pin +full:-

1 // SPDX-License-Identifier: GPL-2.0
3 * ZynqMP pin controller
11 #include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
17 #include <linux/firmware/xlnx-zynqmp.h>
20 #include <linux/pinctrl/pinconf-generic.h>
23 #include "pinctrl-utils.h"
44 * struct zynqmp_pmux_function - a pinmux function
45 * @name: Name of the pin mux function
46 * @groups: List of pin groups for this function
50 * This structure holds information about pin control function
60 * struct zynqmp_pinctrl - driver data
61 * @pctrl: Pin control device
62 * @groups: Pin groups
64 * @funcs: Pin mux functions
68 * information regarding pin control functions, groups and
80 * struct zynqmp_pctrl_group - Pin control group info
82 * @pins: Group pin numbers
97 return pctrl->ngroups; in zynqmp_pctrl_get_groups_count()
105 return pctrl->groups[selector].name; in zynqmp_pctrl_get_group_name()
115 *pins = pctrl->groups[selector].pins; in zynqmp_pctrl_get_group_pins()
116 *npins = pctrl->groups[selector].npins; in zynqmp_pctrl_get_group_pins()
130 unsigned int pin) in zynqmp_pinmux_request_pin() argument
134 ret = zynqmp_pm_pinctrl_request(pin); in zynqmp_pinmux_request_pin()
136 dev_err(pctldev->dev, "request failed for pin %u\n", pin); in zynqmp_pinmux_request_pin()
147 return pctrl->nfuncs; in zynqmp_pmux_get_functions_count()
155 return pctrl->funcs[selector].name; in zynqmp_pmux_get_function_name()
159 * zynqmp_pmux_get_function_groups() - Get groups for the function
176 *groups = pctrl->funcs[selector].groups; in zynqmp_pmux_get_function_groups()
177 *num_groups = pctrl->funcs[selector].ngroups; in zynqmp_pmux_get_function_groups()
183 * zynqmp_pinmux_set_mux() - Set requested function for the group
198 const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[group]; in zynqmp_pinmux_set_mux()
201 for (i = 0; i < pgrp->npins; i++) { in zynqmp_pinmux_set_mux()
202 unsigned int pin = pgrp->pins[i]; in zynqmp_pinmux_set_mux() local
204 ret = zynqmp_pm_pinctrl_set_function(pin, function); in zynqmp_pinmux_set_mux()
206 dev_err(pctldev->dev, "set mux failed for pin %u\n", in zynqmp_pinmux_set_mux()
207 pin); in zynqmp_pinmux_set_mux()
216 unsigned int pin) in zynqmp_pinmux_release_pin() argument
220 ret = zynqmp_pm_pinctrl_release(pin); in zynqmp_pinmux_release_pin()
222 dev_err(pctldev->dev, "free pin failed for pin %u\n", in zynqmp_pinmux_release_pin()
223 pin); in zynqmp_pinmux_release_pin()
240 * zynqmp_pinconf_cfg_get() - get config value for the pin
241 * @pctldev: Pin control device pointer.
242 * @pin: Pin number.
246 * given pin.
251 unsigned int pin, in zynqmp_pinconf_cfg_get() argument
260 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
264 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
266 return -EINVAL; in zynqmp_pinconf_cfg_get()
272 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
274 return -EINVAL; in zynqmp_pinconf_cfg_get()
280 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
282 return -EINVAL; in zynqmp_pinconf_cfg_get()
288 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
292 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
296 ret = zynqmp_pm_pinctrl_get_config(pin, param, &arg); in zynqmp_pinconf_cfg_get()
312 dev_warn(pctldev->dev, in zynqmp_pinconf_cfg_get()
313 "Invalid drive strength for pin %d\n", in zynqmp_pinconf_cfg_get()
314 pin); in zynqmp_pinconf_cfg_get()
315 return -EINVAL; in zynqmp_pinconf_cfg_get()
319 ret = -ENOTSUPP; in zynqmp_pinconf_cfg_get()
333 * zynqmp_pinconf_cfg_set() - Set requested config for the pin
335 * @pin: Pin number.
340 * to set requested configurations for the pin.
345 unsigned int pin, unsigned long *configs, in zynqmp_pinconf_cfg_set() argument
358 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); in zynqmp_pinconf_cfg_set()
363 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); in zynqmp_pinconf_cfg_set()
368 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); in zynqmp_pinconf_cfg_set()
373 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); in zynqmp_pinconf_cfg_set()
377 ret = zynqmp_pm_pinctrl_set_config(pin, param, arg); in zynqmp_pinconf_cfg_set()
395 dev_warn(pctldev->dev, in zynqmp_pinconf_cfg_set()
396 "Invalid drive strength for pin %d\n", in zynqmp_pinconf_cfg_set()
397 pin); in zynqmp_pinconf_cfg_set()
398 return -EINVAL; in zynqmp_pinconf_cfg_set()
402 ret = zynqmp_pm_pinctrl_set_config(pin, param, value); in zynqmp_pinconf_cfg_set()
406 ret = zynqmp_pm_pinctrl_get_config(pin, param, &value); in zynqmp_pinconf_cfg_set()
409 dev_warn(pctldev->dev, in zynqmp_pinconf_cfg_set()
410 "Invalid IO Standard requested for pin %d\n", in zynqmp_pinconf_cfg_set()
411 pin); in zynqmp_pinconf_cfg_set()
424 dev_warn(pctldev->dev, in zynqmp_pinconf_cfg_set()
427 ret = -ENOTSUPP; in zynqmp_pinconf_cfg_set()
434 dev_warn(pctldev->dev, in zynqmp_pinconf_cfg_set()
435 "failed to set: pin %u param %u value %u\n", in zynqmp_pinconf_cfg_set()
436 pin, param, arg); in zynqmp_pinconf_cfg_set()
443 * zynqmp_pinconf_group_set() - Set requested config for the group
449 * Call function to set configs for each pin in the group.
460 const struct zynqmp_pctrl_group *pgrp = &pctrl->groups[selector]; in zynqmp_pinconf_group_set()
462 for (i = 0; i < pgrp->npins; i++) { in zynqmp_pinconf_group_set()
463 ret = zynqmp_pinconf_cfg_set(pctldev, pgrp->pins[i], configs, in zynqmp_pinconf_group_set()
525 * zynqmp_pinctrl_prepare_func_groups() - prepare function and groups data
553 fgroups = devm_kzalloc(dev, sizeof(*fgroups) * func->ngroups, GFP_KERNEL); in zynqmp_pinctrl_prepare_func_groups()
555 return -ENOMEM; in zynqmp_pinctrl_prepare_func_groups()
557 for (index = 0; index < func->ngroups; index += NUM_GROUPS_PER_RESP) { in zynqmp_pinctrl_prepare_func_groups()
571 func->name, in zynqmp_pinctrl_prepare_func_groups()
574 return -ENOMEM; in zynqmp_pinctrl_prepare_func_groups()
578 func->name, in zynqmp_pinctrl_prepare_func_groups()
581 return -ENOMEM; in zynqmp_pinctrl_prepare_func_groups()
585 func->groups = fgroups; in zynqmp_pinctrl_prepare_func_groups()
624 static int zynqmp_pinctrl_get_pin_groups(u32 pin, u32 index, u16 *groups) in zynqmp_pinctrl_get_pin_groups() argument
631 qdata.arg1 = pin; in zynqmp_pinctrl_get_pin_groups()
644 unsigned int pin) in zynqmp_pinctrl_group_add_pin() argument
646 group->pins[group->npins++] = pin; in zynqmp_pinctrl_group_add_pin()
650 * zynqmp_pinctrl_create_pin_groups() - assign pins to respective groups
653 * @pin: Pin number.
655 * Query firmware to get groups available for the given pin.
656 * Based on the firmware response(group IDs for the pin), add
657 * pin number to the respective group's pin array.
660 * of pins and pin numbers data.
666 unsigned int pin) in zynqmp_pinctrl_create_pin_groups() argument
672 ret = zynqmp_pinctrl_get_pin_groups(pin, index, resp); in zynqmp_pinctrl_create_pin_groups()
683 zynqmp_pinctrl_group_add_pin(&groups[resp[i]], pin); in zynqmp_pinctrl_create_pin_groups()
692 * zynqmp_pinctrl_prepare_group_pins() - prepare each group's pin data
697 * Prepare pin number and number of pins data for each pins.
705 unsigned int pin; in zynqmp_pinctrl_prepare_group_pins() local
708 for (pin = 0; pin < zynqmp_desc.npins; pin++) { in zynqmp_pinctrl_prepare_group_pins()
709 ret = zynqmp_pinctrl_create_pin_groups(dev, groups, pin); in zynqmp_pinctrl_prepare_group_pins()
718 * zynqmp_pinctrl_prepare_function_info() - prepare function info
720 * @pctrl: Pin control driver data.
722 * Query firmware for functions, groups and pin information and
723 * prepare pin control driver data.
730 * pins and pin numbers for each group).
741 ret = zynqmp_pinctrl_get_num_functions(&pctrl->nfuncs); in zynqmp_pinctrl_prepare_function_info()
745 funcs = devm_kzalloc(dev, sizeof(*funcs) * pctrl->nfuncs, GFP_KERNEL); in zynqmp_pinctrl_prepare_function_info()
747 return -ENOMEM; in zynqmp_pinctrl_prepare_function_info()
749 for (i = 0; i < pctrl->nfuncs; i++) { in zynqmp_pinctrl_prepare_function_info()
756 pctrl->ngroups += funcs[i].ngroups; in zynqmp_pinctrl_prepare_function_info()
759 groups = devm_kzalloc(dev, sizeof(*groups) * pctrl->ngroups, GFP_KERNEL); in zynqmp_pinctrl_prepare_function_info()
761 return -ENOMEM; in zynqmp_pinctrl_prepare_function_info()
763 for (i = 0; i < pctrl->nfuncs; i++) { in zynqmp_pinctrl_prepare_function_info()
770 ret = zynqmp_pinctrl_prepare_group_pins(dev, groups, pctrl->ngroups); in zynqmp_pinctrl_prepare_function_info()
774 pctrl->funcs = funcs; in zynqmp_pinctrl_prepare_function_info()
775 pctrl->groups = groups; in zynqmp_pinctrl_prepare_function_info()
798 * zynqmp_pinctrl_prepare_pin_desc() - prepare pin description info
800 * @zynqmp_pins: Pin information.
803 * Query number of pins information from firmware and prepare pin
804 * description containing pin number and pin name.
813 struct pinctrl_pin_desc *pins, *pin; in zynqmp_pinctrl_prepare_pin_desc() local
823 return -ENOMEM; in zynqmp_pinctrl_prepare_pin_desc()
826 pin = &pins[i]; in zynqmp_pinctrl_prepare_pin_desc()
827 pin->number = i; in zynqmp_pinctrl_prepare_pin_desc()
828 pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", in zynqmp_pinctrl_prepare_pin_desc()
830 if (!pin->name) in zynqmp_pinctrl_prepare_pin_desc()
831 return -ENOMEM; in zynqmp_pinctrl_prepare_pin_desc()
844 pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL); in zynqmp_pinctrl_probe()
846 return -ENOMEM; in zynqmp_pinctrl_probe()
848 ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev, in zynqmp_pinctrl_probe()
852 dev_err(&pdev->dev, "pin desc prepare fail with %d\n", ret); in zynqmp_pinctrl_probe()
856 ret = zynqmp_pinctrl_prepare_function_info(&pdev->dev, pctrl); in zynqmp_pinctrl_probe()
858 dev_err(&pdev->dev, "function info prepare fail with %d\n", ret); in zynqmp_pinctrl_probe()
862 pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &zynqmp_desc, pctrl); in zynqmp_pinctrl_probe()
863 if (IS_ERR(pctrl->pctrl)) in zynqmp_pinctrl_probe()
864 return PTR_ERR(pctrl->pctrl); in zynqmp_pinctrl_probe()
872 { .compatible = "xlnx,zynqmp-pinctrl" },
879 .name = "zynqmp-pinctrl",
887 MODULE_DESCRIPTION("ZynqMP Pin Controller Driver");