Dne torek, 16. maj 2023 ob 19:47:29 CEST je Jonathan McDowell napisal(a): > The AXP209 device has a 4th GPIO which has a slightly different register > setup, where the control + status bits are held in a single register > rather than sharing AXP20X_GPIO20_SS with GPIOs 0-2. > > Signed-off-by: Jonathan McDowell <noodles@xxxxxxxx> Reviewed-by: Jernej Skrabec <jernej.skrabec@xxxxxxxxx> Best regards, Jernej > --- > drivers/pinctrl/pinctrl-axp209.c | 42 ++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c > index 0bc1b381a2b8..b3ba25435c34 100644 > --- a/drivers/pinctrl/pinctrl-axp209.c > +++ b/drivers/pinctrl/pinctrl-axp209.c > @@ -30,6 +30,11 @@ > #define AXP20X_GPIO_FUNCTION_OUT_HIGH 1 > #define AXP20X_GPIO_FUNCTION_INPUT 2 > > +#define AXP20X_GPIO3_FUNCTIONS GENMASK(2, 1) > +#define AXP20X_GPIO3_FUNCTION_OUT_LOW 0 > +#define AXP20X_GPIO3_FUNCTION_OUT_HIGH 2 > +#define AXP20X_GPIO3_FUNCTION_INPUT 4 > + > #define AXP20X_FUNC_GPIO_OUT 0 > #define AXP20X_FUNC_GPIO_IN 1 > #define AXP20X_FUNC_LDO 2 > @@ -73,6 +78,7 @@ static const struct pinctrl_pin_desc axp209_pins[] = { > PINCTRL_PIN(0, "GPIO0"), > PINCTRL_PIN(1, "GPIO1"), > PINCTRL_PIN(2, "GPIO2"), > + PINCTRL_PIN(3, "GPIO3"), > }; > > static const struct pinctrl_pin_desc axp22x_pins[] = { > @@ -130,6 +136,14 @@ static int axp20x_gpio_get(struct gpio_chip *chip, unsigned int offset) > unsigned int val; > int ret; > > + /* AXP209 has GPIO3 status sharing the settings register */ > + if (offset == 3) { > + ret = regmap_read(pctl->regmap, AXP20X_GPIO3_CTRL, &val); > + if (ret) > + return ret; > + return !!(val & BIT(0)); > + } > + > ret = regmap_read(pctl->regmap, AXP20X_GPIO20_SS, &val); > if (ret) > return ret; > @@ -144,6 +158,17 @@ static int axp20x_gpio_get_direction(struct gpio_chip *chip, > unsigned int val; > int reg, ret; > > + /* AXP209 GPIO3 settings have a different layout */ > + if (offset == 3) { > + ret = regmap_read(pctl->regmap, AXP20X_GPIO3_CTRL, &val); > + if (ret) > + return ret; > + if (val & AXP20X_GPIO3_FUNCTION_INPUT) > + return GPIO_LINE_DIRECTION_IN; > + > + return GPIO_LINE_DIRECTION_OUT; > + } > + > reg = axp20x_gpio_get_reg(offset); > if (reg < 0) > return reg; > @@ -184,6 +209,15 @@ static void axp20x_gpio_set(struct gpio_chip *chip, unsigned int offset, > struct axp20x_pctl *pctl = gpiochip_get_data(chip); > int reg; > > + /* AXP209 has GPIO3 status sharing the settings register */ > + if (offset == 3) { > + regmap_update_bits(pctl->regmap, AXP20X_GPIO3_CTRL, > + AXP20X_GPIO3_FUNCTIONS, > + value ? AXP20X_GPIO3_FUNCTION_OUT_HIGH : > + AXP20X_GPIO3_FUNCTION_OUT_LOW); > + return; > + } > + > reg = axp20x_gpio_get_reg(offset); > if (reg < 0) > return; > @@ -200,6 +234,14 @@ static int axp20x_pmx_set(struct pinctrl_dev *pctldev, unsigned int offset, > struct axp20x_pctl *pctl = pinctrl_dev_get_drvdata(pctldev); > int reg; > > + /* AXP209 GPIO3 settings have a different layout */ > + if (offset == 3) { > + return regmap_update_bits(pctl->regmap, AXP20X_GPIO3_CTRL, > + AXP20X_GPIO3_FUNCTIONS, > + config == AXP20X_MUX_GPIO_OUT ? AXP20X_GPIO3_FUNCTION_OUT_LOW : > + AXP20X_GPIO3_FUNCTION_INPUT); > + } > + > reg = axp20x_gpio_get_reg(offset); > if (reg < 0) > return reg; >