diff options
-rw-r--r-- | common/usb_pd_dual_role.c | 45 | ||||
-rw-r--r-- | common/usb_pd_policy.c | 6 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 61 | ||||
-rw-r--r-- | include/usb_pd.h | 11 |
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 |