summaryrefslogtreecommitdiff
path: root/common/charge_manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/charge_manager.c')
-rw-r--r--common/charge_manager.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/common/charge_manager.c b/common/charge_manager.c
index c3e5b4d0ce..7ee86081a6 100644
--- a/common/charge_manager.c
+++ b/common/charge_manager.c
@@ -32,6 +32,9 @@ static struct charge_port_info available_charge[CHARGE_SUPPLIER_COUNT]
*/
static int charge_ceil[PD_PORT_COUNT];
+/* Dual-role capability of attached partner port */
+static enum dualrole_capabilities dualrole_capability[PD_PORT_COUNT];
+
/* Store current state of port enable / charge current. */
static int charge_port = CHARGE_PORT_NONE;
static int charge_current = CHARGE_CURRENT_UNINITIALIZED;
@@ -64,6 +67,7 @@ static void charge_manager_init(void)
CHARGE_VOLTAGE_UNINITIALIZED;
}
charge_ceil[i] = CHARGE_CEIL_NONE;
+ dualrole_capability[i] = CAP_UNKNOWN;
}
}
DECLARE_HOOK(HOOK_INIT, charge_manager_init, HOOK_PRIO_DEFAULT-1);
@@ -132,7 +136,7 @@ static void charge_manager_fill_power_info(int port,
r->role = USB_PD_PORT_POWER_DISCONNECTED;
/* Is port partner dual-role capable */
- r->dualrole = (pd_get_partner_dualrole_capable(port) == CAP_DUALROLE);
+ r->dualrole = (dualrole_capability[port] == CAP_DUALROLE);
if (sup == CHARGE_SUPPLIER_NONE ||
r->role == USB_PD_PORT_POWER_SOURCE) {
@@ -231,7 +235,7 @@ static void charge_manager_cleanup_override_port(int port)
if (port < 0 || port >= PD_PORT_COUNT)
return;
- if (pd_get_partner_dualrole_capable(port) == CAP_DUALROLE &&
+ if (dualrole_capability[port] == CAP_DUALROLE &&
pd_get_role(port) == PD_ROLE_SINK)
pd_request_power_swap(port);
}
@@ -282,8 +286,7 @@ static void charge_manager_get_best_charge_port(int *new_port,
* Don't charge from a dual-role port unless
* it is our override port.
*/
- if (pd_get_partner_dualrole_capable(j) !=
- CAP_DEDICATED &&
+ if (dualrole_capability[j] != CAP_DEDICATED &&
override_port != j)
continue;
@@ -457,7 +460,7 @@ static void charge_manager_make_change(enum charge_manager_change_type change,
* Ignore all except for transition to non-dualrole,
* which may occur some time after we see a charge
*/
- if (pd_get_partner_dualrole_capable(port) != CAP_DEDICATED)
+ if (dualrole_capability[port] != CAP_DEDICATED)
return;
/* Clear override only if a charge is present on the port */
for (i = 0; i < CHARGE_SUPPLIER_COUNT; ++i)
@@ -476,7 +479,7 @@ static void charge_manager_make_change(enum charge_manager_change_type change,
/* Remove override when a dedicated charger is plugged */
if (clear_override && override_port != port &&
- pd_get_partner_dualrole_capable(port) == CAP_DEDICATED) {
+ dualrole_capability[port] == CAP_DEDICATED) {
charge_manager_cleanup_override_port(override_port);
override_port = OVERRIDE_OFF;
if (delayed_override_port != OVERRIDE_OFF) {
@@ -532,16 +535,19 @@ void charge_manager_update_charge(int supplier,
}
/**
- * Notify charge_manager of a partner dualrole capability change. There is
- * no capability parameter to this function, since the capability can be
- * checked with pd_get_partner_dualrole_capable().
+ * Notify charge_manager of a partner dualrole capability change.
*
* @param port Charge port which changed.
+ * @param cap New port capability.
*/
-void charge_manager_update_dualrole(int port)
+void charge_manager_update_dualrole(int port, enum dualrole_capabilities cap)
{
ASSERT(port >= 0 && port < PD_PORT_COUNT);
- charge_manager_make_change(CHANGE_DUALROLE, 0, port, NULL);
+ /* Ignore when capability is unchanged */
+ if (cap != dualrole_capability[port]) {
+ dualrole_capability[port] = cap;
+ charge_manager_make_change(CHANGE_DUALROLE, 0, port, NULL);
+ }
}
/**
@@ -603,7 +609,7 @@ int charge_manager_set_override(int port)
* power swap and set the delayed override for swap completion.
*/
else if (pd_get_role(port) != PD_ROLE_SINK &&
- pd_get_partner_dualrole_capable(port) == CAP_DUALROLE) {
+ dualrole_capability[port] == CAP_DUALROLE) {
delayed_override_deadline.val = get_time().val +
POWER_SWAP_TIMEOUT;
delayed_override_port = port;