Commit 8cda395b authored by Amit Sunil Dhamne's avatar Amit Sunil Dhamne Committed by Greg Kroah-Hartman
Browse files

usb: typec: tcpm: Add new AMS for Get_Revision response



This commit adds a new AMS for responding to a "Get_Revision" request.
Revision message consists of the following fields:

 +----------------------------------------------------+
 |         Header             |         RMDO          |
 |  No. of data objects = 1   |                       |
 +----------------------------------------------------+

 While RMDO consists of:
  * B31..28     Revision Major
  * B27..24     Revision Minor
  * B23..20     Version Major
  * B19..16     Version Minor
  * B15..0      Reserved, shall be set to zero.

As per the PD spec ("8.3.3.16.2.1 PR_Give_Revision State"), a request is
only expected when an explicit contract is established and the port is
in ready state. This AMS is only supported for PD >= 3.0.

Signed-off-by: default avatarAmit Sunil Dhamne <amitsd@google.com>
Reviewed-by: default avatarBadhri Jagan Sridharan <badhri@google.com>
Link: https://lore.kernel.org/r/20241210-get_rev_upstream-v2-3-d0094e52d48f@google.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8ecf60c3
Loading
Loading
Loading
Loading
+40 −1
Original line number Diff line number Diff line
@@ -185,7 +185,8 @@
	S(UNSTRUCTURED_VDMS),			\
	S(STRUCTURED_VDMS),			\
	S(COUNTRY_INFO),			\
	S(COUNTRY_CODES)
	S(COUNTRY_CODES),			\
	S(REVISION_INFORMATION)

#define GENERATE_ENUM(e)	e
#define GENERATE_STRING(s)	#s
@@ -225,6 +226,7 @@ enum pd_msg_request {
	PD_MSG_CTRL_NOT_SUPP,
	PD_MSG_DATA_SINK_CAP,
	PD_MSG_DATA_SOURCE_CAP,
	PD_MSG_DATA_REV,
};

enum adev_actions {
@@ -1244,6 +1246,24 @@ static u32 tcpm_forge_legacy_pdo(struct tcpm_port *port, u32 pdo, enum typec_rol
	}
}

static int tcpm_pd_send_revision(struct tcpm_port *port)
{
	struct pd_message msg;
	u32 rmdo;

	memset(&msg, 0, sizeof(msg));
	rmdo = RMDO(port->pd_rev.rev_major, port->pd_rev.rev_minor,
		    port->pd_rev.ver_major, port->pd_rev.ver_minor);
	msg.payload[0] = cpu_to_le32(rmdo);
	msg.header = PD_HEADER_LE(PD_DATA_REVISION,
				  port->pwr_role,
				  port->data_role,
				  port->negotiated_rev,
				  port->message_id,
				  1);
	return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
}

static int tcpm_pd_send_source_caps(struct tcpm_port *port)
{
	struct pd_message msg;
@@ -3547,6 +3567,17 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port,
				   PD_MSG_CTRL_NOT_SUPP,
				   NONE_AMS);
		break;
	case PD_CTRL_GET_REVISION:
		if (port->negotiated_rev >= PD_REV30 && port->pd_rev.rev_major)
			tcpm_pd_handle_msg(port, PD_MSG_DATA_REV,
					   REVISION_INFORMATION);
		else
			tcpm_pd_handle_msg(port,
					   port->negotiated_rev < PD_REV30 ?
					   PD_MSG_CTRL_REJECT :
					   PD_MSG_CTRL_NOT_SUPP,
					   NONE_AMS);
		break;
	default:
		tcpm_pd_handle_msg(port,
				   port->negotiated_rev < PD_REV30 ?
@@ -3791,6 +3822,14 @@ static bool tcpm_send_queued_message(struct tcpm_port *port)
				tcpm_ams_finish(port);
			}
			break;
		case PD_MSG_DATA_REV:
			ret = tcpm_pd_send_revision(port);
			if (ret)
				tcpm_log(port,
					 "Unable to send revision msg, ret=%d",
					 ret);
			tcpm_ams_finish(port);
			break;
		default:
			break;
		}
+20 −2
Original line number Diff line number Diff line
@@ -33,7 +33,9 @@ enum pd_ctrl_msg_type {
	PD_CTRL_FR_SWAP = 19,
	PD_CTRL_GET_PPS_STATUS = 20,
	PD_CTRL_GET_COUNTRY_CODES = 21,
	/* 22-31 Reserved */
	/* 22-23 Reserved */
	PD_CTRL_GET_REVISION = 24,
	/* 25-31 Reserved */
};

enum pd_data_msg_type {
@@ -46,7 +48,9 @@ enum pd_data_msg_type {
	PD_DATA_ALERT = 6,
	PD_DATA_GET_COUNTRY_INFO = 7,
	PD_DATA_ENTER_USB = 8,
	/* 9-14 Reserved */
	/* 9-11 Reserved */
	PD_DATA_REVISION = 12,
	/* 13-14 Reserved */
	PD_DATA_VENDOR_DEF = 15,
	/* 16-31 Reserved */
};
@@ -453,6 +457,20 @@ static inline unsigned int rdo_max_power(u32 rdo)
#define EUDO_TBT_SUPPORT		BIT(14)
#define EUDO_HOST_PRESENT		BIT(13)

/*
 * Request Message Data Object (PD Revision 3.1+ only)
 * --------
 * <31:28> :: Revision Major
 * <27:24> :: Revision Minor
 * <23:20> :: Version Major
 * <19:16> :: Version Minor
 * <15:0>  :: Reserved, Shall be set to zero
 */

#define RMDO(rev_maj, rev_min, ver_maj, ver_min)			\
	(((rev_maj) & 0xf) << 28 | ((rev_min) & 0xf) << 24 |		\
	 ((ver_maj) & 0xf) << 20 | ((ver_min) & 0xf) << 16)

/* USB PD timers and counters */
#define PD_T_NO_RESPONSE	5000	/* 4.5 - 5.5 seconds */
#define PD_T_DB_DETECT		10000	/* 10 - 15 seconds */