Re: [PATCH v5 1/3] usb: typec: tcpm: AMS and Collision Avoidance

2021-01-13 Thread Hans de Goede
Hi,

On 1/13/21 3:46 PM, Kyle Tso wrote:
> On Wed, Jan 13, 2021 at 2:11 PM Badhri Jagan Sridharan
>  wrote:
>>
>> Hi Kyle,
>>
>> Do you want to handle the FAST_ROLE_SWAP case as well ?
>>
> I forgot this part
> Thanks for catching this.
> I will fix it.

That sounds like a v6 is upcoming which not only will have
code-style changes but also some functional changes ?

In that case I will wait a bit before running the tests
which I want to run with this patch-set and run those
tests with v6 so that I don't have to redo them later.

Regards,

Hans



> 
> 
>> You would have to fix up in two places:
>>
>> #1
>> -   if (port->state == SNK_READY)
>> -   tcpm_set_state(port, FR_SWAP_SEND, 0);
>> -   else
>> +   if (port->state == SNK_READY) {
>> +   int ret;
>> +
>> +   port->upcoming_state = FR_SWAP_SEND;
>> +   ret = tcpm_ams_start(port, FAST_ROLE_SWAP);
>> +   if (ret == -EAGAIN)
>> +   port->upcoming_state = INVALID_STATE;
>> +   } else {
>> tcpm_log(port, "Discarding FRS_SIGNAL!
>> Not in sink ready");
>> +   }
>>
>> #2
>> --- a/drivers/usb/typec/tcpm/tcpm.c
>> +++ b/drivers/usb/typec/tcpm/tcpm.c
>> @@ -4449,9 +4449,14 @@ static void tcpm_enable_frs_work(struct
>> kthread_work *work)
>> if (port->state != SNK_READY || port->vdm_state !=
>> VDM_STATE_DONE || port->send_discover)
>> goto resched;
>>
>> -   tcpm_set_state(port, GET_SINK_CAP, 0);
>> -   port->sink_cap_done = true;
>> -
>> +   port->upcoming_state = GET_SINK_CAP;
>> +   ret = tcpm_ams_start(port, GET_SINK_CAPABILITIES);
>> +   if (ret == -EAGAIN) {
>> +   port->upcoming_state = INVALID_STATE;
>> +   } else {
>> +   port->sink_cap_done = true;
>> +   goto unlock;
>> +   }
>>
>> Thanks,
>> Badhri
>>
>>
> 



Re: [PATCH v5 1/3] usb: typec: tcpm: AMS and Collision Avoidance

2021-01-13 Thread Kyle Tso
On Wed, Jan 13, 2021 at 2:11 PM Badhri Jagan Sridharan
 wrote:
>
> Hi Kyle,
>
> Do you want to handle the FAST_ROLE_SWAP case as well ?
>
I forgot this part
Thanks for catching this.
I will fix it.


> You would have to fix up in two places:
>
> #1
> -   if (port->state == SNK_READY)
> -   tcpm_set_state(port, FR_SWAP_SEND, 0);
> -   else
> +   if (port->state == SNK_READY) {
> +   int ret;
> +
> +   port->upcoming_state = FR_SWAP_SEND;
> +   ret = tcpm_ams_start(port, FAST_ROLE_SWAP);
> +   if (ret == -EAGAIN)
> +   port->upcoming_state = INVALID_STATE;
> +   } else {
> tcpm_log(port, "Discarding FRS_SIGNAL!
> Not in sink ready");
> +   }
>
> #2
> --- a/drivers/usb/typec/tcpm/tcpm.c
> +++ b/drivers/usb/typec/tcpm/tcpm.c
> @@ -4449,9 +4449,14 @@ static void tcpm_enable_frs_work(struct
> kthread_work *work)
> if (port->state != SNK_READY || port->vdm_state !=
> VDM_STATE_DONE || port->send_discover)
> goto resched;
>
> -   tcpm_set_state(port, GET_SINK_CAP, 0);
> -   port->sink_cap_done = true;
> -
> +   port->upcoming_state = GET_SINK_CAP;
> +   ret = tcpm_ams_start(port, GET_SINK_CAPABILITIES);
> +   if (ret == -EAGAIN) {
> +   port->upcoming_state = INVALID_STATE;
> +   } else {
> +   port->sink_cap_done = true;
> +   goto unlock;
> +   }
>
> Thanks,
> Badhri
>
>


Re: [PATCH v5 1/3] usb: typec: tcpm: AMS and Collision Avoidance

2021-01-13 Thread Kyle Tso
On Tue, Jan 12, 2021 at 9:29 PM Heikki Krogerus
 wrote:
>
> On Wed, Jan 06, 2021 at 12:39:25AM +0800, Kyle Tso wrote:
> > This patch provides the implementation of Collision Avoidance introduced
> > in PD3.0. The start of each Atomic Message Sequence (AMS) initiated by
> > the port will be denied if the current AMS is not interruptible. The
> > Source port will set the CC to SinkTxNG if it is going to initiate an
> > AMS, and SinkTxOk otherwise. Meanwhile, any AMS initiated by a Sink port
> > will be denied in TCPM if the port partner (Source) sets SinkTxNG except
> > for HARD_RESET and SOFT_RESET.
> >
> > Signed-off-by: Kyle Tso 
> > Signed-off-by: Will McVicker 
>
> So did you and Will develop this patch together?
>
Not really.
Will cherry-picked the patch from our old branch to a later one which
is more close to Upstream.
And I cherry-picked his version so the signed-off is here.
I will remove the signed-off if that is the right move.

> Few nitpicks below.
>

> > +static void tcpm_set_cc(struct tcpm_port *port, enum typec_cc_status cc)
> > +{
> > + tcpm_log(port, "cc:=%d", cc);
> > + port->cc_req = cc;
> > + port->tcpc->set_cc(port->tcpc, cc);
> > +}
> > +
> > +static enum typec_cc_status tcpm_rp_cc(struct tcpm_port *port);
>
> I think you should move the function here instead of adding the
> prototype for it.
>
will fix this in the next patch version.


> > + case CMD_DISCOVER_MODES:
> > + res = tcpm_ams_start(port, DISCOVER_MODES);
> > + break;
> > + case CMD_ENTER_MODE:
> > + res = tcpm_ams_start(port,
> > +  DFP_TO_UFP_ENTER_MODE);
>
> One line is enough:
>
> res = tcpm_ams_start(port, 
> DFP_TO_UFP_ENTER_MODE);
>
will fix this in the next patch version.

> > + break;
> > + case CMD_EXIT_MODE:
> > + res = tcpm_ams_start(port,
> > +  DFP_TO_UFP_EXIT_MODE);
>
> Ditto.
>
will fix this in the next patch version.

> > + break;
> > + case CMD_ATTENTION:
> > + res = tcpm_ams_start(port, ATTENTION);
> > + break;
> > + case VDO_CMD_VENDOR(0) ... VDO_CMD_VENDOR(15):
> > + res = tcpm_ams_start(port, STRUCTURED_VDMS);
> > + break;
> > + default:
> > + res = -EOPNOTSUPP;
> > + break;
> > + }
> >
> > - port->vdm_retries = 0;
> > - port->vdm_state = VDM_STATE_BUSY;
> > - timeout = vdm_ready_timeout(port->vdo_data[0]);
> > - mod_vdm_delayed_work(port, timeout);
> > + if (res < 0)
> > + return;
> >   }
> > +
> > + port->vdm_state = VDM_STATE_SEND_MESSAGE;
> > + mod_vdm_delayed_work(port, (port->negotiated_rev >= PD_REV30) 
> > &&
> > +(port->pwr_role == TYPEC_SOURCE) &&
> > +(PD_VDO_SVDM(vdo_hdr)) &&
> > +(PD_VDO_CMDT(vdo_hdr) == 
> > CMDT_INIT) ?
> > +PD_T_SINK_TX : 0);
>
> I don't think you need all those brackets. This would look better, and
> I bet it would make also scripts/checkpatch.pl happy:
>
> mod_vdm_delayed_work(port, (port->negotiated_rev >= PD_REV30 
> &&
> port->pwr_role == TYPEC_SOURCE &&
> PD_VDO_SVDM(vdo_hdr) &&
> PD_VDO_CMDT(vdo_hdr) == 
> CMDT_INIT) ?
>PD_T_SINK_TX : 0);
>
will fix this in the next patch version.


