diff mbox series

[v3,2/5] pinctrl: axp209: Add support for GPIO3 on the AXP209

Message ID dde40307f0ebc23b9841c32e702b481ab5193dc4.1684258957.git.noodles@earth.li
State Accepted
Commit 44825e5ead0f3e8dda4bbc1c20175c42942659ab
Headers show
Series Minor device-tree additions for C.H.I.P | expand

Commit Message

Jonathan McDowell May 16, 2023, 5:47 p.m. UTC
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>
---
 drivers/pinctrl/pinctrl-axp209.c | 42 ++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

Comments

Andy Shevchenko May 16, 2023, 6:55 p.m. UTC | #1
On Tue, May 16, 2023 at 8:47 PM Jonathan McDowell <noodles@earth.li> wrote:
>
> 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.

LGTM,
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Signed-off-by: Jonathan McDowell <noodles@earth.li>
> ---
>  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;
> --
> 2.39.2
>
Jernej Škrabec May 18, 2023, 9:21 p.m. UTC | #2
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@earth.li>

Reviewed-by: Jernej Skrabec <jernej.skrabec@gmail.com>

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;
>
diff mbox series

Patch

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;