qpnp-smb2: fix incorrect type detection

Sometimes the apsd results show up as Unkonwn for SDP and SDP
for DCP. These are especially after reboot.

For such situations introduce code to rerun APSD right at bootup.
While at it also ensure that APSD rerun is enabled while shutting
down.

Change-Id: Ic81e270fd6efcf619624cb336cb0b8b41193913f
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2017-01-25 16:40:08 -08:00
parent fdddc49ef2
commit 44a400c291
3 changed files with 73 additions and 1 deletions

View file

@ -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[] = {

View file

@ -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 *
*********************/

View file

@ -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);