[U-Boot] [PATCH 06/14] sunxi: axp221: Explicitly turn off unused voltages

Hans de Goede hdegoede at redhat.com
Tue Dec 16 21:31:31 CET 2014


Explicitly turn off unused voltages, rather then leaving them as is. Likewise
explictly enabled the dcdc convertors, rather then assuming they are already
enabled at boot.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 board/sunxi/board.c    |  10 -----
 drivers/power/Kconfig  |  16 ++++----
 drivers/power/axp221.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++---
 include/axp221.h       |   8 +++-
 4 files changed, 111 insertions(+), 25 deletions(-)

diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index e2ebf83..5bf19b7 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -180,22 +180,12 @@ void sunxi_board_init(void)
 	power_failed |= axp221_set_dcdc3(1200);
 	power_failed |= axp221_set_dcdc4(1200);
 	power_failed |= axp221_set_dcdc5(1500);
-#if CONFIG_AXP221_DLDO1_VOLT != -1
 	power_failed |= axp221_set_dldo1(CONFIG_AXP221_DLDO1_VOLT);
-#endif
-#if CONFIG_AXP221_DLDO4_VOLT != -1
 	power_failed |= axp221_set_dldo4(CONFIG_AXP221_DLDO4_VOLT);
-#endif
-#if CONFIG_AXP221_ALDO1_VOLT != -1
 	power_failed |= axp221_set_aldo1(CONFIG_AXP221_ALDO1_VOLT);
-#endif
-#if CONFIG_AXP221_ALDO2_VOLT != -1
 	power_failed |= axp221_set_aldo2(CONFIG_AXP221_ALDO2_VOLT);
-#endif
-#if CONFIG_AXP221_ALDO3_VOLT != -1
 	power_failed |= axp221_set_aldo3(CONFIG_AXP221_ALDO3_VOLT);
 #endif
-#endif
 
 	printf("DRAM:");
 	ramsize = sunxi_dram_init();
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index e132759..ef0c093 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -19,9 +19,9 @@ config AXP221_DCDC1_VOLT
 config AXP221_DLDO1_VOLT
 	int "axp221 dldo1 voltage"
 	depends on AXP221_POWER
-	default -1
+	default 0
 	---help---
-	Set the voltage (mV) to program the axp221 dldo1 at, set to -1 to
+	Set the voltage (mV) to program the axp221 dldo1 at, set to 0 to
 	disable dldo1. On sun6i (A31) boards with ethernet this is often used
 	to power the ethernet phy. On sun8i (A23) boards this is often used to
 	power the wifi.
@@ -29,17 +29,17 @@ config AXP221_DLDO1_VOLT
 config AXP221_DLDO4_VOLT
 	int "axp221 dldo4 voltage"
 	depends on AXP221_POWER
-	default -1
+	default 0
 	---help---
-	Set the voltage (mV) to program the axp221 dldo4 at, set to -1 to
+	Set the voltage (mV) to program the axp221 dldo4 at, set to 0 to
 	disable dldo4.
 
 config AXP221_ALDO1_VOLT
 	int "axp221 aldo1 voltage"
 	depends on AXP221_POWER
-	default -1
+	default 0
 	---help---
-	Set the voltage (mV) to program the axp221 aldo1 at, set to -1 to
+	Set the voltage (mV) to program the axp221 aldo1 at, set to 0 to
 	disable aldo1. On sun6i (A31) boards which have a wifi module this is
 	often used to power the wifi module.
 
@@ -49,7 +49,7 @@ config AXP221_ALDO2_VOLT
 	default 1800 if MACH_SUN6I
 	default 2500 if MACH_SUN8I
 	---help---
-	Set the voltage (mV) to program the axp221 aldo2 at, set to -1 to
+	Set the voltage (mV) to program the axp221 aldo2 at, set to 0 to
 	disable aldo2. On sun6i (A31) boards this is typically connected to
 	VCC-PM, which powers the port M gpios, and should be set to 1.8V.
 	On sun8i (A23) this is typically connected to VDD-DLL and must be
