[ar71xx_gpio] handle AR934x and QCA953x GPIO OE polarity.

For reasons I won't comment on, the AR934x and QCA953x GPIO_OE register
value is inverted - bit set == input, bit clear == output.

So, fix this in the output setting, in reading the initial state from
the boot loader, and also setting any gpiofunc pins that are necessary.
This commit is contained in:
Adrian Chadd 2016-07-31 06:51:34 +00:00
parent 4fcae4df7e
commit accdd12e71

View File

@ -138,13 +138,56 @@ ar71xx_gpio_function_disable(struct ar71xx_gpio_softc *sc, uint32_t mask)
GPIO_CLEAR_BITS(sc, AR71XX_GPIO_FUNCTION, mask);
}
/*
* On most platforms, GPIO_OE is a bitmap where the bit set
* means "enable output."
*
* On AR934x and QCA953x, it's the opposite - the bit set means
* "input enable".
*/
static int
ar71xx_gpio_oe_is_high(void)
{
switch (ar71xx_soc) {
case AR71XX_SOC_AR9344:
case AR71XX_SOC_QCA9533:
case AR71XX_SOC_QCA9533_V2:
return 0;
default:
return 1;
}
}
static void
ar71xx_gpio_oe_set_output(struct ar71xx_gpio_softc *sc, int b)
{
uint32_t mask;
mask = 1 << b;
if (ar71xx_gpio_oe_is_high())
GPIO_SET_BITS(sc, AR71XX_GPIO_OE, mask);
else
GPIO_CLEAR_BITS(sc, AR71XX_GPIO_OE, mask);
}
static void
ar71xx_gpio_oe_set_input(struct ar71xx_gpio_softc *sc, int b)
{
uint32_t mask;
mask = 1 << b;
if (ar71xx_gpio_oe_is_high())
GPIO_CLEAR_BITS(sc, AR71XX_GPIO_OE, mask);
else
GPIO_SET_BITS(sc, AR71XX_GPIO_OE, mask);
}
static void
ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, struct gpio_pin *pin,
unsigned int flags)
{
uint32_t mask;
mask = 1 << pin->gp_pin;
/*
* Manage input/output
@ -153,11 +196,10 @@ ar71xx_gpio_pin_configure(struct ar71xx_gpio_softc *sc, struct gpio_pin *pin,
pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
if (flags & GPIO_PIN_OUTPUT) {
pin->gp_flags |= GPIO_PIN_OUTPUT;
GPIO_SET_BITS(sc, AR71XX_GPIO_OE, mask);
}
else {
ar71xx_gpio_oe_set_output(sc, pin->gp_pin);
} else {
pin->gp_flags |= GPIO_PIN_INPUT;
GPIO_CLEAR_BITS(sc, AR71XX_GPIO_OE, mask);
ar71xx_gpio_oe_set_input(sc, pin->gp_pin);
}
}
}
@ -455,6 +497,14 @@ ar71xx_gpio_attach(device_t dev)
}
/* Iniatilize the GPIO pins, keep the loader settings. */
oe = GPIO_READ(sc, AR71XX_GPIO_OE);
/*
* For AR934x and QCA953x, the meaning of oe is inverted;
* so flip it the right way around so we can parse the GPIO
* state.
*/
if (!ar71xx_gpio_oe_is_high())
oe = ~oe;
sc->gpio_pins = malloc(sizeof(*sc->gpio_pins) * sc->gpio_npins,
M_DEVBUF, M_WAITOK | M_ZERO);
for (i = 0, j = 0; j <= maxpin; j++) {
@ -515,16 +565,14 @@ ar71xx_gpio_attach(device_t dev)
gpiofunc,
gpiomode);
/* Set output (bit == 0) */
oe = GPIO_READ(sc, AR71XX_GPIO_OE);
oe &= ~ (1 << i);
GPIO_WRITE(sc, AR71XX_GPIO_OE, oe);
/* Set pin value = 0, so it stays low by default */
oe = GPIO_READ(sc, AR71XX_GPIO_OUT);
oe &= ~ (1 << i);
GPIO_WRITE(sc, AR71XX_GPIO_OUT, oe);
/* Set output */
ar71xx_gpio_oe_set_output(sc, i);
/* Finally: Set the output config */
ar71xx_gpio_ouput_configure(i, gpiofunc);
}