Commit 8db73e6a authored by Michal Grzeschik's avatar Michal Grzeschik Committed by Greg Kroah-Hartman
Browse files

usb: typec: tcpm: allow sink (ufp) to toggle into accessory mode debug



This patch extends the is_debug macro to cover the sink case (ufp). It
also handles the transition to access the DEBUG_ACC_ATTACHED state in
the sink case. It also handles the debounce case in which the cc
pins are not immediately valid after the plug event.

Signed-off-by: default avatarMichael Grzeschik <m.grzeschik@pengutronix.de>
Reviewed-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20250404-ml-topic-tcpm-v1-2-b99f44badce8@pengutronix.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 64843d0b
Loading
Loading
Loading
Loading
+29 −5
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@
						\
	S(ACC_UNATTACHED),			\
	S(DEBUG_ACC_ATTACHED),			\
	S(DEBUG_ACC_DEBOUNCE),			\
	S(AUDIO_ACC_ATTACHED),			\
	S(AUDIO_ACC_DEBOUNCE),			\
						\
@@ -621,7 +622,8 @@ static const char * const pd_rev[] = {
	  !tcpm_cc_is_source((port)->cc1)))

#define tcpm_port_is_debug(port) \
	(tcpm_cc_is_source((port)->cc1) && tcpm_cc_is_source((port)->cc2))
	((tcpm_cc_is_source((port)->cc1) && tcpm_cc_is_source((port)->cc2)) || \
	 (tcpm_cc_is_sink((port)->cc1) && tcpm_cc_is_sink((port)->cc2)))

#define tcpm_port_is_audio(port) \
	(tcpm_cc_is_audio((port)->cc1) && tcpm_cc_is_audio((port)->cc2))
@@ -4969,7 +4971,13 @@ static void run_state_machine(struct tcpm_port *port)
			tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC);
		break;
	case SNK_ATTACH_WAIT:
		if ((port->cc1 == TYPEC_CC_OPEN &&
		if (tcpm_port_is_debug(port))
			tcpm_set_state(port, DEBUG_ACC_ATTACHED,
				       PD_T_CC_DEBOUNCE);
		else if (tcpm_port_is_audio(port))
			tcpm_set_state(port, AUDIO_ACC_ATTACHED,
				       PD_T_CC_DEBOUNCE);
		else if ((port->cc1 == TYPEC_CC_OPEN &&
		     port->cc2 != TYPEC_CC_OPEN) ||
		    (port->cc1 != TYPEC_CC_OPEN &&
		     port->cc2 == TYPEC_CC_OPEN))
@@ -4983,6 +4991,12 @@ static void run_state_machine(struct tcpm_port *port)
		if (tcpm_port_is_disconnected(port))
			tcpm_set_state(port, SNK_UNATTACHED,
				       PD_T_PD_DEBOUNCE);
		else if (tcpm_port_is_debug(port))
			tcpm_set_state(port, DEBUG_ACC_ATTACHED,
				       PD_T_CC_DEBOUNCE);
		else if (tcpm_port_is_audio(port))
			tcpm_set_state(port, AUDIO_ACC_ATTACHED,
				       PD_T_CC_DEBOUNCE);
		else if (port->vbus_present)
			tcpm_set_state(port,
				       tcpm_try_src(port) ? SRC_TRY
@@ -5281,7 +5295,10 @@ static void run_state_machine(struct tcpm_port *port)
	/* Accessory states */
	case ACC_UNATTACHED:
		tcpm_acc_detach(port);
		if (port->port_type == TYPEC_PORT_SRC)
			tcpm_set_state(port, SRC_UNATTACHED, 0);
		else
			tcpm_set_state(port, SNK_UNATTACHED, 0);
		break;
	case DEBUG_ACC_ATTACHED:
	case AUDIO_ACC_ATTACHED:
@@ -5289,6 +5306,7 @@ static void run_state_machine(struct tcpm_port *port)
		if (ret < 0)
			tcpm_set_state(port, ACC_UNATTACHED, 0);
		break;
	case DEBUG_ACC_DEBOUNCE:
	case AUDIO_ACC_DEBOUNCE:
		tcpm_set_state(port, ACC_UNATTACHED, port->timings.cc_debounce_time);
		break;
@@ -5880,7 +5898,8 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,
		}
		break;
	case SNK_UNATTACHED:
		if (tcpm_port_is_sink(port))
		if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) ||
		    tcpm_port_is_sink(port))
			tcpm_set_state(port, SNK_ATTACH_WAIT, 0);
		break;
	case SNK_ATTACH_WAIT:
@@ -5943,7 +5962,12 @@ static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1,

	case DEBUG_ACC_ATTACHED:
		if (cc1 == TYPEC_CC_OPEN || cc2 == TYPEC_CC_OPEN)
			tcpm_set_state(port, ACC_UNATTACHED, 0);
			tcpm_set_state(port, DEBUG_ACC_DEBOUNCE, 0);
		break;

	case DEBUG_ACC_DEBOUNCE:
		if (tcpm_port_is_debug(port))
			tcpm_set_state(port, DEBUG_ACC_ATTACHED, 0);
		break;

	case SNK_TRY: