^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AXP20x pinctrl and GPIO driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2017 Quentin Schulz <quentin.schulz@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mfd/axp20x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pinctrl/pinmux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define AXP20X_GPIO_FUNCTIONS 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define AXP20X_GPIO_FUNCTION_OUT_LOW 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AXP20X_GPIO_FUNCTION_OUT_HIGH 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AXP20X_GPIO_FUNCTION_INPUT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define AXP20X_FUNC_GPIO_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AXP20X_FUNC_GPIO_IN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AXP20X_FUNC_LDO 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AXP20X_FUNC_ADC 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define AXP20X_FUNCS_NB 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define AXP20X_MUX_GPIO_OUT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define AXP20X_MUX_GPIO_IN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define AXP20X_MUX_ADC BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define AXP813_MUX_ADC (BIT(2) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct axp20x_pctrl_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) const struct pinctrl_pin_desc *pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Stores the pins supporting LDO function. Bit offset is pin number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u8 ldo_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Stores the pins supporting ADC function. Bit offset is pin number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u8 adc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u8 gpio_status_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 adc_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct axp20x_pinctrl_function {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned int muxval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) const char **groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int ngroups;
^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) struct axp20x_pctl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct gpio_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct pinctrl_dev *pctl_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const struct axp20x_pctrl_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct axp20x_pinctrl_function funcs[AXP20X_FUNCS_NB];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const struct pinctrl_pin_desc axp209_pins[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) PINCTRL_PIN(0, "GPIO0"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) PINCTRL_PIN(1, "GPIO1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) PINCTRL_PIN(2, "GPIO2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static const struct pinctrl_pin_desc axp813_pins[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) PINCTRL_PIN(0, "GPIO0"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) PINCTRL_PIN(1, "GPIO1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static const struct axp20x_pctrl_desc axp20x_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .pins = axp209_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .npins = ARRAY_SIZE(axp209_pins),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .ldo_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .adc_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .gpio_status_offset = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .adc_mux = AXP20X_MUX_ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static const struct axp20x_pctrl_desc axp813_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .pins = axp813_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .npins = ARRAY_SIZE(axp813_pins),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .ldo_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .adc_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .gpio_status_offset = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .adc_mux = AXP813_MUX_ADC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int axp20x_gpio_get_reg(unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) switch (offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return AXP20X_GPIO0_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return AXP20X_GPIO1_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return AXP20X_GPIO2_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int axp20x_gpio_input(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return pinctrl_gpio_direction_input(chip->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static int axp20x_gpio_get(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct axp20x_pctl *pctl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) ret = regmap_read(pctl->regmap, AXP20X_GPIO20_SS, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return !!(val & BIT(offset + pctl->desc->gpio_status_offset));
^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) static int axp20x_gpio_get_direction(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct axp20x_pctl *pctl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int reg, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) reg = axp20x_gpio_get_reg(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ret = regmap_read(pctl->regmap, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * This shouldn't really happen if the pin is in use already,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * or if it's not in use yet, it doesn't matter since we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * going to change the value soon anyway. Default to output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if ((val & AXP20X_GPIO_FUNCTIONS) > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * The GPIO directions are the three lowest values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * 2 is input, 0 and 1 are output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (val & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return GPIO_LINE_DIRECTION_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return GPIO_LINE_DIRECTION_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int axp20x_gpio_output(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) chip->set(chip, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void axp20x_gpio_set(struct gpio_chip *chip, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct axp20x_pctl *pctl = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) reg = axp20x_gpio_get_reg(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) regmap_update_bits(pctl->regmap, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) AXP20X_GPIO_FUNCTIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) value ? AXP20X_GPIO_FUNCTION_OUT_HIGH :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) AXP20X_GPIO_FUNCTION_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u8 config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) reg = axp20x_gpio_get_reg(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return regmap_update_bits(pctl->regmap, reg, AXP20X_GPIO_FUNCTIONS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int axp20x_pmx_func_cnt(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return ARRAY_SIZE(pctl->funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static const char *axp20x_pmx_func_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return pctl->funcs[selector].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int axp20x_pmx_func_groups(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) unsigned int selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) const char * const **groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) unsigned int *num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) *groups = pctl->funcs[selector].groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) *num_groups = pctl->funcs[selector].ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int axp20x_pmx_set_mux(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned int function, unsigned int group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Every pin supports GPIO_OUT and GPIO_IN functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (function <= AXP20X_FUNC_GPIO_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return axp20x_pmx_set(pctldev, group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) pctl->funcs[function].muxval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (function == AXP20X_FUNC_LDO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mask = pctl->desc->ldo_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) mask = pctl->desc->adc_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!(BIT(group) & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * We let the regulator framework handle the LDO muxing as muxing bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * are basically also regulators on/off bits. It's better not to enforce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * any state of the regulator when selecting LDO mux so that we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * interfere with the regulator driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (function == AXP20X_FUNC_LDO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return axp20x_pmx_set(pctldev, group, pctl->funcs[function].muxval);
^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) static int axp20x_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct pinctrl_gpio_range *range,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int offset, bool input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return axp20x_pmx_set(pctldev, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) pctl->funcs[AXP20X_FUNC_GPIO_IN].muxval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return axp20x_pmx_set(pctldev, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static const struct pinmux_ops axp20x_pmx_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .get_functions_count = axp20x_pmx_func_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .get_function_name = axp20x_pmx_func_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) .get_function_groups = axp20x_pmx_func_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) .set_mux = axp20x_pmx_set_mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) .gpio_set_direction = axp20x_pmx_gpio_set_direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .strict = true,
^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) static int axp20x_groups_cnt(struct pinctrl_dev *pctldev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return pctl->desc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int axp20x_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const unsigned int **pins, unsigned int *num_pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *pins = (unsigned int *)&pctl->desc->pins[selector];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *num_pins = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static const char *axp20x_group_name(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return pctl->desc->pins[selector].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static const struct pinctrl_ops axp20x_pctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .dt_free_map = pinconf_generic_dt_free_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .get_groups_count = axp20x_groups_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .get_group_name = axp20x_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .get_group_pins = axp20x_group_pins,
^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) static int axp20x_funcs_groups_from_mask(struct device *dev, unsigned int mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned int mask_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct axp20x_pinctrl_function *func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) const struct pinctrl_pin_desc *pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) unsigned long int mask_cpy = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) const char **group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) unsigned int ngroups = hweight8(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) func->ngroups = ngroups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (func->ngroups > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) func->groups = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ngroups, sizeof(const char *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!func->groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) group = func->groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) for_each_set_bit(bit, &mask_cpy, mask_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) *group = pins[bit].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) group++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int axp20x_build_funcs_groups(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int i, ret, pin, npins = pctl->desc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pctl->funcs[AXP20X_FUNC_GPIO_OUT].name = "gpio_out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) pctl->funcs[AXP20X_FUNC_GPIO_OUT].muxval = AXP20X_MUX_GPIO_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) pctl->funcs[AXP20X_FUNC_GPIO_IN].name = "gpio_in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pctl->funcs[AXP20X_FUNC_GPIO_IN].muxval = AXP20X_MUX_GPIO_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) pctl->funcs[AXP20X_FUNC_LDO].name = "ldo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * Muxval for LDO is useless as we won't use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * See comment in axp20x_pmx_set_mux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) pctl->funcs[AXP20X_FUNC_ADC].name = "adc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pctl->funcs[AXP20X_FUNC_ADC].muxval = pctl->desc->adc_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Every pin supports GPIO_OUT and GPIO_IN functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) for (i = 0; i <= AXP20X_FUNC_GPIO_IN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) pctl->funcs[i].ngroups = npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) pctl->funcs[i].groups = devm_kcalloc(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) npins, sizeof(char *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (!pctl->funcs[i].groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) for (pin = 0; pin < npins; pin++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) pctl->funcs[i].groups[pin] = pctl->desc->pins[pin].name;
^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) ret = axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->ldo_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) npins, &pctl->funcs[AXP20X_FUNC_LDO],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) pctl->desc->pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ret = axp20x_funcs_groups_from_mask(&pdev->dev, pctl->desc->adc_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) npins, &pctl->funcs[AXP20X_FUNC_ADC],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) pctl->desc->pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static const struct of_device_id axp20x_pctl_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { .compatible = "x-powers,axp209-gpio", .data = &axp20x_data, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) { .compatible = "x-powers,axp813-gpio", .data = &axp813_data, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) MODULE_DEVICE_TABLE(of, axp20x_pctl_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int axp20x_pctl_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct axp20x_pctl *pctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct pinctrl_desc *pctrl_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!of_device_is_available(pdev->dev.of_node))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!axp20x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_err(&pdev->dev, "Parent drvdata not set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (!pctl)
^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) pctl->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pctl->chip.can_sleep = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pctl->chip.request = gpiochip_generic_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pctl->chip.free = gpiochip_generic_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) pctl->chip.parent = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) pctl->chip.label = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) pctl->chip.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pctl->chip.get = axp20x_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) pctl->chip.get_direction = axp20x_gpio_get_direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) pctl->chip.set = axp20x_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) pctl->chip.direction_input = axp20x_gpio_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pctl->chip.direction_output = axp20x_gpio_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) pctl->desc = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pctl->chip.ngpio = pctl->desc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pctl->regmap = axp20x->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) pctl->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) platform_set_drvdata(pdev, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = axp20x_build_funcs_groups(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dev_err(&pdev->dev, "failed to build groups\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) pctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*pctrl_desc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (!pctrl_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pctrl_desc->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pctrl_desc->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pctrl_desc->pins = pctl->desc->pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) pctrl_desc->npins = pctl->desc->npins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) pctrl_desc->pctlops = &axp20x_pctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pctrl_desc->pmxops = &axp20x_pmx_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, pctrl_desc, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (IS_ERR(pctl->pctl_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return PTR_ERR(pctl->pctl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret = devm_gpiochip_add_data(&pdev->dev, &pctl->chip, pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dev_err(&pdev->dev, "Failed to register GPIO chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ret = gpiochip_add_pin_range(&pctl->chip, dev_name(&pdev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) pctl->desc->pins->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pctl->desc->pins->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) pctl->desc->npins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dev_err(&pdev->dev, "failed to add pin range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return ret;
^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) dev_info(&pdev->dev, "AXP209 pinctrl and GPIO driver loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static struct platform_driver axp20x_pctl_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .probe = axp20x_pctl_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .name = "axp20x-gpio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .of_match_table = axp20x_pctl_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) module_platform_driver(axp20x_pctl_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) MODULE_DESCRIPTION("AXP20x PMIC pinctrl and GPIO driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) MODULE_LICENSE("GPL");