diff --git a/drivers/allwinner/axp/axp805.c b/drivers/allwinner/axp/axp805.c new file mode 100644 index 0000000..8d029c0 --- /dev/null +++ b/drivers/allwinner/axp/axp805.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +const uint8_t axp_chip_id = AXP805_CHIP_ID; +const char *const axp_compatible = "x-powers,axp805"; + +/* + * The "dcdcd" split changes the step size by a factor of 5, not 2; + * disallow values above the split to maintain accuracy. + */ +const struct axp_regulator axp_regulators[] = { + {"dcdca", 600, 1520, 10, 50, 0x12, 0x10, 0}, + {"dcdcb", 1000, 2550, 50, NA, 0x13, 0x10, 1}, + {"dcdcc", 600, 1520, 10, 50, 0x14, 0x10, 2}, + {"dcdcd", 600, 1500, 20, NA, 0x15, 0x10, 3}, + {"dcdce", 1100, 3400, 100, NA, 0x16, 0x10, 4}, + {"aldo1", 700, 3300, 100, NA, 0x17, 0x10, 5}, + {"aldo2", 700, 3300, 100, NA, 0x18, 0x10, 6}, + {"aldo3", 700, 3300, 100, NA, 0x19, 0x10, 7}, + {"bldo1", 700, 1900, 100, NA, 0x20, 0x11, 0}, + {"bldo2", 700, 1900, 100, NA, 0x21, 0x11, 1}, + {"bldo3", 700, 1900, 100, NA, 0x22, 0x11, 2}, + {"bldo4", 700, 1900, 100, NA, 0x23, 0x11, 3}, + {"cldo1", 700, 3300, 100, NA, 0x24, 0x11, 4}, + {"cldo2", 700, 4200, 100, 27, 0x25, 0x11, 5}, + {"cldo3", 700, 3300, 100, NA, 0x26, 0x11, 6}, + {} +}; diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c index a021e1c..13437fe 100644 --- a/drivers/allwinner/axp/common.c +++ b/drivers/allwinner/axp/common.c @@ -108,7 +108,7 @@ void axp_setup_regulators(const void *fdt) { int node; - bool dc1sw = false; + bool sw = false; if (fdt == NULL) return; @@ -120,6 +120,7 @@ return; } + /* This applies to AXP803 only. */ if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) { axp_clrbits(0x8f, BIT(4)); axp_setbits(0x30, BIT(2)); @@ -144,26 +145,31 @@ continue; name = fdt_get_name(fdt, node, &length); + + /* Enable the switch last to avoid overheating. */ + if (!strncmp(name, "dc1sw", length) || + !strncmp(name, "sw", length)) { + sw = true; + continue; + } + for (reg = axp_regulators; reg->dt_name; reg++) { if (!strncmp(name, reg->dt_name, length)) { setup_regulator(fdt, node, reg); break; } } - - if (!strncmp(name, "dc1sw", length)) { - /* Delay DC1SW enablement to avoid overheating. */ - dc1sw = true; - continue; - } } /* - * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts - * down. So always enable DC1SW as the very last regulator. + * On the AXP803, if DLDO2 is enabled after DC1SW, the PMIC overheats + * and shuts down. So always enable DC1SW as the very last regulator. */ - if (dc1sw) { - INFO("PMIC: Enabling DC1SW\n"); - axp_setbits(0x12, BIT(7)); + if (sw) { + INFO("PMIC: Enabling DC SW\n"); + if (axp_chip_id == AXP803_CHIP_ID) + axp_setbits(0x12, BIT(7)); + if (axp_chip_id == AXP805_CHIP_ID) + axp_setbits(0x11, BIT(7)); } } diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h index f3d6277..9c0035f 100644 --- a/include/drivers/allwinner/axp.h +++ b/include/drivers/allwinner/axp.h @@ -13,6 +13,7 @@ enum { AXP803_CHIP_ID = 0x41, + AXP805_CHIP_ID = 0x40, }; struct axp_regulator {