> > + /*
> > +  * If previous AMS is interrupted, switch to the upcoming
> > +  * state.
> > +  */
> > + upcoming_state = port->upcoming_state;
> > + if (port->upcoming_state != INVALID_STATE) {
> > + port->upcoming_state = INVALID_STATE;
> > + tcpm_set_state(port, upcoming_state, 0);
> > + break;
> > + }
>
> I don't see the local upcoming_state variable is being used anywhere
> outside of these conditions, so please set it inside the condition
> block:
>
> if (port->upcoming_state != INVALID_STATE) {
> upcoming_state = port->upcoming_state;
> port->upcoming_state = INVALID_STATE;
> tcpm_set_state(port, upcoming_state, 0);
>   

Re: [PATCH v5 1/3] usb: typec: tcpm: AMS and Collision Avoidance

2021-01-12 Thread Badhri Jagan Sridharan
Hi Kyle,

Do you want to handle the FAST_ROLE_SWAP case as well ?

You would have to fix up in two places:

#1
-   if (port->state == SNK_READY)
-   tcpm_set_state(port, FR_SWAP_SEND, 0);
-   else
+   if (port->state == SNK_READY) {
+   int ret;
+
+   port->upcoming_state = FR_SWAP_SEND;
+   ret = tcpm_ams_start(port, FAST_ROLE_SWAP);
+   if (ret == -EAGAIN)
+   port->upcoming_state = INVALID_STATE;
+   } else {
tcpm_log(port, "Discarding FRS_SIGNAL!
Not in sink ready");
+   }

#2
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -4449,9 +4449,14 @@ static void tcpm_enable_frs_work(struct
kthread_work *work)
if (port->state != SNK_READY || port->vdm_state !=
VDM_STATE_DONE || port->send_discover)
goto resched;

-   tcpm_set_state(port, GET_SINK_CAP, 0);
-   port->sink_cap_done = true;
-
+   port->upcoming_state = GET_SINK_CAP;
+   ret = tcpm_ams_start(port, GET_SINK_CAPABILITIES);
+   if (ret == -EAGAIN) {
+   port->upcoming_state = INVALID_STATE;
+   } else {
+   port->sink_cap_done = true;
+   goto unlock;
+   }

Thanks,
Badhri


On Tue, Jan 12, 2021 at 5:29 AM Heikki Krogerus
 wrote:
>
> On Wed, Jan 06, 2021 at 12:39:25AM +0800, Kyle Tso wrote:
> > This patch provides the implementation of Collision Avoidance introduced
> > in PD3.0. The start of each Atomic Message Sequence (AMS) initiated by
> > the port will be denied if the current AMS is not interruptible. The
> > Source port will set the CC to SinkTxNG if it is going to initiate an
> > AMS, and SinkTxOk otherwise. Meanwhile, any AMS initiated by a Sink port
> > will be denied in TCPM if the port partner (Source) sets SinkTxNG except
> > for HARD_RESET and SOFT_RESET.
> >
> > Signed-off-by: Kyle Tso 
> > Signed-off-by: Will McVicker 
>
> So did you and Will develop this patch together?
>
> Few nitpicks below.
>
> > ---
> > Changelog since v4:
> >  - rebased to ToT
> >
> >  drivers/usb/typec/tcpm/tcpm.c | 533 ++
> >  include/linux/usb/pd.h|   1 +
> >  include/linux/usb/tcpm.h  |   4 +
> >  3 files changed, 479 insertions(+), 59 deletions(-)
> >
> > diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
> > index 22a85b396f69..9fb3ec176f42 100644
> > --- a/drivers/usb/typec/tcpm/tcpm.c
> > +++ b/drivers/usb/typec/tcpm/tcpm.c
> > @@ -76,6 +76,8 @@
> >   S(SNK_HARD_RESET_SINK_ON),  \
> >   \
> >   S(SOFT_RESET),  \
> > + S(SRC_SOFT_RESET_WAIT_SNK_TX),  \
> > + S(SNK_SOFT_RESET),  \
> >   S(SOFT_RESET_SEND), \
> >   \
> >   S(DR_SWAP_ACCEPT),  \
> > @@ -139,7 +141,45 @@
> >   \
> >   S(ERROR_RECOVERY),  \
> >   S(PORT_RESET),  \
> > - S(PORT_RESET_WAIT_OFF)
> > + S(PORT_RESET_WAIT_OFF), \
> > + \
> > + S(AMS_START)
> > +
> > +#define FOREACH_AMS(S)   \
> > + S(NONE_AMS),\
> > + S(POWER_NEGOTIATION),   \
> > + S(GOTOMIN), \
> > + S(SOFT_RESET_AMS),  \
> > + S(HARD_RESET),  \
> > + S(CABLE_RESET), \
> > + S(GET_SOURCE_CAPABILITIES), \
> > + S(GET_SINK_CAPABILITIES),   \
> > + S(POWER_ROLE_SWAP), \
> > + S(FAST_ROLE_SWAP),  \
> > + S(DATA_ROLE_SWAP),  \
> > + S(VCONN_SWAP),  \
> > + S(SOURCE_ALERT),\
> > + S(GETTING_SOURCE_EXTENDED_CAPABILITIES),\
> > + S(GETTING_SOURCE_SINK_STATUS),  \
> > + S(GETTING_BATTERY_CAPABILITIES),\
> > + S(GETTING_BATTERY_STATUS),  \
> > + S(GETTING_MANUFACTURER_INFORMATION),\
> > + S(SECURITY),\
> > + S(FIRMWARE_UPDATE), \
> > + S(DISCOVER_IDENTITY),   \
> > + S(SOURCE_STARTUP_CABLE_PLUG_DISCOVER_IDENTITY), \
> > + S(DISCOVER_SVIDS),  \
> > + S(DISCOVER_MODES),  \
> > + S(DFP_TO_UFP_ENTER_MODE),   \
> > + S(DFP_TO_UFP_EXIT_MODE),\
> > + S(DFP_TO_CABLE_PLUG_ENTER_MODE),\
> > + 

Re: [PATCH v5 1/3] usb: typec: tcpm: AMS and Collision Avoidance

2021-01-12 Thread Heikki Krogerus
On Wed, Jan 06, 2021 at 12:39:25AM +0800, Kyle Tso wrote:
> This patch provides the implementation of Collision Avoidance introduced
> in PD3.0. The start of each Atomic Message Sequence (AMS) initiated by
> the port will be denied if the current AMS is not interruptible. The
> Source port will set the CC to SinkTxNG if it is going to initiate an
> AMS, and SinkTxOk otherwise. Meanwhile, any AMS initiated by a Sink port
> will be denied in TCPM if the port partner (Source) sets SinkTxNG except
> for HARD_RESET and SOFT_RESET.
> 
> Signed-off-by: Kyle Tso 
> Signed-off-by: Will McVicker 

So did you and Will develop this patch together?

Few nitpicks below.

> ---
> Changelog since v4:
>  - rebased to ToT
> 
>  drivers/usb/typec/tcpm/tcpm.c | 533 ++
>  include/linux/usb/pd.h|   1 +
>  include/linux/usb/tcpm.h  |   4 +
>  3 files changed, 479 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
> index 22a85b396f69..9fb3ec176f42 100644
> --- a/drivers/usb/typec/tcpm/tcpm.c
> +++ b/drivers/usb/typec/tcpm/tcpm.c
> @@ -76,6 +76,8 @@
>   S(SNK_HARD_RESET_SINK_ON),  \
>   \
>   S(SOFT_RESET),  \
> + S(SRC_SOFT_RESET_WAIT_SNK_TX),  \
> + S(SNK_SOFT_RESET),  \
>   S(SOFT_RESET_SEND), \
>   \
>   S(DR_SWAP_ACCEPT),  \
> @@ -139,7 +141,45 @@
>   \
>   S(ERROR_RECOVERY),  \
>   S(PORT_RESET),  \
> - S(PORT_RESET_WAIT_OFF)
> + S(PORT_RESET_WAIT_OFF), \
> + \
> + S(AMS_START)
> +
> +#define FOREACH_AMS(S)   \
> + S(NONE_AMS),\
> + S(POWER_NEGOTIATION),   \
> + S(GOTOMIN), \
> + S(SOFT_RESET_AMS),  \
> + S(HARD_RESET),  \
> + S(CABLE_RESET), \
> + S(GET_SOURCE_CAPABILITIES), \
> + S(GET_SINK_CAPABILITIES),   \
> + S(POWER_ROLE_SWAP), \
> + S(FAST_ROLE_SWAP),  \
> + S(DATA_ROLE_SWAP),  \
> + S(VCONN_SWAP),  \
> + S(SOURCE_ALERT),\
> + S(GETTING_SOURCE_EXTENDED_CAPABILITIES),\
> + S(GETTING_SOURCE_SINK_STATUS),  \
> + S(GETTING_BATTERY_CAPABILITIES),\
> + S(GETTING_BATTERY_STATUS),  \
> + S(GETTING_MANUFACTURER_INFORMATION),\
> + S(SECURITY),\
> + S(FIRMWARE_UPDATE), \
> + S(DISCOVER_IDENTITY),   \
> + S(SOURCE_STARTUP_CABLE_PLUG_DISCOVER_IDENTITY), \
> + S(DISCOVER_SVIDS),  \
> + S(DISCOVER_MODES),  \
> + S(DFP_TO_UFP_ENTER_MODE),   \
> + S(DFP_TO_UFP_EXIT_MODE),\
> + S(DFP_TO_CABLE_PLUG_ENTER_MODE),\
> + S(DFP_TO_CABLE_PLUG_EXIT_MODE), \
> + S(ATTENTION),   \
> + S(BIST),\
> + S(UNSTRUCTURED_VDMS),   \
> + S(STRUCTURED_VDMS), \
> + S(COUNTRY_INFO),\
> + S(COUNTRY_CODES)
>  
>  #define GENERATE_ENUM(e) e
>  #define GENERATE_STRING(s)   #s
> @@ -152,6 +192,14 @@ static const char * const tcpm_states[] = {
>   FOREACH_STATE(GENERATE_STRING)
>  };
>  
> +enum tcpm_ams {
> + FOREACH_AMS(GENERATE_ENUM)
> +};
> +
> +static const char * const tcpm_ams_str[] = {
> + FOREACH_AMS(GENERATE_STRING)
> +};
> +
>  enum vdm_states {
>   VDM_STATE_ERR_BUSY = -3,
>   VDM_STATE_ERR_SEND = -2,
> @@ -161,6 +209,7 @@ enum vdm_states {
>   VDM_STATE_READY = 1,
>   VDM_STATE_BUSY = 2,
>   VDM_STATE_WAIT_RSP_BUSY = 3,
> + VDM_STATE_SEND_MESSAGE = 4,
>  };
>  
>  enum pd_msg_request {
> @@ -381,6 +430,11 @@ struct tcpm_port {
>   /* Sink caps have been queried */
>   bool sink_cap_done;
>  
> + /* Collision Avoidance and Atomic Message Sequence */
> + enum tcpm_state upcoming_state;
> + enum tcpm_ams ams;
> + bool in_ams;
> +
>  #ifdef CONFIG_DEBUG_FS
>   struct dentry *dentry;
>   struct mutex logbuffer_lock;/* log buffer access lock */
> @@ -396,6 +450,12 @@ struct pd_rx_event {
>   struct pd_message msg;
>  };
>  
> +static const char * const pd_rev[] = {
> + [PD_REV10]  = "rev1",
> + [PD_REV20]  = "rev2",
> + [PD_REV30]  = "rev3",
> +};
> +
>  #define tcpm_cc_is_sink(cc) \
>   ((cc) == TYPEC_CC_RP_DEF || (cc) == 

[PATCH v5 1/3] usb: typec: tcpm: AMS and Collision Avoidance

2021-01-05 Thread Kyle Tso
This patch provides the implementation of Collision Avoidance introduced
in PD3.0. The start of each Atomic Message Sequence (AMS) initiated by
the port will be denied if the current AMS is not interruptible. The
Source port will set the CC to SinkTxNG if it is going to initiate an
AMS, and SinkTxOk otherwise. Meanwhile, any AMS initiated by a Sink port
will be denied in TCPM if the port partner (Source) sets SinkTxNG except
for HARD_RESET and SOFT_RESET.

Signed-off-by: Kyle Tso 
Signed-off-by: Will McVicker 
---
Changelog since v4:
 - rebased to ToT

 drivers/usb/typec/tcpm/tcpm.c | 533 ++
 include/linux/usb/pd.h|   1 +
 include/linux/usb/tcpm.h  |   4 +
 3 files changed, 479 insertions(+), 59 deletions(-)

diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 22a85b396f69..9fb3ec176f42 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -76,6 +76,8 @@
S(SNK_HARD_RESET_SINK_ON),  \
\
S(SOFT_RESET),  \
+   S(SRC_SOFT_RESET_WAIT_SNK_TX),  \
+   S(SNK_SOFT_RESET),  \
S(SOFT_RESET_SEND), \
\
S(DR_SWAP_ACCEPT),  \
@@ -139,7 +141,45 @@
\
S(ERROR_RECOVERY),  \
S(PORT_RESET),  \
-   S(PORT_RESET_WAIT_OFF)
+   S(PORT_RESET_WAIT_OFF), \
+   \
+   S(AMS_START)
+
+#define FOREACH_AMS(S) \
+   S(NONE_AMS),\
+   S(POWER_NEGOTIATION),   \
+   S(GOTOMIN), \
+   S(SOFT_RESET_AMS),  \
+   S(HARD_RESET),  \
+   S(CABLE_RESET), \
+   S(GET_SOURCE_CAPABILITIES), \
+   S(GET_SINK_CAPABILITIES),   \
+   S(POWER_ROLE_SWAP), \
+   S(FAST_ROLE_SWAP),  \
+   S(DATA_ROLE_SWAP),  \
+   S(VCONN_SWAP),  \
+   S(SOURCE_ALERT),\
+   S(GETTING_SOURCE_EXTENDED_CAPABILITIES),\
+   S(GETTING_SOURCE_SINK_STATUS),  \
+   S(GETTING_BATTERY_CAPABILITIES),\
+   S(GETTING_BATTERY_STATUS),  \
+   S(GETTING_MANUFACTURER_INFORMATION),\
+   S(SECURITY),\
+   S(FIRMWARE_UPDATE), \
+   S(DISCOVER_IDENTITY),   \
+   S(SOURCE_STARTUP_CABLE_PLUG_DISCOVER_IDENTITY), \
+   S(DISCOVER_SVIDS),  \
+   S(DISCOVER_MODES),  \
+   S(DFP_TO_UFP_ENTER_MODE),   \
+   S(DFP_TO_UFP_EXIT_MODE),\
+   S(DFP_TO_CABLE_PLUG_ENTER_MODE),\
+   S(DFP_TO_CABLE_PLUG_EXIT_MODE), \
+   S(ATTENTION),   \
+   S(BIST),\
+   S(UNSTRUCTURED_VDMS),   \
+   S(STRUCTURED_VDMS), \
+   S(COUNTRY_INFO),\
+   S(COUNTRY_CODES)
 
 #define GENERATE_ENUM(e)   e
 #define GENERATE_STRING(s) #s
@@ -152,6 +192,14 @@ static const char * const tcpm_states[] = {
FOREACH_STATE(GENERATE_STRING)
 };
 
+enum tcpm_ams {
+   FOREACH_AMS(GENERATE_ENUM)
+};
+
+static const char * const tcpm_ams_str[] = {
+   FOREACH_AMS(GENERATE_STRING)
+};
+
 enum vdm_states {
VDM_STATE_ERR_BUSY = -3,
VDM_STATE_ERR_SEND = -2,
@@ -161,6 +209,7 @@ enum vdm_states {
VDM_STATE_READY = 1,
VDM_STATE_BUSY = 2,
VDM_STATE_WAIT_RSP_BUSY = 3,
+   VDM_STATE_SEND_MESSAGE = 4,
 };
 
 enum pd_msg_request {
@@ -381,6 +430,11 @@ struct tcpm_port {
/* Sink caps have been queried */
bool sink_cap_done;
 
+   /* Collision Avoidance and Atomic Message Sequence */
+   enum tcpm_state upcoming_state;
+   enum tcpm_ams ams;
+   bool in_ams;
+
 #ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
struct mutex logbuffer_lock;/* log buffer access lock */
@@ -396,6 +450,12 @@ struct pd_rx_event {
struct pd_message msg;
 };
 
+static const char * const pd_rev[] = {
+   [PD_REV10]  = "rev1",
+   [PD_REV20]  = "rev2",
+   [PD_REV30]  = "rev3",
+};
+
 #define tcpm_cc_is_sink(cc) \
((cc) == TYPEC_CC_RP_DEF || (cc) == TYPEC_CC_RP_1_5 || \
 (cc) == TYPEC_CC_RP_3_0)
@@ -440,6 +500,10 @@ struct pd_rx_event {
((port)->typec_caps.data == TYPEC_PORT_DFP ? \
TYPEC_HOST : TYPEC_DEVICE)
 
+#define tcpm_sink_tx_ok(port) \
+