diff options
Diffstat (limited to 'driver/charger/isl923x.c')
-rw-r--r-- | driver/charger/isl923x.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c index 24e9e488a5..a5fae9329d 100644 --- a/driver/charger/isl923x.c +++ b/driver/charger/isl923x.c @@ -887,7 +887,28 @@ enum ec_error_list raa489000_is_acok(int chgnum, bool *acok) rv = raw_read16(chgnum, ISL9238_REG_INFO2, ®val); if (rv != EC_SUCCESS) return rv; - *acok = (regval & RAA489000_INFO2_ACOK); + + /* + * ACOK can sometimes be asserted when RAA489000 is sourcing VBUS in OTG + * mode, because that bit is derived from the VBUS comparator. If the + * charger reports it's in OTG mode, always say ACOK is false because we + * can't be running from a charger if we're also sourcing VBUS and the + * ACOK bit may be untrustworthy. + * + * This may sometimes report incorrectly because the state bits of + * the Information2 register take a small amount of time to update on + * a state change. In most cases the event hooks used to trigger + * raa489000_check_ac_present are good indications of a state change, + * but during power role swaps there may be no hooks executed so it's + * most consistent to use the charger's reported state only (otherwise + * some situations could use the EC's view of the current state and + * others would require asking the charger). + */ + if (((regval >> RAA489000_INFO2_STATE_SHIFT) & + RAA489000_INFO2_STATE_MASK) == RAA489000_INFO2_STATE_OTG) + *acok = false; + else + *acok = (regval & RAA489000_INFO2_ACOK) != 0; return EC_SUCCESS; } @@ -1460,6 +1481,7 @@ static enum ec_error_list raa489000_set_vsys_compensation(int chgnum, */ return EC_ERROR_UNIMPLEMENTED; } +#endif /* CONFIG_CHARGER_RAA489000 && CONFIG_OCPC */ #ifdef CONFIG_PLATFORM_EC_RAA489000_AC_PRESENT_CONTROL /* @@ -1477,8 +1499,14 @@ void raa489000_check_ac_delayed(void) static bool current_val; bool new_val; int rv, regval; + int chgnum = +#ifdef CONFIG_OCPC + CHARGER_PRIMARY; +#else + 0; +#endif - rv = raw_read16(CHARGER_PRIMARY, ISL9238_REG_INFO2, ®val); + rv = raw_read16(chgnum, ISL9238_REG_INFO2, ®val); if (rv == EC_SUCCESS) { new_val = (((regval >> RAA489000_INFO2_STATE_SHIFT) & RAA489000_INFO2_STATE_MASK) == @@ -1492,8 +1520,7 @@ void raa489000_check_ac_delayed(void) * be low. */ current_val = new_val; - isl923x_set_comparator_inversion(CHARGER_PRIMARY, - new_val); + isl923x_set_comparator_inversion(chgnum, new_val); } } } @@ -1521,8 +1548,6 @@ DECLARE_HOOK(HOOK_POWER_SUPPLY_CHANGE, raa489000_check_ac_present, HOOK_PRIO_DEFAULT); #endif /* CONFIG_PLATFORM_EC_RAA489000_AC_PRESENT_CONTROL */ -#endif /* CONFIG_CHARGER_RAA489000 && CONFIG_OCPC */ - const struct charger_drv isl923x_drv = { .init = &isl923x_init, .post_init = &isl923x_post_init, |