diff options
-rw-r--r-- | driver/charger/rt946x.c | 52 | ||||
-rw-r--r-- | driver/charger/rt946x.h | 8 |
2 files changed, 60 insertions, 0 deletions
diff --git a/driver/charger/rt946x.c b/driver/charger/rt946x.c index b864acaf3f..f389188bad 100644 --- a/driver/charger/rt946x.c +++ b/driver/charger/rt946x.c @@ -312,6 +312,53 @@ out: mutex_unlock(&hidden_mode_lock); return rv; } + +/* + * Vsys short protection: + * When the system is charging at 500mA, and if Isys > 3600mA, the + * power path will be turned off and cause the system shutdown. + * When Ichg < 400mA, then power path is roughly 1/8 of the original. + * When Isys > 3600mA, this cause the voltage between Vbat and Vsys too + * huge (Vbat - Vsys > Vsys short portection) and turns off the power + * path. + * To workaround this, + * 1. disable Vsys short protection when Ichg is set below 900mA + * 2. forbids Ichg <= 400mA (this is done natually on mt6370, since mt6370's + * minimum current is 512) + */ +static int mt6370_ichg_workaround(int new_ichg) +{ + int rv = EC_SUCCESS; + int curr_ichg; + + /* + * TODO(b:144532905): The workaround should be applied to rt9466 as + * well. But this needs rt9466's hidden register datasheet. Enable + * this if we need it in the future. + */ + if (!IS_ENABLED(CONFIG_CHARGER_MT6370)) + return EC_SUCCESS; + + rv = charger_get_current(&curr_ichg); + if (rv) + return rv; + + mt6370_enable_hidden_mode(1); + + /* disable Vsys protect if if the new ichg is below 900mA */ + if (curr_ichg >= 900 && new_ichg < 900) + rv = rt946x_update_bits(RT946X_REG_CHGHIDDENCTRL7, + RT946X_MASK_HIDDENCTRL7_VSYS_PROTECT, + 0); + /* enable Vsys protect if the new ichg is above 900mA */ + else if (new_ichg >= 900 && curr_ichg < 900) + rv = rt946x_update_bits(RT946X_REG_CHGHIDDENCTRL7, + RT946X_MASK_HIDDENCTRL7_VSYS_PROTECT, + RT946X_ENABLE_VSYS_PROTECT); + + mt6370_enable_hidden_mode(0); + return rv; +} #endif /* CONFIG_CHARGER_MT6370 */ static int rt946x_chip_rev(int *chip_rev) @@ -782,6 +829,11 @@ int charger_set_current(int current) if (IS_ENABLED(CONFIG_CHARGER_MT6370)) current = MAX(500, current); +#ifdef CONFIG_CHARGER_MT6370 + rv = mt6370_ichg_workaround(current); + if (rv) + return rv; +#endif reg_icc = rt946x_closest_reg(info->current_min, info->current_max, info->current_step, current); diff --git a/driver/charger/rt946x.h b/driver/charger/rt946x.h index 9797e95255..6b0228bb3b 100644 --- a/driver/charger/rt946x.h +++ b/driver/charger/rt946x.h @@ -124,6 +124,7 @@ #define MT6370_REG_QCSTATUS2 0x29 #define RT946X_REG_CHGCTRL17 0X2B #define RT946X_REG_CHGCTRL18 0X2C +#define RT946X_REG_CHGHIDDENCTRL7 0x36 #define MT6370_REG_CHGHIDDENCTRL15 0x3E #define RT946X_REG_CHGSTAT 0X4A #define RT946X_REG_CHGNTC 0X4B @@ -444,6 +445,13 @@ MT6370_MASK_APP_DPDM_IN | \ MT6370_MASK_APP_REF) +/* ========= CHGHIDDENCTRL7 0x36 (mt6370) ======== */ +#define RT946X_ENABLE_VSYS_PROTECT 0x40 + +#define RT946X_SHIFT_HIDDENCTRL7_VSYS_PROTECT 5 +#define RT946X_MASK_HIDDENCTRL7_VSYS_PROTECT \ + (0x3 << RT946X_SHIFT_HIDDENCTRL7_VSYS_PROTECT) + /* ========== CHGCTRL18 0x1A ============ */ #define RT946X_SHIFT_IRCMP_RES 3 #define RT946X_SHIFT_IRCMP_VCLAMP 0 |