mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-08 16:41:55 +00:00
pd: Add Try.SRC functionality to the pd_protocol state machine
1. Added new config option CONFIG_USB_PD_TRY_SRC
2. Added pd_try_source_enable global flag with console command
3. Added bit to pd.flags to indicate Try.SRC states are active
BUG=chrome-os-partner:39724
TEST=Manual samus to samus with the Try.SRC enabled on both and just
one samus. Tested Samus to Honeybuns and Samus to Zinger connections.
BRANCH=TOT
Change-Id: Ifa5d5d82e443f376e546aaf852ff24d92ef04d72
Signed-off-by: Scott Collyer <scollyer@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/282052
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Tested-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
4cd2b6c011
commit
e9cd229216
@@ -52,6 +52,7 @@
|
||||
#define CONFIG_USB_PD_COMM_ENABLED 0
|
||||
#define CONFIG_USB_PD_CUSTOM_VDM
|
||||
#define CONFIG_USB_PD_DUAL_ROLE
|
||||
#define CONFIG_USB_PD_TRY_SRC
|
||||
#define CONFIG_USB_PD_FLASH_ERASE_CHECK
|
||||
#define CONFIG_USB_PD_INTERNAL_COMP
|
||||
#define CONFIG_USB_PD_LOGGING
|
||||
|
||||
@@ -87,6 +87,9 @@ enum pd_dual_role_states drp_state = PD_DRP_TOGGLE_OFF;
|
||||
/* Last received source cap */
|
||||
static uint32_t pd_src_caps[CONFIG_USB_PD_PORT_COUNT][PDO_MAX_OBJECTS];
|
||||
static int pd_src_cap_cnt[CONFIG_USB_PD_PORT_COUNT];
|
||||
|
||||
/* Enable varible for Try.SRC states */
|
||||
static uint8_t pd_try_src_enable;
|
||||
#endif
|
||||
|
||||
static struct pd_protocol {
|
||||
@@ -127,6 +130,8 @@ static struct pd_protocol {
|
||||
int new_power_request;
|
||||
/* Store previously requested voltage request */
|
||||
int prev_request_mv;
|
||||
/* Time for Try.SRC states */
|
||||
uint64_t try_src_marker;
|
||||
#endif
|
||||
|
||||
/* PD state for Vendor Defined Messages */
|
||||
@@ -260,6 +265,9 @@ static inline void set_state(int port, enum pd_states next_state)
|
||||
typec_set_input_current_limit(port, 0, 0);
|
||||
charge_manager_set_ceil(port, CHARGE_CEIL_NONE);
|
||||
#endif
|
||||
#ifdef CONFIG_USBC_VCONN
|
||||
tcpm_set_vconn(port, 0);
|
||||
#endif
|
||||
#else /* CONFIG_USB_PD_DUAL_ROLE */
|
||||
if (next_state == PD_STATE_SRC_DISCONNECTED) {
|
||||
#endif
|
||||
@@ -274,9 +282,6 @@ static inline void set_state(int port, enum pd_states next_state)
|
||||
#ifdef CONFIG_USBC_SS_MUX
|
||||
usb_mux_set(port, TYPEC_MUX_NONE, USB_SWITCH_DISCONNECT,
|
||||
pd[port].polarity);
|
||||
#endif
|
||||
#ifdef CONFIG_USBC_VCONN
|
||||
tcpm_set_vconn(port, 0);
|
||||
#endif
|
||||
/* Disable TCPC RX */
|
||||
tcpm_set_rx_enable(port, 0);
|
||||
@@ -1166,6 +1171,18 @@ void pd_set_dual_role(enum pd_dual_role_states state)
|
||||
int i;
|
||||
drp_state = state;
|
||||
|
||||
#ifdef CONFIG_USB_PD_TRY_SRC
|
||||
pd_try_src_enable = (state == PD_DRP_TOGGLE_ON) ? 1 : 0;
|
||||
for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
|
||||
/*
|
||||
* Clear this flag to cover case where a TrySrc
|
||||
* mode went from enabled to disabled and trying_source
|
||||
* was active at that time.
|
||||
*/
|
||||
pd[i].flags &= ~PD_FLAGS_TRY_SRC;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < CONFIG_USB_PD_PORT_COUNT; i++) {
|
||||
/*
|
||||
* Change to sink if port is currently a source AND (new DRP
|
||||
@@ -1416,13 +1433,25 @@ void pd_task(void)
|
||||
PD_STATE_SRC_DISCONNECTED_DEBOUNCE);
|
||||
}
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/* Swap roles if time expired */
|
||||
else if (drp_state != PD_DRP_FORCE_SOURCE &&
|
||||
get_time().val >= next_role_swap) {
|
||||
/*
|
||||
* Try.SRC state is embedded here. Wait for SNK
|
||||
* detect, or if timer expires, transition to
|
||||
* SNK_DISCONNETED.
|
||||
*
|
||||
* If Try.SRC state is not active, then this block
|
||||
* handles the normal DRP toggle from SRC->SNK
|
||||
*/
|
||||
else if ((pd[port].flags & PD_FLAGS_TRY_SRC &&
|
||||
get_time().val >= pd[port].try_src_marker) ||
|
||||
(!(pd[port].flags & PD_FLAGS_TRY_SRC) &&
|
||||
drp_state != PD_DRP_FORCE_SOURCE &&
|
||||
get_time().val >= next_role_swap)) {
|
||||
pd[port].power_role = 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;
|
||||
pd[port].try_src_marker = get_time().val
|
||||
+ PD_T_TRY_WAIT;
|
||||
|
||||
/* Swap states quickly */
|
||||
timeout = 2*MSEC;
|
||||
@@ -1455,15 +1484,18 @@ void pd_task(void)
|
||||
timeout = 5*MSEC;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Debounce the cc state */
|
||||
if (new_cc_state != pd[port].cc_state) {
|
||||
pd[port].cc_debounce = get_time().val +
|
||||
PD_T_CC_DEBOUNCE;
|
||||
pd[port].cc_state = new_cc_state;
|
||||
break;
|
||||
} else if (get_time().val < pd[port].cc_debounce) {
|
||||
break;
|
||||
/* If in Try.SRC state, then don't need to debounce */
|
||||
if (!(pd[port].flags & PD_FLAGS_TRY_SRC)) {
|
||||
/* Debounce the cc state */
|
||||
if (new_cc_state != pd[port].cc_state) {
|
||||
pd[port].cc_debounce = get_time().val +
|
||||
PD_T_CC_DEBOUNCE;
|
||||
pd[port].cc_state = new_cc_state;
|
||||
break;
|
||||
} else if (get_time().val <
|
||||
pd[port].cc_debounce) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Debounce complete */
|
||||
@@ -1857,6 +1889,18 @@ void pd_task(void)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If Try.SRC is active and failed to detect a SNK,
|
||||
* then it transitions to TryWait.SNK. Need to prevent
|
||||
* normal dual role toggle until tDRPTryWait timer
|
||||
* expires.
|
||||
*/
|
||||
if (pd[port].flags & PD_FLAGS_TRY_SRC) {
|
||||
if (get_time().val > pd[port].try_src_marker)
|
||||
pd[port].flags &= ~PD_FLAGS_TRY_SRC;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no source detected, check for role toggle.
|
||||
* If VBUS is detected, and we are in the debug
|
||||
@@ -1892,6 +1936,24 @@ void pd_task(void)
|
||||
!pd_snk_is_vbus_provided(port))
|
||||
break;
|
||||
|
||||
if (pd_try_src_enable &&
|
||||
!(pd[port].flags & PD_FLAGS_TRY_SRC)) {
|
||||
/*
|
||||
* If TRY_SRC is enabled, but not active,
|
||||
* then force attempt to connect as source.
|
||||
*/
|
||||
pd[port].try_src_marker = get_time().val
|
||||
+ PD_T_TRY_SRC;
|
||||
/* Swap roles to source */
|
||||
pd[port].power_role = PD_ROLE_SOURCE;
|
||||
tcpm_set_cc(port, TYPEC_CC_RP);
|
||||
timeout = 2*MSEC;
|
||||
set_state(port, PD_STATE_SRC_DISCONNECTED);
|
||||
/* Set flag after the state change */
|
||||
pd[port].flags |= PD_FLAGS_TRY_SRC;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are attached */
|
||||
pd[port].polarity = (cc2 != TYPEC_CC_VOLT_OPEN);
|
||||
tcpm_set_polarity(port, pd[port].polarity);
|
||||
@@ -2376,6 +2438,26 @@ void pd_task(void)
|
||||
set_state(port, PD_STATE_SRC_DISCONNECTED);
|
||||
/* Debouncing */
|
||||
timeout = 10*MSEC;
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
/*
|
||||
* If Try.SRC is configured, then ATTACHED_SRC
|
||||
* needs to transition to TryWait.SNK. Change
|
||||
* power role to SNK and start state timer.
|
||||
*/
|
||||
if (pd_try_src_enable) {
|
||||
/* Swap roles to sink */
|
||||
pd[port].power_role = PD_ROLE_SINK;
|
||||
tcpm_set_cc(port, TYPEC_CC_RD);
|
||||
/* Set timer for TryWait.SNK state */
|
||||
pd[port].try_src_marker = get_time().val
|
||||
+ PD_T_TRY_WAIT;
|
||||
/* Advance to TryWait.SNK state */
|
||||
set_state(port,
|
||||
PD_STATE_SNK_DISCONNECTED);
|
||||
/* Mark state as TryWait.SNK */
|
||||
pd[port].flags |= PD_FLAGS_TRY_SRC;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_USB_PD_DUAL_ROLE
|
||||
@@ -2678,7 +2760,21 @@ static int command_pd(int argc, char **argv)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_CMD_PD_DEV_DUMP_INFO */
|
||||
#ifdef CONFIG_USB_PD_TRY_SRC
|
||||
else if (!strncasecmp(argv[1], "trysrc", 6)) {
|
||||
int enable;
|
||||
|
||||
if (argc < 3)
|
||||
return EC_ERROR_PARAM_COUNT;
|
||||
|
||||
enable = strtoi(argv[2], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM3;
|
||||
pd_try_src_enable = enable ? 1 : 0;
|
||||
ccprintf("Try.SRC %s\n", enable ? "on" : "off");
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* command: pd <port> <subcmd> [args] */
|
||||
port = strtoi(argv[1], &e, 10);
|
||||
@@ -2800,7 +2896,8 @@ static int command_pd(int argc, char **argv)
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
DECLARE_CONSOLE_COMMAND(pd, command_pd,
|
||||
"dualrole|dump|enable [0|1]|rwhashtable|\n\t<port> "
|
||||
"dualrole|dump|enable [0|1]|rwhashtable"
|
||||
"trysrc [0|1]\n\t<port> "
|
||||
"[tx|bist_rx|bist_tx|charger|clock|dev"
|
||||
"|soft|hash|hard|ping|state|swap [power|data]|"
|
||||
"vdm [ping | curr | vers]]",
|
||||
|
||||
@@ -1535,6 +1535,9 @@
|
||||
/* Define the type-c port controller I2C base address. */
|
||||
#undef CONFIG_TCPC_I2C_BASE_ADDR
|
||||
|
||||
/* Use this option to enable Try.SRC mode for Dual Role devices */
|
||||
#undef CONFIG_USB_PD_TRY_SRC
|
||||
|
||||
/* Alternative configuration keeping only the TX part of PHY */
|
||||
#undef CONFIG_USB_PD_TX_PHY_ONLY
|
||||
|
||||
|
||||
@@ -160,6 +160,8 @@ enum pd_rx_errors {
|
||||
#define PD_T_BIST_TRANSMIT (50*MSEC) /* 50ms (used for task_wait arg) */
|
||||
#define PD_T_BIST_RECEIVE (60*MSEC) /* 60ms (max time to process bist) */
|
||||
#define PD_T_VCONN_SOURCE_ON (100*MSEC) /* 100ms */
|
||||
#define PD_T_TRY_SRC (125*MSEC) /* Max time for Try.SRC state */
|
||||
#define PD_T_TRY_WAIT (600*MSEC) /* Max time for TryWait.SNK state */
|
||||
|
||||
/* number of edges and time window to detect CC line is not idle */
|
||||
#define PD_RX_TRANSITION_COUNT 3
|
||||
@@ -699,6 +701,7 @@ enum pd_states {
|
||||
#define PD_FLAGS_CHECK_DR_ROLE (1 << 10)/* check data role in READY */
|
||||
#define PD_FLAGS_PARTNER_EXTPOWER (1 << 11)/* port partner has external pwr */
|
||||
#define PD_FLAGS_VCONN_ON (1 << 12)/* vconn is being sourced */
|
||||
#define PD_FLAGS_TRY_SRC (1 << 13)/* Try.SRC states are active */
|
||||
/* Flags to clear on a disconnect */
|
||||
#define PD_FLAGS_RESET_ON_DISCONNECT_MASK (PD_FLAGS_PARTNER_DR_POWER | \
|
||||
PD_FLAGS_PARTNER_DR_DATA | \
|
||||
@@ -710,7 +713,8 @@ enum pd_states {
|
||||
PD_FLAGS_CHECK_PR_ROLE | \
|
||||
PD_FLAGS_CHECK_DR_ROLE | \
|
||||
PD_FLAGS_PARTNER_EXTPOWER | \
|
||||
PD_FLAGS_VCONN_ON)
|
||||
PD_FLAGS_VCONN_ON | \
|
||||
PD_FLAGS_TRY_SRC)
|
||||
|
||||
|
||||
enum pd_cc_states {
|
||||
|
||||
Reference in New Issue
Block a user