diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 4a12af466c36..8dc93f42b059 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -1214,6 +1214,8 @@ static int smb2_init_hw(struct smb2 *chip) return rc; } + smblib_rerun_apsd_if_required(chg); + /* clear the ICL override if it is set */ if (stat & ICL_OVERRIDE_LATCH_BIT) { rc = smblib_write(chg, CMD_APSD_REG, ICL_OVERRIDE_BIT); @@ -1820,6 +1822,8 @@ static int smb2_probe(struct platform_device *pdev) struct smb_charger *chg; int rc = 0; u8 stat; + union power_supply_propval val; + int usb_present, batt_present, batt_health, batt_charge_type; chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) @@ -1943,7 +1947,37 @@ static int smb2_probe(struct platform_device *pdev) smb2_create_debugfs(chip); - pr_info("QPNP SMB2 probed successfully\n"); + rc = smblib_get_prop_usb_present(chg, &val); + if (rc < 0) { + pr_err("Couldn't get usb present rc=%d\n", rc); + goto cleanup; + } + usb_present = val.intval; + + rc = smblib_get_prop_batt_present(chg, &val); + if (rc < 0) { + pr_err("Couldn't get batt present rc=%d\n", rc); + goto cleanup; + } + batt_present = val.intval; + + rc = smblib_get_prop_batt_health(chg, &val); + if (rc < 0) { + pr_err("Couldn't get batt health rc=%d\n", rc); + goto cleanup; + } + batt_health = val.intval; + + rc = smblib_get_prop_batt_charge_type(chg, &val); + if (rc < 0) { + pr_err("Couldn't get batt charge type rc=%d\n", rc); + goto cleanup; + } + batt_charge_type = val.intval; + + pr_info("QPNP SMB2 probed successfully usb:present=%d type=%d batt:present = %d health = %d charge = %d\n", + usb_present, chg->usb_psy_desc.type, + batt_present, batt_health, batt_charge_type); return rc; cleanup: @@ -1987,6 +2021,10 @@ static void smb2_shutdown(struct platform_device *pdev) smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT, 0); smblib_write(chg, CMD_HVDCP_2_REG, FORCE_5V_BIT); + + /* force enable APSD */ + smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG, + AUTO_SRC_DETECT_BIT, AUTO_SRC_DETECT_BIT); } static const struct of_device_id match_table[] = { diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index d3f7e43ea10e..864152ca463d 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -660,6 +660,39 @@ void smblib_suspend_on_debug_battery(struct smb_charger *chg) pr_info("Input suspended: Fake battery\n"); } +int smblib_rerun_apsd_if_required(struct smb_charger *chg) +{ + const struct apsd_result *apsd_result; + union power_supply_propval val; + int rc; + + rc = smblib_get_prop_usb_present(chg, &val); + if (rc < 0) { + smblib_err(chg, "Couldn't get usb present rc = %d\n", rc); + return rc; + } + + if (!val.intval) + return 0; + + apsd_result = smblib_get_apsd_result(chg); + if ((apsd_result->pst == POWER_SUPPLY_TYPE_UNKNOWN) + || (apsd_result->pst == POWER_SUPPLY_TYPE_USB)) { + /* rerun APSD */ + pr_info("Reruning APSD type = %s at bootup\n", + apsd_result->name); + rc = smblib_masked_write(chg, CMD_APSD_REG, + APSD_RERUN_BIT, + APSD_RERUN_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't rerun APSD rc = %d\n", rc); + return rc; + } + } + + return 0; +} + /********************* * VOTABLE CALLBACKS * *********************/ diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index c5d014193fd6..a4121224b121 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -385,6 +385,7 @@ int smblib_get_prop_slave_current_now(struct smb_charger *chg, int smblib_set_prop_ship_mode(struct smb_charger *chg, const union power_supply_propval *val); void smblib_suspend_on_debug_battery(struct smb_charger *chg); +int smblib_rerun_apsd_if_required(struct smb_charger *chg); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg);