Lines Matching +full:mdio +full:- +full:pins

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2014-2018 Renesas Electronics Europe Limited
9 #include <dt-bindings/pinctrl/rzn1-pinctrl.h>
19 #include <linux/pinctrl/pinconf-generic.h>
26 #include "../pinctrl-utils.h"
45 * the multiplexing for Ethernet MDIO signals.
49 * going from 0 to 61. Level 3 allows selection of MDIO functions which can be
51 * level 2 functions that can select MDIO, and two MDIO channels so we have four
57 * 72 to 79 is 72 + MDIO0 source for level 2 MDIO function.
59 * 88 to 95 is 88 + MDIO1 source for level 2 MDIO function.
65 * There are 170 configurable pins (called PL_GPIO in the datasheet).
71 * structure. The only difference is that Level 2 has additional MDIO registers
78 /* MDIO mux registers, level2 only */
83 * struct rzn1_pmx_func - describes rzn1 pinmux functions
95 * struct rzn1_pin_group - describes an rzn1 pin group
98 * @npins: the number of pins in this group array, i.e. the number of
99 * elements in .pins so we can iterate over that array
100 * @pins: array of pins. Needed due to pinctrl_ops.get_group_pins()
107 unsigned int *pins; member
187 u32 val = ipctl->lev1_protect_phys | !(value & LOCK_LEVEL1); in rzn1_hw_set_lock()
189 writel(val, &ipctl->lev1->status_protect); in rzn1_hw_set_lock()
193 u32 val = ipctl->lev2_protect_phys | !(value & LOCK_LEVEL2); in rzn1_hw_set_lock()
195 writel(val, &ipctl->lev2->status_protect); in rzn1_hw_set_lock()
199 static void rzn1_pinctrl_mdio_select(struct rzn1_pinctrl *ipctl, int mdio, in rzn1_pinctrl_mdio_select() argument
202 if (ipctl->mdio_func[mdio] >= 0 && ipctl->mdio_func[mdio] != func) in rzn1_pinctrl_mdio_select()
203 dev_warn(ipctl->dev, "conflicting setting for mdio%d!\n", mdio); in rzn1_pinctrl_mdio_select()
204 ipctl->mdio_func[mdio] = func; in rzn1_pinctrl_mdio_select()
206 dev_dbg(ipctl->dev, "setting mdio%d to %u\n", mdio, func); in rzn1_pinctrl_mdio_select()
208 writel(func, &ipctl->lev2->l2_mdio[mdio]); in rzn1_pinctrl_mdio_select()
227 /* Level 3 MDIO multiplexing */ in rzn1_set_hw_pin_func()
238 /* Get MDIO func, and convert the func to the level 2 number */ in rzn1_set_hw_pin_func()
240 mdio_func = pin_config - RZN1_FUNC_MDIO0_HIGHZ; in rzn1_set_hw_pin_func()
243 mdio_func = pin_config - RZN1_FUNC_MDIO0_E1_HIGHZ; in rzn1_set_hw_pin_func()
246 mdio_func = pin_config - RZN1_FUNC_MDIO1_HIGHZ; in rzn1_set_hw_pin_func()
249 mdio_func = pin_config - RZN1_FUNC_MDIO1_E1_HIGHZ; in rzn1_set_hw_pin_func()
255 /* Note here, we do not allow anything past the MDIO Mux values */ in rzn1_set_hw_pin_func()
256 if (pin >= ARRAY_SIZE(ipctl->lev1->conf) || in rzn1_set_hw_pin_func()
258 return -EINVAL; in rzn1_set_hw_pin_func()
260 l1 = readl(&ipctl->lev1->conf[pin]); in rzn1_set_hw_pin_func()
262 l2 = readl(&ipctl->lev2->conf[pin]); in rzn1_set_hw_pin_func()
265 dev_dbg(ipctl->dev, "setting func for pin %u to %u\n", pin, pin_config); in rzn1_set_hw_pin_func()
274 l2 = pin_config - RZN1_FUNC_L2_OFFSET; in rzn1_set_hw_pin_func()
279 writel(l1, &ipctl->lev1->conf[pin]); in rzn1_set_hw_pin_func()
280 writel(l2, &ipctl->lev2->conf[pin]); in rzn1_set_hw_pin_func()
291 for (i = 0; i < ipctl->ngroups; i++) { in rzn1_pinctrl_find_group_by_name()
292 if (!strcmp(ipctl->groups[i].name, name)) in rzn1_pinctrl_find_group_by_name()
293 return &ipctl->groups[i]; in rzn1_pinctrl_find_group_by_name()
303 return ipctl->ngroups; in rzn1_get_groups_count()
311 return ipctl->groups[selector].name; in rzn1_get_group_name()
315 unsigned int selector, const unsigned int **pins, in rzn1_get_group_pins() argument
320 if (selector >= ipctl->ngroups) in rzn1_get_group_pins()
321 return -EINVAL; in rzn1_get_group_pins()
323 *pins = ipctl->groups[selector].pins; in rzn1_get_group_pins()
324 *npins = ipctl->groups[selector].npins; in rzn1_get_group_pins()
331 * Sub-nodes can be used to describe multiple 'Groups' for the 'Function'
332 * If there aren't any sub-nodes, the 'Group' is essentially the 'Function'.
333 * Each 'Group' uses pinmux = <...> to detail the pins and data used to select
335 * to all pins in the 'Group'.
350 dev_dbg(ipctl->dev, "processing node %pOF\n", np); in rzn1_dt_node_to_map_one()
352 grp = rzn1_pinctrl_find_group_by_name(ipctl, np->name); in rzn1_dt_node_to_map_one()
354 dev_err(ipctl->dev, "unable to find group for node %pOF\n", np); in rzn1_dt_node_to_map_one()
356 return -EINVAL; in rzn1_dt_node_to_map_one()
363 dev_err(ipctl->dev, "%pOF: could not parse property\n", np); in rzn1_dt_node_to_map_one()
379 grp->name, grp->func); in rzn1_dt_node_to_map_one()
386 &reserved_maps, num_maps, grp->name, in rzn1_dt_node_to_map_one()
393 dev_dbg(pctldev->dev, "maps: function %s group %s (%d pins)\n", in rzn1_dt_node_to_map_one()
394 grp->func, grp->name, grp->npins); in rzn1_dt_node_to_map_one()
437 return ipctl->nfunctions; in rzn1_pmx_get_funcs_count()
445 return ipctl->functions[selector].name; in rzn1_pmx_get_func_name()
455 *groups = ipctl->functions[selector].groups; in rzn1_pmx_get_groups()
456 *num_groups = ipctl->functions[selector].num_groups; in rzn1_pmx_get_groups()
465 struct rzn1_pin_group *grp = &ipctl->groups[group]; in rzn1_set_mux()
466 unsigned int i, grp_pins = grp->npins; in rzn1_set_mux()
468 dev_dbg(ipctl->dev, "set mux %s(%d) group %s(%d)\n", in rzn1_set_mux()
469 ipctl->functions[selector].name, selector, grp->name, group); in rzn1_set_mux()
473 rzn1_set_hw_pin_func(ipctl, grp->pins[i], grp->pin_ids[i], 0); in rzn1_set_mux()
495 if (pin >= ARRAY_SIZE(ipctl->lev1->conf)) in rzn1_pinconf_get()
496 return -EINVAL; in rzn1_pinconf_get()
498 l1 = readl(&ipctl->lev1->conf[pin]); in rzn1_pinconf_get()
507 return -EINVAL; in rzn1_pinconf_get()
511 return -EINVAL; in rzn1_pinconf_get()
515 return -EINVAL; in rzn1_pinconf_get()
521 l2 = readl(&ipctl->lev2->conf[pin]); in rzn1_pinconf_get()
524 return -EINVAL; in rzn1_pinconf_get()
526 return -EINVAL; in rzn1_pinconf_get()
530 return -ENOTSUPP; in rzn1_pinconf_get()
548 if (pin >= ARRAY_SIZE(ipctl->lev1->conf)) in rzn1_pinconf_set()
549 return -EINVAL; in rzn1_pinconf_set()
551 l1 = readl(&ipctl->lev1->conf[pin]); in rzn1_pinconf_set()
560 dev_dbg(ipctl->dev, "set pin %d pull up\n", pin); in rzn1_pinconf_set()
565 dev_dbg(ipctl->dev, "set pin %d pull down\n", pin); in rzn1_pinconf_set()
570 dev_dbg(ipctl->dev, "set pin %d bias off\n", pin); in rzn1_pinconf_set()
575 dev_dbg(ipctl->dev, "set pin %d drv %umA\n", pin, arg); in rzn1_pinconf_set()
590 dev_err(ipctl->dev, in rzn1_pinconf_set()
594 return -EINVAL; in rzn1_pinconf_set()
602 dev_dbg(ipctl->dev, "set pin %d High-Z\n", pin); in rzn1_pinconf_set()
607 return -ENOTSUPP; in rzn1_pinconf_set()
613 writel(l1, &ipctl->lev1->conf[pin]); in rzn1_pinconf_set()
625 struct rzn1_pin_group *grp = &ipctl->groups[selector]; in rzn1_pinconf_group_get()
629 dev_dbg(ipctl->dev, "group get %s selector:%u\n", grp->name, selector); in rzn1_pinconf_group_get()
631 for (i = 0; i < grp->npins; i++) { in rzn1_pinconf_group_get()
632 if (rzn1_pinconf_get(pctldev, grp->pins[i], config)) in rzn1_pinconf_group_get()
633 return -ENOTSUPP; in rzn1_pinconf_group_get()
635 /* configs do not match between two pins */ in rzn1_pinconf_group_get()
637 return -ENOTSUPP; in rzn1_pinconf_group_get()
651 struct rzn1_pin_group *grp = &ipctl->groups[selector]; in rzn1_pinconf_group_set()
655 dev_dbg(ipctl->dev, "group set %s selector:%u configs:%p/%d\n", in rzn1_pinconf_group_set()
656 grp->name, selector, configs, num_configs); in rzn1_pinconf_group_set()
658 for (i = 0; i < grp->npins; i++) { in rzn1_pinconf_group_set()
659 unsigned int pin = grp->pins[i]; in rzn1_pinconf_group_set()
693 dev_dbg(ipctl->dev, "%s: %s\n", __func__, np->name); in rzn1_pinctrl_parse_groups()
696 grp->name = np->name; in rzn1_pinctrl_parse_groups()
701 * do sanity check and calculate pins number in rzn1_pinctrl_parse_groups()
705 dev_err(ipctl->dev, in rzn1_pinctrl_parse_groups()
708 return -EINVAL; in rzn1_pinctrl_parse_groups()
712 dev_err(ipctl->dev, "Invalid " RZN1_PINS_PROP " in node %pOF\n", in rzn1_pinctrl_parse_groups()
715 return -EINVAL; in rzn1_pinctrl_parse_groups()
718 grp->npins = size / sizeof(list[0]); in rzn1_pinctrl_parse_groups()
719 grp->pin_ids = devm_kmalloc_array(ipctl->dev, in rzn1_pinctrl_parse_groups()
720 grp->npins, sizeof(grp->pin_ids[0]), in rzn1_pinctrl_parse_groups()
722 grp->pins = devm_kmalloc_array(ipctl->dev, in rzn1_pinctrl_parse_groups()
723 grp->npins, sizeof(grp->pins[0]), in rzn1_pinctrl_parse_groups()
725 if (!grp->pin_ids || !grp->pins) in rzn1_pinctrl_parse_groups()
726 return -ENOMEM; in rzn1_pinctrl_parse_groups()
728 for (i = 0; i < grp->npins; i++) { in rzn1_pinctrl_parse_groups()
731 grp->pins[i] = pin_id & 0xff; in rzn1_pinctrl_parse_groups()
732 grp->pin_ids[i] = (pin_id >> 8) & 0x7f; in rzn1_pinctrl_parse_groups()
735 return grp->npins; in rzn1_pinctrl_parse_groups()
762 func = &ipctl->functions[index]; in rzn1_pinctrl_parse_functions()
765 func->name = np->name; in rzn1_pinctrl_parse_functions()
766 func->num_groups = rzn1_pinctrl_count_function_groups(np); in rzn1_pinctrl_parse_functions()
767 if (func->num_groups == 0) { in rzn1_pinctrl_parse_functions()
768 dev_err(ipctl->dev, "no groups defined in %pOF\n", np); in rzn1_pinctrl_parse_functions()
769 return -EINVAL; in rzn1_pinctrl_parse_functions()
771 dev_dbg(ipctl->dev, "function %s has %d groups\n", in rzn1_pinctrl_parse_functions()
772 np->name, func->num_groups); in rzn1_pinctrl_parse_functions()
774 func->groups = devm_kmalloc_array(ipctl->dev, in rzn1_pinctrl_parse_functions()
775 func->num_groups, sizeof(char *), in rzn1_pinctrl_parse_functions()
777 if (!func->groups) in rzn1_pinctrl_parse_functions()
778 return -ENOMEM; in rzn1_pinctrl_parse_functions()
781 func->groups[i] = np->name; in rzn1_pinctrl_parse_functions()
782 grp = &ipctl->groups[ipctl->ngroups]; in rzn1_pinctrl_parse_functions()
783 grp->func = func->name; in rzn1_pinctrl_parse_functions()
788 ipctl->ngroups++; in rzn1_pinctrl_parse_functions()
792 func->groups[i] = child->name; in rzn1_pinctrl_parse_functions()
793 grp = &ipctl->groups[ipctl->ngroups]; in rzn1_pinctrl_parse_functions()
794 grp->func = func->name; in rzn1_pinctrl_parse_functions()
799 ipctl->ngroups++; in rzn1_pinctrl_parse_functions()
802 dev_dbg(ipctl->dev, "function %s parsed %u/%u groups\n", in rzn1_pinctrl_parse_functions()
803 np->name, i, func->num_groups); in rzn1_pinctrl_parse_functions()
811 struct device_node *np = pdev->dev.of_node; in rzn1_pinctrl_probe_dt()
821 ipctl->nfunctions = nfuncs; in rzn1_pinctrl_probe_dt()
822 ipctl->functions = devm_kmalloc_array(&pdev->dev, nfuncs, in rzn1_pinctrl_probe_dt()
823 sizeof(*ipctl->functions), in rzn1_pinctrl_probe_dt()
825 if (!ipctl->functions) in rzn1_pinctrl_probe_dt()
826 return -ENOMEM; in rzn1_pinctrl_probe_dt()
828 ipctl->ngroups = 0; in rzn1_pinctrl_probe_dt()
832 ipctl->groups = devm_kmalloc_array(&pdev->dev, in rzn1_pinctrl_probe_dt()
834 sizeof(*ipctl->groups), in rzn1_pinctrl_probe_dt()
836 if (!ipctl->groups) in rzn1_pinctrl_probe_dt()
837 return -ENOMEM; in rzn1_pinctrl_probe_dt()
855 ipctl = devm_kzalloc(&pdev->dev, sizeof(*ipctl), GFP_KERNEL); in rzn1_pinctrl_probe()
857 return -ENOMEM; in rzn1_pinctrl_probe()
859 ipctl->mdio_func[0] = -1; in rzn1_pinctrl_probe()
860 ipctl->mdio_func[1] = -1; in rzn1_pinctrl_probe()
862 ipctl->lev1 = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in rzn1_pinctrl_probe()
863 if (IS_ERR(ipctl->lev1)) in rzn1_pinctrl_probe()
864 return PTR_ERR(ipctl->lev1); in rzn1_pinctrl_probe()
865 ipctl->lev1_protect_phys = (u32)res->start + 0x400; in rzn1_pinctrl_probe()
867 ipctl->lev2 = devm_platform_get_and_ioremap_resource(pdev, 1, &res); in rzn1_pinctrl_probe()
868 if (IS_ERR(ipctl->lev2)) in rzn1_pinctrl_probe()
869 return PTR_ERR(ipctl->lev2); in rzn1_pinctrl_probe()
870 ipctl->lev2_protect_phys = (u32)res->start + 0x400; in rzn1_pinctrl_probe()
872 ipctl->clk = devm_clk_get(&pdev->dev, NULL); in rzn1_pinctrl_probe()
873 if (IS_ERR(ipctl->clk)) in rzn1_pinctrl_probe()
874 return PTR_ERR(ipctl->clk); in rzn1_pinctrl_probe()
875 ret = clk_prepare_enable(ipctl->clk); in rzn1_pinctrl_probe()
879 ipctl->dev = &pdev->dev; in rzn1_pinctrl_probe()
880 rzn1_pinctrl_desc.name = dev_name(&pdev->dev); in rzn1_pinctrl_probe()
881 rzn1_pinctrl_desc.pins = rzn1_pins; in rzn1_pinctrl_probe()
886 dev_err(&pdev->dev, "fail to probe dt properties\n"); in rzn1_pinctrl_probe()
892 ret = devm_pinctrl_register_and_init(&pdev->dev, &rzn1_pinctrl_desc, in rzn1_pinctrl_probe()
893 ipctl, &ipctl->pctl); in rzn1_pinctrl_probe()
895 dev_err(&pdev->dev, "could not register rzn1 pinctrl driver\n"); in rzn1_pinctrl_probe()
899 ret = pinctrl_enable(ipctl->pctl); in rzn1_pinctrl_probe()
903 dev_info(&pdev->dev, "probed\n"); in rzn1_pinctrl_probe()
908 clk_disable_unprepare(ipctl->clk); in rzn1_pinctrl_probe()
917 clk_disable_unprepare(ipctl->clk); in rzn1_pinctrl_remove()
921 { .compatible = "renesas,rzn1-pinctrl", },
930 .name = "rzn1-pinctrl",