allwinner: power: fix DRIVEVBUS pin setup
The DRIVEVBUS pin setup was broken in two ways: - To configure this pin as an output pin, one has to *clear* the bit in register 0x8f. It is 0 by default, but rebooting from Linux might have left this bit set. - Doing this just configures the pin as an output pin, but doesn't actually drive power to it. This is done via bit 2 in register 0x30. Fix the routine to both properly configure the pin and drive power to it. Add an axp_clrsetbits() helper on the way. Now this isn't really perfect, still: We only need to setup the PMIC power rails that are needed for U-Boot. DRIVEVBUS typically controls the VBUS voltage for the host function of an USB-OTG port, something we typically don't want in U-Boot (fastboot, using the USB *device* functionality, is much more common). The BananaPi-M64 uses the regulator in this way, but the Remix Mini PC actually controls the power of both its USB ports via this line. Technically we should differentiate here: if DRIVEVBUS controls a microUSB-B socket, the power should stay off, any host-type A sockets should be supplied, though. For now just always enable the power, that shouldn't really hurt the USB-OTG functionality anyway. Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
parent
19a7507a9e
commit
d93eb4467a
|
@ -118,7 +118,7 @@ static int axp_write(uint8_t reg, uint8_t val)
|
||||||
return rsb_write(AXP803_RT_ADDR, reg, val);
|
return rsb_write(AXP803_RT_ADDR, reg, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int axp_setbits(uint8_t reg, uint8_t set_mask)
|
static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
|
||||||
{
|
{
|
||||||
uint8_t regval;
|
uint8_t regval;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -127,11 +127,14 @@ static int axp_setbits(uint8_t reg, uint8_t set_mask)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
regval = ret | set_mask;
|
regval = (ret & ~clr_mask) | set_mask;
|
||||||
|
|
||||||
return rsb_write(AXP803_RT_ADDR, reg, regval);
|
return rsb_write(AXP803_RT_ADDR, reg, regval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
|
||||||
|
#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
|
||||||
|
|
||||||
static bool should_enable_regulator(const void *fdt, int node)
|
static bool should_enable_regulator(const void *fdt, int node)
|
||||||
{
|
{
|
||||||
if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
|
if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
|
||||||
|
@ -226,8 +229,11 @@ static void setup_axp803_rails(const void *fdt)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL))
|
if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
|
||||||
axp_setbits(0x8f, BIT(4));
|
axp_clrbits(0x8f, BIT(4));
|
||||||
|
axp_setbits(0x30, BIT(2));
|
||||||
|
INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* descend into the "regulators" subnode */
|
/* descend into the "regulators" subnode */
|
||||||
node = fdt_first_subnode(fdt, node);
|
node = fdt_first_subnode(fdt, node);
|
||||||
|
|
Loading…
Reference in New Issue