power: msm_charger: control system power
Some chargers can control their current supply for the system. Provide
facility in the msm_charger to choose which charger supplies system
current. It is guaranteed that start charging will always be called
on a charger that has been previously been asked to provide system
current.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/msm_charger.c b/drivers/power/msm_charger.c
index f82df2a..2dbc629 100644
--- a/drivers/power/msm_charger.c
+++ b/drivers/power/msm_charger.c
@@ -480,6 +480,19 @@
return ret;
}
+static void msm_enable_system_current(struct msm_hardware_charger_priv *priv)
+{
+ if (priv->hw_chg->start_system_current)
+ priv->hw_chg->start_system_current(priv->hw_chg,
+ priv->max_source_current);
+}
+
+static void msm_disable_system_current(struct msm_hardware_charger_priv *priv)
+{
+ if (priv->hw_chg->stop_system_current)
+ priv->hw_chg->stop_system_current(priv->hw_chg);
+}
+
/* the best charger has been selected -start charging from current_chg_priv */
static int msm_start_charging(void)
{
@@ -630,11 +643,17 @@
/* set the charger state to READY before calling this */
static void handle_charger_ready(struct msm_hardware_charger_priv *hw_chg_priv)
{
+ struct msm_hardware_charger_priv *old_chg_priv = NULL;
+
debug_print(__func__, hw_chg_priv);
if (msm_chg.current_chg_priv != NULL
&& hw_chg_priv->hw_chg->rating >
msm_chg.current_chg_priv->hw_chg->rating) {
+ /*
+ * a better charger was found, ask the current charger
+ * to stop charging if it was charging
+ */
if (msm_chg.current_chg_priv->hw_chg_state ==
CHG_CHARGING_STATE) {
if (msm_stop_charging(msm_chg.current_chg_priv)) {
@@ -649,6 +668,7 @@
}
}
msm_chg.current_chg_priv->hw_chg_state = CHG_READY_STATE;
+ old_chg_priv = msm_chg.current_chg_priv;
msm_chg.current_chg_priv = NULL;
}
@@ -658,6 +678,14 @@
"%s: best charger = %s\n", __func__,
msm_chg.current_chg_priv->hw_chg->name);
+ msm_enable_system_current(msm_chg.current_chg_priv);
+ /*
+ * since a better charger was chosen, ask the old
+ * charger to stop providing system current
+ */
+ if (old_chg_priv != NULL)
+ msm_disable_system_current(old_chg_priv);
+
if (!is_batt_status_capable_of_charging())
return;
@@ -693,6 +721,7 @@
debug_print(__func__, hw_chg_removed);
if (msm_chg.current_chg_priv == hw_chg_removed) {
+ msm_disable_system_current(hw_chg_removed);
if (msm_chg.current_chg_priv->hw_chg_state
== CHG_CHARGING_STATE) {
if (msm_stop_charging(hw_chg_removed)) {
@@ -717,6 +746,7 @@
msm_chg.batt_status = BATT_STATUS_DISCHARGING;
} else {
msm_chg.current_chg_priv = hw_chg_priv;
+ msm_enable_system_current(hw_chg_priv);
dev_info(msm_chg.dev,
"%s: best charger = %s\n", __func__,
msm_chg.current_chg_priv->hw_chg->name);