| USB Type-C connector class |
| ========================== |
| |
| Introduction |
| ------------ |
| The typec class is meant for describing the USB Type-C ports in a system to the |
| user space in unified fashion. The class is designed to provide nothing else |
| except the user space interface implementation in hope that it can be utilized |
| on as many platforms as possible. |
| |
| The platforms are expected to register every USB Type-C port they have with the |
| class. In a normal case the registration will be done by a USB Type-C or PD PHY |
| driver, but it may be a driver for firmware interface such as UCSI, driver for |
| USB PD controller or even driver for Thunderbolt3 controller. This document |
| considers the component registering the USB Type-C ports with the class as "port |
| driver". |
| |
| On top of showing the capabilities, the class also offer the user space control |
| over the roles and alternate modes they support when the port driver is capable |
| of supporting those features. |
| |
| The class provides an API for the port drivers described in this document. The |
| attributes are described in Documentation/ABI/testing/sysfs-class-typec. |
| |
| |
| Interface |
| --------- |
| Every port will be presented as its own device under /sys/class/typec/. The |
| first port will be named "usbc0", the second "usbc1" and so on. |
| |
| When connected, the partner will be presented also as its own device under |
| /sys/class/typec/. The parent of the partner device will always be the port. The |
| partner attached to port "usbc0" will be named "usbc0-partner". Full path to the |
| device would be /sys/class/typec/usb0/usb0-partner/. |
| |
| The cable and the two plugs on it may also be optionally presented as their own |
| devices under /sys/class/typec/. The cable attached to the port "usbc0" port |
| will be named usbc0-cable and the plug on the SOP Prime end (see USB Power |
| Delivery Specification ch. 2.4) will be named "usbc-plug0" and on the SOP Double |
| Prime end "usbc0-plug1". The parent of a cable will always be the port, and the |
| parent of the cable plugs will always be the cable. |
| |
| If the port, partner or cable plug support Alternate Modes, every Alternate Mode |
| SVID will have their own device describing them. The Alternate Modes will not be |
| attached to the typec class. For the port's "usbc0" partner, the Alternate Modes |
| would have devices presented under /sys/class/typec/usbc0-partner/. Every mode |
| that is supported will have its own group under the Alternate Mode device named |
| "mode<id>". For example /sys/class/typec/usbc0/usbc0.svid:xxxx/mode0/. The |
| requests for entering/exiting the modes happens with the "active" attribute in |
| that group. |
| |
| |
| API |
| --- |
| |
| * Registering the ports |
| |
| The port drivers will describe every Type-C port they control with struct |
| typec_capability data structure, and register them with the following API: |
| |
| struct typec_port *typec_register_port(struct device *dev, |
| const struct typec_capability *cap); |
| |
| The class will provide handle to struct typec_port on success and ERR_PTR on |
| failure. The un-registration of the port happens with the following API: |
| |
| void typec_unregister_port(struct typec_port *port); |
| |
| When registering the ports, the prefer_role member in struct typec_capability |
| deservers special notice. If the port that is being registered does not have |
| initial role preference, which means the port does not execute Try.SNK or |
| Try.SRC by default, the member must have value TYPEC_NO_PREFERRED_ROLE. |
| Otherwise if the port executes Try.SNK by default the member must have value |
| TYPEC_DEVICE and with Try.SRC the value must be TYPEC_HOST. |
| |
| |
| * Notifications |
| |
| When connection happens on a port, the port driver fills struct typec_connection |
| which is passed to the class. The class provides the following API for reporting |
| connection/disconnection: |
| |
| int typec_connect(struct typec_port *port, struct typec_connection *); |
| void typec_disconnect(struct typec_port *); |
| |
| When the partner end has executed a role change, the port driver uses the |
| following APIs to report it to the class: |
| |
| void typec_set_data_role(struct typec_port *, enum typec_data_role); |
| void typec_set_pwr_role(struct typec_port *, enum typec_role); |
| void typec_set_vconn_role(struct typec_port *, enum typec_role); |
| void typec_set_pwr_opmode(struct typec_port *, enum typec_pwr_opmode); |
| |
| |
| * Alternate Modes |
| |
| After connection, the port drivers register the alternate modes the partner |
| and/or cable plugs support. And before reporting disconnection, the port driver |
| _must_ unregister all the alternate modes registered for the partner and cable |
| plugs. The API takes the struct device of the partner or the cable plug as |
| parameter: |
| |
| int typec_register_altmodes(struct device *, struct typec_altmode *); |
| void typec_unregister_altmodes(struct device *); |
| |
| When the partner end enters or exits the modes, the port driver needs to notify |
| the class with the following API: |
| |
| void typec_altmode_update_active(struct typec_altmode *alt, int mode, |
| bool active); |