diff options
author | Sam Hurst <shurst@google.com> | 2021-03-08 13:54:51 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-19 17:39:44 +0000 |
commit | 8ce9fc9e2b3070dc63f9bcabe9eeb78db8bf1b0b (patch) | |
tree | 9f30db99c8959d51c66cc27887563a7acbd18ace | |
parent | 7bc2599f6c803e6248b793d11300e2262e0908ed (diff) | |
download | chrome-ec-8ce9fc9e2b3070dc63f9bcabe9eeb78db8bf1b0b.tar.gz |
TCPMV2: Add support for (CT) Vconn Powered Devices
Add support for Charge Through Vconn Powered Devices
BUG=b:165934405
BRANCH=none
TEST=make runtests
1) Verified that Apple VPD audio device worked.
2) With charger plugged into Chocodile_Vpdmcu,
verified that a Voxel could be charged.
3) FAILED: Plugging Chocodile_Vpdmcu into Voxel
first and then plugging in charger to
Chocodile_Vpdmcu, Chocodile is detected
as a Debug Accessory (CC1 = Rd and CC2 = Rd)
and VCONN is never applied.
Signed-off-by: Sam Hurst <shurst@google.com>
Change-Id: I977b316dc531aa33bb6a236523c8ddbbb23014d0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2748429
Reviewed-by: Diana Z <dzigterman@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2774583
Tested-by: Abe Levkoy <alevkoy@chromium.org>
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Commit-Queue: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r-- | common/usb_pd_alt_mode_dfp.c | 79 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 19 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 16 | ||||
-rw-r--r-- | include/usb_pd.h | 70 | ||||
-rw-r--r-- | include/usb_pd_vdo.h | 19 |
5 files changed, 196 insertions, 7 deletions
diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c index 4039b394c2..1c683145f1 100644 --- a/common/usb_pd_alt_mode_dfp.c +++ b/common/usb_pd_alt_mode_dfp.c @@ -684,6 +684,85 @@ static inline bool is_pd_rev3(int port, enum tcpm_transmit_type type) /* * ############################################################################ * + * (Charge Through) Vconn Powered Device functions + * + * ############################################################################ + */ +bool is_vpd_ct_supported(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.ct_support; +} + +uint8_t get_vpd_ct_gnd_impedance(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.gnd_impedance; +} + +uint8_t get_vpd_ct_vbus_impedance(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.vbus_impedance; +} + +uint8_t get_vpd_ct_current_support(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.ct_current_support; +} + +uint8_t get_vpd_ct_max_vbus_voltage(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.max_vbus_voltage; +} + +uint8_t get_vpd_ct_vdo_version(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.vdo_version; +} + +uint8_t get_vpd_ct_firmware_verion(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.firmware_version; +} + +uint8_t get_vpd_ct_hw_version(int port) +{ + struct pd_discovery *disc = + pd_get_am_discovery(port, TCPC_TX_SOP_PRIME); + union vpd_vdo vpd = disc->identity.product_t1.vpd; + + return vpd.hw_version; +} + +/* + * ############################################################################ + * * Cable communication functions * * ############################################################################ diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 85caf0473c..e539558ec3 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -1683,12 +1683,26 @@ static void send_source_cap(int port) */ static void pe_send_request_msg(int port) { + uint32_t vpd_vdo = 0; uint32_t rdo; uint32_t curr_limit; uint32_t supply_voltage; + /* + * If we are charging through a VPD, the requested voltage and current + * might need adjusting. + */ + if ((get_usb_pd_cable_type(port) == IDH_PTYPE_VPD) && + is_vpd_ct_supported(port)) { + union vpd_vdo vpd = pd_get_am_discovery(port, + TCPC_TX_SOP_PRIME)->identity.product_t1.vpd; + + /* The raw vpd_vdo is passed to pd_build_request */ + vpd_vdo = vpd.raw_value; + } + /* Build and send request RDO */ - pd_build_request(pe[port].vpd_vdo, &rdo, &curr_limit, + pd_build_request(vpd_vdo, &rdo, &curr_limit, &supply_voltage, port); CPRINTF("C%d: Req [%d] %dmV %dmA", port, RDO_POS(rdo), @@ -2704,7 +2718,8 @@ static void pe_src_disabled_entry(int port) { print_current_state(port); - if ((pe[port].vpd_vdo >= 0) && VPD_VDO_CTS(pe[port].vpd_vdo)) { + if ((get_usb_pd_cable_type(port) == IDH_PTYPE_VPD) && + is_vpd_ct_supported(port)) { /* * Inform the Device Policy Manager that a Charge-Through VCONN * Powered Device was detected. diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 981227f468..054d7f9f79 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -1131,7 +1131,8 @@ int pd_is_connected(int port) { return (IS_ATTACHED_SRC(port) || (IS_ENABLED(CONFIG_USB_PE_SM) && - (get_state_tc(port) == TC_CT_ATTACHED_SNK)) || + ((get_state_tc(port) == TC_CT_UNATTACHED_SNK) || + (get_state_tc(port) == TC_CT_ATTACHED_SNK))) || IS_ATTACHED_SNK(port)); } @@ -3151,7 +3152,6 @@ static void tc_attached_src_run(const int port) */ if (!TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER) && TC_CHK_FLAG(port, TC_FLAGS_CTVPD_DETECTED)) { - TC_CLR_FLAG(port, TC_FLAGS_CTVPD_DETECTED); /* Clear TC_FLAGS_DISC_IDENT_IN_PROGRESS */ TC_CLR_FLAG(port, TC_FLAGS_DISC_IDENT_IN_PROGRESS); @@ -3186,11 +3186,18 @@ static void tc_attached_src_exit(const int port) /* Attached.SRC exit - disable AutoDischargeDisconnect */ tcpm_enable_auto_discharge_disconnect(port, 0); - /* Disable VCONN if not power role swapping */ - if (TC_CHK_FLAG(port, TC_FLAGS_VCONN_ON)) + /* + * Disable VCONN if not power role swapping and + * a CTVPD was not detected + */ + if (TC_CHK_FLAG(port, TC_FLAGS_VCONN_ON) && + !TC_CHK_FLAG(port, TC_FLAGS_CTVPD_DETECTED)) set_vconn(port, 0); } + /* Clear CTVPD detected after checking for Vconn */ + TC_CLR_FLAG(port, TC_FLAGS_CTVPD_DETECTED); + /* Clear PR swap flag after checking for Vconn */ TC_CLR_FLAG(port, TC_FLAGS_REQUEST_PR_SWAP); @@ -3518,7 +3525,6 @@ __maybe_unused static void tc_ct_unattached_snk_entry(int port) * ground through Rd. */ typec_select_pull(port, TYPEC_CC_RD); - typec_select_src_current_limit_rp(port, CONFIG_USB_PD_PULLUP); typec_update_cc(port); tc[port].cc_state = PD_CC_UNSET; diff --git a/include/usb_pd.h b/include/usb_pd.h index ee76496235..c8f91fbed2 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -1808,6 +1808,76 @@ void dfp_consume_modes(int port, enum tcpm_transmit_type type, int cnt, uint32_t *payload); /** + * Returns true if connected VPD supports Charge Through + * + * @param port USB-C port number + * @return TRUE if Charge Through is supported, else FALSE + */ +bool is_vpd_ct_supported(int port); + +/** + * Returns CTVPD ground impedance + * + * @param port USB-C port number + * @return Ground impedance through the VPD in 1 mOhm increments, else + * 0 if Charge Through isn't supported + */ +uint8_t get_vpd_ct_gnd_impedance(int port); + +/** + * Returns CTVPD VBUS impedance + * + * @param port USB-C port number + * @return VBUS impedance through the VPD in 2 mOhm increments, else + * 0 if Charge Through isn't supported + */ +uint8_t get_vpd_ct_vbus_impedance(int port); + +/** + * Returns CTVPD Current support + * + * @param port USB-C port number + * @return 0 - 3A capable or + * 1 - 5A capable + */ +uint8_t get_vpd_ct_current_support(int port); + +/** + * Returns CTVPD Maximum VBUS Voltage + * + * @param port USB-C port number + * @return 0 - 20V + * 1 - 30V + * 2 - 40V + * 3 - 50V + */ +uint8_t get_vpd_ct_max_vbus_voltage(int port); + +/** + * Returns VPD VDO Version + * + * @param port USB-C port number + * @return 0 for Version 1.0 + */ +uint8_t get_vpd_ct_vdo_version(int port); + +/** + * Returns VPD Firmware Version + * + * @param port USB-C port number + * @return Firmware version assigned by the VID owner + */ +uint8_t get_vpd_ct_firmware_verion(int port); + +/** + * Returns HW Firmware Version + * + * @param port USB-C port number + * @return HW version assigned by the VID owner + */ +uint8_t get_vpd_ct_hw_version(int port); + +/** * Initialize alternate mode discovery info for DFP * * @param port USB-C port number diff --git a/include/usb_pd_vdo.h b/include/usb_pd_vdo.h index ac8e67b73e..b146fde179 100644 --- a/include/usb_pd_vdo.h +++ b/include/usb_pd_vdo.h @@ -965,6 +965,22 @@ union enter_usb_data_obj { uint32_t raw_value; }; +union vpd_vdo { + struct { + uint32_t ct_support : 1; + uint32_t gnd_impedance : 6; + uint32_t vbus_impedance : 6; + uint32_t reserved0 : 1; + uint32_t ct_current_support : 1; + uint32_t max_vbus_voltage : 2; + uint32_t reserved1 : 4; + uint32_t vdo_version : 3; + uint32_t firmware_version : 4; + uint32_t hw_version : 4; + }; + uint32_t raw_value; +}; + /* * ############################################################################ * @@ -982,6 +998,9 @@ union product_type_vdo1 { union active_cable_vdo_rev20 a_rev20; union active_cable_vdo1_rev30 a_rev30; + /* Vconn Power USB Device VDO */ + union vpd_vdo vpd; + uint32_t raw_value; }; BUILD_ASSERT(sizeof(uint32_t) == sizeof(union product_type_vdo1)); |