Back to home page

OSCL-LXR

 
 

    


0001 .. _typec:
0002 
0003 USB Type-C connector class
0004 ==========================
0005 
0006 Introduction
0007 ------------
0008 
0009 The typec class is meant for describing the USB Type-C ports in a system to the
0010 user space in unified fashion. The class is designed to provide nothing else
0011 except the user space interface implementation in hope that it can be utilized
0012 on as many platforms as possible.
0013 
0014 The platforms are expected to register every USB Type-C port they have with the
0015 class. In a normal case the registration will be done by a USB Type-C or PD PHY
0016 driver, but it may be a driver for firmware interface such as UCSI, driver for
0017 USB PD controller or even driver for Thunderbolt3 controller. This document
0018 considers the component registering the USB Type-C ports with the class as "port
0019 driver".
0020 
0021 On top of showing the capabilities, the class also offer user space control over
0022 the roles and alternate modes of ports, partners and cable plugs when the port
0023 driver is capable of supporting those features.
0024 
0025 The class provides an API for the port drivers described in this document. The
0026 attributes are described in Documentation/ABI/testing/sysfs-class-typec.
0027 
0028 User space interface
0029 --------------------
0030 Every port will be presented as its own device under /sys/class/typec/. The
0031 first port will be named "port0", the second "port1" and so on.
0032 
0033 When connected, the partner will be presented also as its own device under
0034 /sys/class/typec/. The parent of the partner device will always be the port it
0035 is attached to. The partner attached to port "port0" will be named
0036 "port0-partner". Full path to the device would be
0037 /sys/class/typec/port0/port0-partner/.
0038 
0039 The cable and the two plugs on it may also be optionally presented as their own
0040 devices under /sys/class/typec/. The cable attached to the port "port0" port
0041 will be named port0-cable and the plug on the SOP Prime end (see USB Power
0042 Delivery Specification ch. 2.4) will be named "port0-plug0" and on the SOP
0043 Double Prime end "port0-plug1". The parent of a cable will always be the port,
0044 and the parent of the cable plugs will always be the cable.
0045 
0046 If the port, partner or cable plug supports Alternate Modes, every supported
0047 Alternate Mode SVID will have their own device describing them. Note that the
0048 Alternate Mode devices will not be attached to the typec class. The parent of an
0049 alternate mode will be the device that supports it, so for example an alternate
0050 mode of port0-partner will be presented under /sys/class/typec/port0-partner/.
0051 Every mode that is supported will have its own group under the Alternate Mode
0052 device named "mode<index>", for example /sys/class/typec/port0/<alternate
0053 mode>/mode1/. The requests for entering/exiting a mode can be done with "active"
0054 attribute file in that group.
0055 
0056 Driver API
0057 ----------
0058 
0059 Registering the ports
0060 ~~~~~~~~~~~~~~~~~~~~~
0061 
0062 The port drivers will describe every Type-C port they control with struct
0063 typec_capability data structure, and register them with the following API:
0064 
0065 .. kernel-doc:: drivers/usb/typec/class.c
0066    :functions: typec_register_port typec_unregister_port
0067 
0068 When registering the ports, the prefer_role member in struct typec_capability
0069 deserves special notice. If the port that is being registered does not have
0070 initial role preference, which means the port does not execute Try.SNK or
0071 Try.SRC by default, the member must have value TYPEC_NO_PREFERRED_ROLE.
0072 Otherwise if the port executes Try.SNK by default, the member must have value
0073 TYPEC_DEVICE, and with Try.SRC the value must be TYPEC_HOST.
0074 
0075 Registering Partners
0076 ~~~~~~~~~~~~~~~~~~~~
0077 
0078 After successful connection of a partner, the port driver needs to register the
0079 partner with the class. Details about the partner need to be described in struct
0080 typec_partner_desc. The class copies the details of the partner during
0081 registration. The class offers the following API for registering/unregistering
0082 partners.
0083 
0084 .. kernel-doc:: drivers/usb/typec/class.c
0085    :functions: typec_register_partner typec_unregister_partner
0086 
0087 The class will provide a handle to struct typec_partner if the registration was
0088 successful, or NULL.
0089 
0090 If the partner is USB Power Delivery capable, and the port driver is able to
0091 show the result of Discover Identity command, the partner descriptor structure
0092 should include handle to struct usb_pd_identity instance. The class will then
0093 create a sysfs directory for the identity under the partner device. The result
0094 of Discover Identity command can then be reported with the following API:
0095 
0096 .. kernel-doc:: drivers/usb/typec/class.c
0097    :functions: typec_partner_set_identity
0098 
0099 Registering Cables
0100 ~~~~~~~~~~~~~~~~~~
0101 
0102 After successful connection of a cable that supports USB Power Delivery
0103 Structured VDM "Discover Identity", the port driver needs to register the cable
0104 and one or two plugs, depending if there is CC Double Prime controller present
0105 in the cable or not. So a cable capable of SOP Prime communication, but not SOP
0106 Double Prime communication, should only have one plug registered. For more
0107 information about SOP communication, please read chapter about it from the
0108 latest USB Power Delivery specification.
0109 
0110 The plugs are represented as their own devices. The cable is registered first,
0111 followed by registration of the cable plugs. The cable will be the parent device
0112 for the plugs. Details about the cable need to be described in struct
0113 typec_cable_desc and about a plug in struct typec_plug_desc. The class copies
0114 the details during registration. The class offers the following API for
0115 registering/unregistering cables and their plugs:
0116 
0117 .. kernel-doc:: drivers/usb/typec/class.c
0118    :functions: typec_register_cable typec_unregister_cable typec_register_plug typec_unregister_plug
0119 
0120 The class will provide a handle to struct typec_cable and struct typec_plug if
0121 the registration is successful, or NULL if it isn't.
0122 
0123 If the cable is USB Power Delivery capable, and the port driver is able to show
0124 the result of Discover Identity command, the cable descriptor structure should
0125 include handle to struct usb_pd_identity instance. The class will then create a
0126 sysfs directory for the identity under the cable device. The result of Discover
0127 Identity command can then be reported with the following API:
0128 
0129 .. kernel-doc:: drivers/usb/typec/class.c
0130    :functions: typec_cable_set_identity
0131 
0132 Notifications
0133 ~~~~~~~~~~~~~
0134 
0135 When the partner has executed a role change, or when the default roles change
0136 during connection of a partner or cable, the port driver must use the following
0137 APIs to report it to the class:
0138 
0139 .. kernel-doc:: drivers/usb/typec/class.c
0140    :functions: typec_set_data_role typec_set_pwr_role typec_set_vconn_role typec_set_pwr_opmode
0141 
0142 Alternate Modes
0143 ~~~~~~~~~~~~~~~
0144 
0145 USB Type-C ports, partners and cable plugs may support Alternate Modes. Each
0146 Alternate Mode will have identifier called SVID, which is either a Standard ID
0147 given by USB-IF or vendor ID, and each supported SVID can have 1 - 6 modes. The
0148 class provides struct typec_mode_desc for describing individual mode of a SVID,
0149 and struct typec_altmode_desc which is a container for all the supported modes.
0150 
0151 Ports that support Alternate Modes need to register each SVID they support with
0152 the following API:
0153 
0154 .. kernel-doc:: drivers/usb/typec/class.c
0155    :functions: typec_port_register_altmode
0156 
0157 If a partner or cable plug provides a list of SVIDs as response to USB Power
0158 Delivery Structured VDM Discover SVIDs message, each SVID needs to be
0159 registered.
0160 
0161 API for the partners:
0162 
0163 .. kernel-doc:: drivers/usb/typec/class.c
0164    :functions: typec_partner_register_altmode
0165 
0166 API for the Cable Plugs:
0167 
0168 .. kernel-doc:: drivers/usb/typec/class.c
0169    :functions: typec_plug_register_altmode
0170 
0171 So ports, partners and cable plugs will register the alternate modes with their
0172 own functions, but the registration will always return a handle to struct
0173 typec_altmode on success, or NULL. The unregistration will happen with the same
0174 function:
0175 
0176 .. kernel-doc:: drivers/usb/typec/class.c
0177    :functions: typec_unregister_altmode
0178 
0179 If a partner or cable plug enters or exits a mode, the port driver needs to
0180 notify the class with the following API:
0181 
0182 .. kernel-doc:: drivers/usb/typec/class.c
0183    :functions: typec_altmode_update_active
0184 
0185 Multiplexer/DeMultiplexer Switches
0186 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0187 
0188 USB Type-C connectors may have one or more mux/demux switches behind them. Since
0189 the plugs can be inserted right-side-up or upside-down, a switch is needed to
0190 route the correct data pairs from the connector to the USB controllers. If
0191 Alternate or Accessory Modes are supported, another switch is needed that can
0192 route the pins on the connector to some other component besides USB. USB Type-C
0193 Connector Class supplies an API for registering those switches.
0194 
0195 .. kernel-doc:: drivers/usb/typec/mux.c
0196    :functions: typec_switch_register typec_switch_unregister typec_mux_register typec_mux_unregister
0197 
0198 In most cases the same physical mux will handle both the orientation and mode.
0199 However, as the port drivers will be responsible for the orientation, and the
0200 alternate mode drivers for the mode, the two are always separated into their
0201 own logical components: "mux" for the mode and "switch" for the orientation.
0202 
0203 When a port is registered, USB Type-C Connector Class requests both the mux and
0204 the switch for the port. The drivers can then use the following API for
0205 controlling them:
0206 
0207 .. kernel-doc:: drivers/usb/typec/class.c
0208    :functions: typec_set_orientation typec_set_mode
0209 
0210 If the connector is dual-role capable, there may also be a switch for the data
0211 role. USB Type-C Connector Class does not supply separate API for them. The
0212 port drivers can use USB Role Class API with those.
0213 
0214 Illustration of the muxes behind a connector that supports an alternate mode::
0215 
0216                      ------------------------
0217                      |       Connector      |
0218                      ------------------------
0219                             |         |
0220                      ------------------------
0221                       \     Orientation    /
0222                        --------------------
0223                                 |
0224                        --------------------
0225                       /        Mode        \
0226                      ------------------------
0227                          /              \
0228       ------------------------        --------------------
0229       |       Alt Mode       |       /      USB Role      \
0230       ------------------------      ------------------------
0231                                          /            \
0232                      ------------------------      ------------------------
0233                      |       USB Host       |      |       USB Device     |
0234                      ------------------------      ------------------------