@@ -60,6 +60,6 @@ config AXP221_ALDO3_VOLT
 	depends on AXP221_POWER
 	default 3000
 	---help---
-	Set the voltage (mV) to program the axp221 aldo3 at, set to -1 to
+	Set the voltage (mV) to program the axp221 aldo3 at, set to 0 to
 	disable aldo3. This is typically connected to VCC-PLL and AVCC and
 	must be set to 3V.
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index 717adad..c438849 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -80,45 +80,107 @@ static int axp221_setbits(u8 reg, u8 bits)
 	return pmic_bus_write(reg, val);
 }
 
+static int axp221_clrbits(u8 reg, u8 bits)
+{
+	int ret;
+	u8 val;
+
+	ret = pmic_bus_read(reg, &val);
+	if (ret)
+		return ret;
+
+	val &= ~bits;
+	return pmic_bus_write(reg, val);
+}
+
 int axp221_set_dcdc1(unsigned int mvolt)
 {
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 1600, 3400, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_DCDC1_EN);
+
 	ret = pmic_bus_write(AXP221_DCDC1_CTRL, cfg);
 	if (ret)
 		return ret;
 
-	return axp221_setbits(AXP221_OUTPUT_CTRL2,
-			      AXP221_OUTPUT_CTRL2_DCDC1_EN);
+	ret = axp221_setbits(AXP221_OUTPUT_CTRL2,
+			     AXP221_OUTPUT_CTRL2_DCDC1SW_EN);
+	if (ret)
+		return ret;
+
+	return axp221_setbits(AXP221_OUTPUT_CTRL1,
+			      AXP221_OUTPUT_CTRL1_DCDC1_EN);
 }
 
 int axp221_set_dcdc2(unsigned int mvolt)
 {
+	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
 
-	return pmic_bus_write(AXP221_DCDC2_CTRL, cfg);
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_DCDC2_EN);
+
+	ret = pmic_bus_write(AXP221_DCDC2_CTRL, cfg);
+	if (ret)
+		return ret;
+
+	return axp221_setbits(AXP221_OUTPUT_CTRL1,
+			      AXP221_OUTPUT_CTRL1_DCDC2_EN);
 }
 
 int axp221_set_dcdc3(unsigned int mvolt)
 {
+	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1860, 20);
 
-	return pmic_bus_write(AXP221_DCDC3_CTRL, cfg);
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_DCDC3_EN);
+
+	ret = pmic_bus_write(AXP221_DCDC3_CTRL, cfg);
+	if (ret)
+		return ret;
+
+	return axp221_setbits(AXP221_OUTPUT_CTRL1,
+			      AXP221_OUTPUT_CTRL1_DCDC3_EN);
 }
 
 int axp221_set_dcdc4(unsigned int mvolt)
 {
+	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 600, 1540, 20);
 
-	return pmic_bus_write(AXP221_DCDC4_CTRL, cfg);
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_DCDC4_EN);
+
+	ret = pmic_bus_write(AXP221_DCDC4_CTRL, cfg);
+	if (ret)
+		return ret;
+
+	return axp221_setbits(AXP221_OUTPUT_CTRL1,
+			      AXP221_OUTPUT_CTRL1_DCDC4_EN);
 }
 
 int axp221_set_dcdc5(unsigned int mvolt)
 {
+	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 1000, 2550, 50);
 
-	return pmic_bus_write(AXP221_DCDC5_CTRL, cfg);
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_DCDC5_EN);
+
+	ret = pmic_bus_write(AXP221_DCDC5_CTRL, cfg);
+	if (ret)
+		return ret;
+
+	return axp221_setbits(AXP221_OUTPUT_CTRL1,
+			      AXP221_OUTPUT_CTRL1_DCDC5_EN);
 }
 
 int axp221_set_dldo1(unsigned int mvolt)
@@ -126,6 +188,10 @@ int axp221_set_dldo1(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL2,
+				      AXP221_OUTPUT_CTRL2_DLDO1_EN);
+
 	ret = pmic_bus_write(AXP221_DLDO1_CTRL, cfg);
 	if (ret)
 		return ret;
