Allows decreasing initial charge current, e.g. when power
supply is too weak to support both charging and other operations.

Signed-off-by: Marcin Ślusarz <mslus...@renau.com>
Cc: Jagan Teki <ja...@amarulasolutions.com>
Cc: Andre Przywara <andre.przyw...@arm.com>
---
 board/sunxi/board.c    |  4 ++++
 drivers/power/Kconfig  |  7 +++++++
 drivers/power/axp221.c | 33 +++++++++++++++++++++++++++++++++
 include/axp221.h       |  3 +++
 include/axp_pmic.h     |  1 +
 5 files changed, 48 insertions(+)

diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 824c322a0d..07fccf972a 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -623,6 +623,10 @@ void sunxi_board_init(void)
 #if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
        power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON));
 #endif
+
+#ifdef CONFIG_AXP221_POWER
+       power_failed |= axp221_set_charge_current(CONFIG_AXP221_CHARGE_CURRENT);
+#endif
 #endif /* CONFIG_AXPxxx_POWER */
        printf("DRAM:");
        gd->ram_size = sunxi_dram_init();
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 4b81aeb749..06b509a383 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -142,6 +142,13 @@ config SY8106A_POWER
 
 endchoice
 
+config AXP221_CHARGE_CURRENT
+       int "axp221 constant charge current in mA"
+       depends on AXP221_POWER
+       default 1200
+       ---help---
+       Any value between 300 and 2100 in 150 increments, or 0 to disable 
charging.
+
 config AXP_DCDC1_VOLT
        int "axp pmic dcdc1 voltage"
        depends on AXP221_POWER || AXP809_POWER || AXP818_POWER
diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index c22ca03f46..bf48585da0 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -205,6 +205,39 @@ int axp_set_eldo(int eldo_num, unsigned int mvolt)
                                AXP221_OUTPUT_CTRL2_ELDO1_EN << (eldo_num - 1));
 }
 
+static u8 axp221_mamp_to_cfg(int mamp, int min, int max, int div)
+{
+       if (mamp < min)
+               mamp = min;
+       else if (mamp > max)
+               mamp = max;
+
+       return (mamp - min) / div;
+}
+
+int axp221_set_charge_current(unsigned int mamp)
+{
+       int ret;
+       u8 cfg, chrg_ctrl;
+
+       cfg = axp221_mamp_to_cfg(mamp, 300, 2100, 150);
+       if (cfg > 0x0f)
+               return -EINVAL;
+
+       ret = pmic_bus_read(AXP221_CHRG_CTRL1, &chrg_ctrl);
+       if (ret)
+               return ret;
+
+       chrg_ctrl = (chrg_ctrl & 0xf0) | cfg;
+
+       if (mamp == 0)
+               chrg_ctrl &= 0x7f;
+       else
+               chrg_ctrl |= 0x80;
+
+       return pmic_bus_write(AXP221_CHRG_CTRL1, chrg_ctrl);
+}
+
 int axp_init(void)
 {
        u8 axp_chip_id;
diff --git a/include/axp221.h b/include/axp221.h
index 32b988f3a9..8eb1792435 100644
--- a/include/axp221.h
+++ b/include/axp221.h
@@ -44,6 +44,9 @@
 #define AXP221_ALDO3_CTRL      0x2a
 #define AXP221_SHUTDOWN                0x32
 #define AXP221_SHUTDOWN_POWEROFF       (1 << 7)
+#define AXP221_CHRG_CTRL1      0x33
+#define AXP221_CHRG_CTRL2      0x34
+#define AXP221_CHRG_CTRL3      0x35
 #define AXP221_PAGE            0xff
 
 /* Page 1 addresses */
diff --git a/include/axp_pmic.h b/include/axp_pmic.h
index ae62ef0d76..3bcd8f9ca9 100644
--- a/include/axp_pmic.h
+++ b/include/axp_pmic.h
@@ -52,6 +52,7 @@ int axp_set_aldo4(unsigned int mvolt);
 int axp_set_dldo(int dldo_num, unsigned int mvolt);
 int axp_set_eldo(int eldo_num, unsigned int mvolt);
 int axp_set_fldo(int fldo_num, unsigned int mvolt);
+int axp221_set_charge_current(unsigned int mamp);
 int axp_set_sw(bool on);
 int axp_init(void);
 int axp_get_sid(unsigned int *sid);
-- 
2.25.1

Reply via email to