Commit 44825e5e authored by Jonathan McDowell's avatar Jonathan McDowell Committed by Linus Walleij
Browse files

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: default avatarJonathan McDowell <noodles@earth.li>
Reviewed-by: default avatarJernej Skrabec <jernej.skrabec@gmail.com>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/dde40307f0ebc23b9841c32e702b481ab5193dc4.1684258957.git.noodles@earth.li


Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 0f936752
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -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;