diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index ca39f08c6b..fbb657cfa2 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1302,6 +1302,14 @@ static void pd_set_data_role(int port, int role) pd_update_roles(port); } +static void pd_set_power_role(int port, int role) +{ + pd[port].power_role = role; +#ifdef CONFIG_USB_PD_DUAL_ROLE + pd_update_saved_port_flags(port, PD_BBRMFLG_POWER_ROLE, role); +#endif /* defined(CONFIG_USB_PD_DUAL_ROLE) */ +} + static void pd_dr_swap(int port) { pd_set_data_role(port, !pd[port].data_role); @@ -1358,7 +1366,7 @@ static void handle_ctrl_request(int port, uint16_t head, } else if (pd[port].task_state == PD_STATE_SRC_SWAP_STANDBY) { /* reset message ID and swap roles */ pd[port].msg_id = 0; - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); pd_update_roles(port); set_state(port, PD_STATE_SNK_DISCOVERY); #ifdef CONFIG_USBC_VCONN_SWAP @@ -1840,7 +1848,7 @@ void pd_update_dual_role_config(int port) ((drp_state == PD_DRP_FORCE_SINK && !pd_ts_dts_plugged(port)) || (drp_state == PD_DRP_TOGGLE_OFF && pd[port].task_state == PD_STATE_SRC_DISCONNECTED))) { - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); set_state(port, PD_STATE_SNK_DISCONNECTED); tcpm_set_cc(port, TYPEC_CC_RD); /* Make sure we're not sourcing VBUS. */ @@ -1853,7 +1861,7 @@ void pd_update_dual_role_config(int port) */ if (pd[port].power_role == PD_ROLE_SINK && drp_state == PD_DRP_FORCE_SOURCE) { - pd[port].power_role = PD_ROLE_SOURCE; + pd_set_power_role(port, PD_ROLE_SOURCE); set_state(port, PD_STATE_SRC_DISCONNECTED); tcpm_set_cc(port, TYPEC_CC_RP); } @@ -2171,7 +2179,7 @@ void pd_task(void *u) #endif /* Initialize PD protocol state variables for each port. */ - pd[port].power_role = PD_ROLE_DEFAULT(port); + pd_set_power_role(port, PD_ROLE_DEFAULT(port)); pd[port].vdm_state = VDM_STATE_DONE; set_state(port, this_state); #ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT @@ -2272,7 +2280,7 @@ void pd_task(void *u) tcpm_set_rx_enable(port, 1); } else { /* Ensure state variables are at default */ - pd[port].power_role = PD_ROLE_DEFAULT(port); + pd_set_power_role(port, PD_ROLE_DEFAULT(port)); pd[port].vdm_state = VDM_STATE_DONE; set_state(port, PD_DEFAULT_STATE(port)); } @@ -2344,7 +2352,7 @@ void pd_task(void *u) drp_state != PD_DRP_FORCE_SOURCE && drp_state != PD_DRP_FREEZE && get_time().val >= next_role_swap)) { - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); set_state(port, PD_STATE_SNK_DISCONNECTED); tcpm_set_cc(port, TYPEC_CC_RD); next_role_swap = get_time().val + PD_T_DRP_SNK; @@ -2735,7 +2743,7 @@ void pd_task(void *u) } /* Switch to Rd and swap roles to sink */ tcpm_set_cc(port, TYPEC_CC_RD); - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); /* Wait for PS_RDY from new source */ set_state_timeout(port, get_time().val + @@ -2831,7 +2839,7 @@ void pd_task(void *u) if (drp_state == PD_DRP_TOGGLE_ON && get_time().val >= next_role_swap) { /* Swap roles to source */ - pd[port].power_role = PD_ROLE_SOURCE; + pd_set_power_role(port, PD_ROLE_SOURCE); set_state(port, PD_STATE_SRC_DISCONNECTED); tcpm_set_cc(port, TYPEC_CC_RP); next_role_swap = get_time().val + PD_T_DRP_SRC; @@ -2878,7 +2886,7 @@ void pd_task(void *u) pd[port].try_src_marker = get_time().val + PD_T_TRY_SRC; /* Swap roles to source */ - pd[port].power_role = PD_ROLE_SOURCE; + pd_set_power_role(port, PD_ROLE_SOURCE); tcpm_set_cc(port, TYPEC_CC_RP); timeout = 2*MSEC; set_state(port, PD_STATE_SRC_DISCONNECTED); @@ -3191,7 +3199,7 @@ void pd_task(void *u) snk_cap_count = PD_SNK_CAP_RETRIES+1; caps_count = 0; pd[port].msg_id = 0; - pd[port].power_role = PD_ROLE_SOURCE; + pd_set_power_role(port, PD_ROLE_SOURCE); pd_update_roles(port); set_state(port, PD_STATE_SRC_DISCOVERY); timeout = 10*MSEC; @@ -3407,11 +3415,11 @@ void pd_task(void *u) if (next_state == PD_STATE_SNK_DISCONNECTED) { tcpm_set_cc(port, TYPEC_CC_RD); - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); timeout = 2*MSEC; } else if (next_state == PD_STATE_SRC_DISCONNECTED) { tcpm_set_cc(port, TYPEC_CC_RP); - pd[port].power_role = PD_ROLE_SOURCE; + pd_set_power_role(port, PD_ROLE_SOURCE); timeout = 2*MSEC; } else { tcpm_set_drp_toggle(port, 1); @@ -3471,7 +3479,7 @@ void pd_task(void *u) */ if (pd_try_src_enable) { /* Swap roles to sink */ - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); tcpm_set_cc(port, TYPEC_CC_RD); /* Set timer for TryWait.SNK state */ pd[port].try_src_marker = get_time().val @@ -3730,7 +3738,7 @@ void pd_request_source_voltage(int port, int mv) /* Set flag to send new power request in pd_task */ pd[port].new_power_request = 1; } else { - pd[port].power_role = PD_ROLE_SINK; + pd_set_power_role(port, PD_ROLE_SINK); tcpm_set_cc(port, TYPEC_CC_RD); set_state(port, PD_STATE_SNK_DISCONNECTED); } @@ -3873,7 +3881,7 @@ static int command_pd(int argc, char **argv) set_state(port, PD_STATE_BIST_TX); task_wake(PD_PORT_TO_TASK_ID(port)); } else if (!strcasecmp(argv[2], "charger")) { - pd[port].power_role = PD_ROLE_SOURCE; + pd_set_power_role(port, PD_ROLE_SOURCE); tcpm_set_cc(port, TYPEC_CC_RP); set_state(port, PD_STATE_SRC_DISCONNECTED); task_wake(PD_PORT_TO_TASK_ID(port)); diff --git a/include/usb_pd.h b/include/usb_pd.h index 3d87edab9f..33a8c79121 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -736,6 +736,7 @@ enum pd_states { /* Per-port battery backed RAM flags */ #define PD_BBRMFLG_EXPLICIT_CONTRACT (1 << 0) +#define PD_BBRMFLG_POWER_ROLE (1 << 1) enum pd_cc_states { PD_CC_NONE,