diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 90d2d265690b..afeb93b2df85 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -2629,6 +2629,11 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, } else { next_state = SNK_WAIT_CAPABILITIES; } + + /* Threshold was relaxed before sending Request. Restore it back. */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); tcpm_set_state(port, next_state, 0); break; case SNK_NEGOTIATE_PPS_CAPABILITIES: @@ -2642,6 +2647,11 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, port->send_discover) port->vdm_sm_running = true; + /* Threshold was relaxed before sending Request. Restore it back. */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); + tcpm_set_state(port, SNK_READY, 0); break; case DR_SWAP_SEND: @@ -3361,6 +3371,12 @@ static int tcpm_pd_send_request(struct tcpm_port *port) if (ret < 0) return ret; + /* + * Relax the threshold as voltage will be adjusted after Accept Message plus tSrcTransition. + * It is safer to modify the threshold here. + */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0); + memset(&msg, 0, sizeof(msg)); msg.header = PD_HEADER_LE(PD_DATA_REQUEST, port->pwr_role, @@ -3458,6 +3474,9 @@ static int tcpm_pd_send_pps_request(struct tcpm_port *port) if (ret < 0) return ret; + /* Relax the threshold as voltage will be adjusted right after Accept Message. */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0); + memset(&msg, 0, sizeof(msg)); msg.header = PD_HEADER_LE(PD_DATA_REQUEST, port->pwr_role, @@ -4285,6 +4304,10 @@ static void run_state_machine(struct tcpm_port *port) port->hard_reset_count = 0; ret = tcpm_pd_send_request(port); if (ret < 0) { + /* Restore back to the original state */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); /* Let the Source send capabilities again. */ tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); } else { @@ -4295,6 +4318,10 @@ static void run_state_machine(struct tcpm_port *port) case SNK_NEGOTIATE_PPS_CAPABILITIES: ret = tcpm_pd_send_pps_request(port); if (ret < 0) { + /* Restore back to the original state */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); port->pps_status = ret; /* * If this was called due to updates to sink