pinctrl: axp209: Add support for GPIO3 on the AXP209

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@earth.li>
Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/dde40307f0ebc23b9841c32e702b481ab5193dc4.1684258957.git.noodles@earth.li
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
Jonathan McDowell 2023-05-16 18:47:29 +01:00 committed by Linus Walleij
parent 0f9367525a
commit 44825e5ead
1 changed files with 42 additions and 0 deletions

View File

@ -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;