From 0dfa84e381cc377cd0276b99530a47640f763814 Mon Sep 17 00:00:00 2001 From: Anirudh Ghayal Date: Wed, 19 Jul 2017 16:04:44 +0530 Subject: [PATCH] power: smb-lib: Restart charging from soft JEITA In the scenario where the charging is terminated in the JEITA soft condition, the HW is expected to restart charging when battery temperature returns back to normal. However, this does not work as expected and the charging stays terminated. Fix this by disabling and re-enabling charging CMD bit to restart charging. CRs-Fixed: 2071261 Change-Id: I81d2a89c72ede840cc561b736ce1366c65da8c42 Signed-off-by: Anirudh Ghayal --- drivers/power/supply/qcom/qpnp-smb2.c | 2 + drivers/power/supply/qcom/smb-lib.c | 53 +++++++++++++++++++++++++++ drivers/power/supply/qcom/smb-lib.h | 1 + 3 files changed, 56 insertions(+) diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 7b7f991ecba9..240531948710 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1946,6 +1946,7 @@ static int smb2_determine_initial_status(struct smb2 *chip) smblib_handle_icl_change(0, &irq_data); smblib_handle_step_chg_state_change(0, &irq_data); smblib_handle_step_chg_soc_update_request(0, &irq_data); + smblib_handle_batt_temp_changed(0, &irq_data); return 0; } @@ -2001,6 +2002,7 @@ static struct smb_irq_info smb2_irqs[] = { [BATT_TEMP_IRQ] = { .name = "bat-temp", .handler = smblib_handle_batt_temp_changed, + .wake = true, }, [BATT_OCP_IRQ] = { .name = "bat-ocp", diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 64d71727f7e6..6be8b1714cdb 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -2883,6 +2883,51 @@ int smblib_set_prop_pd_in_hard_reset(struct smb_charger *chg, return rc; } +static int smblib_recover_from_soft_jeita(struct smb_charger *chg) +{ + u8 stat_1, stat_2; + int rc; + + rc = smblib_read(chg, BATTERY_CHARGER_STATUS_1_REG, &stat_1); + if (rc < 0) { + smblib_err(chg, "Couldn't read BATTERY_CHARGER_STATUS_1 rc=%d\n", + rc); + return rc; + } + + rc = smblib_read(chg, BATTERY_CHARGER_STATUS_2_REG, &stat_2); + if (rc < 0) { + smblib_err(chg, "Couldn't read BATTERY_CHARGER_STATUS_2 rc=%d\n", + rc); + return rc; + } + + if ((chg->jeita_status && !(stat_2 & BAT_TEMP_STATUS_SOFT_LIMIT_MASK) && + ((stat_1 & BATTERY_CHARGER_STATUS_MASK) == TERMINATE_CHARGE))) { + /* + * We are moving from JEITA soft -> Normal and charging + * is terminated + */ + rc = smblib_write(chg, CHARGING_ENABLE_CMD_REG, 0); + if (rc < 0) { + smblib_err(chg, "Couldn't disable charging rc=%d\n", + rc); + return rc; + } + rc = smblib_write(chg, CHARGING_ENABLE_CMD_REG, + CHARGING_ENABLE_CMD_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't enable charging rc=%d\n", + rc); + return rc; + } + } + + chg->jeita_status = stat_2 & BAT_TEMP_STATUS_SOFT_LIMIT_MASK; + + return 0; +} + /*********************** * USB MAIN PSY GETTERS * *************************/ @@ -3144,6 +3189,14 @@ irqreturn_t smblib_handle_batt_temp_changed(int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; + int rc; + + rc = smblib_recover_from_soft_jeita(chg); + if (rc < 0) { + smblib_err(chg, "Couldn't recover chg from soft jeita rc=%d\n", + rc); + return IRQ_HANDLED; + } rerun_election(chg->fcc_votable); power_supply_changed(chg->batt_psy); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index 18714827b8d2..d088167d4405 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -329,6 +329,7 @@ struct smb_charger { bool pr_swap_in_progress; int typec_mode; int usb_icl_change_irq_enabled; + u32 jeita_status; /* workaround flag */ u32 wa_flags;