Lines Matching +full:group +full:- +full:index +full:- +full:shift
6 * Maxime Ripard <maxime.ripard@free-electrons.com>
28 #include <linux/pinctrl/pinconf-generic.h>
33 #include <dt-bindings/pinctrl/sun4i-a10.h>
36 #include "pinctrl-sunxi.h"
51 * - Mux config
52 * - Data value
53 * - Drive level
54 * - Pull direction
62 u32 pin, u32 *reg, u32 *shift, u32 *mask) in sunxi_mux_reg() argument
67 *reg = bank * pctl->bank_mem_size + MUX_REGS_OFFSET + in sunxi_mux_reg()
69 *shift = offset % BITS_PER_TYPE(u32); in sunxi_mux_reg()
70 *mask = (BIT(MUX_FIELD_WIDTH) - 1) << *shift; in sunxi_mux_reg()
74 u32 pin, u32 *reg, u32 *shift, u32 *mask) in sunxi_data_reg() argument
79 *reg = bank * pctl->bank_mem_size + DATA_REGS_OFFSET + in sunxi_data_reg()
81 *shift = offset % BITS_PER_TYPE(u32); in sunxi_data_reg()
82 *mask = (BIT(DATA_FIELD_WIDTH) - 1) << *shift; in sunxi_data_reg()
86 u32 pin, u32 *reg, u32 *shift, u32 *mask) in sunxi_dlevel_reg() argument
89 u32 offset = pin % PINS_PER_BANK * pctl->dlevel_field_width; in sunxi_dlevel_reg()
91 *reg = bank * pctl->bank_mem_size + DLEVEL_REGS_OFFSET + in sunxi_dlevel_reg()
93 *shift = offset % BITS_PER_TYPE(u32); in sunxi_dlevel_reg()
94 *mask = (BIT(pctl->dlevel_field_width) - 1) << *shift; in sunxi_dlevel_reg()
98 u32 pin, u32 *reg, u32 *shift, u32 *mask) in sunxi_pull_reg() argument
103 *reg = bank * pctl->bank_mem_size + pctl->pull_regs_offset + in sunxi_pull_reg()
105 *shift = offset % BITS_PER_TYPE(u32); in sunxi_pull_reg()
106 *mask = (BIT(PULL_FIELD_WIDTH) - 1) << *shift; in sunxi_pull_reg()
110 sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group) in sunxi_pinctrl_find_group_by_name() argument
114 for (i = 0; i < pctl->ngroups; i++) { in sunxi_pinctrl_find_group_by_name()
115 struct sunxi_pinctrl_group *grp = pctl->groups + i; in sunxi_pinctrl_find_group_by_name()
117 if (!strcmp(grp->name, group)) in sunxi_pinctrl_find_group_by_name()
128 struct sunxi_pinctrl_function *func = pctl->functions; in sunxi_pinctrl_find_function_by_name()
131 for (i = 0; i < pctl->nfunctions; i++) { in sunxi_pinctrl_find_function_by_name()
149 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_desc_find_function_by_name()
150 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_desc_find_function_by_name()
152 if (!strcmp(pin->pin.name, pin_name)) { in sunxi_pinctrl_desc_find_function_by_name()
153 struct sunxi_desc_function *func = pin->functions; in sunxi_pinctrl_desc_find_function_by_name()
155 while (func->name) { in sunxi_pinctrl_desc_find_function_by_name()
156 if (!strcmp(func->name, func_name) && in sunxi_pinctrl_desc_find_function_by_name()
157 (!func->variant || in sunxi_pinctrl_desc_find_function_by_name()
158 func->variant & pctl->variant)) in sunxi_pinctrl_desc_find_function_by_name()
176 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_desc_find_function_by_pin()
177 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_desc_find_function_by_pin()
179 if (pin->pin.number == pin_num) { in sunxi_pinctrl_desc_find_function_by_pin()
180 struct sunxi_desc_function *func = pin->functions; in sunxi_pinctrl_desc_find_function_by_pin()
182 while (func->name) { in sunxi_pinctrl_desc_find_function_by_pin()
183 if (!strcmp(func->name, func_name)) in sunxi_pinctrl_desc_find_function_by_pin()
198 return pctl->ngroups; in sunxi_pctrl_get_groups_count()
202 unsigned group) in sunxi_pctrl_get_group_name() argument
206 return pctl->groups[group].name; in sunxi_pctrl_get_group_name()
210 unsigned group, in sunxi_pctrl_get_group_pins() argument
216 *pins = (unsigned *)&pctl->groups[group].pin; in sunxi_pctrl_get_group_pins()
224 return of_property_present(node, "bias-pull-up") || in sunxi_pctrl_has_bias_prop()
225 of_property_present(node, "bias-pull-down") || in sunxi_pctrl_has_bias_prop()
226 of_property_present(node, "bias-disable") || in sunxi_pctrl_has_bias_prop()
232 return of_property_present(node, "drive-strength") || in sunxi_pctrl_has_drive_prop()
241 if (of_property_present(node, "bias-pull-up")) in sunxi_pctrl_parse_bias_prop()
244 if (of_property_present(node, "bias-pull-down")) in sunxi_pctrl_parse_bias_prop()
247 if (of_property_present(node, "bias-disable")) in sunxi_pctrl_parse_bias_prop()
252 return -EINVAL; in sunxi_pctrl_parse_bias_prop()
263 return -EINVAL; in sunxi_pctrl_parse_bias_prop()
271 if (!of_property_read_u32(node, "drive-strength", &val)) { in sunxi_pctrl_parse_drive_prop()
274 return -EINVAL; in sunxi_pctrl_parse_drive_prop()
286 return -EINVAL; in sunxi_pctrl_parse_drive_prop()
351 return ERR_PTR(-ENOMEM); in sunxi_pctrl_build_pin_config()
396 const char *group; in sunxi_pctrl_dt_node_to_map() local
404 dev_err(pctl->dev, "missing function property in node %pOFn\n", in sunxi_pctrl_dt_node_to_map()
406 return -EINVAL; in sunxi_pctrl_dt_node_to_map()
411 dev_err(pctl->dev, "missing pins property in node %pOFn\n", in sunxi_pctrl_dt_node_to_map()
413 return -EINVAL; in sunxi_pctrl_dt_node_to_map()
426 return -ENOMEM; in sunxi_pctrl_dt_node_to_map()
434 of_property_for_each_string(node, pin_prop, prop, group) { in sunxi_pctrl_dt_node_to_map()
436 sunxi_pinctrl_find_group_by_name(pctl, group); in sunxi_pctrl_dt_node_to_map()
439 dev_err(pctl->dev, "unknown pin %s", group); in sunxi_pctrl_dt_node_to_map()
444 grp->name, in sunxi_pctrl_dt_node_to_map()
446 dev_err(pctl->dev, "unsupported function %s on pin %s", in sunxi_pctrl_dt_node_to_map()
447 function, group); in sunxi_pctrl_dt_node_to_map()
452 (*map)[i].data.mux.group = group; in sunxi_pctrl_dt_node_to_map()
459 (*map)[i].data.configs.group_or_pin = group; in sunxi_pctrl_dt_node_to_map()
474 return -ENOMEM; in sunxi_pctrl_dt_node_to_map()
516 u32 *reg, u32 *shift, u32 *mask) in sunxi_pconf_reg() argument
520 sunxi_dlevel_reg(pctl, pin, reg, shift, mask); in sunxi_pconf_reg()
526 sunxi_pull_reg(pctl, pin, reg, shift, mask); in sunxi_pconf_reg()
530 return -ENOTSUPP; in sunxi_pconf_reg()
541 u32 reg, shift, mask, val; in sunxi_pconf_get() local
545 pin -= pctl->desc->pin_base; in sunxi_pconf_get()
547 ret = sunxi_pconf_reg(pctl, pin, param, ®, &shift, &mask); in sunxi_pconf_get()
551 val = (readl(pctl->membase + reg) & mask) >> shift; in sunxi_pconf_get()
560 return -EINVAL; in sunxi_pconf_get()
561 arg = 1; /* hardware is weak pull-up */ in sunxi_pconf_get()
566 return -EINVAL; in sunxi_pconf_get()
567 arg = 1; /* hardware is weak pull-down */ in sunxi_pconf_get()
572 return -EINVAL; in sunxi_pconf_get()
579 return -ENOTSUPP; in sunxi_pconf_get()
588 unsigned group, in sunxi_pconf_group_get() argument
592 struct sunxi_pinctrl_group *g = &pctl->groups[group]; in sunxi_pconf_group_get()
594 /* We only support 1 pin per group. Chain it to the pin callback */ in sunxi_pconf_group_get()
595 return sunxi_pconf_get(pctldev, g->pin, config); in sunxi_pconf_group_get()
604 pin -= pctl->desc->pin_base; in sunxi_pconf_set()
607 u32 arg, reg, shift, mask, val; in sunxi_pconf_set() local
615 ret = sunxi_pconf_reg(pctl, pin, param, ®, &shift, &mask); in sunxi_pconf_set()
622 return -EINVAL; in sunxi_pconf_set()
630 val = arg / 10 - 1; in sunxi_pconf_set()
637 return -EINVAL; in sunxi_pconf_set()
642 return -EINVAL; in sunxi_pconf_set()
648 return -ENOTSUPP; in sunxi_pconf_set()
651 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pconf_set()
652 writel((readl(pctl->membase + reg) & ~mask) | val << shift, in sunxi_pconf_set()
653 pctl->membase + reg); in sunxi_pconf_set()
654 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pconf_set()
660 static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, in sunxi_pconf_group_set() argument
664 struct sunxi_pinctrl_group *g = &pctl->groups[group]; in sunxi_pconf_group_set()
666 /* We only support 1 pin per group. Chain it to the pin callback */ in sunxi_pconf_group_set()
667 return sunxi_pconf_set(pctldev, g->pin, configs, num_configs); in sunxi_pconf_group_set()
687 if (!pctl->desc->io_bias_cfg_variant) in sunxi_pinctrl_set_io_bias_cfg()
698 pin -= pctl->desc->pin_base; in sunxi_pinctrl_set_io_bias_cfg()
701 switch (pctl->desc->io_bias_cfg_variant) { in sunxi_pinctrl_set_io_bias_cfg()
718 reg = readl(pctl->membase + sunxi_grp_config_reg(pin)); in sunxi_pinctrl_set_io_bias_cfg()
720 writel(reg | val, pctl->membase + sunxi_grp_config_reg(pin)); in sunxi_pinctrl_set_io_bias_cfg()
725 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
726 reg = readl(pctl->membase + PIO_POW_MOD_CTL_REG); in sunxi_pinctrl_set_io_bias_cfg()
728 writel(reg | val, pctl->membase + PIO_POW_MOD_CTL_REG); in sunxi_pinctrl_set_io_bias_cfg()
729 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
735 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
736 reg = readl(pctl->membase + PIO_POW_MOD_SEL_REG); in sunxi_pinctrl_set_io_bias_cfg()
738 writel(reg | val << bank, pctl->membase + PIO_POW_MOD_SEL_REG); in sunxi_pinctrl_set_io_bias_cfg()
739 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
742 return -EINVAL; in sunxi_pinctrl_set_io_bias_cfg()
750 return pctl->nfunctions; in sunxi_pmx_get_funcs_cnt()
758 return pctl->functions[function].name; in sunxi_pmx_get_func_name()
768 *groups = pctl->functions[function].groups; in sunxi_pmx_get_func_groups()
769 *num_groups = pctl->functions[function].ngroups; in sunxi_pmx_get_func_groups()
779 u32 reg, shift, mask; in sunxi_pmx_set() local
782 pin -= pctl->desc->pin_base; in sunxi_pmx_set()
783 sunxi_mux_reg(pctl, pin, ®, &shift, &mask); in sunxi_pmx_set()
785 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pmx_set()
787 writel((readl(pctl->membase + reg) & ~mask) | config << shift, in sunxi_pmx_set()
788 pctl->membase + reg); in sunxi_pmx_set()
790 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pmx_set()
795 unsigned group) in sunxi_pmx_set_mux() argument
798 struct sunxi_pinctrl_group *g = pctl->groups + group; in sunxi_pmx_set_mux()
799 struct sunxi_pinctrl_function *func = pctl->functions + function; in sunxi_pmx_set_mux()
802 g->name, in sunxi_pmx_set_mux()
803 func->name); in sunxi_pmx_set_mux()
806 return -EINVAL; in sunxi_pmx_set_mux()
808 sunxi_pmx_set(pctldev, g->pin, desc->muxval); in sunxi_pmx_set_mux()
830 return -EINVAL; in sunxi_pmx_gpio_set_direction()
832 sunxi_pmx_set(pctldev, offset, desc->muxval); in sunxi_pmx_gpio_set_direction()
841 unsigned short bank_offset = bank - pctl->desc->pin_base / in sunxi_pmx_request()
843 struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset]; in sunxi_pmx_request()
844 struct regulator *reg = s_reg->regulator; in sunxi_pmx_request()
848 if (WARN_ON_ONCE(bank_offset >= ARRAY_SIZE(pctl->regulators))) in sunxi_pmx_request()
849 return -EINVAL; in sunxi_pmx_request()
852 refcount_inc(&s_reg->refcount); in sunxi_pmx_request()
856 snprintf(supply, sizeof(supply), "vcc-p%c", 'a' + bank); in sunxi_pmx_request()
857 reg = regulator_get(pctl->dev, supply); in sunxi_pmx_request()
859 return dev_err_probe(pctl->dev, PTR_ERR(reg), in sunxi_pmx_request()
865 dev_err(pctl->dev, in sunxi_pmx_request()
872 s_reg->regulator = reg; in sunxi_pmx_request()
873 refcount_set(&s_reg->refcount, 1); in sunxi_pmx_request()
878 regulator_put(s_reg->regulator); in sunxi_pmx_request()
887 unsigned short bank_offset = bank - pctl->desc->pin_base / in sunxi_pmx_free()
889 struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset]; in sunxi_pmx_free()
891 if (!refcount_dec_and_test(&s_reg->refcount)) in sunxi_pmx_free()
894 regulator_disable(s_reg->regulator); in sunxi_pmx_free()
895 regulator_put(s_reg->regulator); in sunxi_pmx_free()
896 s_reg->regulator = NULL; in sunxi_pmx_free()
917 return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, in sunxi_pinctrl_gpio_direction_input()
918 chip->base + offset, true); in sunxi_pinctrl_gpio_direction_input()
924 bool set_mux = pctl->desc->irq_read_needs_mux && in sunxi_pinctrl_gpio_get()
926 u32 pin = offset + chip->base; in sunxi_pinctrl_gpio_get()
927 u32 reg, shift, mask, val; in sunxi_pinctrl_gpio_get() local
929 sunxi_data_reg(pctl, offset, ®, &shift, &mask); in sunxi_pinctrl_gpio_get()
932 sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_INPUT); in sunxi_pinctrl_gpio_get()
934 val = (readl(pctl->membase + reg) & mask) >> shift; in sunxi_pinctrl_gpio_get()
937 sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_IRQ); in sunxi_pinctrl_gpio_get()
946 u32 reg, shift, mask, val; in sunxi_pinctrl_gpio_set() local
949 sunxi_data_reg(pctl, offset, ®, &shift, &mask); in sunxi_pinctrl_gpio_set()
951 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_gpio_set()
953 val = readl(pctl->membase + reg); in sunxi_pinctrl_gpio_set()
960 writel(val, pctl->membase + reg); in sunxi_pinctrl_gpio_set()
962 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_gpio_set()
971 return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, in sunxi_pinctrl_gpio_direction_output()
972 chip->base + offset, false); in sunxi_pinctrl_gpio_direction_output()
981 base = PINS_PER_BANK * gpiospec->args[0]; in sunxi_pinctrl_gpio_of_xlate()
982 pin = base + gpiospec->args[1]; in sunxi_pinctrl_gpio_of_xlate()
984 if (pin > gc->ngpio) in sunxi_pinctrl_gpio_of_xlate()
985 return -EINVAL; in sunxi_pinctrl_gpio_of_xlate()
988 *flags = gpiospec->args[2]; in sunxi_pinctrl_gpio_of_xlate()
997 unsigned pinnum = pctl->desc->pin_base + offset; in sunxi_pinctrl_gpio_to_irq()
1000 if (offset >= chip->ngpio) in sunxi_pinctrl_gpio_to_irq()
1001 return -ENXIO; in sunxi_pinctrl_gpio_to_irq()
1005 return -EINVAL; in sunxi_pinctrl_gpio_to_irq()
1007 irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum; in sunxi_pinctrl_gpio_to_irq()
1009 dev_dbg(chip->parent, "%s: request IRQ for GPIO %d, return %d\n", in sunxi_pinctrl_gpio_to_irq()
1010 chip->label, offset + chip->base, irqnum); in sunxi_pinctrl_gpio_to_irq()
1012 return irq_find_mapping(pctl->domain, irqnum); in sunxi_pinctrl_gpio_to_irq()
1022 pctl->irq_array[d->hwirq], "irq"); in sunxi_pinctrl_irq_request_resources()
1024 return -EINVAL; in sunxi_pinctrl_irq_request_resources()
1026 ret = gpiochip_lock_as_irq(pctl->chip, in sunxi_pinctrl_irq_request_resources()
1027 pctl->irq_array[d->hwirq] - pctl->desc->pin_base); in sunxi_pinctrl_irq_request_resources()
1029 dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n", in sunxi_pinctrl_irq_request_resources()
1035 sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); in sunxi_pinctrl_irq_request_resources()
1044 gpiochip_unlock_as_irq(pctl->chip, in sunxi_pinctrl_irq_release_resources()
1045 pctl->irq_array[d->hwirq] - pctl->desc->pin_base); in sunxi_pinctrl_irq_release_resources()
1051 u32 reg = sunxi_irq_cfg_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_set_type()
1052 u8 index = sunxi_irq_cfg_offset(d->hwirq); in sunxi_pinctrl_irq_set_type() local
1074 return -EINVAL; in sunxi_pinctrl_irq_set_type()
1077 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_irq_set_type()
1086 regval = readl(pctl->membase + reg); in sunxi_pinctrl_irq_set_type()
1087 regval &= ~(IRQ_CFG_IRQ_MASK << index); in sunxi_pinctrl_irq_set_type()
1088 writel(regval | (mode << index), pctl->membase + reg); in sunxi_pinctrl_irq_set_type()
1090 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_irq_set_type()
1098 u32 status_reg = sunxi_irq_status_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_ack()
1099 u8 status_idx = sunxi_irq_status_offset(d->hwirq); in sunxi_pinctrl_irq_ack()
1102 writel(1 << status_idx, pctl->membase + status_reg); in sunxi_pinctrl_irq_ack()
1108 u32 reg = sunxi_irq_ctrl_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_mask()
1109 u8 idx = sunxi_irq_ctrl_offset(d->hwirq); in sunxi_pinctrl_irq_mask()
1113 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_irq_mask()
1116 val = readl(pctl->membase + reg); in sunxi_pinctrl_irq_mask()
1117 writel(val & ~(1 << idx), pctl->membase + reg); in sunxi_pinctrl_irq_mask()
1119 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_irq_mask()
1125 u32 reg = sunxi_irq_ctrl_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_unmask()
1126 u8 idx = sunxi_irq_ctrl_offset(d->hwirq); in sunxi_pinctrl_irq_unmask()
1130 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_irq_unmask()
1133 val = readl(pctl->membase + reg); in sunxi_pinctrl_irq_unmask()
1134 writel(val | (1 << idx), pctl->membase + reg); in sunxi_pinctrl_irq_unmask()
1136 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_irq_unmask()
1148 u8 bank = d->hwirq / IRQ_PER_BANK; in sunxi_pinctrl_irq_set_wake()
1150 return irq_set_irq_wake(pctl->irq[bank], on); in sunxi_pinctrl_irq_set_wake()
1190 struct sunxi_pinctrl *pctl = d->host_data; in sunxi_pinctrl_irq_of_xlate()
1195 return -EINVAL; in sunxi_pinctrl_irq_of_xlate()
1198 pin = pctl->desc->pin_base + base + intspec[1]; in sunxi_pinctrl_irq_of_xlate()
1202 return -EINVAL; in sunxi_pinctrl_irq_of_xlate()
1204 *out_hwirq = desc->irqbank * PINS_PER_BANK + desc->irqnum; in sunxi_pinctrl_irq_of_xlate()
1221 for (bank = 0; bank < pctl->desc->irq_banks; bank++) in sunxi_pinctrl_irq_handler()
1222 if (irq == pctl->irq[bank]) in sunxi_pinctrl_irq_handler()
1225 WARN_ON(bank == pctl->desc->irq_banks); in sunxi_pinctrl_irq_handler()
1229 reg = sunxi_irq_status_reg_from_bank(pctl->desc, bank); in sunxi_pinctrl_irq_handler()
1230 val = readl(pctl->membase + reg); in sunxi_pinctrl_irq_handler()
1236 generic_handle_domain_irq(pctl->domain, in sunxi_pinctrl_irq_handler()
1246 struct sunxi_pinctrl_function *func = pctl->functions; in sunxi_pinctrl_add_function()
1248 while (func->name) { in sunxi_pinctrl_add_function()
1250 if (strcmp(func->name, name) == 0) { in sunxi_pinctrl_add_function()
1251 func->ngroups++; in sunxi_pinctrl_add_function()
1252 return -EEXIST; in sunxi_pinctrl_add_function()
1257 func->name = name; in sunxi_pinctrl_add_function()
1258 func->ngroups = 1; in sunxi_pinctrl_add_function()
1260 pctl->nfunctions++; in sunxi_pinctrl_add_function()
1279 * this means that the number of pins is the maximum group in sunxi_pinctrl_build_state()
1282 pctl->groups = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_build_state()
1283 pctl->desc->npins, sizeof(*pctl->groups), in sunxi_pinctrl_build_state()
1285 if (!pctl->groups) in sunxi_pinctrl_build_state()
1286 return -ENOMEM; in sunxi_pinctrl_build_state()
1288 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_build_state()
1289 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_build_state()
1290 struct sunxi_pinctrl_group *group = pctl->groups + pctl->ngroups; in sunxi_pinctrl_build_state() local
1292 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_build_state()
1295 group->name = pin->pin.name; in sunxi_pinctrl_build_state()
1296 group->pin = pin->pin.number; in sunxi_pinctrl_build_state()
1299 pctl->ngroups++; in sunxi_pinctrl_build_state()
1308 pctl->functions = kcalloc(7 * pctl->ngroups + 4, in sunxi_pinctrl_build_state()
1309 sizeof(*pctl->functions), in sunxi_pinctrl_build_state()
1311 if (!pctl->functions) in sunxi_pinctrl_build_state()
1312 return -ENOMEM; in sunxi_pinctrl_build_state()
1315 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_build_state()
1316 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_build_state()
1319 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_build_state()
1322 for (func = pin->functions; func->name; func++) { in sunxi_pinctrl_build_state()
1323 if (func->variant && !(pctl->variant & func->variant)) in sunxi_pinctrl_build_state()
1327 if (!strcmp(func->name, "irq")) { in sunxi_pinctrl_build_state()
1328 int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK; in sunxi_pinctrl_build_state()
1329 pctl->irq_array[irqnum] = pin->pin.number; in sunxi_pinctrl_build_state()
1332 sunxi_pinctrl_add_function(pctl, func->name); in sunxi_pinctrl_build_state()
1337 ptr = krealloc(pctl->functions, in sunxi_pinctrl_build_state()
1338 pctl->nfunctions * sizeof(*pctl->functions), in sunxi_pinctrl_build_state()
1341 kfree(pctl->functions); in sunxi_pinctrl_build_state()
1342 pctl->functions = NULL; in sunxi_pinctrl_build_state()
1343 return -ENOMEM; in sunxi_pinctrl_build_state()
1345 pctl->functions = ptr; in sunxi_pinctrl_build_state()
1347 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_build_state()
1348 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_build_state()
1351 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_build_state()
1354 for (func = pin->functions; func->name; func++) { in sunxi_pinctrl_build_state()
1358 if (func->variant && !(pctl->variant & func->variant)) in sunxi_pinctrl_build_state()
1362 func->name); in sunxi_pinctrl_build_state()
1364 kfree(pctl->functions); in sunxi_pinctrl_build_state()
1365 return -EINVAL; in sunxi_pinctrl_build_state()
1368 if (!func_item->groups) { in sunxi_pinctrl_build_state()
1369 func_item->groups = in sunxi_pinctrl_build_state()
1370 devm_kcalloc(&pdev->dev, in sunxi_pinctrl_build_state()
1371 func_item->ngroups, in sunxi_pinctrl_build_state()
1372 sizeof(*func_item->groups), in sunxi_pinctrl_build_state()
1374 if (!func_item->groups) { in sunxi_pinctrl_build_state()
1375 kfree(pctl->functions); in sunxi_pinctrl_build_state()
1376 return -ENOMEM; in sunxi_pinctrl_build_state()
1380 func_grp = func_item->groups; in sunxi_pinctrl_build_state()
1384 *func_grp = pin->pin.name; in sunxi_pinctrl_build_state()
1397 best_diff = abs(freq - clock); in sunxi_pinctrl_get_debounce_div()
1401 int cur_diff = abs(freq - (clock >> i)); in sunxi_pinctrl_get_debounce_div()
1427 if (!of_property_present(node, "input-debounce")) in sunxi_pinctrl_setup_debounce()
1430 losc = devm_clk_get(pctl->dev, "losc"); in sunxi_pinctrl_setup_debounce()
1434 hosc = devm_clk_get(pctl->dev, "hosc"); in sunxi_pinctrl_setup_debounce()
1438 for (i = 0; i < pctl->desc->irq_banks; i++) { in sunxi_pinctrl_setup_debounce()
1442 ret = of_property_read_u32_index(node, "input-debounce", in sunxi_pinctrl_setup_debounce()
1468 pctl->membase + in sunxi_pinctrl_setup_debounce()
1469 sunxi_irq_debounce_reg_from_bank(pctl->desc, i)); in sunxi_pinctrl_setup_debounce()
1479 struct device_node *node = pdev->dev.of_node; in sunxi_pinctrl_init_with_variant()
1487 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); in sunxi_pinctrl_init_with_variant()
1489 return -ENOMEM; in sunxi_pinctrl_init_with_variant()
1492 raw_spin_lock_init(&pctl->lock); in sunxi_pinctrl_init_with_variant()
1494 pctl->membase = devm_platform_ioremap_resource(pdev, 0); in sunxi_pinctrl_init_with_variant()
1495 if (IS_ERR(pctl->membase)) in sunxi_pinctrl_init_with_variant()
1496 return PTR_ERR(pctl->membase); in sunxi_pinctrl_init_with_variant()
1498 pctl->dev = &pdev->dev; in sunxi_pinctrl_init_with_variant()
1499 pctl->desc = desc; in sunxi_pinctrl_init_with_variant()
1500 pctl->variant = variant; in sunxi_pinctrl_init_with_variant()
1501 if (pctl->variant >= PINCTRL_SUN20I_D1) { in sunxi_pinctrl_init_with_variant()
1502 pctl->bank_mem_size = D1_BANK_MEM_SIZE; in sunxi_pinctrl_init_with_variant()
1503 pctl->pull_regs_offset = D1_PULL_REGS_OFFSET; in sunxi_pinctrl_init_with_variant()
1504 pctl->dlevel_field_width = D1_DLEVEL_FIELD_WIDTH; in sunxi_pinctrl_init_with_variant()
1506 pctl->bank_mem_size = BANK_MEM_SIZE; in sunxi_pinctrl_init_with_variant()
1507 pctl->pull_regs_offset = PULL_REGS_OFFSET; in sunxi_pinctrl_init_with_variant()
1508 pctl->dlevel_field_width = DLEVEL_FIELD_WIDTH; in sunxi_pinctrl_init_with_variant()
1511 pctl->irq_array = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_init_with_variant()
1512 IRQ_PER_BANK * pctl->desc->irq_banks, in sunxi_pinctrl_init_with_variant()
1513 sizeof(*pctl->irq_array), in sunxi_pinctrl_init_with_variant()
1515 if (!pctl->irq_array) in sunxi_pinctrl_init_with_variant()
1516 return -ENOMEM; in sunxi_pinctrl_init_with_variant()
1520 dev_err(&pdev->dev, "dt probe failed: %d\n", ret); in sunxi_pinctrl_init_with_variant()
1524 pins = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_init_with_variant()
1525 pctl->desc->npins, sizeof(*pins), in sunxi_pinctrl_init_with_variant()
1528 return -ENOMEM; in sunxi_pinctrl_init_with_variant()
1530 for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_init_with_variant()
1531 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_init_with_variant()
1533 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_init_with_variant()
1536 pins[pin_idx++] = pin->pin; in sunxi_pinctrl_init_with_variant()
1539 pctrl_desc = devm_kzalloc(&pdev->dev, in sunxi_pinctrl_init_with_variant()
1543 return -ENOMEM; in sunxi_pinctrl_init_with_variant()
1545 pctrl_desc->name = dev_name(&pdev->dev); in sunxi_pinctrl_init_with_variant()
1546 pctrl_desc->owner = THIS_MODULE; in sunxi_pinctrl_init_with_variant()
1547 pctrl_desc->pins = pins; in sunxi_pinctrl_init_with_variant()
1548 pctrl_desc->npins = pctl->ngroups; in sunxi_pinctrl_init_with_variant()
1549 pctrl_desc->confops = &sunxi_pconf_ops; in sunxi_pinctrl_init_with_variant()
1550 pctrl_desc->pctlops = &sunxi_pctrl_ops; in sunxi_pinctrl_init_with_variant()
1552 pmxops = devm_kmemdup(&pdev->dev, &sunxi_pmx_ops, sizeof(sunxi_pmx_ops), in sunxi_pinctrl_init_with_variant()
1555 return -ENOMEM; in sunxi_pinctrl_init_with_variant()
1557 if (desc->disable_strict_mode) in sunxi_pinctrl_init_with_variant()
1558 pmxops->strict = false; in sunxi_pinctrl_init_with_variant()
1560 pctrl_desc->pmxops = pmxops; in sunxi_pinctrl_init_with_variant()
1562 pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl); in sunxi_pinctrl_init_with_variant()
1563 if (IS_ERR(pctl->pctl_dev)) { in sunxi_pinctrl_init_with_variant()
1564 dev_err(&pdev->dev, "couldn't register pinctrl driver\n"); in sunxi_pinctrl_init_with_variant()
1565 return PTR_ERR(pctl->pctl_dev); in sunxi_pinctrl_init_with_variant()
1568 pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL); in sunxi_pinctrl_init_with_variant()
1569 if (!pctl->chip) in sunxi_pinctrl_init_with_variant()
1570 return -ENOMEM; in sunxi_pinctrl_init_with_variant()
1572 last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number; in sunxi_pinctrl_init_with_variant()
1573 pctl->chip->owner = THIS_MODULE; in sunxi_pinctrl_init_with_variant()
1574 pctl->chip->request = gpiochip_generic_request; in sunxi_pinctrl_init_with_variant()
1575 pctl->chip->free = gpiochip_generic_free; in sunxi_pinctrl_init_with_variant()
1576 pctl->chip->set_config = gpiochip_generic_config; in sunxi_pinctrl_init_with_variant()
1577 pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; in sunxi_pinctrl_init_with_variant()
1578 pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; in sunxi_pinctrl_init_with_variant()
1579 pctl->chip->get = sunxi_pinctrl_gpio_get; in sunxi_pinctrl_init_with_variant()
1580 pctl->chip->set = sunxi_pinctrl_gpio_set; in sunxi_pinctrl_init_with_variant()
1581 pctl->chip->of_xlate = sunxi_pinctrl_gpio_of_xlate; in sunxi_pinctrl_init_with_variant()
1582 pctl->chip->to_irq = sunxi_pinctrl_gpio_to_irq; in sunxi_pinctrl_init_with_variant()
1583 pctl->chip->of_gpio_n_cells = 3; in sunxi_pinctrl_init_with_variant()
1584 pctl->chip->can_sleep = false; in sunxi_pinctrl_init_with_variant()
1585 pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK) - in sunxi_pinctrl_init_with_variant()
1586 pctl->desc->pin_base; in sunxi_pinctrl_init_with_variant()
1587 pctl->chip->label = dev_name(&pdev->dev); in sunxi_pinctrl_init_with_variant()
1588 pctl->chip->parent = &pdev->dev; in sunxi_pinctrl_init_with_variant()
1589 pctl->chip->base = pctl->desc->pin_base; in sunxi_pinctrl_init_with_variant()
1591 ret = gpiochip_add_data(pctl->chip, pctl); in sunxi_pinctrl_init_with_variant()
1595 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_init_with_variant()
1596 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_init_with_variant()
1598 ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev), in sunxi_pinctrl_init_with_variant()
1599 pin->pin.number - pctl->desc->pin_base, in sunxi_pinctrl_init_with_variant()
1600 pin->pin.number, 1); in sunxi_pinctrl_init_with_variant()
1606 clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb"); in sunxi_pinctrl_init_with_variant()
1612 pctl->irq = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_init_with_variant()
1613 pctl->desc->irq_banks, in sunxi_pinctrl_init_with_variant()
1614 sizeof(*pctl->irq), in sunxi_pinctrl_init_with_variant()
1616 if (!pctl->irq) { in sunxi_pinctrl_init_with_variant()
1617 ret = -ENOMEM; in sunxi_pinctrl_init_with_variant()
1621 for (i = 0; i < pctl->desc->irq_banks; i++) { in sunxi_pinctrl_init_with_variant()
1622 pctl->irq[i] = platform_get_irq(pdev, i); in sunxi_pinctrl_init_with_variant()
1623 if (pctl->irq[i] < 0) { in sunxi_pinctrl_init_with_variant()
1624 ret = pctl->irq[i]; in sunxi_pinctrl_init_with_variant()
1629 pctl->domain = irq_domain_add_linear(node, in sunxi_pinctrl_init_with_variant()
1630 pctl->desc->irq_banks * IRQ_PER_BANK, in sunxi_pinctrl_init_with_variant()
1633 if (!pctl->domain) { in sunxi_pinctrl_init_with_variant()
1634 dev_err(&pdev->dev, "Couldn't register IRQ domain\n"); in sunxi_pinctrl_init_with_variant()
1635 ret = -ENOMEM; in sunxi_pinctrl_init_with_variant()
1639 for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) { in sunxi_pinctrl_init_with_variant()
1640 int irqno = irq_create_mapping(pctl->domain, i); in sunxi_pinctrl_init_with_variant()
1649 for (i = 0; i < pctl->desc->irq_banks; i++) { in sunxi_pinctrl_init_with_variant()
1651 writel(0, pctl->membase + in sunxi_pinctrl_init_with_variant()
1652 sunxi_irq_ctrl_reg_from_bank(pctl->desc, i)); in sunxi_pinctrl_init_with_variant()
1654 pctl->membase + in sunxi_pinctrl_init_with_variant()
1655 sunxi_irq_status_reg_from_bank(pctl->desc, i)); in sunxi_pinctrl_init_with_variant()
1657 irq_set_chained_handler_and_data(pctl->irq[i], in sunxi_pinctrl_init_with_variant()
1664 dev_info(&pdev->dev, "initialized sunXi PIO driver\n"); in sunxi_pinctrl_init_with_variant()
1669 gpiochip_remove(pctl->chip); in sunxi_pinctrl_init_with_variant()