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 <bad...@google.com>
Reviewed-by: Guenter Roeck <li...@roeck-us.net>
---
Changelog since previous version:
- Only one previous version of the patch was sent.
  Numbering this V3 instead of V2 to keep the sequence
  number in sync with the rest of the patches in the
  patch list.
- added Reviewed-by: Guenter Roeck <li...@roeck-us.net>
- fixed version/sequence numbers

 drivers/staging/typec/pd.h   |  2 ++
 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 1f6827f32b29..a7da609006f5 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),                     \
@@ -1395,7 +1397,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:
@@ -2679,11 +2681,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
@@ -2709,6 +2717,15 @@ static void run_state_machine(struct tcpm_port *port)
        case PR_SWAP_SNK_SRC_SOURCE_ON:
                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,
@@ -2979,8 +2996,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;
-- 
2.14.1.342.g6490525c54-goog

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to