summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/imx233/powermgmt-imx233.c
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-05-02 21:49:13 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2016-05-28 16:21:03 +0100
commit941ac165d864ccdd4e4ae870366f4e0a6bc30055 (patch)
treed0030c16f10321833f383baafaf3b78610951526 /firmware/target/arm/imx233/powermgmt-imx233.c
parentd245b7a2a1113b6dbdbfb10f5ee984a00c987844 (diff)
downloadrockbox-941ac165d864ccdd4e4ae870366f4e0a6bc30055.tar.gz
rockbox-941ac165d864ccdd4e4ae870366f4e0a6bc30055.tar.bz2
rockbox-941ac165d864ccdd4e4ae870366f4e0a6bc30055.zip
imx233: speedup charging trickle phase
Per Freescale recommandation, we need to ramp up the 4.2V rail before enabling charging. Ramping should be done at 1 step/10ms, but the old code did 1 step/1s because the powermgmt_step() function is called once every second. Use a tick task to ramp up much faster. Change-Id: I9a52bdd0c2ba5426d83ed42db8db7ecce2fea1f7
Diffstat (limited to 'firmware/target/arm/imx233/powermgmt-imx233.c')
-rw-r--r--firmware/target/arm/imx233/powermgmt-imx233.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/firmware/target/arm/imx233/powermgmt-imx233.c b/firmware/target/arm/imx233/powermgmt-imx233.c
index 50ab8451bb..2706ee99fa 100644
--- a/firmware/target/arm/imx233/powermgmt-imx233.c
+++ b/firmware/target/arm/imx233/powermgmt-imx233.c
@@ -39,7 +39,6 @@
/* charger state is maintained in charge_state (see powermgmt.h) */
static int timeout_charging; /* timeout before charging will be declared broken */
static int timeout_topping_off; /* timeout before stopping charging after topping off */
-static int timeout_4p2_ilimit_increase; /* timeout before increasing 4p2 ilimit */
/* Returns battery voltage from ADC [millivolts] */
int _battery_voltage(void)
@@ -69,9 +68,24 @@ void imx233_powermgmt_init(void)
#endif
}
+#define MAX_4P2_ILIMIT 0x3f
+
+/* The code below assumes HZ = 100 so that it runs every 10ms */
+#if HZ != 100
+#warning The ramp_up_4p2_rail() tick task assumes HZ = 100, this may break charging
+#endif
+
+static void ramp_up_4p2_rail(void)
+{
+ /* only ramp up in the TRICKLE state and if we haven't reached the maximum yet */
+ if(charge_state == TRICKLE && BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) < MAX_4P2_ILIMIT)
+ HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1);
+}
+
void powermgmt_init_target(void)
{
charge_state = DISCHARGING;
+ tick_add_task(&ramp_up_4p2_rail);
}
void charging_algorithm_step(void)
@@ -84,15 +98,15 @@ void charging_algorithm_step(void)
{
logf("pwrmgmt: * -> discharging");
logf("pwrmgmt: disable charger and 4p2");
+ charge_state = DISCHARGING;
/* 5V has been lost: disable 4p2 power rail */
BF_SET(POWER_CHARGE, PWD_BATTCHRG);
#if IMX233_SUBTARGET >= 3780
BF_WR(POWER_DCDC4P2, ENABLE_DCDC(0));
BF_WR(POWER_DCDC4P2, ENABLE_4P2(0));
- BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(1));
+ BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0));
BF_SET(POWER_5VCTRL, PWD_CHARGE_4P2);
#endif
- charge_state = DISCHARGING;
}
/* battery -> 5v transition */
else if(is_5v_present && charge_state == DISCHARGING)
@@ -108,26 +122,22 @@ void charging_algorithm_step(void)
* limit on the 4P2 rail. */
BF_WR(POWER_DCDC4P2, ENABLE_4P2(1));
BF_SET(POWER_CHARGE, ENABLE_LOAD);
- BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(1)); /* start by drawing 10mA only */
+ BF_WR(POWER_5VCTRL, CHARGE_4P2_ILIMIT(0)); /* start by drawing 0mA */
BF_CLR(POWER_5VCTRL, PWD_CHARGE_4P2);// FIXME: manual error ?
BF_WR(POWER_DCDC4P2, ENABLE_DCDC(1));
+ /* the tick task will take care of slowly ramping up the current in the rail
+ * every 10ms (since it runs at HZ and HZ=100) */
#endif
- timeout_4p2_ilimit_increase = current_tick + HZ / 100;
charge_state = TRICKLE;
}
- else if(charge_state == TRICKLE && TIME_AFTER(current_tick, timeout_4p2_ilimit_increase))
+ /* trickle -> charging transition */
+ else if(charge_state == TRICKLE)
{
#if IMX233_SUBTARGET >= 3780
- /* if 4.2V current limit has not reached 780mA, increase it slowly to
- * charge the 4.2V capacitance */
- if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) != 0x3f)
- {
- //logf("pwrmgmt: incr 4.2 ilimit");
- HW_POWER_5VCTRL += BF_POWER_5VCTRL_CHARGE_4P2_ILIMIT(1);
- timeout_4p2_ilimit_increase = current_tick + HZ / 100;
- }
- /* we've reached the maximum, take action */
- else
+ /* If 4.2V current limit has not reached 780mA, don't do anything, the
+ * DPC is still running */
+ /* If we've reached the maximum, take action */
+ if(BF_RD(POWER_5VCTRL, CHARGE_4P2_ILIMIT) == MAX_4P2_ILIMIT)
#endif
{
logf("pwrmgmt: enable dcdc and charger");
@@ -181,6 +191,7 @@ void charging_algorithm_step(void)
void charging_algorithm_close(void)
{
+ tick_remove_task(&ramp_up_4p2_rail);
}
struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void)
@@ -192,7 +203,5 @@ struct imx233_powermgmt_info_t imx233_powermgmt_get_info(void)
charge_state == CHARGING ? timeout_charging - current_tick : 0;
info.topoff_timeout =
charge_state == TOPOFF ? timeout_topping_off - current_tick : 0;
- info.incr_4p2_ilimit_timeout =
- charge_state == TRICKLE ? timeout_4p2_ilimit_increase - current_tick : 0;
return info;
}