summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Hurst <shurst@google.com>2021-03-08 13:54:51 -0800
committerCommit Bot <commit-bot@chromium.org>2021-03-19 17:39:44 +0000
commit8ce9fc9e2b3070dc63f9bcabe9eeb78db8bf1b0b (patch)
tree9f30db99c8959d51c66cc27887563a7acbd18ace
parent7bc2599f6c803e6248b793d11300e2262e0908ed (diff)
downloadchrome-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.c79
-rw-r--r--common/usbc/usb_pe_drp_sm.c19
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c16
-rw-r--r--include/usb_pd.h70
-rw-r--r--include/usb_pd_vdo.h19
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));