@@ -139,6 +205,10 @@ int axp221_set_dldo2(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL2,
+				      AXP221_OUTPUT_CTRL2_DLDO2_EN);
+
 	ret = pmic_bus_write(AXP221_DLDO2_CTRL, cfg);
 	if (ret)
 		return ret;
@@ -152,6 +222,10 @@ int axp221_set_dldo3(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL2,
+				      AXP221_OUTPUT_CTRL2_DLDO3_EN);
+
 	ret = pmic_bus_write(AXP221_DLDO3_CTRL, cfg);
 	if (ret)
 		return ret;
@@ -165,6 +239,10 @@ int axp221_set_dldo4(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL2,
+				      AXP221_OUTPUT_CTRL2_DLDO4_EN);
+
 	ret = pmic_bus_write(AXP221_DLDO4_CTRL, cfg);
 	if (ret)
 		return ret;
@@ -178,6 +256,10 @@ int axp221_set_aldo1(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_ALDO1_EN);
+
 	ret = pmic_bus_write(AXP221_ALDO1_CTRL, cfg);
 	if (ret)
 		return ret;
@@ -191,6 +273,10 @@ int axp221_set_aldo2(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL1,
+				      AXP221_OUTPUT_CTRL1_ALDO2_EN);
+
 	ret = pmic_bus_write(AXP221_ALDO2_CTRL, cfg);
 	if (ret)
 		return ret;
@@ -204,6 +290,10 @@ int axp221_set_aldo3(unsigned int mvolt)
 	int ret;
 	u8 cfg = axp221_mvolt_to_cfg(mvolt, 700, 3300, 100);
 
+	if (mvolt == 0)
+		return axp221_clrbits(AXP221_OUTPUT_CTRL3,
+				      AXP221_OUTPUT_CTRL3_ALDO3_EN);
+
 	ret = pmic_bus_write(AXP221_ALDO3_CTRL, cfg);
 	if (ret)
 		return ret;
diff --git a/include/axp221.h b/include/axp221.h
index 10d35e1..a6e52e3 100644
--- a/include/axp221.h
+++ b/include/axp221.h
@@ -17,6 +17,12 @@
 /* Page 0 addresses */
 #define AXP221_CHIP_ID		0x03
 #define AXP221_OUTPUT_CTRL1	0x10
+#define AXP221_OUTPUT_CTRL1_DCDC0_EN	(1 << 0)
+#define AXP221_OUTPUT_CTRL1_DCDC1_EN	(1 << 1)
+#define AXP221_OUTPUT_CTRL1_DCDC2_EN	(1 << 2)
+#define AXP221_OUTPUT_CTRL1_DCDC3_EN	(1 << 3)
+#define AXP221_OUTPUT_CTRL1_DCDC4_EN	(1 << 4)
+#define AXP221_OUTPUT_CTRL1_DCDC5_EN	(1 << 5)
 #define AXP221_OUTPUT_CTRL1_ALDO1_EN	(1 << 6)
 #define AXP221_OUTPUT_CTRL1_ALDO2_EN	(1 << 7)
 #define AXP221_OUTPUT_CTRL2	0x12
@@ -24,7 +30,7 @@
 #define AXP221_OUTPUT_CTRL2_DLDO2_EN	(1 << 4)
 #define AXP221_OUTPUT_CTRL2_DLDO3_EN	(1 << 5)
 #define AXP221_OUTPUT_CTRL2_DLDO4_EN	(1 << 6)
-#define AXP221_OUTPUT_CTRL2_DCDC1_EN	(1 << 7)
+#define AXP221_OUTPUT_CTRL2_DCDC1SW_EN	(1 << 7)
 #define AXP221_OUTPUT_CTRL3	0x13
 #define AXP221_OUTPUT_CTRL3_ALDO3_EN	(1 << 7)
 #define AXP221_DLDO1_CTRL	0x15
-- 
2.1.0



More information about the U-Boot mailing list