Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Amit Sunil Dhamne <amitsd@google.com>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
Link: https://lore.kernel.org/r/20241210-get_rev_upstream-v2-3-d0094e52d48f@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Amit Sunil Dhamne and committed by
Greg Kroah-Hartman
8cda395b 8ecf60c3

+60 -3
+40 -1
drivers/usb/typec/tcpm/tcpm.c
··· 185 185 S(UNSTRUCTURED_VDMS), \ 186 186 S(STRUCTURED_VDMS), \ 187 187 S(COUNTRY_INFO), \ 188 - S(COUNTRY_CODES) 188 + S(COUNTRY_CODES), \ 189 + S(REVISION_INFORMATION) 189 190 190 191 #define GENERATE_ENUM(e) e 191 192 #define GENERATE_STRING(s) #s ··· 226 225 PD_MSG_CTRL_NOT_SUPP, 227 226 PD_MSG_DATA_SINK_CAP, 228 227 PD_MSG_DATA_SOURCE_CAP, 228 + PD_MSG_DATA_REV, 229 229 }; 230 230 231 231 enum adev_actions { ··· 1244 1242 default: 1245 1243 return 0; 1246 1244 } 1245 + } 1246 + 1247 + static int tcpm_pd_send_revision(struct tcpm_port *port) 1248 + { 1249 + struct pd_message msg; 1250 + u32 rmdo; 1251 + 1252 + memset(&msg, 0, sizeof(msg)); 1253 + rmdo = RMDO(port->pd_rev.rev_major, port->pd_rev.rev_minor, 1254 + port->pd_rev.ver_major, port->pd_rev.ver_minor); 1255 + msg.payload[0] = cpu_to_le32(rmdo); 1256 + msg.header = PD_HEADER_LE(PD_DATA_REVISION, 1257 + port->pwr_role, 1258 + port->data_role, 1259 + port->negotiated_rev, 1260 + port->message_id, 1261 + 1); 1262 + return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg); 1247 1263 } 1248 1264 1249 1265 static int tcpm_pd_send_source_caps(struct tcpm_port *port) ··· 3567 3547 PD_MSG_CTRL_NOT_SUPP, 3568 3548 NONE_AMS); 3569 3549 break; 3550 + case PD_CTRL_GET_REVISION: 3551 + if (port->negotiated_rev >= PD_REV30 && port->pd_rev.rev_major) 3552 + tcpm_pd_handle_msg(port, PD_MSG_DATA_REV, 3553 + REVISION_INFORMATION); 3554 + else 3555 + tcpm_pd_handle_msg(port, 3556 + port->negotiated_rev < PD_REV30 ? 3557 + PD_MSG_CTRL_REJECT : 3558 + PD_MSG_CTRL_NOT_SUPP, 3559 + NONE_AMS); 3560 + break; 3570 3561 default: 3571 3562 tcpm_pd_handle_msg(port, 3572 3563 port->negotiated_rev < PD_REV30 ? ··· 3821 3790 } else { 3822 3791 tcpm_ams_finish(port); 3823 3792 } 3793 + break; 3794 + case PD_MSG_DATA_REV: 3795 + ret = tcpm_pd_send_revision(port); 3796 + if (ret) 3797 + tcpm_log(port, 3798 + "Unable to send revision msg, ret=%d", 3799 + ret); 3800 + tcpm_ams_finish(port); 3824 3801 break; 3825 3802 default: 3826 3803 break;
+20 -2
include/linux/usb/pd.h
··· 33 33 PD_CTRL_FR_SWAP = 19, 34 34 PD_CTRL_GET_PPS_STATUS = 20, 35 35 PD_CTRL_GET_COUNTRY_CODES = 21, 36 - /* 22-31 Reserved */ 36 + /* 22-23 Reserved */ 37 + PD_CTRL_GET_REVISION = 24, 38 + /* 25-31 Reserved */ 37 39 }; 38 40 39 41 enum pd_data_msg_type { ··· 48 46 PD_DATA_ALERT = 6, 49 47 PD_DATA_GET_COUNTRY_INFO = 7, 50 48 PD_DATA_ENTER_USB = 8, 51 - /* 9-14 Reserved */ 49 + /* 9-11 Reserved */ 50 + PD_DATA_REVISION = 12, 51 + /* 13-14 Reserved */ 52 52 PD_DATA_VENDOR_DEF = 15, 53 53 /* 16-31 Reserved */ 54 54 }; ··· 456 452 #define EUDO_DP_SUPPORT BIT(15) 457 453 #define EUDO_TBT_SUPPORT BIT(14) 458 454 #define EUDO_HOST_PRESENT BIT(13) 455 + 456 + /* 457 + * Request Message Data Object (PD Revision 3.1+ only) 458 + * -------- 459 + * <31:28> :: Revision Major 460 + * <27:24> :: Revision Minor 461 + * <23:20> :: Version Major 462 + * <19:16> :: Version Minor 463 + * <15:0> :: Reserved, Shall be set to zero 464 + */ 465 + 466 + #define RMDO(rev_maj, rev_min, ver_maj, ver_min) \ 467 + (((rev_maj) & 0xf) << 28 | ((rev_min) & 0xf) << 24 | \ 468 + ((ver_maj) & 0xf) << 20 | ((ver_min) & 0xf) << 16) 459 469 460 470 /* USB PD timers and counters */ 461 471 #define PD_T_NO_RESPONSE 5000 /* 4.5 - 5.5 seconds */