diff options
-rw-r--r-- | common/charge_state_v2.c | 5 | ||||
-rw-r--r-- | driver/charger/bd9995x.c | 58 |
2 files changed, 39 insertions, 24 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index a7b1ddf708..5810f9c8fd 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -441,12 +441,7 @@ static int charge_request(int voltage, int current) * Set the charge inhibit bit when possible as it appears to save * power in some cases (e.g. Nyan with BQ24735). */ -#if defined(CONFIG_CHARGER_BD99955) || defined(CONFIG_CHARGER_BD99956) - /* Charger auto exits from battery learn mode if charge inhibited */ - if (current > 0 || chg_ctl_mode == CHARGE_CONTROL_DISCHARGE) -#else if (voltage > 0 || current > 0) -#endif r3 = charger_set_mode(0); else r3 = charger_set_mode(CHARGE_FLAG_INHIBIT_CHARGE); diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c index d74e0cd635..506026f620 100644 --- a/driver/charger/bd9995x.c +++ b/driver/charger/bd9995x.c @@ -149,6 +149,17 @@ static int bd9995x_set_vsysreg(int voltage) BD9995X_EXTENDED_COMMAND); } +static int bd9995x_is_discharging_on_ac(void) +{ + int reg; + + if (ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, + BD9995X_EXTENDED_COMMAND)) + return 0; + + return !!(reg & BD9995X_CMD_CHGOP_SET2_BATT_LEARN); +} + static int bd9995x_charger_enable(int enable) { int rv, reg; @@ -611,10 +622,6 @@ int charger_set_mode(int mode) { int rv; - rv = bd9995x_charger_enable(mode & CHARGE_FLAG_INHIBIT_CHARGE ? 0 : 1); - if (rv) - return rv; - if (mode & CHARGE_FLAG_POR_RESET) { rv = bd9995x_por_reset(); if (rv) @@ -639,6 +646,7 @@ int charger_get_current(int *current) int charger_set_current(int current) { int rv; + int chg_enable = 1; /* Charge current step 64 mA */ current &= ~0x3F; @@ -646,9 +654,20 @@ int charger_set_current(int current) if (current < BD9995X_NO_BATTERY_CHARGE_I_MIN && (battery_is_present() != BP_YES || battery_is_cut_off())) current = BD9995X_NO_BATTERY_CHARGE_I_MIN; - else if (current < bd9995x_charger_info.current_min && - !(charge_get_flags() & CHARGE_FLAG_FORCE_IDLE)) - current = bd9995x_charger_info.current_min; + + /* + * Disable charger before setting charge current to 0 or when + * discharging on AC. + * If charging current is set to 0mA during charging, reference of + * the charge current feedback amp (VREF_CHG) is set to 0V. Hence + * the DCDC stops switching (because of the EA offset). + */ + if (!current || bd9995x_is_discharging_on_ac()) { + chg_enable = 0; + rv = bd9995x_charger_enable(0); + if (rv) + return rv; + } rv = ch_raw_write16(BD9995X_CMD_IPRECH_SET, MIN(current, BD9995X_IPRECH_MAX), @@ -656,8 +675,16 @@ int charger_set_current(int current) if (rv) return rv; - return ch_raw_write16(BD9995X_CMD_CHG_CURRENT, current, + rv = ch_raw_write16(BD9995X_CMD_CHG_CURRENT, current, BD9995X_BAT_CHG_COMMAND); + if (rv) + return rv; + + /* + * Enable charger if charge current is non-zero or not discharging + * on AC. + */ + return chg_enable ? bd9995x_charger_enable(1) : EC_SUCCESS; } int charger_get_voltage(int *voltage) @@ -669,23 +696,16 @@ int charger_get_voltage(int *voltage) int charger_set_voltage(int voltage) { const int battery_voltage_max = battery_get_info()->voltage_max; - int rv; - int reg; /* * Regulate the system voltage to battery max if the battery * is not present or the battery is discharging on AC. */ - rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, - BD9995X_EXTENDED_COMMAND); - if (rv) - return rv; - if (voltage == 0 || - reg & BD9995X_CMD_CHGOP_SET2_BATT_LEARN || - battery_is_present() != BP_YES || - battery_is_cut_off() || - voltage > battery_voltage_max) + bd9995x_is_discharging_on_ac() || + battery_is_present() != BP_YES || + battery_is_cut_off() || + voltage > battery_voltage_max) voltage = battery_voltage_max; /* Charge voltage step 16 mV */ |