diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c index e28eeb0db2..33ff4c78af 100644 --- a/driver/charger/bd9995x.c +++ b/driver/charger/bd9995x.c @@ -111,10 +111,48 @@ bd9995x_write_cleanup: /* BD9995X local interfaces */ +static int bd9995x_set_vfastchg(int voltage) +{ + + int rv; + + /* Fast Charge Voltage Regulation Settings for fast charging. */ + rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET1, + voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); + if (rv) + return rv; + +#ifndef CONFIG_CHARGER_BATTERY_TSENSE + /* + * If TSENSE is not connected set all the VFASTCHG_REG_SETx + * to same voltage. + */ + rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET2, + voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); + if (rv) + return rv; + + rv = ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET3, + voltage & 0x7FF0, BD9995X_EXTENDED_COMMAND); +#endif + + return rv; +} + +static int bd9995x_set_vsysreg(int voltage) +{ + /* VSYS Regulation voltage is in 64mV steps. */ + voltage &= ~0x3F; + + return ch_raw_write16(BD9995X_CMD_VSYSREG_SET, voltage, + BD9995X_EXTENDED_COMMAND); +} + static int bd9995x_charger_enable(int enable) { - int rv; - int reg; + int rv, reg; + static int prev_chg_enable = -1; + const struct battery_info *bi = battery_get_info(); #ifdef CONFIG_CHARGER_BD9995X_CHGEN /* @@ -124,6 +162,44 @@ static int bd9995x_charger_enable(int enable) if (!enable && !board_battery_initialized()) return EC_SUCCESS; #endif + + /* Nothing to change */ + if (enable == prev_chg_enable) + return EC_SUCCESS; + + prev_chg_enable = enable; + + if (enable) { + /* + * BGATE capacitor max : 0.1uF + 20% + * Charge MOSFET threshold max : 2.8V + * BGATE charge pump current min : 3uA + * T = C * V / I so, Tmax = 112ms + */ + msleep(115); + + /* + * Set VSYSREG_SET <= VBAT so that the charger is in Fast-Charge + * state when charging. + */ + rv = bd9995x_set_vsysreg(bi->voltage_min); + } else { + /* + * Set VSYSREG_SET > VBAT so that the charger is in Pre-Charge + * state when not charging or discharging. + */ + rv = bd9995x_set_vsysreg(bi->voltage_max + 200); + + /* + * Allow charger in pre-charge state for 50ms before disabling + * the charger which prevents inrush current while moving from + * fast-charge state to pre-charge state. + */ + msleep(50); + } + if (rv) + return rv; + rv = ch_raw_read16(BD9995X_CMD_CHGOP_SET2, ®, BD9995X_EXTENDED_COMMAND); if (rv) @@ -380,15 +456,6 @@ static void usb_charger_process(enum bd9995x_charge_port port) } #endif /* HAS_TASK_USB_CHG */ -static int bd9995x_set_vsysreg(int voltage) -{ - /* VSYS Regulation voltage is in 64mV steps. */ - voltage &= ~0x3F; - - return ch_raw_write16(BD9995X_CMD_VSYSREG_SET, voltage, - BD9995X_EXTENDED_COMMAND); -} - /* chip specific interfaces */ int charger_set_input_current(int input_current) @@ -541,31 +608,11 @@ int charger_get_status(int *status) int charger_set_mode(int mode) { - int rv, inhibit_chg; - static int inhibit_chg_prev = -1; + int rv; - inhibit_chg = mode & CHARGE_FLAG_INHIBIT_CHARGE; - - if (inhibit_chg != inhibit_chg_prev) { - if (inhibit_chg) { - rv = bd9995x_set_vsysreg(BD9995X_DISCHARGE_VSYSREG); - msleep(50); - rv |= bd9995x_charger_enable(0); - } else { - rv = bd9995x_charger_enable(1); - /* - * BGATE capacitor max : 0.1uF + 20% - * Charge MOSFET threshold max : 2.8V - * BGATE charge pump current min : 3uA - * T = C * V / I so, Tmax = 112ms - */ - msleep(115); - rv |= bd9995x_set_vsysreg(BD9995X_CHARGE_VSYSREG); - } - inhibit_chg_prev = inhibit_chg; - if (rv) - return 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(); @@ -642,12 +689,11 @@ int charger_set_voltage(int voltage) /* Charge voltage step 16 mV */ voltage &= ~0x0F; - /* Assumes charger's voltage_min < battery's voltagte_max */ + /* Assumes charger's voltage_min < battery's voltage_max */ if (voltage < bd9995x_charger_info.voltage_min) voltage = bd9995x_charger_info.voltage_min; - return ch_raw_write16(BD9995X_CMD_CHG_VOLTAGE, voltage, - BD9995X_BAT_CHG_COMMAND); + return bd9995x_set_vfastchg(voltage); } static void bd9995x_battery_charging_profile_settings(void) @@ -670,18 +716,7 @@ static void bd9995x_battery_charging_profile_settings(void) bi->precharge_current & 0x07C0, BD9995X_EXTENDED_COMMAND); - /* Fast Charge Voltage Regulation Settings for fast charging. */ - ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET1, - bi->voltage_max & 0x7FF0, - BD9995X_EXTENDED_COMMAND); - - ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET2, - bi->voltage_max & 0x7FF0, - BD9995X_EXTENDED_COMMAND); - - ch_raw_write16(BD9995X_CMD_VFASTCHG_REG_SET3, - bi->voltage_max & 0x7FF0, - BD9995X_EXTENDED_COMMAND); + bd9995x_set_vfastchg(bi->voltage_max); /* Set Pre-charge Voltage Threshold for trickle charging. */ ch_raw_write16(BD9995X_CMD_VPRECHG_TH_SET, diff --git a/driver/charger/bd9995x.h b/driver/charger/bd9995x.h index 00b6d1032c..a5ce174aea 100644 --- a/driver/charger/bd9995x.h +++ b/driver/charger/bd9995x.h @@ -49,10 +49,6 @@ enum bd9995x_charge_port { /* Min. charge current w/ no battery to prevent collapse */ #define BD9995X_NO_BATTERY_CHARGE_I_MIN 512 -/* VSYSREG settings */ -#define BD9995X_DISCHARGE_VSYSREG 8960 -#define BD9995X_CHARGE_VSYSREG 6144 - /* * BC1.2 minimum voltage threshold. * BC1.2 charging port output voltage range is 4.75V to 5.25V,