[v2,2/5] pinctrl: axp209: Add support for GPIO3 on the AXP209
Commit Message
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
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;
> + }
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
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.
@@ -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;