summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usb_pd_dual_role.c45
-rw-r--r--common/usb_pd_policy.c6
-rw-r--r--common/usb_pd_protocol.c61
-rw-r--r--include/usb_pd.h11
4 files changed, 31 insertions, 92 deletions
diff --git a/common/usb_pd_dual_role.c b/common/usb_pd_dual_role.c
index 683c2f1837..d571200c2c 100644
--- a/common/usb_pd_dual_role.c
+++ b/common/usb_pd_dual_role.c
@@ -21,31 +21,6 @@
*/
static unsigned int max_request_mv = PD_MAX_VOLTAGE_MV;
-/*
- * Partner allow_list pair data to override ability for us to sink from them
- * even if they do not present Unconstrained Power in their SRC_Caps. The
- * partner pairs in this list should be able to perform as a dual role partner
- * and should not present Unconstrained Power. It is best for the partner to
- * fix the device so it is not required to be in this list but some devices
- * are already out in the wild and will require this for the user's sake.
- */
-struct allow_list_pair {
- uint16_t vid;
- uint16_t pid;
-};
-
-static struct allow_list_pair allow_list[] = {
- {USB_VID_APPLE, USB_PID1_APPLE},
- {USB_VID_APPLE, USB_PID2_APPLE},
- {USB_VID_HP, USB_PID_HP_USB_C_DOCK_G5},
- {USB_VID_HP, USB_PID_HP_USB_C_A_UNIV_DOCK_G2},
- {USB_VID_HP, USB_PID_HP_E24D_DOCK_MONITOR},
- {USB_VID_HP, USB_PID_HP_ELITE_E233_MONITOR},
- {USB_VID_HP, USB_PID_HP_E244D_DOCK_MONITOR},
- {USB_VID_HP, USB_PID_HP_E274D_DOCK_MONITOR},
-};
-static int allow_list_count = ARRAY_SIZE(allow_list);
-
STATIC_IF_NOT(CONFIG_USB_PD_PREFER_MV)
struct pd_pref_config_t __maybe_unused pd_pref_config;
@@ -360,26 +335,6 @@ void pd_process_source_cap(int port, int cnt, uint32_t *src_caps)
}
#endif /* defined(PD_MAX_VOLTAGE_MV) && defined(PD_OPERATING_POWER_MW) */
-int pd_charge_from_device(uint16_t vid, uint16_t pid)
-{
- int i;
-
- /*
- * Allow list check for partners that do not set unconstrained bit
- * but we still need to charge from it when we are a sink.
- */
- for (i = 0; i < allow_list_count; ++i) {
- if (vid == allow_list[i].vid &&
- pid == allow_list[i].pid)
- return 1;
- }
-
- if (vid != 0)
- CPRINTS("allow_list[] pair not found: vid=0x%X pid=0x%X",
- vid, pid);
- return 0;
-}
-
bool pd_is_battery_capable(void)
{
bool capable;
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index bdf07452b7..d0194e2cdc 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -723,12 +723,6 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload,
rsize = process_am_discover_ident_sop(port,
cnt, head, payload, rtype);
}
-#ifdef CONFIG_CHARGE_MANAGER
- if (pd_charge_from_device(pd_get_identity_vid(port),
- pd_get_identity_pid(port)))
- charge_manager_update_dualrole(port,
- CAP_DEDICATED);
-#endif
break;
case CMD_DISCOVER_SVID:
rsize = process_am_discover_svids(port, cnt, payload,
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index dd0eaa8c05..d3943ea0d0 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -1487,59 +1487,60 @@ static int pd_send_request_msg(int port, int always_send_request)
}
#endif
-static void pd_update_pdo_flags(int port, uint32_t pdo)
+static void pd_update_pdo_flags(int port, int pdo_cnt, uint32_t *pdos)
{
-#ifdef CONFIG_CHARGE_MANAGER
-#ifdef CONFIG_USB_PD_ALT_MODE_DFP
- int charge_allowlisted =
- (pd[port].power_role == PD_ROLE_SINK &&
- pd_charge_from_device(pd_get_identity_vid(port),
- pd_get_identity_pid(port)));
-#else
- const int charge_allowlisted = 0;
-#endif
-#endif
-
/* can only parse PDO flags if type is fixed */
- if ((pdo & PDO_TYPE_MASK) != PDO_TYPE_FIXED)
+ if ((pdos[0] & PDO_TYPE_MASK) != PDO_TYPE_FIXED)
return;
#ifdef CONFIG_USB_PD_DUAL_ROLE
- if (pdo & PDO_FIXED_DUAL_ROLE)
+ if (pdos[0] & PDO_FIXED_DUAL_ROLE)
pd[port].flags |= PD_FLAGS_PARTNER_DR_POWER;
else
pd[port].flags &= ~PD_FLAGS_PARTNER_DR_POWER;
- if (pdo & PDO_FIXED_UNCONSTRAINED)
+ if (pdos[0] & PDO_FIXED_UNCONSTRAINED)
pd[port].flags |= PD_FLAGS_PARTNER_UNCONSTR;
else
pd[port].flags &= ~PD_FLAGS_PARTNER_UNCONSTR;
- if (pdo & PDO_FIXED_COMM_CAP)
+ if (pdos[0] & PDO_FIXED_COMM_CAP)
pd[port].flags |= PD_FLAGS_PARTNER_USB_COMM;
else
pd[port].flags &= ~PD_FLAGS_PARTNER_USB_COMM;
#endif
- if (pdo & PDO_FIXED_DATA_SWAP)
+ if (pdos[0] & PDO_FIXED_DATA_SWAP)
pd[port].flags |= PD_FLAGS_PARTNER_DR_DATA;
else
pd[port].flags &= ~PD_FLAGS_PARTNER_DR_DATA;
-#ifdef CONFIG_CHARGE_MANAGER
/*
* Treat device as a dedicated charger (meaning we should charge
- * from it) if it does not support power swap, or has unconstrained
- * power, or if we are a sink and the device identity matches a
- * charging allow-list.
+ * from it) if:
+ * - it does not support power swap, or
+ * - it is unconstrained power, or
+ * - it presents at least 27 W of available power
*/
- if (!(pd[port].flags & PD_FLAGS_PARTNER_DR_POWER) ||
- (pd[port].flags & PD_FLAGS_PARTNER_UNCONSTR) ||
- charge_allowlisted)
- charge_manager_update_dualrole(port, CAP_DEDICATED);
- else
- charge_manager_update_dualrole(port, CAP_DUALROLE);
-#endif
+ if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) {
+ uint32_t max_ma, max_mv, max_pdo, max_mw;
+
+ /*
+ * Get max power that the partner offers (not necessarily what
+ * this board will request)
+ */
+ pd_find_pdo_index(pdo_cnt, pdos, PD_REV3_MAX_VOLTAGE,
+ &max_pdo);
+ pd_extract_pdo_power(max_pdo, &max_ma, &max_mv);
+ max_mw = max_ma * max_mv / 1000;
+
+ if (!(pdos[0] & PDO_FIXED_DUAL_ROLE) ||
+ (pdos[0] & PDO_FIXED_UNCONSTRAINED) ||
+ max_mw >= PD_DRP_CHARGE_POWER_MIN)
+ charge_manager_update_dualrole(port, CAP_DEDICATED);
+ else
+ charge_manager_update_dualrole(port, CAP_DUALROLE);
+ }
}
static void handle_data_request(int port, uint32_t head,
@@ -1570,7 +1571,7 @@ static void handle_data_request(int port, uint32_t head,
pd[port].flags |= PD_FLAGS_PREVIOUS_PD_CONN;
/* src cap 0 should be fixed PDO */
- pd_update_pdo_flags(port, payload[0]);
+ pd_update_pdo_flags(port, cnt, payload);
pd_process_source_cap(port, cnt, payload);
@@ -1633,7 +1634,7 @@ static void handle_data_request(int port, uint32_t head,
case PD_DATA_SINK_CAP:
pd[port].flags |= PD_FLAGS_SNK_CAP_RECVD;
/* snk cap 0 should be fixed PDO */
- pd_update_pdo_flags(port, payload[0]);
+ pd_update_pdo_flags(port, cnt, payload);
if (pd[port].task_state == PD_STATE_SRC_GET_SINK_CAP)
set_state(port, PD_STATE_SRC_READY);
break;
diff --git a/include/usb_pd.h b/include/usb_pd.h
index f0997de7b0..071e61386c 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1625,17 +1625,6 @@ __override_proto void pd_check_dr_role(int port,
__override_proto void pd_try_execute_vconn_swap(int port, int flags);
/**
- * Check if we should charge from this device. This is
- * basically a allow-list for chargers that are dual-role,
- * don't set the unconstrained bit, but we should charge
- * from by default.
- *
- * @param vid Port partner Vendor ID
- * @param pid Port partner Product ID
- */
-int pd_charge_from_device(uint16_t vid, uint16_t pid);
-
-/**
* Execute data swap.
*
* @param port USB-C port number