mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-02 12:20:51 +00:00
Add GPIO function mux configuration for AR934x SoCs.
The AR934x (and maybe others in this family) have a more complicated GPIO mux. The AR71xx just has a single function register for a handful of "GPIO or X" options, however the AR934x allows for one of roughly 100 behaviours for each GPIO pin. So, this adds a quick hints based mechanism to configure the output functions, which is required for some of the more interesting board configurations. Specifically, some use external LNAs to improve RX, and without the MUX/output configured right, the 2GHz RX side will be plain terrible. It doesn't yet configure the "input" side yet; I'll add that if it's required. Tested: * TP-Link TL-WDR3600, testing 2GHz STA/AP modes, checking some basic RX sensitivity things (ie, "can I see the AP on the other side of the apartment that intentionally has poor signal reception from where I am right now.") Whilst here, fix a silly bug in the maxpin routine; I was missing a break.
This commit is contained in:
parent
358811c4e3
commit
753370121e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=280315
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/resource.h>
|
||||
#include <mips/atheros/ar71xxreg.h>
|
||||
#include <mips/atheros/ar71xx_setup.h>
|
||||
#include <mips/atheros/ar71xx_cpudef.h>
|
||||
#include <mips/atheros/ar71xx_gpiovar.h>
|
||||
#include <dev/gpio/gpiobusvar.h>
|
||||
#include <mips/atheros/ar933xreg.h>
|
||||
@ -92,6 +93,12 @@ static int ar71xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value);
|
||||
static int ar71xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val);
|
||||
static int ar71xx_gpio_pin_toggle(device_t dev, uint32_t pin);
|
||||
|
||||
/*
|
||||
* Enable/disable the GPIO function control space.
|
||||
*
|
||||
* This is primarily for the AR71xx, which has SPI CS1/CS2, UART, SLIC, I2S
|
||||
* as GPIO pin options.
|
||||
*/
|
||||
static void
|
||||
ar71xx_gpio_function_enable(struct ar71xx_gpio_softc *sc, uint32_t mask)
|
||||
{
|
||||
@ -174,6 +181,7 @@ ar71xx_gpio_pin_max(device_t dev, int *maxpin)
|
||||
case AR71XX_SOC_AR9342:
|
||||
case AR71XX_SOC_AR9344:
|
||||
*maxpin = AR934X_GPIO_COUNT - 1;
|
||||
break;
|
||||
case AR71XX_SOC_QCA9556:
|
||||
case AR71XX_SOC_QCA9558:
|
||||
*maxpin = QCA955X_GPIO_COUNT - 1;
|
||||
@ -445,6 +453,7 @@ ar71xx_gpio_attach(device_t dev)
|
||||
sc->gpio_pins[i].gp_flags = GPIO_PIN_INPUT;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Turn on the hinted pins. */
|
||||
for (i = 0; i < sc->gpio_npins; i++) {
|
||||
j = sc->gpio_pins[i].gp_pin;
|
||||
@ -453,6 +462,56 @@ ar71xx_gpio_attach(device_t dev)
|
||||
ar71xx_gpio_pin_set(dev, j, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Search through the function hints, in case there's some
|
||||
* overrides such as LNA control.
|
||||
*
|
||||
* hint.gpio.X.func.<pin>.gpiofunc=<func value>
|
||||
* hint.gpio.X.func.<pin>.gpiomode=1 (for output, default low)
|
||||
*/
|
||||
for (i = 0; i <= maxpin; i++) {
|
||||
char buf[32];
|
||||
int gpiofunc, gpiomode;
|
||||
|
||||
snprintf(buf, 32, "func.%d.gpiofunc", i);
|
||||
if (resource_int_value(device_get_name(dev),
|
||||
device_get_unit(dev),
|
||||
buf,
|
||||
&gpiofunc) != 0)
|
||||
continue;
|
||||
/* Get the mode too */
|
||||
snprintf(buf, 32, "func.%d.gpiomode", i);
|
||||
if (resource_int_value(device_get_name(dev),
|
||||
device_get_unit(dev),
|
||||
buf,
|
||||
&gpiomode) != 0)
|
||||
continue;
|
||||
|
||||
/* We only handle mode=1 for now */
|
||||
if (gpiomode != 1)
|
||||
continue;
|
||||
|
||||
device_printf(dev, "%s: GPIO %d: func=%d, mode=%d\n",
|
||||
__func__,
|
||||
i,
|
||||
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);
|
||||
|
||||
/* Finally: Set the output config */
|
||||
ar71xx_gpio_ouput_configure(i, gpiofunc);
|
||||
}
|
||||
|
||||
sc->busdev = gpiobus_attach_bus(dev);
|
||||
if (sc->busdev == NULL) {
|
||||
ar71xx_gpio_detach(dev);
|
||||
|
Loading…
Reference in New Issue
Block a user