summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/charger/rt946x.c52
-rw-r--r--driver/charger/rt946x.h8
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