summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Short <keithshort@chromium.org>2020-11-10 10:07:16 -0700
committerCommit Bot <commit-bot@chromium.org>2020-11-12 03:04:30 +0000
commitc91428f889dcf63a2ffd37d2eebbb7a6a356168f (patch)
tree9450eebfb4973a0bf7a31f82926daa3daa30b2ba
parent936df714ebd00e54cd1e9b23d57a8f93f0ae0871 (diff)
downloadchrome-ec-c91428f889dcf63a2ffd37d2eebbb7a6a356168f.tar.gz
tcpmv2: Don't trigger BC1.2 detect if role doesn't change
Don't trigger BC12 client detect or BC1.2 host mode if the data role hasn't changed. This fixes issues seen with some CDP hosts that drop VBUS if BC1.2 client detect is restarted. BUG=b:158708115 BRANCH=firmware-volteer-13521.B-master TEST=Connect laptop CDP to Volteer. CDP falls back to SDP but remains stable instead of looping on BC1.2 detect. TEST=Connect desktop CDP to Volteer, verify 7.5W charging. TEST=Connect DCP to Volteer, verify 7.5W charging. Signed-off-by: Keith Short <keithshort@chromium.org> Change-Id: Ifd0ee379a0d5894894d13fb1a64b4dec2e77ec9e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2529809 Reviewed-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--common/usbc/usb_tc_drp_acc_trysrc_sm.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
index caf421fb54..eb3f7dde60 100644
--- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c
+++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c
@@ -1108,18 +1108,27 @@ bool pd_is_disconnected(int port)
return !pd_is_connected(port);
}
-static __maybe_unused void bc12_role_change_handler(int port)
+static void bc12_role_change_handler(int port, enum pd_data_role prev_data_role,
+ enum pd_data_role data_role)
{
- int event;
+ int event = 0;
int task_id = USB_CHG_PORT_TO_TASK_ID(port);
+ bool role_changed = (data_role != prev_data_role);
+
+ if (!IS_ENABLED(CONFIG_BC12_DETECT_DATA_ROLE_TRIGGER))
+ return;
/* Get the data role of our device */
- switch (pd_get_data_role(port)) {
+ switch (data_role) {
case PD_ROLE_UFP:
- event = USB_CHG_EVENT_DR_UFP;
+ /* Only trigger BC12 detection on a role change */
+ if (role_changed)
+ event = USB_CHG_EVENT_DR_UFP;
break;
case PD_ROLE_DFP:
- event = USB_CHG_EVENT_DR_DFP;
+ /* Only trigger BC12 host mode on a role change */
+ if (role_changed)
+ event = USB_CHG_EVENT_DR_DFP;
break;
case PD_ROLE_DISCONNECTED:
event = USB_CHG_EVENT_CC_OPEN;
@@ -1127,7 +1136,9 @@ static __maybe_unused void bc12_role_change_handler(int port)
default:
return;
}
- task_set_event(task_id, event, 0);
+
+ if (event)
+ task_set_event(task_id, event, 0);
}
/*
@@ -1563,6 +1574,9 @@ void tc_event_check(int port, int evt)
void tc_set_data_role(int port, enum pd_data_role role)
{
+ enum pd_data_role prev_data_role;
+
+ prev_data_role = tc[port].data_role;
tc[port].data_role = role;
if (IS_ENABLED(CONFIG_USBC_SS_MUX))
@@ -1579,8 +1593,7 @@ void tc_set_data_role(int port, enum pd_data_role role)
* instead of VBUS changes, need to set an event to wake up the USB_CHG
* task and indicate the current data role.
*/
- if (IS_ENABLED(CONFIG_BC12_DETECT_DATA_ROLE_TRIGGER))
- bc12_role_change_handler(port);
+ bc12_role_change_handler(port, prev_data_role, tc[port].data_role);
/* Notify TCPC of role update */
tcpm_set_msg_header(port, tc[port].power_role, tc[port].data_role);
@@ -1967,6 +1980,8 @@ static void tc_error_recovery_run(const int port)
*/
static void tc_unattached_snk_entry(const int port)
{
+ enum pd_data_role prev_data_role;
+
if (get_last_state_tc(port) != TC_UNATTACHED_SRC) {
tc_detached(port);
print_current_state(port);
@@ -1984,14 +1999,14 @@ static void tc_unattached_snk_entry(const int port)
typec_select_pull(port, TYPEC_CC_RD);
typec_update_cc(port);
+ prev_data_role = tc[port].data_role;
tc[port].data_role = PD_ROLE_DISCONNECTED;
/*
* When data role set events are used to enable BC1.2, then CC
* detach events are used to notify BC1.2 that it can be powered
* down.
*/
- if (IS_ENABLED(CONFIG_BC12_DETECT_DATA_ROLE_TRIGGER))
- bc12_role_change_handler(port);
+ bc12_role_change_handler(port, prev_data_role, tc[port].data_role);
if (IS_ENABLED(CONFIG_CHARGE_MANAGER))
charge_manager_update_dualrole(port, CAP_UNKNOWN);
@@ -2469,6 +2484,8 @@ static void tc_attached_snk_exit(const int port)
*/
static void tc_unattached_src_entry(const int port)
{
+ enum pd_data_role prev_data_role;
+
if (get_last_state_tc(port) != TC_UNATTACHED_SNK) {
tc_detached(port);
print_current_state(port);
@@ -2487,6 +2504,7 @@ static void tc_unattached_src_entry(const int port)
typec_select_src_current_limit_rp(port, CONFIG_USB_PD_PULLUP);
typec_update_cc(port);
+ prev_data_role = tc[port].data_role;
tc[port].data_role = PD_ROLE_DISCONNECTED;
/*
@@ -2494,8 +2512,7 @@ static void tc_unattached_src_entry(const int port)
* detach events are used to notify BC1.2 that it can be powered
* down.
*/
- if (IS_ENABLED(CONFIG_BC12_DETECT_DATA_ROLE_TRIGGER))
- bc12_role_change_handler(port);
+ bc12_role_change_handler(port, prev_data_role, tc[port].data_role);
if (IS_ENABLED(CONFIG_USBC_PPC)) {
/* There is no sink connected. */