summaryrefslogtreecommitdiff
path: root/driver
diff options
context:
space:
mode:
Diffstat (limited to 'driver')
-rw-r--r--driver/charger/sm5803.c43
-rw-r--r--driver/charger/sm5803.h19
2 files changed, 54 insertions, 8 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c
index 4e274af858..cc06443c5d 100644
--- a/driver/charger/sm5803.c
+++ b/driver/charger/sm5803.c
@@ -603,6 +603,23 @@ static void sm5803_init(int chgnum)
reg = SM5803_CURRENT_TO_REG(batt_info->precharge_current);
reg = MIN(reg, SM5803_PRECHG_ICHG_PRE_SET);
rv |= chg_write8(chgnum, SM5803_REG_PRECHG, reg);
+
+ /*
+ * Set up BFET alerts
+ *
+ * We'll set the soft limit at 1.5W and the hard limit at 6W.
+ *
+ * The register is 29.2 mW per bit.
+ */
+ reg = (1500 * 10) / 292;
+ rv |= meas_write8(chgnum, SM5803_REG_BFET_PWR_MAX_TH, reg);
+ reg = (6000 * 10) / 292;
+ rv |= meas_write8(chgnum, SM5803_REG_BFET_PWR_HWSAFE_MAX_TH,
+ reg);
+ rv |= main_read8(chgnum, SM5803_REG_INT3_EN, &reg);
+ reg |= SM5803_INT3_BFET_PWR_LIMIT |
+ SM5803_INT3_BFET_PWR_HWSAFE_LIMIT;
+ rv |= main_write8(chgnum, SM5803_REG_INT3_EN, reg);
}
if (rv)
@@ -624,6 +641,8 @@ void sm5803_handle_interrupt(int chgnum)
enum ec_error_list rv;
int int_reg, meas_reg;
static bool throttled;
+ struct batt_params bp;
+ int act_chg, val;
/* Note: Interrupt registers are clear on read */
rv = main_read8(chgnum, SM5803_REG_INT1_REQ, &int_reg);
@@ -678,6 +697,30 @@ void sm5803_handle_interrupt(int chgnum)
*/
}
+ /* TODO(b/159376384): Take action on fatal BFET power alert. */
+ rv = main_read8(chgnum, SM5803_REG_INT3_REQ, &int_reg);
+ if (rv) {
+ CPRINTS("%s %d: Failed to read int3 register", CHARGER_NAME,
+ chgnum);
+ return;
+ }
+
+ if ((int_reg & SM5803_INT3_BFET_PWR_LIMIT) ||
+ (int_reg & SM5803_INT3_BFET_PWR_HWSAFE_LIMIT)) {
+ battery_get_params(&bp);
+ act_chg = charge_manager_get_active_charge_port();
+ CPRINTS("%s BFET power limit reached! (%s)", CHARGER_NAME,
+ (int_reg & SM5803_INT3_BFET_PWR_LIMIT) ? "warn" :
+ "FATAL");
+ CPRINTS("\tVbat: %dmV", bp.voltage);
+ CPRINTS("\tIbat: %dmA", bp.current);
+ charger_get_voltage(act_chg, &val);
+ CPRINTS("\tVsys(aux): %dmV", val);
+ charger_get_current(act_chg, &val);
+ CPRINTS("\tIsys: %dmA", val);
+ cflush();
+ }
+
rv = main_read8(chgnum, SM5803_REG_INT4_REQ, &int_reg);
if (rv) {
CPRINTS("%s %d: Failed to read int4 register", CHARGER_NAME,
diff --git a/driver/charger/sm5803.h b/driver/charger/sm5803.h
index 75e4885cbc..7c0eaca78b 100644
--- a/driver/charger/sm5803.h
+++ b/driver/charger/sm5803.h
@@ -52,14 +52,14 @@
#define SM5803_INT2_VSYS BIT(6)
#define SM5803_INT2_TINT BIT(7)
-#define SM5803_REG_INT3_REQ 0x07
-#define SM5803_REG_INT3_EN 0x0C
-#define SM5803_INT3_GPADC0 BIT(0)
-#define SM5803_INT3_VBATC1 BIT(1)
-#define SM5803_INT3_VBATC2 BIT(2)
-#define SM5803_INT3_SPARE BIT(3)
-#define SM5803_INT3_VBUS_PWR_LIMIT BIT(4)
-#define SM5803_INT3_IBAT BIT(5)
+#define SM5803_REG_INT3_REQ 0x07
+#define SM5803_REG_INT3_EN 0x0C
+#define SM5803_INT3_GPADC0 BIT(0)
+#define SM5803_INT3_BFET_PWR_LIMIT BIT(1)
+#define SM5803_INT3_BFET_PWR_HWSAFE_LIMIT BIT(2)
+#define SM5803_INT3_SPARE BIT(3)
+#define SM5803_INT3_VBUS_PWR_LIMIT BIT(4)
+#define SM5803_INT3_IBAT BIT(5)
#define SM5803_REG_INT4_REQ 0x08
#define SM5803_REG_INT4_EN 0x0D
@@ -96,6 +96,9 @@ enum sm5803_gpio0_modes {
GPIO0_MODE_INPUT
};
+#define SM5803_REG_BFET_PWR_MAX_TH 0x35
+#define SM5803_REG_BFET_PWR_HWSAFE_MAX_TH 0x36
+
#define SM5803_REG_PORTS_CTRL 0x40
#define SM5803_PORTS_VBUS_DISCH BIT(0)
#define SM5803_PORTS_VBUS_PULLDOWN BIT(1)