^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Allwinner A1X SoCs pinctrl driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2012 Maxime Ripard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Maxime Ripard <maxime.ripard@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/irqchip/chained_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pinctrl/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/pinctrl/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <dt-bindings/pinctrl/sun4i-a10.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "pinctrl-sunxi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * These lock classes tell lockdep that GPIO IRQs are in a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * category than their parents, so it won't report false recursion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static struct lock_class_key sunxi_pinctrl_irq_lock_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct lock_class_key sunxi_pinctrl_irq_request_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static struct irq_chip sunxi_pinctrl_edge_irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static struct irq_chip sunxi_pinctrl_level_irq_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static struct sunxi_pinctrl_group *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) sunxi_pinctrl_find_group_by_name(struct sunxi_pinctrl *pctl, const char *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) for (i = 0; i < pctl->ngroups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct sunxi_pinctrl_group *grp = pctl->groups + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!strcmp(grp->name, group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static struct sunxi_pinctrl_function *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) sunxi_pinctrl_find_function_by_name(struct sunxi_pinctrl *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct sunxi_pinctrl_function *func = pctl->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) for (i = 0; i < pctl->nfunctions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (!func[i].name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (!strcmp(func[i].name, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return func + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static struct sunxi_desc_function *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) sunxi_pinctrl_desc_find_function_by_name(struct sunxi_pinctrl *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char *pin_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) const char *func_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) for (i = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!strcmp(pin->pin.name, pin_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct sunxi_desc_function *func = pin->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) while (func->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!strcmp(func->name, func_name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (!func->variant ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) func->variant & pctl->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) func++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static struct sunxi_desc_function *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) const u16 pin_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) const char *func_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) for (i = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (pin->pin.number == pin_num) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct sunxi_desc_function *func = pin->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) while (func->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (!strcmp(func->name, func_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) func++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return pctl->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static const char *sunxi_pctrl_get_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return pctl->groups[group].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int sunxi_pctrl_get_group_pins(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) const unsigned **pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) *pins = (unsigned *)&pctl->groups[group].pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) *num_pins = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static bool sunxi_pctrl_has_bias_prop(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return of_find_property(node, "bias-pull-up", NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) of_find_property(node, "bias-pull-down", NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) of_find_property(node, "bias-disable", NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) of_find_property(node, "allwinner,pull", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static bool sunxi_pctrl_has_drive_prop(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return of_find_property(node, "drive-strength", NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) of_find_property(node, "allwinner,drive", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int sunxi_pctrl_parse_bias_prop(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Try the new style binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (of_find_property(node, "bias-pull-up", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return PIN_CONFIG_BIAS_PULL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (of_find_property(node, "bias-pull-down", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return PIN_CONFIG_BIAS_PULL_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (of_find_property(node, "bias-disable", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return PIN_CONFIG_BIAS_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* And fall back to the old binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (of_property_read_u32(node, "allwinner,pull", &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case SUN4I_PINCTRL_NO_PULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return PIN_CONFIG_BIAS_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case SUN4I_PINCTRL_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return PIN_CONFIG_BIAS_PULL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) case SUN4I_PINCTRL_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return PIN_CONFIG_BIAS_PULL_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int sunxi_pctrl_parse_drive_prop(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* Try the new style binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!of_property_read_u32(node, "drive-strength", &val)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* We can't go below 10mA ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (val < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* ... and only up to 40 mA ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (val > 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) val = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* by steps of 10 mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return rounddown(val, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* And then fall back to the old binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (of_property_read_u32(node, "allwinner,drive", &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return (val + 1) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static const char *sunxi_pctrl_parse_function_prop(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) const char *function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Try the generic binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = of_property_read_string(node, "function", &function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* And fall back to our legacy one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ret = of_property_read_string(node, "allwinner,function", &function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static const char *sunxi_pctrl_find_pins_prop(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int *npins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* Try the generic binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) count = of_property_count_strings(node, "pins");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) *npins = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return "pins";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* And fall back to our legacy one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) count = of_property_count_strings(node, "allwinner,pins");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) *npins = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return "allwinner,pins";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static unsigned long *sunxi_pctrl_build_pin_config(struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) unsigned int *len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) unsigned long *pinconfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) unsigned int configlen = 0, idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (sunxi_pctrl_has_drive_prop(node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) configlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (sunxi_pctrl_has_bias_prop(node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) configlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * If we don't have any configuration, bail out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!configlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pinconfig = kcalloc(configlen, sizeof(*pinconfig), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (!pinconfig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (sunxi_pctrl_has_drive_prop(node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int drive = sunxi_pctrl_parse_drive_prop(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (drive < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ret = drive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pinconfig[idx++] = pinconf_to_config_packed(PIN_CONFIG_DRIVE_STRENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) drive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (sunxi_pctrl_has_bias_prop(node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int pull = sunxi_pctrl_parse_bias_prop(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (pull < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (pull != PIN_CONFIG_BIAS_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) arg = 1; /* hardware uses weak pull resistors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) pinconfig[idx++] = pinconf_to_config_packed(pull, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *len = configlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return pinconfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) kfree(pinconfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned long *pinconfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) const char *function, *pin_prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) const char *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int ret, npins, nmaps, configlen = 0, i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *num_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) function = sunxi_pctrl_parse_function_prop(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!function) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev_err(pctl->dev, "missing function property in node %pOFn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pin_prop = sunxi_pctrl_find_pins_prop(node, &npins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!pin_prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev_err(pctl->dev, "missing pins property in node %pOFn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * We have two maps for each pin: one for the function, one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * for the configuration (bias, strength, etc).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * We might be slightly overshooting, since we might not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * any configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) nmaps = npins * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *map = kmalloc_array(nmaps, sizeof(struct pinctrl_map), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!*map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pinconfig = sunxi_pctrl_build_pin_config(node, &configlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (IS_ERR(pinconfig)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ret = PTR_ERR(pinconfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto err_free_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) of_property_for_each_string(node, pin_prop, prop, group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct sunxi_pinctrl_group *grp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) sunxi_pinctrl_find_group_by_name(pctl, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!grp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dev_err(pctl->dev, "unknown pin %s", group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!sunxi_pinctrl_desc_find_function_by_name(pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) grp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) function)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) dev_err(pctl->dev, "unsupported function %s on pin %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) function, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) (*map)[i].data.mux.group = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) (*map)[i].data.mux.function = function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (pinconfig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (*map)[i].data.configs.group_or_pin = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) (*map)[i].data.configs.configs = pinconfig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) (*map)[i].data.configs.num_configs = configlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *num_maps = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * We know have the number of maps we need, we can resize our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * map array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) *map = krealloc(*map, i * sizeof(struct pinctrl_map), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!*map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) err_free_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) kfree(*map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static void sunxi_pctrl_dt_free_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct pinctrl_map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) unsigned num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* pin config is never in the first map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) for (i = 1; i < num_maps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (map[i].type != PIN_MAP_TYPE_CONFIGS_GROUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * All the maps share the same pin config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * free only the first one we find.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) kfree(map[i].data.configs.configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) kfree(map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static const struct pinctrl_ops sunxi_pctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .dt_node_to_map = sunxi_pctrl_dt_node_to_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .dt_free_map = sunxi_pctrl_dt_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .get_groups_count = sunxi_pctrl_get_groups_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .get_group_name = sunxi_pctrl_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .get_group_pins = sunxi_pctrl_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int sunxi_pconf_reg(unsigned pin, enum pin_config_param param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u32 *offset, u32 *shift, u32 *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) case PIN_CONFIG_DRIVE_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *offset = sunxi_dlevel_reg(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) *shift = sunxi_dlevel_offset(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) *mask = DLEVEL_PINS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) *offset = sunxi_pull_reg(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) *shift = sunxi_pull_offset(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *mask = PULL_PINS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static int sunxi_pconf_get(struct pinctrl_dev *pctldev, unsigned pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) enum pin_config_param param = pinconf_to_config_param(*config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u32 offset, shift, mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) u16 arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) pin -= pctl->desc->pin_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) val = (readl(pctl->membase + offset) >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) switch (pinconf_to_config_param(*config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) case PIN_CONFIG_DRIVE_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) arg = (val + 1) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (val != SUN4I_PINCTRL_PULL_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) arg = 1; /* hardware is weak pull-up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (val != SUN4I_PINCTRL_PULL_DOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) arg = 1; /* hardware is weak pull-down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (val != SUN4I_PINCTRL_NO_PULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) arg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* sunxi_pconf_reg should catch anything unsupported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) *config = pinconf_to_config_packed(param, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct sunxi_pinctrl_group *g = &pctl->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* We only support 1 pin per group. Chain it to the pin callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return sunxi_pconf_get(pctldev, g->pin, config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int sunxi_pconf_set(struct pinctrl_dev *pctldev, unsigned pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) unsigned long *configs, unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) for (i = 0; i < num_configs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) enum pin_config_param param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) u32 offset, shift, mask, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) u32 arg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) param = pinconf_to_config_param(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) arg = pinconf_to_config_argument(configs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ret = sunxi_pconf_reg(pin, param, &offset, &shift, &mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) switch (param) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case PIN_CONFIG_DRIVE_STRENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (arg < 10 || arg > 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * We convert from mA to what the register expects:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * 0: 10mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * 1: 20mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * 2: 30mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * 3: 40mA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) val = arg / 10 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) case PIN_CONFIG_BIAS_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) case PIN_CONFIG_BIAS_PULL_UP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (arg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) val = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) case PIN_CONFIG_BIAS_PULL_DOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (arg == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) val = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* sunxi_pconf_reg should catch anything unsupported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) reg = readl(pctl->membase + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) reg &= ~(mask << shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) writel(reg | val << shift, pctl->membase + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) } /* for each config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) unsigned long *configs, unsigned num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct sunxi_pinctrl_group *g = &pctl->groups[group];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* We only support 1 pin per group. Chain it to the pin callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return sunxi_pconf_set(pctldev, g->pin, configs, num_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static const struct pinconf_ops sunxi_pconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) .is_generic = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) .pin_config_get = sunxi_pconf_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) .pin_config_set = sunxi_pconf_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .pin_config_group_get = sunxi_pconf_group_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .pin_config_group_set = sunxi_pconf_group_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int sunxi_pinctrl_set_io_bias_cfg(struct sunxi_pinctrl *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) unsigned pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct regulator *supply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned short bank = pin / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) u32 val, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int uV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (!pctl->desc->io_bias_cfg_variant)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) uV = regulator_get_voltage(supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (uV < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return uV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Might be dummy regulator with no voltage set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (uV == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) switch (pctl->desc->io_bias_cfg_variant) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case BIAS_VOLTAGE_GRP_CONFIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * Configured value must be equal or greater to actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * voltage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (uV <= 1800000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) val = 0x0; /* 1.8V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) else if (uV <= 2500000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) val = 0x6; /* 2.5V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) else if (uV <= 2800000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) val = 0x9; /* 2.8V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) else if (uV <= 3000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) val = 0xA; /* 3.0V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) val = 0xD; /* 3.3V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) pin -= pctl->desc->pin_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) reg = readl(pctl->membase + sunxi_grp_config_reg(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) reg &= ~IO_BIAS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) writel(reg | val, pctl->membase + sunxi_grp_config_reg(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case BIAS_VOLTAGE_PIO_POW_MODE_SEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) val = uV <= 1800000 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) reg = readl(pctl->membase + PIO_POW_MOD_SEL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) reg &= ~(1 << bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) writel(reg | val << bank, pctl->membase + PIO_POW_MOD_SEL_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int sunxi_pmx_get_funcs_cnt(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return pctl->nfunctions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static const char *sunxi_pmx_get_func_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) unsigned function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return pctl->functions[function].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int sunxi_pmx_get_func_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) unsigned * const num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) *groups = pctl->functions[function].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) *num_groups = pctl->functions[function].ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static void sunxi_pmx_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) unsigned pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) u8 config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) pin -= pctl->desc->pin_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) val = readl(pctl->membase + sunxi_mux_reg(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) mask = MUX_PINS_MASK << sunxi_mux_offset(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) writel((val & ~mask) | config << sunxi_mux_offset(pin),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) pctl->membase + sunxi_mux_reg(pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static int sunxi_pmx_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) unsigned function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) unsigned group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct sunxi_pinctrl_group *g = pctl->groups + group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct sunxi_pinctrl_function *func = pctl->functions + function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct sunxi_desc_function *desc =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) sunxi_pinctrl_desc_find_function_by_name(pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) g->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) func->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) sunxi_pmx_set(pctldev, g->pin, desc->muxval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sunxi_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) unsigned offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) bool input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct sunxi_desc_function *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) const char *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) func = "gpio_in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) func = "gpio_out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, offset, func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) sunxi_pmx_set(pctldev, offset, desc->muxval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static int sunxi_pmx_request(struct pinctrl_dev *pctldev, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) unsigned short bank = offset / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) unsigned short bank_offset = bank - pctl->desc->pin_base /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct regulator *reg = s_reg->regulator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) char supply[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) refcount_inc(&s_reg->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) snprintf(supply, sizeof(supply), "vcc-p%c", 'a' + bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) reg = regulator_get(pctl->dev, supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (IS_ERR(reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) dev_err(pctl->dev, "Couldn't get bank P%c regulator\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 'A' + bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return PTR_ERR(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ret = regulator_enable(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dev_err(pctl->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) "Couldn't enable bank P%c regulator\n", 'A' + bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) sunxi_pinctrl_set_io_bias_cfg(pctl, offset, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) s_reg->regulator = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) refcount_set(&s_reg->refcount, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) regulator_put(s_reg->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) static int sunxi_pmx_free(struct pinctrl_dev *pctldev, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) unsigned short bank = offset / PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) unsigned short bank_offset = bank - pctl->desc->pin_base /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) PINS_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct sunxi_pinctrl_regulator *s_reg = &pctl->regulators[bank_offset];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (!refcount_dec_and_test(&s_reg->refcount))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) regulator_disable(s_reg->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) regulator_put(s_reg->regulator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) s_reg->regulator = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static const struct pinmux_ops sunxi_pmx_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .get_functions_count = sunxi_pmx_get_funcs_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .get_function_name = sunxi_pmx_get_func_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .get_function_groups = sunxi_pmx_get_func_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .set_mux = sunxi_pmx_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .gpio_set_direction = sunxi_pmx_gpio_set_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .request = sunxi_pmx_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .free = sunxi_pmx_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .strict = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return pinctrl_gpio_direction_input(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int sunxi_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) u32 reg = sunxi_data_reg(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u8 index = sunxi_data_offset(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) bool set_mux = pctl->desc->irq_read_needs_mux &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) gpiochip_line_is_irq(chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) u32 pin = offset + chip->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (set_mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_INPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) val = (readl(pctl->membase + reg) >> index) & DATA_PINS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (set_mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) sunxi_pmx_set(pctl->pctl_dev, pin, SUN4I_FUNC_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static void sunxi_pinctrl_gpio_set(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) u32 reg = sunxi_data_reg(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) u8 index = sunxi_data_offset(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) regval = readl(pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) regval |= BIT(index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) regval &= ~(BIT(index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) writel(regval, pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) static int sunxi_pinctrl_gpio_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) sunxi_pinctrl_gpio_set(chip, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) return pinctrl_gpio_direction_output(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) static int sunxi_pinctrl_gpio_of_xlate(struct gpio_chip *gc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) const struct of_phandle_args *gpiospec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) u32 *flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int pin, base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) base = PINS_PER_BANK * gpiospec->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pin = base + gpiospec->args[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (pin > gc->ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) *flags = gpiospec->args[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static int sunxi_pinctrl_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct sunxi_desc_function *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) unsigned pinnum = pctl->desc->pin_base + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) unsigned irqnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (offset >= chip->ngpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pinnum, "irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) irqnum = desc->irqbank * IRQ_PER_BANK + desc->irqnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) dev_dbg(chip->parent, "%s: request IRQ for GPIO %d, return %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) chip->label, offset + chip->base, irqnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return irq_find_mapping(pctl->domain, irqnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int sunxi_pinctrl_irq_request_resources(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct sunxi_desc_function *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) func = sunxi_pinctrl_desc_find_function_by_pin(pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) pctl->irq_array[d->hwirq], "irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (!func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) ret = gpiochip_lock_as_irq(pctl->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) irqd_to_hwirq(d));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* Change muxing to INT mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) sunxi_pmx_set(pctl->pctl_dev, pctl->irq_array[d->hwirq], func->muxval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static void sunxi_pinctrl_irq_release_resources(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) gpiochip_unlock_as_irq(pctl->chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) pctl->irq_array[d->hwirq] - pctl->desc->pin_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) static int sunxi_pinctrl_irq_set_type(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) u32 reg = sunxi_irq_cfg_reg(pctl->desc, d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) u8 index = sunxi_irq_cfg_offset(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) u32 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) mode = IRQ_EDGE_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) mode = IRQ_EDGE_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) mode = IRQ_EDGE_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) mode = IRQ_LEVEL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) mode = IRQ_LEVEL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (type & IRQ_TYPE_LEVEL_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) irq_set_chip_handler_name_locked(d, &sunxi_pinctrl_level_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) handle_fasteoi_irq, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) irq_set_chip_handler_name_locked(d, &sunxi_pinctrl_edge_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) handle_edge_irq, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) regval = readl(pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) regval &= ~(IRQ_CFG_IRQ_MASK << index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) writel(regval | (mode << index), pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static void sunxi_pinctrl_irq_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) u32 status_reg = sunxi_irq_status_reg(pctl->desc, d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) u8 status_idx = sunxi_irq_status_offset(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) /* Clear the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) writel(1 << status_idx, pctl->membase + status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static void sunxi_pinctrl_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) u32 reg = sunxi_irq_ctrl_reg(pctl->desc, d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* Mask the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) val = readl(pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) writel(val & ~(1 << idx), pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static void sunxi_pinctrl_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) u32 reg = sunxi_irq_ctrl_reg(pctl->desc, d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) u8 idx = sunxi_irq_ctrl_offset(d->hwirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) raw_spin_lock_irqsave(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* Unmask the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) val = readl(pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) writel(val | (1 << idx), pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) raw_spin_unlock_irqrestore(&pctl->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static void sunxi_pinctrl_irq_ack_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) sunxi_pinctrl_irq_ack(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) sunxi_pinctrl_irq_unmask(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static int sunxi_pinctrl_irq_set_wake(struct irq_data *d, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct sunxi_pinctrl *pctl = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) u8 bank = d->hwirq / IRQ_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return irq_set_irq_wake(pctl->irq[bank], on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static struct irq_chip sunxi_pinctrl_edge_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .name = "sunxi_pio_edge",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .irq_ack = sunxi_pinctrl_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .irq_mask = sunxi_pinctrl_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .irq_unmask = sunxi_pinctrl_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .irq_request_resources = sunxi_pinctrl_irq_request_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .irq_release_resources = sunxi_pinctrl_irq_release_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .irq_set_type = sunxi_pinctrl_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .irq_set_wake = sunxi_pinctrl_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) .flags = IRQCHIP_MASK_ON_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) static struct irq_chip sunxi_pinctrl_level_irq_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .name = "sunxi_pio_level",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .irq_eoi = sunxi_pinctrl_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .irq_mask = sunxi_pinctrl_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) .irq_unmask = sunxi_pinctrl_irq_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /* Define irq_enable / disable to avoid spurious irqs for drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * using these to suppress irqs while they clear the irq source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .irq_enable = sunxi_pinctrl_irq_ack_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .irq_disable = sunxi_pinctrl_irq_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .irq_request_resources = sunxi_pinctrl_irq_request_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .irq_release_resources = sunxi_pinctrl_irq_release_resources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .irq_set_type = sunxi_pinctrl_irq_set_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) .irq_set_wake = sunxi_pinctrl_irq_set_wake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) .flags = IRQCHIP_EOI_THREADED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) IRQCHIP_MASK_ON_SUSPEND |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) IRQCHIP_EOI_IF_HANDLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) static int sunxi_pinctrl_irq_of_xlate(struct irq_domain *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) const u32 *intspec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) unsigned int intsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) unsigned long *out_hwirq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) unsigned int *out_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) struct sunxi_pinctrl *pctl = d->host_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) struct sunxi_desc_function *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) int pin, base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (intsize < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) base = PINS_PER_BANK * intspec[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) pin = pctl->desc->pin_base + base + intspec[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) desc = sunxi_pinctrl_desc_find_function_by_pin(pctl, pin, "irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (!desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) *out_hwirq = desc->irqbank * PINS_PER_BANK + desc->irqnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) *out_type = intspec[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static const struct irq_domain_ops sunxi_pinctrl_irq_domain_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .xlate = sunxi_pinctrl_irq_of_xlate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static void sunxi_pinctrl_irq_handler(struct irq_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) unsigned int irq = irq_desc_get_irq(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) struct irq_chip *chip = irq_desc_get_chip(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) struct sunxi_pinctrl *pctl = irq_desc_get_handler_data(desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) unsigned long bank, reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) for (bank = 0; bank < pctl->desc->irq_banks; bank++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (irq == pctl->irq[bank])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (bank == pctl->desc->irq_banks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) chained_irq_enter(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) reg = sunxi_irq_status_reg_from_bank(pctl->desc, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) val = readl(pctl->membase + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) int irqoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) for_each_set_bit(irqoffset, &val, IRQ_PER_BANK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) int pin_irq = irq_find_mapping(pctl->domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) bank * IRQ_PER_BANK + irqoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) generic_handle_irq(pin_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) chained_irq_exit(chip, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static int sunxi_pinctrl_add_function(struct sunxi_pinctrl *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct sunxi_pinctrl_function *func = pctl->functions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) while (func->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* function already there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (strcmp(func->name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) func->ngroups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) func++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) func->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) func->ngroups = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) pctl->nfunctions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static int sunxi_pinctrl_build_state(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) struct sunxi_pinctrl *pctl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) void *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * Allocate groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * We assume that the number of groups is the number of pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) * given in the data array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) * This will not always be true, since some pins might not be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * available in the current variant, but fortunately for us,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * this means that the number of pins is the maximum group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * number we will ever see.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pctl->groups = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) pctl->desc->npins, sizeof(*pctl->groups),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (!pctl->groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) for (i = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct sunxi_pinctrl_group *group = pctl->groups + pctl->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (pin->variant && !(pctl->variant & pin->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) group->name = pin->pin.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) group->pin = pin->pin.number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) /* And now we count the actual number of pins / groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) pctl->ngroups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * We suppose that we won't have any more functions than pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * we'll reallocate that later anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) pctl->functions = kcalloc(pctl->ngroups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) sizeof(*pctl->functions),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (!pctl->functions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) /* Count functions and their associated groups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) for (i = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct sunxi_desc_function *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (pin->variant && !(pctl->variant & pin->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) for (func = pin->functions; func->name; func++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (func->variant && !(pctl->variant & func->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) /* Create interrupt mapping while we're at it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) if (!strcmp(func->name, "irq")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) int irqnum = func->irqnum + func->irqbank * IRQ_PER_BANK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) pctl->irq_array[irqnum] = pin->pin.number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) sunxi_pinctrl_add_function(pctl, func->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /* And now allocated and fill the array for real */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) ptr = krealloc(pctl->functions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) pctl->nfunctions * sizeof(*pctl->functions),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (!ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) kfree(pctl->functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) pctl->functions = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) pctl->functions = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) for (i = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct sunxi_desc_function *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (pin->variant && !(pctl->variant & pin->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) for (func = pin->functions; func->name; func++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct sunxi_pinctrl_function *func_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) const char **func_grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (func->variant && !(pctl->variant & func->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) func_item = sunxi_pinctrl_find_function_by_name(pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) func->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) if (!func_item) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) kfree(pctl->functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (!func_item->groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) func_item->groups =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) func_item->ngroups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) sizeof(*func_item->groups),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (!func_item->groups) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) kfree(pctl->functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) func_grp = func_item->groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) while (*func_grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) func_grp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) *func_grp = pin->pin.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static int sunxi_pinctrl_get_debounce_div(struct clk *clk, int freq, int *diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) unsigned long clock = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) unsigned int best_diff, best_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) best_diff = abs(freq - clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) best_div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) for (i = 1; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) int cur_diff = abs(freq - (clock >> i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (cur_diff < best_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) best_diff = cur_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) best_div = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) *diff = best_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return best_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) static int sunxi_pinctrl_setup_debounce(struct sunxi_pinctrl *pctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) unsigned int hosc_diff, losc_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) unsigned int hosc_div, losc_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) struct clk *hosc, *losc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) u8 div, src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) /* Deal with old DTs that didn't have the oscillators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) if (of_clk_get_parent_count(node) != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) /* If we don't have any setup, bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (!of_find_property(node, "input-debounce", NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) losc = devm_clk_get(pctl->dev, "losc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (IS_ERR(losc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return PTR_ERR(losc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) hosc = devm_clk_get(pctl->dev, "hosc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (IS_ERR(hosc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return PTR_ERR(hosc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) for (i = 0; i < pctl->desc->irq_banks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) unsigned long debounce_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) u32 debounce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) ret = of_property_read_u32_index(node, "input-debounce",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) i, &debounce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (!debounce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) losc_div = sunxi_pinctrl_get_debounce_div(losc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) debounce_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) &losc_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) hosc_div = sunxi_pinctrl_get_debounce_div(hosc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) debounce_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) &hosc_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (hosc_diff < losc_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) div = hosc_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) src = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) div = losc_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) src = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) writel(src | div << 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) pctl->membase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) sunxi_irq_debounce_reg_from_bank(pctl->desc, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) int sunxi_pinctrl_init_with_variant(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) const struct sunxi_pinctrl_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) unsigned long variant)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct device_node *node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct pinctrl_desc *pctrl_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) struct pinctrl_pin_desc *pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct sunxi_pinctrl *pctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) struct pinmux_ops *pmxops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) int i, ret, last_pin, pin_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (!pctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) platform_set_drvdata(pdev, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) raw_spin_lock_init(&pctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) pctl->membase = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (IS_ERR(pctl->membase))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return PTR_ERR(pctl->membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) pctl->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) pctl->desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) pctl->variant = variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) pctl->irq_array = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) IRQ_PER_BANK * pctl->desc->irq_banks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) sizeof(*pctl->irq_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (!pctl->irq_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ret = sunxi_pinctrl_build_state(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) pins = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) pctl->desc->npins, sizeof(*pins),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (!pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) for (i = 0, pin_idx = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (pin->variant && !(pctl->variant & pin->variant))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) pins[pin_idx++] = pin->pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) pctrl_desc = devm_kzalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) sizeof(*pctrl_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (!pctrl_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) pctrl_desc->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) pctrl_desc->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) pctrl_desc->pins = pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) pctrl_desc->npins = pctl->ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) pctrl_desc->confops = &sunxi_pconf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) pctrl_desc->pctlops = &sunxi_pctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) pmxops = devm_kmemdup(&pdev->dev, &sunxi_pmx_ops, sizeof(sunxi_pmx_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (!pmxops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (desc->disable_strict_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) pmxops->strict = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) pctrl_desc->pmxops = pmxops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (IS_ERR(pctl->pctl_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return PTR_ERR(pctl->pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) if (!pctl->chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) pctl->chip->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) pctl->chip->request = gpiochip_generic_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) pctl->chip->free = gpiochip_generic_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) pctl->chip->set_config = gpiochip_generic_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) pctl->chip->get = sunxi_pinctrl_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) pctl->chip->set = sunxi_pinctrl_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) pctl->chip->of_xlate = sunxi_pinctrl_gpio_of_xlate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) pctl->chip->to_irq = sunxi_pinctrl_gpio_to_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) pctl->chip->of_gpio_n_cells = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) pctl->chip->can_sleep = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) pctl->chip->ngpio = round_up(last_pin, PINS_PER_BANK) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) pctl->desc->pin_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) pctl->chip->label = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) pctl->chip->parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) pctl->chip->base = pctl->desc->pin_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ret = gpiochip_add_data(pctl->chip, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) for (i = 0; i < pctl->desc->npins; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) const struct sunxi_desc_pin *pin = pctl->desc->pins + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) ret = gpiochip_add_pin_range(pctl->chip, dev_name(&pdev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) pin->pin.number - pctl->desc->pin_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) pin->pin.number, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) goto gpiochip_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ret = of_clk_get_parent_count(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) clk = devm_clk_get(&pdev->dev, ret == 1 ? NULL : "apb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) goto gpiochip_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) goto gpiochip_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) pctl->irq = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) pctl->desc->irq_banks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) sizeof(*pctl->irq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (!pctl->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) goto clk_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) for (i = 0; i < pctl->desc->irq_banks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) pctl->irq[i] = platform_get_irq(pdev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (pctl->irq[i] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) ret = pctl->irq[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) goto clk_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) pctl->domain = irq_domain_add_linear(node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) pctl->desc->irq_banks * IRQ_PER_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) &sunxi_pinctrl_irq_domain_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (!pctl->domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) goto clk_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) for (i = 0; i < (pctl->desc->irq_banks * IRQ_PER_BANK); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) int irqno = irq_create_mapping(pctl->domain, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) irq_set_lockdep_class(irqno, &sunxi_pinctrl_irq_lock_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) &sunxi_pinctrl_irq_request_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) irq_set_chip_and_handler(irqno, &sunxi_pinctrl_edge_irq_chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) handle_edge_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) irq_set_chip_data(irqno, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) for (i = 0; i < pctl->desc->irq_banks; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) /* Mask and clear all IRQs before registering a handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) writel(0, pctl->membase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) sunxi_irq_ctrl_reg_from_bank(pctl->desc, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) writel(0xffffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) pctl->membase +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) sunxi_irq_status_reg_from_bank(pctl->desc, i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) irq_set_chained_handler_and_data(pctl->irq[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) sunxi_pinctrl_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) sunxi_pinctrl_setup_debounce(pctl, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) clk_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) clk_disable_unprepare(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) gpiochip_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) gpiochip_remove(pctl->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }