Lines Matching +full:- +full:pinfunc
1 // SPDX-License-Identifier: GPL-2.0-only
9 #include <dt-bindings/pinctrl/at91.h>
18 #include <linux/pinctrl/pinconf-generic.h>
24 #include "pinctrl-utils.h"
68 #define ATMEL_GET_PIN_NO(pinfunc) ((pinfunc) & 0xff) argument
69 #define ATMEL_GET_PIN_FUNC(pinfunc) ((pinfunc >> 16) & 0xf) argument
70 #define ATMEL_GET_PIN_IOSET(pinfunc) ((pinfunc >> 20) & 0xf) argument
76 * struct atmel_pioctrl_data - Atmel PIO controller (pinmux + gpio) data struct
103 * struct atmel_pioctrl - Atmel PIO controller (pinmux + gpio)
153 {"atmel,drive-strength", ATMEL_PIN_CONFIG_DRIVE_STRENGTH, 0},
156 /* --- GPIO --- */
160 return readl_relaxed(atmel_pioctrl->reg_base in atmel_gpio_read()
168 writel_relaxed(val, atmel_pioctrl->reg_base in atmel_gpio_write()
183 struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; in atmel_gpio_irq_set_type()
186 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, in atmel_gpio_irq_set_type()
187 BIT(pin->line)); in atmel_gpio_irq_set_type()
188 reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR); in atmel_gpio_irq_set_type()
214 return -EINVAL; in atmel_gpio_irq_set_type()
217 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR, reg); in atmel_gpio_irq_set_type()
225 struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; in atmel_gpio_irq_mask()
227 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_IDR, in atmel_gpio_irq_mask()
228 BIT(pin->line)); in atmel_gpio_irq_mask()
234 struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; in atmel_gpio_irq_unmask()
236 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_IER, in atmel_gpio_irq_unmask()
237 BIT(pin->line)); in atmel_gpio_irq_unmask()
243 int bank = ATMEL_PIO_BANK(d->hwirq); in atmel_gpio_irq_set_wake()
244 int line = ATMEL_PIO_LINE(d->hwirq); in atmel_gpio_irq_set_wake()
247 irq_set_irq_wake(atmel_pioctrl->irqs[bank], on); in atmel_gpio_irq_set_wake()
250 atmel_pioctrl->pm_wakeup_sources[bank] |= BIT(line); in atmel_gpio_irq_set_wake()
252 atmel_pioctrl->pm_wakeup_sources[bank] &= ~(BIT(line)); in atmel_gpio_irq_set_wake()
270 return irq_find_mapping(atmel_pioctrl->irq_domain, offset); in atmel_gpio_to_irq()
279 int n, bank = -1; in atmel_gpio_irq_handler()
282 for (n = 0; n < atmel_pioctrl->nbanks; n++) { in atmel_gpio_irq_handler()
283 if (atmel_pioctrl->irqs[n] == irq) { in atmel_gpio_irq_handler()
290 dev_err(atmel_pioctrl->dev, in atmel_gpio_irq_handler()
307 atmel_pioctrl->gpio_chip, in atmel_gpio_irq_handler()
318 struct atmel_pin *pin = atmel_pioctrl->pins[offset]; in atmel_gpio_direction_input()
321 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, in atmel_gpio_direction_input()
322 BIT(pin->line)); in atmel_gpio_direction_input()
323 reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR); in atmel_gpio_direction_input()
325 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR, reg); in atmel_gpio_direction_input()
333 struct atmel_pin *pin = atmel_pioctrl->pins[offset]; in atmel_gpio_get()
336 reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_PDSR); in atmel_gpio_get()
338 return !!(reg & BIT(pin->line)); in atmel_gpio_get()
347 bitmap_zero(bits, atmel_pioctrl->npins); in atmel_gpio_get_multiple()
349 for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) { in atmel_gpio_get_multiple()
373 struct atmel_pin *pin = atmel_pioctrl->pins[offset]; in atmel_gpio_direction_output()
376 atmel_gpio_write(atmel_pioctrl, pin->bank, in atmel_gpio_direction_output()
378 BIT(pin->line)); in atmel_gpio_direction_output()
380 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, in atmel_gpio_direction_output()
381 BIT(pin->line)); in atmel_gpio_direction_output()
382 reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR); in atmel_gpio_direction_output()
384 atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_CFGR, reg); in atmel_gpio_direction_output()
392 struct atmel_pin *pin = atmel_pioctrl->pins[offset]; in atmel_gpio_set()
394 atmel_gpio_write(atmel_pioctrl, pin->bank, in atmel_gpio_set()
396 BIT(pin->line)); in atmel_gpio_set()
405 for (bank = 0; bank < atmel_pioctrl->nbanks; bank++) { in atmel_gpio_set_multiple()
410 * On a 64-bit platform, BITS_PER_LONG is 64 so it is necessary to iterate over in atmel_gpio_set_multiple()
443 /* --- PINCTRL --- */
448 unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; in atmel_pin_config_read()
449 unsigned int line = atmel_pioctrl->pins[pin_id]->line; in atmel_pin_config_read()
450 void __iomem *addr = atmel_pioctrl->reg_base in atmel_pin_config_read()
464 unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; in atmel_pin_config_write()
465 unsigned int line = atmel_pioctrl->pins[pin_id]->line; in atmel_pin_config_write()
466 void __iomem *addr = atmel_pioctrl->reg_base in atmel_pin_config_write()
479 return atmel_pioctrl->npins; in atmel_pctl_get_groups_count()
487 return atmel_pioctrl->groups[selector].name; in atmel_pctl_get_group_name()
497 *pins = (unsigned int *)&atmel_pioctrl->groups[selector].pin; in atmel_pctl_get_group_pins()
509 for (i = 0; i < atmel_pioctrl->npins; i++) { in atmel_pctl_find_group_by_pin()
510 struct atmel_group *grp = atmel_pioctrl->groups + i; in atmel_pctl_find_group_by_pin()
512 if (grp->pin == pin) in atmel_pctl_find_group_by_pin()
521 u32 pinfunc, const char **grp_name, in atmel_pctl_xlate_pinfunc() argument
528 pin_id = ATMEL_GET_PIN_NO(pinfunc); in atmel_pctl_xlate_pinfunc()
529 func_id = ATMEL_GET_PIN_FUNC(pinfunc); in atmel_pctl_xlate_pinfunc()
532 return -EINVAL; in atmel_pctl_xlate_pinfunc()
538 return -EINVAL; in atmel_pctl_xlate_pinfunc()
539 *grp_name = grp->name; in atmel_pctl_xlate_pinfunc()
541 atmel_pioctrl->pins[pin_id]->mux = func_id; in atmel_pctl_xlate_pinfunc()
542 atmel_pioctrl->pins[pin_id]->ioset = ATMEL_GET_PIN_IOSET(pinfunc); in atmel_pctl_xlate_pinfunc()
544 if (np->parent == atmel_pioctrl->node) in atmel_pctl_xlate_pinfunc()
545 atmel_pioctrl->pins[pin_id]->device = np->name; in atmel_pctl_xlate_pinfunc()
547 atmel_pioctrl->pins[pin_id]->device = np->parent->name; in atmel_pctl_xlate_pinfunc()
561 u32 pinfunc; in atmel_pctl_dt_subnode_to_map() local
566 return -EINVAL; in atmel_pctl_dt_subnode_to_map()
571 dev_err(pctldev->dev, "%pOF: could not parse node property\n", in atmel_pctl_dt_subnode_to_map()
576 num_pins = pins->length / sizeof(u32); in atmel_pctl_dt_subnode_to_map()
578 dev_err(pctldev->dev, "no pins found in node %pOF\n", np); in atmel_pctl_dt_subnode_to_map()
579 ret = -EINVAL; in atmel_pctl_dt_subnode_to_map()
599 ret = of_property_read_u32_index(np, "pinmux", i, &pinfunc); in atmel_pctl_dt_subnode_to_map()
603 ret = atmel_pctl_xlate_pinfunc(pctldev, np, pinfunc, &group, in atmel_pctl_dt_subnode_to_map()
659 dev_err(pctldev->dev, "can't create maps for node %pOF\n", in atmel_pctl_dt_node_to_map()
692 *groups = atmel_pioctrl->group_names; in atmel_pmx_get_function_groups()
693 *num_groups = atmel_pioctrl->npins; in atmel_pmx_get_function_groups()
706 dev_dbg(pctldev->dev, "enable function %s group %s\n", in atmel_pmx_set_mux()
707 atmel_functions[function], atmel_pioctrl->groups[group].name); in atmel_pmx_set_mux()
709 pin = atmel_pioctrl->groups[group].pin; in atmel_pmx_set_mux()
713 dev_dbg(pctldev->dev, "pin: %u, conf: 0x%08x\n", pin, conf); in atmel_pmx_set_mux()
732 struct atmel_group *grp = atmel_pioctrl->groups + group; in atmel_conf_pin_config_group_get()
733 unsigned int pin_id = grp->pin; in atmel_conf_pin_config_group_get()
741 return -EINVAL; in atmel_conf_pin_config_group_get()
747 return -EINVAL; in atmel_conf_pin_config_group_get()
753 return -EINVAL; in atmel_conf_pin_config_group_get()
758 return -EINVAL; in atmel_conf_pin_config_group_get()
763 return -EINVAL; in atmel_conf_pin_config_group_get()
767 if (!atmel_pioctrl->slew_rate_support) in atmel_conf_pin_config_group_get()
768 return -EOPNOTSUPP; in atmel_conf_pin_config_group_get()
770 return -EINVAL; in atmel_conf_pin_config_group_get()
775 return -EINVAL; in atmel_conf_pin_config_group_get()
779 return -ENOTSUPP; in atmel_conf_pin_config_group_get()
792 struct atmel_group *grp = atmel_pioctrl->groups + group; in atmel_conf_pin_config_group_set()
793 unsigned int bank, pin, pin_id = grp->pin; in atmel_conf_pin_config_group_set()
800 if (atmel_pioctrl->slew_rate_support) in atmel_conf_pin_config_group_set()
807 dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n", in atmel_conf_pin_config_group_set()
842 * - can't have different debounce periods inside a same group, in atmel_conf_pin_config_group_set()
843 * - the register to configure this period is a secure register. in atmel_conf_pin_config_group_set()
858 writel_relaxed(mask, atmel_pioctrl->reg_base + in atmel_conf_pin_config_group_set()
862 writel_relaxed(mask, atmel_pioctrl->reg_base + in atmel_conf_pin_config_group_set()
868 if (!atmel_pioctrl->slew_rate_support) in atmel_conf_pin_config_group_set()
883 dev_warn(pctldev->dev, "drive strength not updated (incorrect value)\n"); in atmel_conf_pin_config_group_set()
887 dev_warn(pctldev->dev, in atmel_conf_pin_config_group_set()
894 dev_dbg(pctldev->dev, "%s: reg=0x%08x\n", __func__, conf); in atmel_conf_pin_config_group_set()
907 if (!atmel_pioctrl->pins[pin_id]->device) in atmel_conf_pin_config_dbg_show()
910 if (atmel_pioctrl->pins[pin_id]) in atmel_conf_pin_config_dbg_show()
912 atmel_pioctrl->pins[pin_id]->device, in atmel_conf_pin_config_dbg_show()
913 atmel_pioctrl->pins[pin_id]->ioset); in atmel_conf_pin_config_dbg_show()
917 seq_printf(s, "%s ", "pull-up"); in atmel_conf_pin_config_dbg_show()
919 seq_printf(s, "%s ", "pull-down"); in atmel_conf_pin_config_dbg_show()
923 seq_printf(s, "%s ", "open-drain"); in atmel_conf_pin_config_dbg_show()
926 if (atmel_pioctrl->slew_rate_support && (conf & ATMEL_PIO_SR_MASK)) in atmel_conf_pin_config_dbg_show()
927 seq_printf(s, "%s ", "slew-rate"); in atmel_conf_pin_config_dbg_show()
931 seq_printf(s, "%s ", "medium-drive"); in atmel_conf_pin_config_dbg_show()
934 seq_printf(s, "%s ", "high-drive"); in atmel_conf_pin_config_dbg_show()
938 seq_printf(s, "%s ", "low-drive"); in atmel_conf_pin_config_dbg_show()
965 for (i = 0; i < atmel_pioctrl->nbanks; i++) { in atmel_pctrl_suspend()
966 atmel_pioctrl->pm_suspend_backup[i].imr = in atmel_pctrl_suspend()
969 ~atmel_pioctrl->pm_wakeup_sources[i]); in atmel_pctrl_suspend()
970 atmel_pioctrl->pm_suspend_backup[i].odsr = in atmel_pctrl_suspend()
975 atmel_pioctrl->pm_suspend_backup[i].cfgr[j] = in atmel_pctrl_suspend()
989 for (i = 0; i < atmel_pioctrl->nbanks; i++) { in atmel_pctrl_resume()
991 atmel_pioctrl->pm_suspend_backup[i].imr); in atmel_pctrl_resume()
993 atmel_pioctrl->pm_suspend_backup[i].odsr); in atmel_pctrl_resume()
998 atmel_pioctrl->pm_suspend_backup[i].cfgr[j]); in atmel_pctrl_resume()
1026 .compatible = "atmel,sama5d2-pinctrl",
1029 .compatible = "microchip,sama7g5-pinctrl",
1038 struct device *dev = &pdev->dev; in atmel_pinctrl_probe()
1048 return -ENOMEM; in atmel_pinctrl_probe()
1049 atmel_pioctrl->dev = dev; in atmel_pinctrl_probe()
1050 atmel_pioctrl->node = dev->of_node; in atmel_pinctrl_probe()
1053 match = of_match_node(atmel_pctrl_of_match, dev->of_node); in atmel_pinctrl_probe()
1056 return -ENODEV; in atmel_pinctrl_probe()
1058 atmel_pioctrl_data = match->data; in atmel_pinctrl_probe()
1059 atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks; in atmel_pinctrl_probe()
1060 atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK; in atmel_pinctrl_probe()
1062 if (atmel_pioctrl_data->last_bank_count != ATMEL_PIO_NPINS_PER_BANK) { in atmel_pinctrl_probe()
1063 atmel_pioctrl->npins -= ATMEL_PIO_NPINS_PER_BANK; in atmel_pinctrl_probe()
1064 atmel_pioctrl->npins += atmel_pioctrl_data->last_bank_count; in atmel_pinctrl_probe()
1066 atmel_pioctrl->slew_rate_support = atmel_pioctrl_data->slew_rate_support; in atmel_pinctrl_probe()
1068 atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0); in atmel_pinctrl_probe()
1069 if (IS_ERR(atmel_pioctrl->reg_base)) in atmel_pinctrl_probe()
1070 return PTR_ERR(atmel_pioctrl->reg_base); in atmel_pinctrl_probe()
1072 atmel_pioctrl->clk = devm_clk_get(dev, NULL); in atmel_pinctrl_probe()
1073 if (IS_ERR(atmel_pioctrl->clk)) { in atmel_pinctrl_probe()
1075 return PTR_ERR(atmel_pioctrl->clk); in atmel_pinctrl_probe()
1078 atmel_pioctrl->pins = devm_kcalloc(dev, in atmel_pinctrl_probe()
1079 atmel_pioctrl->npins, in atmel_pinctrl_probe()
1080 sizeof(*atmel_pioctrl->pins), in atmel_pinctrl_probe()
1082 if (!atmel_pioctrl->pins) in atmel_pinctrl_probe()
1083 return -ENOMEM; in atmel_pinctrl_probe()
1085 pin_desc = devm_kcalloc(dev, atmel_pioctrl->npins, sizeof(*pin_desc), in atmel_pinctrl_probe()
1088 return -ENOMEM; in atmel_pinctrl_probe()
1090 atmel_pinctrl_desc.npins = atmel_pioctrl->npins; in atmel_pinctrl_probe()
1096 atmel_pioctrl->npins, sizeof(*group_names), in atmel_pinctrl_probe()
1099 return -ENOMEM; in atmel_pinctrl_probe()
1100 atmel_pioctrl->group_names = group_names; in atmel_pinctrl_probe()
1102 atmel_pioctrl->groups = devm_kcalloc(&pdev->dev, in atmel_pinctrl_probe()
1103 atmel_pioctrl->npins, sizeof(*atmel_pioctrl->groups), in atmel_pinctrl_probe()
1105 if (!atmel_pioctrl->groups) in atmel_pinctrl_probe()
1106 return -ENOMEM; in atmel_pinctrl_probe()
1107 for (i = 0 ; i < atmel_pioctrl->npins; i++) { in atmel_pinctrl_probe()
1108 struct atmel_group *group = atmel_pioctrl->groups + i; in atmel_pinctrl_probe()
1112 atmel_pioctrl->pins[i] = devm_kzalloc(dev, in atmel_pinctrl_probe()
1113 sizeof(**atmel_pioctrl->pins), GFP_KERNEL); in atmel_pinctrl_probe()
1114 if (!atmel_pioctrl->pins[i]) in atmel_pinctrl_probe()
1115 return -ENOMEM; in atmel_pinctrl_probe()
1117 atmel_pioctrl->pins[i]->pin_id = i; in atmel_pinctrl_probe()
1118 atmel_pioctrl->pins[i]->bank = bank; in atmel_pinctrl_probe()
1119 atmel_pioctrl->pins[i]->line = line; in atmel_pinctrl_probe()
1126 group->name = group_names[i] = pin_desc[i].name; in atmel_pinctrl_probe()
1127 group->pin = pin_desc[i].number; in atmel_pinctrl_probe()
1132 atmel_pioctrl->gpio_chip = &atmel_gpio_chip; in atmel_pinctrl_probe()
1133 atmel_pioctrl->gpio_chip->ngpio = atmel_pioctrl->npins; in atmel_pinctrl_probe()
1134 atmel_pioctrl->gpio_chip->label = dev_name(dev); in atmel_pinctrl_probe()
1135 atmel_pioctrl->gpio_chip->parent = dev; in atmel_pinctrl_probe()
1136 atmel_pioctrl->gpio_chip->names = atmel_pioctrl->group_names; in atmel_pinctrl_probe()
1138 atmel_pioctrl->pm_wakeup_sources = devm_kcalloc(dev, in atmel_pinctrl_probe()
1139 atmel_pioctrl->nbanks, in atmel_pinctrl_probe()
1140 sizeof(*atmel_pioctrl->pm_wakeup_sources), in atmel_pinctrl_probe()
1142 if (!atmel_pioctrl->pm_wakeup_sources) in atmel_pinctrl_probe()
1143 return -ENOMEM; in atmel_pinctrl_probe()
1145 atmel_pioctrl->pm_suspend_backup = devm_kcalloc(dev, in atmel_pinctrl_probe()
1146 atmel_pioctrl->nbanks, in atmel_pinctrl_probe()
1147 sizeof(*atmel_pioctrl->pm_suspend_backup), in atmel_pinctrl_probe()
1149 if (!atmel_pioctrl->pm_suspend_backup) in atmel_pinctrl_probe()
1150 return -ENOMEM; in atmel_pinctrl_probe()
1152 atmel_pioctrl->irqs = devm_kcalloc(dev, in atmel_pinctrl_probe()
1153 atmel_pioctrl->nbanks, in atmel_pinctrl_probe()
1154 sizeof(*atmel_pioctrl->irqs), in atmel_pinctrl_probe()
1156 if (!atmel_pioctrl->irqs) in atmel_pinctrl_probe()
1157 return -ENOMEM; in atmel_pinctrl_probe()
1160 for (i = 0; i < atmel_pioctrl->nbanks; i++) { in atmel_pinctrl_probe()
1167 atmel_pioctrl->irqs[i] = ret; in atmel_pinctrl_probe()
1172 atmel_pioctrl->irq_domain = irq_domain_add_linear(dev->of_node, in atmel_pinctrl_probe()
1173 atmel_pioctrl->gpio_chip->ngpio, in atmel_pinctrl_probe()
1175 if (!atmel_pioctrl->irq_domain) { in atmel_pinctrl_probe()
1177 return -ENODEV; in atmel_pinctrl_probe()
1179 atmel_pioctrl->irq_domain->name = "atmel gpio"; in atmel_pinctrl_probe()
1181 for (i = 0; i < atmel_pioctrl->npins; i++) { in atmel_pinctrl_probe()
1182 int irq = irq_create_mapping(atmel_pioctrl->irq_domain, i); in atmel_pinctrl_probe()
1192 ret = clk_prepare_enable(atmel_pioctrl->clk); in atmel_pinctrl_probe()
1198 atmel_pioctrl->pinctrl_dev = devm_pinctrl_register(&pdev->dev, in atmel_pinctrl_probe()
1201 if (IS_ERR(atmel_pioctrl->pinctrl_dev)) { in atmel_pinctrl_probe()
1202 ret = PTR_ERR(atmel_pioctrl->pinctrl_dev); in atmel_pinctrl_probe()
1207 ret = gpiochip_add_data(atmel_pioctrl->gpio_chip, atmel_pioctrl); in atmel_pinctrl_probe()
1213 ret = gpiochip_add_pin_range(atmel_pioctrl->gpio_chip, dev_name(dev), in atmel_pinctrl_probe()
1214 0, 0, atmel_pioctrl->gpio_chip->ngpio); in atmel_pinctrl_probe()
1220 dev_info(&pdev->dev, "atmel pinctrl initialized\n"); in atmel_pinctrl_probe()
1225 gpiochip_remove(atmel_pioctrl->gpio_chip); in atmel_pinctrl_probe()
1228 clk_disable_unprepare(atmel_pioctrl->clk); in atmel_pinctrl_probe()
1231 irq_domain_remove(atmel_pioctrl->irq_domain); in atmel_pinctrl_probe()
1238 .name = "pinctrl-at91-pio4",