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

Message ID f9b643ff0d0ed770f5a841111f213f8481dc920f.1683719613.git.noodles@earth.li
State New
Headers
Series Minor device-tree additions for C.H.I.P |

Commit Message

Jonathan McDowell May 10, 2023, 12:01 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 10, 2023, 2:15 p.m. UTC | #1
Wed, May 10, 2023 at 01:01:27PM +0100, Jonathan McDowell kirjoitti:
> 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.

...

> +#define AXP20X_GPIO3_FUNCTIONS		(BIT(2) | BIT(1))

GENMASK() ?

...


> +#define AXP20X_GPIO3_FUNCTION_OUT_LOW	0
> +#define AXP20X_GPIO3_FUNCTION_OUT_HIGH	BIT(1)
> +#define AXP20X_GPIO3_FUNCTION_INPUT	BIT(2)

Seems mixed use of decimal and bitwise values, switch to decimal, since it
makes more sense in my opinion.

...

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

> +		else

Redundant 'else'.

> +			return GPIO_LINE_DIRECTION_OUT;
> +	}
  
Linus Walleij May 29, 2023, 9:51 a.m. UTC | #2
On Wed, May 10, 2023 at 2:01 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.
>
> Signed-off-by: Jonathan McDowell <noodles@earth.li>

This patch 2/5 applied to the pinctrl tree.

I just assume it is fine to apply this one patch, Bartosz already
applied the binding patch.

Tell me if this works.

Yours,
Linus Walleij
  
Jonathan McDowell June 1, 2023, 7:30 a.m. UTC | #3
On Mon, May 29, 2023 at 11:51:46AM +0200, Linus Walleij wrote:
> On Wed, May 10, 2023 at 2:01 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.
> >
> > Signed-off-by: Jonathan McDowell <noodles@earth.li>
> 
> This patch 2/5 applied to the pinctrl tree.
> 
> I just assume it is fine to apply this one patch, Bartosz already
> applied the binding patch.
> 
> Tell me if this works.

Everything else seems to have been picked up, so that works for me.


J.
  

Patch

diff --git a/drivers/pinctrl/pinctrl-axp209.c b/drivers/pinctrl/pinctrl-axp209.c
index 0bc1b381a2b8..317691aee86b 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		(BIT(2) | BIT(1))
+#define AXP20X_GPIO3_FUNCTION_OUT_LOW	0
+#define AXP20X_GPIO3_FUNCTION_OUT_HIGH	BIT(1)
+#define AXP20X_GPIO3_FUNCTION_INPUT	BIT(2)
+
 #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;
+		else
+			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;