Lines Matching +full:bank +full:- +full:name

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"
50 * for each bank in the following order:
51 * - Mux config
52 * - Data value
53 * - Drive level
54 * - Pull direction
63 * When using the extended register layout, Bank K does not fit into the
71 pin -= PK_BASE; in sunxi_bank_offset()
75 return offset + (pin / PINS_PER_BANK) * pctl->bank_mem_size; in sunxi_bank_offset()
86 *mask = (BIT(MUX_FIELD_WIDTH) - 1) << *shift; in sunxi_mux_reg()
97 *mask = (BIT(DATA_FIELD_WIDTH) - 1) << *shift; in sunxi_data_reg()
103 u32 offset = pin % PINS_PER_BANK * pctl->dlevel_field_width; in sunxi_dlevel_reg()
108 *mask = (BIT(pctl->dlevel_field_width) - 1) << *shift; in sunxi_dlevel_reg()
116 *reg = sunxi_bank_offset(pctl, pin) + pctl->pull_regs_offset + in sunxi_pull_reg()
119 *mask = (BIT(PULL_FIELD_WIDTH) - 1) << *shift; in sunxi_pull_reg()
127 for (i = 0; i < pctl->ngroups; i++) { in sunxi_pinctrl_find_group_by_name()
128 struct sunxi_pinctrl_group *grp = pctl->groups + i; in sunxi_pinctrl_find_group_by_name()
130 if (!strcmp(grp->name, group)) in sunxi_pinctrl_find_group_by_name()
139 const char *name) in sunxi_pinctrl_find_function_by_name() argument
141 struct sunxi_pinctrl_function *func = pctl->functions; in sunxi_pinctrl_find_function_by_name()
144 for (i = 0; i < pctl->nfunctions; i++) { in sunxi_pinctrl_find_function_by_name()
145 if (!func[i].name) in sunxi_pinctrl_find_function_by_name()
148 if (!strcmp(func[i].name, name)) in sunxi_pinctrl_find_function_by_name()
162 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_desc_find_function_by_name()
163 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_desc_find_function_by_name()
165 if (!strcmp(pin->pin.name, pin_name)) { in sunxi_pinctrl_desc_find_function_by_name()
166 struct sunxi_desc_function *func = pin->functions; in sunxi_pinctrl_desc_find_function_by_name()
168 while (func->name) { in sunxi_pinctrl_desc_find_function_by_name()
169 if (!strcmp(func->name, func_name) && in sunxi_pinctrl_desc_find_function_by_name()
170 (!func->variant || in sunxi_pinctrl_desc_find_function_by_name()
171 func->variant & pctl->variant)) in sunxi_pinctrl_desc_find_function_by_name()
189 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_desc_find_function_by_pin()
190 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_desc_find_function_by_pin()
192 if (pin->pin.number == pin_num) { in sunxi_pinctrl_desc_find_function_by_pin()
193 struct sunxi_desc_function *func = pin->functions; in sunxi_pinctrl_desc_find_function_by_pin()
195 while (func->name) { in sunxi_pinctrl_desc_find_function_by_pin()
196 if (!strcmp(func->name, func_name)) in sunxi_pinctrl_desc_find_function_by_pin()
211 return pctl->ngroups; in sunxi_pctrl_get_groups_count()
219 return pctl->groups[group].name; in sunxi_pctrl_get_group_name()
229 *pins = (unsigned *)&pctl->groups[group].pin; in sunxi_pctrl_get_group_pins()
237 return of_property_present(node, "bias-pull-up") || in sunxi_pctrl_has_bias_prop()
238 of_property_present(node, "bias-pull-down") || in sunxi_pctrl_has_bias_prop()
239 of_property_present(node, "bias-disable") || in sunxi_pctrl_has_bias_prop()
245 return of_property_present(node, "drive-strength") || in sunxi_pctrl_has_drive_prop()
254 if (of_property_present(node, "bias-pull-up")) in sunxi_pctrl_parse_bias_prop()
257 if (of_property_present(node, "bias-pull-down")) in sunxi_pctrl_parse_bias_prop()
260 if (of_property_present(node, "bias-disable")) in sunxi_pctrl_parse_bias_prop()
265 return -EINVAL; in sunxi_pctrl_parse_bias_prop()
276 return -EINVAL; in sunxi_pctrl_parse_bias_prop()
284 if (!of_property_read_u32(node, "drive-strength", &val)) { in sunxi_pctrl_parse_drive_prop()
287 return -EINVAL; in sunxi_pctrl_parse_drive_prop()
299 return -EINVAL; in sunxi_pctrl_parse_drive_prop()
364 return ERR_PTR(-ENOMEM); in sunxi_pctrl_build_pin_config()
418 dev_err(pctl->dev, "missing function property in node %pOFn\n", in sunxi_pctrl_dt_node_to_map()
420 return -EINVAL; in sunxi_pctrl_dt_node_to_map()
425 dev_err(pctl->dev, "missing pins property in node %pOFn\n", in sunxi_pctrl_dt_node_to_map()
427 return -EINVAL; in sunxi_pctrl_dt_node_to_map()
440 return -ENOMEM; in sunxi_pctrl_dt_node_to_map()
453 dev_err(pctl->dev, "unknown pin %s", group); in sunxi_pctrl_dt_node_to_map()
458 grp->name, in sunxi_pctrl_dt_node_to_map()
460 dev_err(pctl->dev, "unsupported function %s on pin %s", in sunxi_pctrl_dt_node_to_map()
488 ret = -ENOMEM; in sunxi_pctrl_dt_node_to_map()
548 return -ENOTSUPP; in sunxi_pconf_reg()
563 pin -= pctl->desc->pin_base; in sunxi_pconf_get()
569 val = (readl(pctl->membase + reg) & mask) >> shift; in sunxi_pconf_get()
578 return -EINVAL; in sunxi_pconf_get()
579 arg = 1; /* hardware is weak pull-up */ in sunxi_pconf_get()
584 return -EINVAL; in sunxi_pconf_get()
585 arg = 1; /* hardware is weak pull-down */ in sunxi_pconf_get()
590 return -EINVAL; in sunxi_pconf_get()
597 return -ENOTSUPP; in sunxi_pconf_get()
610 struct sunxi_pinctrl_group *g = &pctl->groups[group]; in sunxi_pconf_group_get()
613 return sunxi_pconf_get(pctldev, g->pin, config); in sunxi_pconf_group_get()
622 pin -= pctl->desc->pin_base; in sunxi_pconf_set()
640 return -EINVAL; in sunxi_pconf_set()
648 val = arg / 10 - 1; in sunxi_pconf_set()
655 return -EINVAL; in sunxi_pconf_set()
660 return -EINVAL; in sunxi_pconf_set()
666 return -ENOTSUPP; in sunxi_pconf_set()
669 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pconf_set()
670 writel((readl(pctl->membase + reg) & ~mask) | val << shift, in sunxi_pconf_set()
671 pctl->membase + reg); in sunxi_pconf_set()
672 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pconf_set()
682 struct sunxi_pinctrl_group *g = &pctl->groups[group]; in sunxi_pconf_group_set()
685 return sunxi_pconf_set(pctldev, g->pin, configs, num_configs); in sunxi_pconf_group_set()
700 unsigned short bank; in sunxi_pinctrl_set_io_bias_cfg() local
705 if (!pctl->desc->io_bias_cfg_variant) in sunxi_pinctrl_set_io_bias_cfg()
716 pin -= pctl->desc->pin_base; in sunxi_pinctrl_set_io_bias_cfg()
717 bank = pin / PINS_PER_BANK; in sunxi_pinctrl_set_io_bias_cfg()
719 switch (pctl->desc->io_bias_cfg_variant) { in sunxi_pinctrl_set_io_bias_cfg()
736 reg = readl(pctl->membase + sunxi_grp_config_reg(pin)); in sunxi_pinctrl_set_io_bias_cfg()
738 writel(reg | val, pctl->membase + sunxi_grp_config_reg(pin)); in sunxi_pinctrl_set_io_bias_cfg()
741 val = uV > 1800000 && uV <= 2500000 ? BIT(bank) : 0; in sunxi_pinctrl_set_io_bias_cfg()
743 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
744 reg = readl(pctl->membase + pctl->pow_mod_sel_offset + in sunxi_pinctrl_set_io_bias_cfg()
746 reg &= ~BIT(bank); in sunxi_pinctrl_set_io_bias_cfg()
747 writel(reg | val, pctl->membase + pctl->pow_mod_sel_offset + in sunxi_pinctrl_set_io_bias_cfg()
749 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
755 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
756 reg = readl(pctl->membase + pctl->pow_mod_sel_offset); in sunxi_pinctrl_set_io_bias_cfg()
757 reg &= ~(1 << bank); in sunxi_pinctrl_set_io_bias_cfg()
758 writel(reg | val << bank, in sunxi_pinctrl_set_io_bias_cfg()
759 pctl->membase + pctl->pow_mod_sel_offset); in sunxi_pinctrl_set_io_bias_cfg()
760 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_set_io_bias_cfg()
763 return -EINVAL; in sunxi_pinctrl_set_io_bias_cfg()
771 return pctl->nfunctions; in sunxi_pmx_get_funcs_cnt()
779 return pctl->functions[function].name; in sunxi_pmx_get_func_name()
789 *groups = pctl->functions[function].groups; in sunxi_pmx_get_func_groups()
790 *num_groups = pctl->functions[function].ngroups; in sunxi_pmx_get_func_groups()
803 pin -= pctl->desc->pin_base; in sunxi_pmx_set()
806 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pmx_set()
808 writel((readl(pctl->membase + reg) & ~mask) | config << shift, in sunxi_pmx_set()
809 pctl->membase + reg); in sunxi_pmx_set()
811 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pmx_set()
819 struct sunxi_pinctrl_group *g = pctl->groups + group; in sunxi_pmx_set_mux()
820 struct sunxi_pinctrl_function *func = pctl->functions + function; in sunxi_pmx_set_mux()
823 g->name, in sunxi_pmx_set_mux()
824 func->name); in sunxi_pmx_set_mux()
827 return -EINVAL; in sunxi_pmx_set_mux()
829 sunxi_pmx_set(pctldev, g->pin, desc->muxval); in sunxi_pmx_set_mux()
851 return -EINVAL; in sunxi_pmx_gpio_set_direction()
853 sunxi_pmx_set(pctldev, offset, desc->muxval); in sunxi_pmx_gpio_set_direction()
861 unsigned short bank = offset / PINS_PER_BANK; in sunxi_pmx_request() local
862 unsigned short bank_offset = bank - pctl->desc->pin_base / in sunxi_pmx_request()
864 struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset]; in sunxi_pmx_request()
865 struct regulator *reg = s_reg->regulator; in sunxi_pmx_request()
869 if (WARN_ON_ONCE(bank_offset >= ARRAY_SIZE(pctl->regulators))) in sunxi_pmx_request()
870 return -EINVAL; in sunxi_pmx_request()
873 refcount_inc(&s_reg->refcount); in sunxi_pmx_request()
877 snprintf(supply, sizeof(supply), "vcc-p%c", 'a' + bank); in sunxi_pmx_request()
878 reg = regulator_get(pctl->dev, supply); in sunxi_pmx_request()
880 return dev_err_probe(pctl->dev, PTR_ERR(reg), in sunxi_pmx_request()
881 "Couldn't get bank P%c regulator\n", in sunxi_pmx_request()
882 'A' + bank); in sunxi_pmx_request()
886 dev_err(pctl->dev, in sunxi_pmx_request()
887 "Couldn't enable bank P%c regulator\n", 'A' + bank); in sunxi_pmx_request()
893 s_reg->regulator = reg; in sunxi_pmx_request()
894 refcount_set(&s_reg->refcount, 1); in sunxi_pmx_request()
899 regulator_put(s_reg->regulator); in sunxi_pmx_request()
907 unsigned short bank = offset / PINS_PER_BANK; in sunxi_pmx_free() local
908 unsigned short bank_offset = bank - pctl->desc->pin_base / in sunxi_pmx_free()
910 struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset]; in sunxi_pmx_free()
912 if (!refcount_dec_and_test(&s_reg->refcount)) in sunxi_pmx_free()
915 regulator_disable(s_reg->regulator); in sunxi_pmx_free()
916 regulator_put(s_reg->regulator); in sunxi_pmx_free()
917 s_reg->regulator = NULL; in sunxi_pmx_free()
938 return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, in sunxi_pinctrl_gpio_direction_input()
939 chip->base + offset, true); in sunxi_pinctrl_gpio_direction_input()
945 bool set_mux = pctl->desc->irq_read_needs_mux && in sunxi_pinctrl_gpio_get()
947 u32 pin = offset + chip->base; in sunxi_pinctrl_gpio_get()
953 sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_INPUT); in sunxi_pinctrl_gpio_get()
955 val = (readl(pctl->membase + reg) & mask) >> shift; in sunxi_pinctrl_gpio_get()
958 sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_IRQ); in sunxi_pinctrl_gpio_get()
972 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_gpio_set()
974 val = readl(pctl->membase + reg); in sunxi_pinctrl_gpio_set()
981 writel(val, pctl->membase + reg); in sunxi_pinctrl_gpio_set()
983 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_gpio_set()
994 return sunxi_pmx_gpio_set_direction(pctl->pctl_dev, NULL, in sunxi_pinctrl_gpio_direction_output()
995 chip->base + offset, false); in sunxi_pinctrl_gpio_direction_output()
1004 base = PINS_PER_BANK * gpiospec->args[0]; in sunxi_pinctrl_gpio_of_xlate()
1005 pin = base + gpiospec->args[1]; in sunxi_pinctrl_gpio_of_xlate()
1007 if (pin > gc->ngpio) in sunxi_pinctrl_gpio_of_xlate()
1008 return -EINVAL; in sunxi_pinctrl_gpio_of_xlate()
1011 *flags = gpiospec->args[2]; in sunxi_pinctrl_gpio_of_xlate()
1020 unsigned pinnum = pctl->desc->pin_base + offset; in sunxi_pinctrl_gpio_to_irq()
1023 if (offset >= chip->ngpio) in sunxi_pinctrl_gpio_to_irq()
1024 return -ENXIO; in sunxi_pinctrl_gpio_to_irq()
1028 return -EINVAL; in sunxi_pinctrl_gpio_to_irq()
1030 irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum; in sunxi_pinctrl_gpio_to_irq()
1032 dev_dbg(chip->parent, "%s: request IRQ for GPIO %d, return %d\n", in sunxi_pinctrl_gpio_to_irq()
1033 chip->label, offset + chip->base, irqnum); in sunxi_pinctrl_gpio_to_irq()
1035 return irq_find_mapping(pctl->domain, irqnum); in sunxi_pinctrl_gpio_to_irq()
1045 pctl->irq_array[d->hwirq], "irq"); in sunxi_pinctrl_irq_request_resources()
1047 return -EINVAL; in sunxi_pinctrl_irq_request_resources()
1049 ret = gpiochip_lock_as_irq(pctl->chip, in sunxi_pinctrl_irq_request_resources()
1050 pctl->irq_array[d->hwirq] - pctl->desc->pin_base); in sunxi_pinctrl_irq_request_resources()
1052 dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n", in sunxi_pinctrl_irq_request_resources()
1058 sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval); in sunxi_pinctrl_irq_request_resources()
1067 gpiochip_unlock_as_irq(pctl->chip, in sunxi_pinctrl_irq_release_resources()
1068 pctl->irq_array[d->hwirq] - pctl->desc->pin_base); in sunxi_pinctrl_irq_release_resources()
1074 u32 reg = sunxi_irq_cfg_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_set_type()
1075 u8 index = sunxi_irq_cfg_offset(d->hwirq); in sunxi_pinctrl_irq_set_type()
1097 return -EINVAL; in sunxi_pinctrl_irq_set_type()
1100 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_irq_set_type()
1109 regval = readl(pctl->membase + reg); in sunxi_pinctrl_irq_set_type()
1111 writel(regval | (mode << index), pctl->membase + reg); in sunxi_pinctrl_irq_set_type()
1113 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_irq_set_type()
1121 u32 status_reg = sunxi_irq_status_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_ack()
1122 u8 status_idx = sunxi_irq_status_offset(d->hwirq); in sunxi_pinctrl_irq_ack()
1125 writel(1 << status_idx, pctl->membase + status_reg); in sunxi_pinctrl_irq_ack()
1131 u32 reg = sunxi_irq_ctrl_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_mask()
1132 u8 idx = sunxi_irq_ctrl_offset(d->hwirq); in sunxi_pinctrl_irq_mask()
1136 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_irq_mask()
1139 val = readl(pctl->membase + reg); in sunxi_pinctrl_irq_mask()
1140 writel(val & ~(1 << idx), pctl->membase + reg); in sunxi_pinctrl_irq_mask()
1142 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_irq_mask()
1148 u32 reg = sunxi_irq_ctrl_reg(pctl->desc, d->hwirq); in sunxi_pinctrl_irq_unmask()
1149 u8 idx = sunxi_irq_ctrl_offset(d->hwirq); in sunxi_pinctrl_irq_unmask()
1153 raw_spin_lock_irqsave(&pctl->lock, flags); in sunxi_pinctrl_irq_unmask()
1156 val = readl(pctl->membase + reg); in sunxi_pinctrl_irq_unmask()
1157 writel(val | (1 << idx), pctl->membase + reg); in sunxi_pinctrl_irq_unmask()
1159 raw_spin_unlock_irqrestore(&pctl->lock, flags); in sunxi_pinctrl_irq_unmask()
1171 u8 bank = d->hwirq / IRQ_PER_BANK; in sunxi_pinctrl_irq_set_wake() local
1173 return irq_set_irq_wake(pctl->irq[bank], on); in sunxi_pinctrl_irq_set_wake()
1177 .name = "sunxi_pio_edge",
1189 .name = "sunxi_pio_level",
1213 struct sunxi_pinctrl *pctl = d->host_data; in sunxi_pinctrl_irq_of_xlate()
1218 return -EINVAL; in sunxi_pinctrl_irq_of_xlate()
1221 pin = pctl->desc->pin_base + base + intspec[1]; in sunxi_pinctrl_irq_of_xlate()
1225 return -EINVAL; in sunxi_pinctrl_irq_of_xlate()
1227 *out_hwirq = desc->irqbank * PINS_PER_BANK + desc->irqnum; in sunxi_pinctrl_irq_of_xlate()
1242 unsigned long bank, reg, val; in sunxi_pinctrl_irq_handler() local
1244 for (bank = 0; bank < pctl->desc->irq_banks; bank++) in sunxi_pinctrl_irq_handler()
1245 if (irq == pctl->irq[bank]) in sunxi_pinctrl_irq_handler()
1248 WARN_ON(bank == pctl->desc->irq_banks); in sunxi_pinctrl_irq_handler()
1252 reg = sunxi_irq_status_reg_from_bank(pctl->desc, bank); in sunxi_pinctrl_irq_handler()
1253 val = readl(pctl->membase + reg); in sunxi_pinctrl_irq_handler()
1259 generic_handle_domain_irq(pctl->domain, in sunxi_pinctrl_irq_handler()
1260 bank * IRQ_PER_BANK + irqoffset); in sunxi_pinctrl_irq_handler()
1267 const char *name) in sunxi_pinctrl_add_function() argument
1269 struct sunxi_pinctrl_function *func = pctl->functions; in sunxi_pinctrl_add_function()
1271 while (func->name) { in sunxi_pinctrl_add_function()
1273 if (strcmp(func->name, name) == 0) { in sunxi_pinctrl_add_function()
1274 func->ngroups++; in sunxi_pinctrl_add_function()
1275 return -EEXIST; in sunxi_pinctrl_add_function()
1280 func->name = name; in sunxi_pinctrl_add_function()
1281 func->ngroups = 1; in sunxi_pinctrl_add_function()
1283 pctl->nfunctions++; in sunxi_pinctrl_add_function()
1305 pctl->groups = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_build_state()
1306 pctl->desc->npins, sizeof(*pctl->groups), in sunxi_pinctrl_build_state()
1308 if (!pctl->groups) in sunxi_pinctrl_build_state()
1309 return -ENOMEM; in sunxi_pinctrl_build_state()
1311 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_build_state()
1312 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_build_state()
1313 struct sunxi_pinctrl_group *group = pctl->groups + pctl->ngroups; in sunxi_pinctrl_build_state()
1315 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_build_state()
1318 group->name = pin->pin.name; in sunxi_pinctrl_build_state()
1319 group->pin = pin->pin.number; in sunxi_pinctrl_build_state()
1322 pctl->ngroups++; in sunxi_pinctrl_build_state()
1331 pctl->functions = kcalloc(7 * pctl->ngroups + 4, in sunxi_pinctrl_build_state()
1332 sizeof(*pctl->functions), in sunxi_pinctrl_build_state()
1334 if (!pctl->functions) in sunxi_pinctrl_build_state()
1335 return -ENOMEM; in sunxi_pinctrl_build_state()
1338 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_build_state()
1339 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_build_state()
1342 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_build_state()
1345 for (func = pin->functions; func->name; func++) { in sunxi_pinctrl_build_state()
1346 if (func->variant && !(pctl->variant & func->variant)) in sunxi_pinctrl_build_state()
1350 if (!strcmp(func->name, "irq")) { in sunxi_pinctrl_build_state()
1351 int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK; in sunxi_pinctrl_build_state()
1352 pctl->irq_array[irqnum] = pin->pin.number; in sunxi_pinctrl_build_state()
1355 sunxi_pinctrl_add_function(pctl, func->name); in sunxi_pinctrl_build_state()
1360 ptr = krealloc(pctl->functions, in sunxi_pinctrl_build_state()
1361 pctl->nfunctions * sizeof(*pctl->functions), in sunxi_pinctrl_build_state()
1364 kfree(pctl->functions); in sunxi_pinctrl_build_state()
1365 pctl->functions = NULL; in sunxi_pinctrl_build_state()
1366 return -ENOMEM; in sunxi_pinctrl_build_state()
1368 pctl->functions = ptr; in sunxi_pinctrl_build_state()
1370 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_build_state()
1371 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_build_state()
1374 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_build_state()
1377 for (func = pin->functions; func->name; func++) { in sunxi_pinctrl_build_state()
1381 if (func->variant && !(pctl->variant & func->variant)) in sunxi_pinctrl_build_state()
1385 func->name); in sunxi_pinctrl_build_state()
1387 kfree(pctl->functions); in sunxi_pinctrl_build_state()
1388 return -EINVAL; in sunxi_pinctrl_build_state()
1391 if (!func_item->groups) { in sunxi_pinctrl_build_state()
1392 func_item->groups = in sunxi_pinctrl_build_state()
1393 devm_kcalloc(&pdev->dev, in sunxi_pinctrl_build_state()
1394 func_item->ngroups, in sunxi_pinctrl_build_state()
1395 sizeof(*func_item->groups), in sunxi_pinctrl_build_state()
1397 if (!func_item->groups) { in sunxi_pinctrl_build_state()
1398 kfree(pctl->functions); in sunxi_pinctrl_build_state()
1399 return -ENOMEM; in sunxi_pinctrl_build_state()
1403 func_grp = func_item->groups; in sunxi_pinctrl_build_state()
1407 *func_grp = pin->pin.name; in sunxi_pinctrl_build_state()
1420 best_diff = abs(freq - clock); in sunxi_pinctrl_get_debounce_div()
1424 int cur_diff = abs(freq - (clock >> i)); in sunxi_pinctrl_get_debounce_div()
1450 if (!of_property_present(node, "input-debounce")) in sunxi_pinctrl_setup_debounce()
1453 losc = devm_clk_get(pctl->dev, "losc"); in sunxi_pinctrl_setup_debounce()
1457 hosc = devm_clk_get(pctl->dev, "hosc"); in sunxi_pinctrl_setup_debounce()
1461 for (i = 0; i < pctl->desc->irq_banks; i++) { in sunxi_pinctrl_setup_debounce()
1465 ret = of_property_read_u32_index(node, "input-debounce", in sunxi_pinctrl_setup_debounce()
1491 pctl->membase + in sunxi_pinctrl_setup_debounce()
1492 sunxi_irq_debounce_reg_from_bank(pctl->desc, i)); in sunxi_pinctrl_setup_debounce()
1502 struct device_node *node = pdev->dev.of_node; in sunxi_pinctrl_init_with_flags()
1510 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); in sunxi_pinctrl_init_with_flags()
1512 return -ENOMEM; in sunxi_pinctrl_init_with_flags()
1515 raw_spin_lock_init(&pctl->lock); in sunxi_pinctrl_init_with_flags()
1517 pctl->membase = devm_platform_ioremap_resource(pdev, 0); in sunxi_pinctrl_init_with_flags()
1518 if (IS_ERR(pctl->membase)) in sunxi_pinctrl_init_with_flags()
1519 return PTR_ERR(pctl->membase); in sunxi_pinctrl_init_with_flags()
1521 pctl->dev = &pdev->dev; in sunxi_pinctrl_init_with_flags()
1522 pctl->desc = desc; in sunxi_pinctrl_init_with_flags()
1523 pctl->variant = flags & SUNXI_PINCTRL_VARIANT_MASK; in sunxi_pinctrl_init_with_flags()
1525 pctl->bank_mem_size = D1_BANK_MEM_SIZE; in sunxi_pinctrl_init_with_flags()
1526 pctl->pull_regs_offset = D1_PULL_REGS_OFFSET; in sunxi_pinctrl_init_with_flags()
1527 pctl->dlevel_field_width = D1_DLEVEL_FIELD_WIDTH; in sunxi_pinctrl_init_with_flags()
1529 pctl->bank_mem_size = BANK_MEM_SIZE; in sunxi_pinctrl_init_with_flags()
1530 pctl->pull_regs_offset = PULL_REGS_OFFSET; in sunxi_pinctrl_init_with_flags()
1531 pctl->dlevel_field_width = DLEVEL_FIELD_WIDTH; in sunxi_pinctrl_init_with_flags()
1534 pctl->pow_mod_sel_offset = PIO_11B_POW_MOD_SEL_REG; in sunxi_pinctrl_init_with_flags()
1536 pctl->pow_mod_sel_offset = PIO_POW_MOD_SEL_REG; in sunxi_pinctrl_init_with_flags()
1538 pctl->irq_array = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_init_with_flags()
1539 IRQ_PER_BANK * pctl->desc->irq_banks, in sunxi_pinctrl_init_with_flags()
1540 sizeof(*pctl->irq_array), in sunxi_pinctrl_init_with_flags()
1542 if (!pctl->irq_array) in sunxi_pinctrl_init_with_flags()
1543 return -ENOMEM; in sunxi_pinctrl_init_with_flags()
1547 dev_err(&pdev->dev, "dt probe failed: %d\n", ret); in sunxi_pinctrl_init_with_flags()
1551 pins = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_init_with_flags()
1552 pctl->desc->npins, sizeof(*pins), in sunxi_pinctrl_init_with_flags()
1555 return -ENOMEM; in sunxi_pinctrl_init_with_flags()
1557 for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_init_with_flags()
1558 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_init_with_flags()
1560 if (pin->variant && !(pctl->variant & pin->variant)) in sunxi_pinctrl_init_with_flags()
1563 pins[pin_idx++] = pin->pin; in sunxi_pinctrl_init_with_flags()
1566 pctrl_desc = devm_kzalloc(&pdev->dev, in sunxi_pinctrl_init_with_flags()
1570 return -ENOMEM; in sunxi_pinctrl_init_with_flags()
1572 pctrl_desc->name = dev_name(&pdev->dev); in sunxi_pinctrl_init_with_flags()
1573 pctrl_desc->owner = THIS_MODULE; in sunxi_pinctrl_init_with_flags()
1574 pctrl_desc->pins = pins; in sunxi_pinctrl_init_with_flags()
1575 pctrl_desc->npins = pctl->ngroups; in sunxi_pinctrl_init_with_flags()
1576 pctrl_desc->confops = &sunxi_pconf_ops; in sunxi_pinctrl_init_with_flags()
1577 pctrl_desc->pctlops = &sunxi_pctrl_ops; in sunxi_pinctrl_init_with_flags()
1579 pmxops = devm_kmemdup(&pdev->dev, &sunxi_pmx_ops, sizeof(sunxi_pmx_ops), in sunxi_pinctrl_init_with_flags()
1582 return -ENOMEM; in sunxi_pinctrl_init_with_flags()
1584 if (desc->disable_strict_mode) in sunxi_pinctrl_init_with_flags()
1585 pmxops->strict = false; in sunxi_pinctrl_init_with_flags()
1587 pctrl_desc->pmxops = pmxops; in sunxi_pinctrl_init_with_flags()
1589 pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl); in sunxi_pinctrl_init_with_flags()
1590 if (IS_ERR(pctl->pctl_dev)) { in sunxi_pinctrl_init_with_flags()
1591 dev_err(&pdev->dev, "couldn't register pinctrl driver\n"); in sunxi_pinctrl_init_with_flags()
1592 return PTR_ERR(pctl->pctl_dev); in sunxi_pinctrl_init_with_flags()
1595 pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL); in sunxi_pinctrl_init_with_flags()
1596 if (!pctl->chip) in sunxi_pinctrl_init_with_flags()
1597 return -ENOMEM; in sunxi_pinctrl_init_with_flags()
1599 last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number; in sunxi_pinctrl_init_with_flags()
1600 pctl->chip->owner = THIS_MODULE; in sunxi_pinctrl_init_with_flags()
1601 pctl->chip->request = gpiochip_generic_request; in sunxi_pinctrl_init_with_flags()
1602 pctl->chip->free = gpiochip_generic_free; in sunxi_pinctrl_init_with_flags()
1603 pctl->chip->set_config = gpiochip_generic_config; in sunxi_pinctrl_init_with_flags()
1604 pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; in sunxi_pinctrl_init_with_flags()
1605 pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; in sunxi_pinctrl_init_with_flags()
1606 pctl->chip->get = sunxi_pinctrl_gpio_get; in sunxi_pinctrl_init_with_flags()
1607 pctl->chip->set = sunxi_pinctrl_gpio_set; in sunxi_pinctrl_init_with_flags()
1608 pctl->chip->of_xlate = sunxi_pinctrl_gpio_of_xlate; in sunxi_pinctrl_init_with_flags()
1609 pctl->chip->to_irq = sunxi_pinctrl_gpio_to_irq; in sunxi_pinctrl_init_with_flags()
1610 pctl->chip->of_gpio_n_cells = 3; in sunxi_pinctrl_init_with_flags()
1611 pctl->chip->can_sleep = false; in sunxi_pinctrl_init_with_flags()
1612 pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK) - in sunxi_pinctrl_init_with_flags()
1613 pctl->desc->pin_base; in sunxi_pinctrl_init_with_flags()
1614 pctl->chip->label = dev_name(&pdev->dev); in sunxi_pinctrl_init_with_flags()
1615 pctl->chip->parent = &pdev->dev; in sunxi_pinctrl_init_with_flags()
1616 pctl->chip->base = pctl->desc->pin_base; in sunxi_pinctrl_init_with_flags()
1618 ret = gpiochip_add_data(pctl->chip, pctl); in sunxi_pinctrl_init_with_flags()
1622 for (i = 0; i < pctl->desc->npins; i++) { in sunxi_pinctrl_init_with_flags()
1623 const struct sunxi_desc_pin *pin = pctl->desc->pins + i; in sunxi_pinctrl_init_with_flags()
1625 ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev), in sunxi_pinctrl_init_with_flags()
1626 pin->pin.number - pctl->desc->pin_base, in sunxi_pinctrl_init_with_flags()
1627 pin->pin.number, 1); in sunxi_pinctrl_init_with_flags()
1633 clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb"); in sunxi_pinctrl_init_with_flags()
1639 pctl->irq = devm_kcalloc(&pdev->dev, in sunxi_pinctrl_init_with_flags()
1640 pctl->desc->irq_banks, in sunxi_pinctrl_init_with_flags()
1641 sizeof(*pctl->irq), in sunxi_pinctrl_init_with_flags()
1643 if (!pctl->irq) { in sunxi_pinctrl_init_with_flags()
1644 ret = -ENOMEM; in sunxi_pinctrl_init_with_flags()
1648 for (i = 0; i < pctl->desc->irq_banks; i++) { in sunxi_pinctrl_init_with_flags()
1649 pctl->irq[i] = platform_get_irq(pdev, i); in sunxi_pinctrl_init_with_flags()
1650 if (pctl->irq[i] < 0) { in sunxi_pinctrl_init_with_flags()
1651 ret = pctl->irq[i]; in sunxi_pinctrl_init_with_flags()
1656 pctl->domain = irq_domain_create_linear(dev_fwnode(&pdev->dev), in sunxi_pinctrl_init_with_flags()
1657 pctl->desc->irq_banks * IRQ_PER_BANK, in sunxi_pinctrl_init_with_flags()
1659 if (!pctl->domain) { in sunxi_pinctrl_init_with_flags()
1660 dev_err(&pdev->dev, "Couldn't register IRQ domain\n"); in sunxi_pinctrl_init_with_flags()
1661 ret = -ENOMEM; in sunxi_pinctrl_init_with_flags()
1665 for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) { in sunxi_pinctrl_init_with_flags()
1666 int irqno = irq_create_mapping(pctl->domain, i); in sunxi_pinctrl_init_with_flags()
1675 for (i = 0; i < pctl->desc->irq_banks; i++) { in sunxi_pinctrl_init_with_flags()
1677 writel(0, pctl->membase + in sunxi_pinctrl_init_with_flags()
1678 sunxi_irq_ctrl_reg_from_bank(pctl->desc, i)); in sunxi_pinctrl_init_with_flags()
1680 pctl->membase + in sunxi_pinctrl_init_with_flags()
1681 sunxi_irq_status_reg_from_bank(pctl->desc, i)); in sunxi_pinctrl_init_with_flags()
1683 irq_set_chained_handler_and_data(pctl->irq[i], in sunxi_pinctrl_init_with_flags()
1690 dev_info(&pdev->dev, "initialized sunXi PIO driver\n"); in sunxi_pinctrl_init_with_flags()
1695 gpiochip_remove(pctl->chip); in sunxi_pinctrl_init_with_flags()