summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/charge_manager.c15
-rw-r--r--common/charge_state_v2.c13
-rw-r--r--include/charge_manager.h9
3 files changed, 37 insertions, 0 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c
index 862bb28725..14c869c3b2 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -107,6 +107,7 @@ static int charge_current = CHARGE_CURRENT_UNINITIALIZED;
static int charge_current_uncapped = CHARGE_CURRENT_UNINITIALIZED;
static int charge_voltage;
static int charge_supplier = CHARGE_SUPPLIER_NONE;
+static int charge_pd_current_uncapped = CHARGE_CURRENT_UNINITIALIZED;
static int override_port = OVERRIDE_OFF;
static int delayed_override_port = OVERRIDE_OFF;
@@ -267,6 +268,11 @@ static int charge_manager_is_seeded(void)
return 1;
}
+int charge_manager_get_pd_current_uncapped(void)
+{
+ return charge_pd_current_uncapped;
+}
+
#ifndef TEST_BUILD
/**
* Get the maximum charge current for a port.
@@ -828,6 +834,15 @@ static void charge_manager_refresh(void)
available_charge[new_supplier][new_port].voltage;
}
+ /*
+ * Record the PD current limit to prevent from over-sinking
+ * the charger.
+ */
+ if (new_supplier == CHARGE_SUPPLIER_PD)
+ charge_pd_current_uncapped = new_charge_current_uncapped;
+ else
+ charge_pd_current_uncapped = CHARGE_CURRENT_UNINITIALIZED;
+
/* Change the charge limit + charge port/supplier if modified. */
if (new_port != charge_port || new_charge_current != charge_current ||
new_supplier != charge_supplier) {
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 59f38edee8..abfabda7a3 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -2694,6 +2694,19 @@ int charge_set_input_current_limit(int ma, int mv)
/* Limit input current limit to max limit for this board */
ma = MIN(ma, CONFIG_CHARGER_MAX_INPUT_CURRENT);
#endif
+
+ if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) {
+ int pd_current_uncapped =
+ charge_manager_get_pd_current_uncapped();
+
+ /*
+ * clamp the input current to not exceeded the PD's limitation.
+ */
+ if (pd_current_uncapped != CHARGE_CURRENT_UNINITIALIZED &&
+ ma > pd_current_uncapped)
+ ma = pd_current_uncapped;
+ }
+
curr.desired_input_current = ma;
#ifdef CONFIG_EC_EC_COMM_BATTERY_CLIENT
/* Wake up charger task to allocate current between lid and base. */
diff --git a/include/charge_manager.h b/include/charge_manager.h
index cb6591df3b..2cded28295 100644
--- a/include/charge_manager.h
+++ b/include/charge_manager.h
@@ -231,6 +231,15 @@ enum charge_supplier charge_manager_get_supplier(void);
*/
int charge_manager_get_vbus_voltage(int port);
+/**
+ * Get the current limit of CHARGE_PD_SUPPLIER.
+ *
+ * @return The CHARGE_SUPPLIER_PD current limit in mA or
+ * CHARGE_CURRENT_UNINITIALIZED if the supplier is not
+ * CHARGE_SUPPLIER_PD.
+ */
+int charge_manager_get_pd_current_uncapped(void);
+
#ifdef CONFIG_USB_PD_LOGGING
/* Save power state log entry for the given port */
void charge_manager_save_log(int port);