diff options
author | Badhri Jagan Sridharan <badhri@google.com> | 2017-08-28 10:23:20 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-08-29 08:21:10 +0200 |
commit | b965b6317ff147d379c7a60c852f6027a724634f (patch) | |
tree | 1fc98ad3c3438c8e8dcb82075506d3fc2adb1014 | |
parent | f3b73364a1f2ac1a54f58c2387e6593b3d49c965 (diff) |
staging: typec: tcpm: typec: tcpm: Wait for CC debounce before PD excg
Once, Rp or Rd is switched, wait for PD_T_CC_DEBOUNCE. If not the
PS_RDY message transmitted might result in failure.
Also, Only wait for PD_T_SRCSWAPSTDBY while in
PR_SWAP_SRC_SNK_TRANSITION_OFF. PD_T_PS_SOURCE_OFF is the overall
time after which the initial sink would issue hard reset.
Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/typec/pd.h | 2 | ||||
-rw-r--r-- | drivers/staging/typec/tcpm.c | 25 |
2 files changed, 24 insertions, 3 deletions
diff --git a/drivers/staging/typec/pd.h b/drivers/staging/typec/pd.h index 510ef7279900..30b32ad72acd 100644 --- a/drivers/staging/typec/pd.h +++ b/drivers/staging/typec/pd.h @@ -278,6 +278,8 @@ static inline unsigned int rdo_max_power(u32 rdo) #define PD_T_VCONN_SOURCE_ON 100 #define PD_T_SINK_REQUEST 100 /* 100 ms minimum */ #define PD_T_ERROR_RECOVERY 100 /* minimum 25 is insufficient */ +#define PD_T_SRCSWAPSTDBY 625 /* Maximum of 650ms */ +#define PD_T_NEWSRC 250 /* Maximum of 275ms */ #define PD_T_DRP_TRY 100 /* 75 - 150 ms */ #define PD_T_DRP_TRYWAIT 600 /* 400 - 800 ms */ diff --git a/drivers/staging/typec/tcpm.c b/drivers/staging/typec/tcpm.c index fa2e59b5ab69..36a70989d3cd 100644 --- a/drivers/staging/typec/tcpm.c +++ b/drivers/staging/typec/tcpm.c @@ -90,9 +90,11 @@ S(PR_SWAP_START), \ S(PR_SWAP_SRC_SNK_TRANSITION_OFF), \ S(PR_SWAP_SRC_SNK_SOURCE_OFF), \ + S(PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED), \ S(PR_SWAP_SRC_SNK_SINK_ON), \ S(PR_SWAP_SNK_SRC_SINK_OFF), \ S(PR_SWAP_SNK_SRC_SOURCE_ON), \ + S(PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP), \ \ S(VCONN_SWAP_ACCEPT), \ S(VCONN_SWAP_SEND), \ @@ -1400,7 +1402,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, SNK_TRANSITION_SINK_VBUS, 0); } break; - case PR_SWAP_SRC_SNK_SOURCE_OFF: + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: tcpm_set_state(port, PR_SWAP_SRC_SNK_SINK_ON, 0); break; case PR_SWAP_SNK_SRC_SINK_OFF: @@ -2684,11 +2686,17 @@ static void run_state_machine(struct tcpm_port *port) case PR_SWAP_SRC_SNK_TRANSITION_OFF: tcpm_set_vbus(port, false); port->explicit_contract = false; + /* allow time for Vbus discharge, must be < tSrcSwapStdby */ tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, - PD_T_PS_SOURCE_OFF); + PD_T_SRCSWAPSTDBY); break; case PR_SWAP_SRC_SNK_SOURCE_OFF: tcpm_set_cc(port, TYPEC_CC_RD); + /* allow CC debounce */ + tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED, + PD_T_CC_DEBOUNCE); + break; + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: /* * USB-PD standard, 6.2.1.4, Port Power Role: * "During the Power Role Swap Sequence, for the initial Source @@ -2715,6 +2723,15 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_cc(port, tcpm_rp_cc(port)); tcpm_set_vbus(port, true); /* + * allow time VBUS ramp-up, must be < tNewSrc + * Also, this window overlaps with CC debounce as well. + * So, Wait for the max of two which is PD_T_NEWSRC + */ + tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP, + PD_T_NEWSRC); + break; + case PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP: + /* * USB PD standard, 6.2.1.4: * "Subsequent Messages initiated by the Policy Engine, * such as the PS_RDY Message sent to indicate that Vbus @@ -2984,8 +3001,10 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, case PR_SWAP_SNK_SRC_SINK_OFF: case PR_SWAP_SRC_SNK_TRANSITION_OFF: case PR_SWAP_SRC_SNK_SOURCE_OFF: + case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED: + case PR_SWAP_SNK_SRC_SOURCE_ON: /* - * CC state change is expected here; we just turned off power. + * CC state change is expected in PR_SWAP * Ignore it. */ break; |