@@ -1556,7 +1556,7 @@ static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
15561556}
15571557
15581558static void tcpm_queue_vdm_unlocked (struct tcpm_port * port , const u32 header ,
1559- const u32 * data , int cnt )
1559+ const u32 * data , int cnt , enum tcpm_transmit_type tx_sop_type )
15601560{
15611561 mutex_lock (& port -> lock );
15621562 tcpm_queue_vdm (port , header , data , cnt , TCPC_TX_SOP );
@@ -2144,14 +2144,28 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
21442144 }
21452145 break ;
21462146 case CMD_ENTER_MODE :
2147- if (adev && pdev )
2148- * adev_action = ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL ;
2147+ * response_tx_sop_type = rx_sop_type ;
2148+ if (rx_sop_type == TCPC_TX_SOP ) {
2149+ if (adev && pdev ) {
2150+ typec_altmode_update_active (pdev , true);
2151+ * adev_action = ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL ;
2152+ }
2153+ } else if (rx_sop_type == TCPC_TX_SOP_PRIME ) {
2154+ if (adev && pdev_prime ) {
2155+ typec_altmode_update_active (pdev_prime , true);
2156+ * adev_action = ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL ;
2157+ }
2158+ }
21492159 return 0 ;
21502160 case CMD_EXIT_MODE :
2151- if (adev && pdev ) {
2152- /* Back to USB Operation */
2153- * adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM ;
2154- return 0 ;
2161+ * response_tx_sop_type = rx_sop_type ;
2162+ if (rx_sop_type == TCPC_TX_SOP ) {
2163+ if (adev && pdev ) {
2164+ typec_altmode_update_active (pdev , false);
2165+ /* Back to USB Operation */
2166+ * adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM ;
2167+ return 0 ;
2168+ }
21552169 }
21562170 break ;
21572171 case VDO_CMD_VENDOR (0 ) ... VDO_CMD_VENDOR (15 ):
@@ -2284,19 +2298,37 @@ static void tcpm_handle_vdm_request(struct tcpm_port *port,
22842298 typec_altmode_vdm (adev , p [0 ], & p [1 ], cnt );
22852299 break ;
22862300 case ADEV_QUEUE_VDM :
2287- typec_altmode_vdm (adev , p [0 ], & p [1 ], cnt );
2301+ if (response_tx_sop_type == TCPC_TX_SOP_PRIME )
2302+ typec_cable_altmode_vdm (adev , TYPEC_PLUG_SOP_P , p [0 ], & p [1 ], cnt );
2303+ else
2304+ typec_altmode_vdm (adev , p [0 ], & p [1 ], cnt );
22882305 break ;
22892306 case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL :
2290- if (typec_altmode_vdm (adev , p [0 ], & p [1 ], cnt )) {
2291- int svdm_version = typec_get_negotiated_svdm_version (
2292- port -> typec_port );
2293- if (svdm_version < 0 )
2294- break ;
2307+ if (response_tx_sop_type == TCPC_TX_SOP_PRIME ) {
2308+ if (typec_cable_altmode_vdm (adev , TYPEC_PLUG_SOP_P ,
2309+ p [0 ], & p [1 ], cnt )) {
2310+ int svdm_version = typec_get_cable_svdm_version (
2311+ port -> typec_port );
2312+ if (svdm_version < 0 )
2313+ break ;
22952314
2296- response [0 ] = VDO (adev -> svid , 1 , svdm_version ,
2297- CMD_EXIT_MODE );
2298- response [0 ] |= VDO_OPOS (adev -> mode );
2299- rlen = 1 ;
2315+ response [0 ] = VDO (adev -> svid , 1 , svdm_version ,
2316+ CMD_EXIT_MODE );
2317+ response [0 ] |= VDO_OPOS (adev -> mode );
2318+ rlen = 1 ;
2319+ }
2320+ } else {
2321+ if (typec_altmode_vdm (adev , p [0 ], & p [1 ], cnt )) {
2322+ int svdm_version = typec_get_negotiated_svdm_version (
2323+ port -> typec_port );
2324+ if (svdm_version < 0 )
2325+ break ;
2326+
2327+ response [0 ] = VDO (adev -> svid , 1 , svdm_version ,
2328+ CMD_EXIT_MODE );
2329+ response [0 ] |= VDO_OPOS (adev -> mode );
2330+ rlen = 1 ;
2331+ }
23002332 }
23012333 break ;
23022334 case ADEV_ATTENTION :
@@ -2731,7 +2763,7 @@ static int tcpm_altmode_enter(struct typec_altmode *altmode, u32 *vdo)
27312763 header = VDO (altmode -> svid , vdo ? 2 : 1 , svdm_version , CMD_ENTER_MODE );
27322764 header |= VDO_OPOS (altmode -> mode );
27332765
2734- tcpm_queue_vdm_unlocked (port , header , vdo , vdo ? 1 : 0 );
2766+ tcpm_queue_vdm_unlocked (port , header , vdo , vdo ? 1 : 0 , TCPC_TX_SOP );
27352767 return 0 ;
27362768}
27372769
@@ -2748,7 +2780,7 @@ static int tcpm_altmode_exit(struct typec_altmode *altmode)
27482780 header = VDO (altmode -> svid , 1 , svdm_version , CMD_EXIT_MODE );
27492781 header |= VDO_OPOS (altmode -> mode );
27502782
2751- tcpm_queue_vdm_unlocked (port , header , NULL , 0 );
2783+ tcpm_queue_vdm_unlocked (port , header , NULL , 0 , TCPC_TX_SOP );
27522784 return 0 ;
27532785}
27542786
@@ -2757,7 +2789,7 @@ static int tcpm_altmode_vdm(struct typec_altmode *altmode,
27572789{
27582790 struct tcpm_port * port = typec_altmode_get_drvdata (altmode );
27592791
2760- tcpm_queue_vdm_unlocked (port , header , data , count - 1 );
2792+ tcpm_queue_vdm_unlocked (port , header , data , count - 1 , TCPC_TX_SOP );
27612793
27622794 return 0 ;
27632795}
@@ -2768,6 +2800,58 @@ static const struct typec_altmode_ops tcpm_altmode_ops = {
27682800 .vdm = tcpm_altmode_vdm ,
27692801};
27702802
2803+
2804+ static int tcpm_cable_altmode_enter (struct typec_altmode * altmode , enum typec_plug_index sop ,
2805+ u32 * vdo )
2806+ {
2807+ struct tcpm_port * port = typec_altmode_get_drvdata (altmode );
2808+ int svdm_version ;
2809+ u32 header ;
2810+
2811+ svdm_version = typec_get_cable_svdm_version (port -> typec_port );
2812+ if (svdm_version < 0 )
2813+ return svdm_version ;
2814+
2815+ header = VDO (altmode -> svid , vdo ? 2 : 1 , svdm_version , CMD_ENTER_MODE );
2816+ header |= VDO_OPOS (altmode -> mode );
2817+
2818+ tcpm_queue_vdm_unlocked (port , header , vdo , vdo ? 1 : 0 , TCPC_TX_SOP_PRIME );
2819+ return 0 ;
2820+ }
2821+
2822+ static int tcpm_cable_altmode_exit (struct typec_altmode * altmode , enum typec_plug_index sop )
2823+ {
2824+ struct tcpm_port * port = typec_altmode_get_drvdata (altmode );
2825+ int svdm_version ;
2826+ u32 header ;
2827+
2828+ svdm_version = typec_get_cable_svdm_version (port -> typec_port );
2829+ if (svdm_version < 0 )
2830+ return svdm_version ;
2831+
2832+ header = VDO (altmode -> svid , 1 , svdm_version , CMD_EXIT_MODE );
2833+ header |= VDO_OPOS (altmode -> mode );
2834+
2835+ tcpm_queue_vdm_unlocked (port , header , NULL , 0 , TCPC_TX_SOP_PRIME );
2836+ return 0 ;
2837+ }
2838+
2839+ static int tcpm_cable_altmode_vdm (struct typec_altmode * altmode , enum typec_plug_index sop ,
2840+ u32 header , const u32 * data , int count )
2841+ {
2842+ struct tcpm_port * port = typec_altmode_get_drvdata (altmode );
2843+
2844+ tcpm_queue_vdm_unlocked (port , header , data , count - 1 , TCPC_TX_SOP_PRIME );
2845+
2846+ return 0 ;
2847+ }
2848+
2849+ static const struct typec_cable_ops tcpm_cable_ops = {
2850+ .enter = tcpm_cable_altmode_enter ,
2851+ .exit = tcpm_cable_altmode_exit ,
2852+ .vdm = tcpm_cable_altmode_vdm ,
2853+ };
2854+
27712855/*
27722856 * PD (data, control) command handling functions
27732857 */
@@ -7507,6 +7591,8 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
75077591 typec_port_register_altmodes (port -> typec_port ,
75087592 & tcpm_altmode_ops , port ,
75097593 port -> port_altmode , ALTMODE_DISCOVERY_MAX );
7594+ typec_port_register_cable_ops (port -> port_altmode , ARRAY_SIZE (port -> port_altmode ),
7595+ & tcpm_cable_ops );
75107596 port -> registered = true;
75117597
75127598 mutex_lock (& port -> lock );
0 commit comments