API for USB Type-C Alternate Mode drivers¶
Introduction¶
Alternate modes require communication with the partner using Vendor DefinedMessages (VDM) as defined in USB Type-C and USB Power Delivery Specifications.The communication is SVID (Standard or Vendor ID) specific, i.e. specific forevery alternate mode, so every alternate mode will need a custom driver.
USB Type-C bus allows binding a driver to the discovered partner alternatemodes by using the SVID and the mode number.
USB Type-C Connector Class provides a device for every alternatemode a port supports, and separate device for every alternate mode the partnersupports. The drivers for the alternate modes are bound to the partner alternatemode devices, and the port alternate mode devices must be handled by the portdrivers.
When a new partner alternate mode device is registered, it is linked to thealternate mode device of the port that the partner is attached to, that hasmatching SVID and mode. Communication between the port driver and alternate modedriver will happen using the same API.
The port alternate mode devices are used as a proxy between the partner and thealternate mode drivers, so the port drivers are only expected to pass the SVIDspecific commands from the alternate mode drivers to the partner, and from thepartners to the alternate mode drivers. No direct SVID specific communication isneeded from the port drivers, but the port drivers need to provide the operationcallbacks for the port alternate mode devices, just like the alternate modedrivers need to provide them for the partner alternate mode devices.
Usage:¶
General¶
By default, the alternate mode drivers are responsible for entering the mode.It is also possible to leave the decision about entering the mode to the userspace (See Documentation/ABI/testing/sysfs-class-typec). Port drivers should notenter any modes on their own.
->vdm is the most important callback in the operation callbacks vector. Itwill be used to deliver all the SVID specific commands from the partner to thealternate mode driver, and vice versa in case of port drivers. The drivers sendthe SVID specific commands to each other usingtypec_altmode_vdm().
If the communication with the partner using the SVID specific commands resultsin need to reconfigure the pins on the connector, the alternate mode driverneeds to notify the bus usingtypec_altmode_notify(). The driverpasses the negotiated SVID specific pin configuration value to the function asparameter. The bus driver will then configure the mux behind the connector usingthat value as the state value for the mux.
NOTE: The SVID specific pin configuration values must always start fromTYPEC_STATE_MODAL. USB Type-C specification defines two default states forthe connector:TYPEC_STATE_USB andTYPEC_STATE_SAFE. These values arereserved by the bus as the first possible values for the state. When thealternate mode is entered, the bus will put the connector intoTYPEC_STATE_SAFE before sending Enter or Exit Mode command as defined in USBType-C Specification, and also put the connector back toTYPEC_STATE_USBafter the mode has been exited.
An example of working definitions for SVID specific pin configurations wouldlook like this:
enum { ALTMODEX_CONF_A = TYPEC_STATE_MODAL, ALTMODEX_CONF_B, ...};Helper macroTYPEC_MODAL_STATE() can also be used:
#define ALTMODEX_CONF_A = TYPEC_MODAL_STATE(0);#define ALTMODEX_CONF_B = TYPEC_MODAL_STATE(1);
Cable plug alternate modes¶
The alternate mode drivers are not bound to cable plug alternate mode devices,only to the partner alternate mode devices. If the alternate mode supports, orrequires, a cable that responds to SOP Prime, and optionally SOP Double Primemessages, the driver for that alternate mode must request handle to the cableplug alternate modes usingtypec_altmode_get_plug(), and take overtheir control.
Driver API¶
Alternate mode driver registering/unregistering¶
Alternate mode driver operations¶
- int
typec_altmode_notify(struct typec_altmode * adev, unsigned long conf, void * data)¶ Communication between the OS and alternate mode driver
Parameters
structtypec_altmode*adev- Handle to the alternate mode
unsignedlongconf- Alternate mode specific configuration value
void*data- Alternate mode specific data
Description
The primary purpose for this function is to allow the alternate mode driversto tell which pin configuration has been negotiated with the partner. Thatinformation will then be used for example to configure the muxes.Communication to the other direction is also possible, and low level devicedrivers can also send notifications to the alternate mode drivers. The actualcommunication will be specific for every SVID.
- int
typec_altmode_enter(struct typec_altmode * adev, u32 * vdo)¶ Enter Mode
Parameters
structtypec_altmode*adev- The alternate mode
u32*vdo- VDO for the Enter Mode command
Description
The alternate mode drivers use this function to enter mode. The port driversuse this to inform the alternate mode drivers that the partner has initiatedEnter Mode command. If the alternate mode does not require VDO,vdo must beNULL.
- int
typec_altmode_exit(struct typec_altmode * adev)¶ Exit Mode
Parameters
structtypec_altmode*adev- The alternate mode
Description
The partner ofadev has initiated Exit Mode command.
- void
typec_altmode_attention(struct typec_altmode * adev, u32 vdo)¶ Attention command
Parameters
structtypec_altmode*adev- The alternate mode
u32vdo- VDO for the Attention command
Description
Notifies the partner ofadev about Attention command.
- int
typec_altmode_vdm(struct typec_altmode * adev, const u32 header, const u32 * vdo, int count)¶ Send Vendor Defined Messages (VDM) to the partner
Parameters
structtypec_altmode*adev- Alternate mode handle
constu32header- VDM Header
constu32*vdo- Array of Vendor Defined Data Objects
intcount- Number of Data Objects
Description
The alternate mode drivers use this function for SVID specific communicationwith the partner. The port drivers use it to deliver the Structured VDMsreceived from the partners to the alternate mode drivers.
API for the port drivers¶
- struct typec_altmode *
typec_match_altmode(struct typec_altmode ** altmodes, size_t n, u16 svid, u8 mode)¶ Match SVID and mode to an array of alternate modes
Parameters
structtypec_altmode**altmodes- Array of alternate modes
size_tn- Number of elements in the array, or -1 for NULL terminated arrays
u16svid- Standard or Vendor ID to match with
u8mode- Mode to match with
Description
Return pointer to an alternate mode with SVID matchingsvid, or NULL when nomatch is found.
Cable Plug operations¶
- struct typec_altmode *
typec_altmode_get_plug(struct typec_altmode * adev, enum typec_plug_index index)¶ Find cable plug alternate mode
Parameters
structtypec_altmode*adev- Handle to partner alternate mode
enumtypec_plug_indexindex- Cable plug index
Description
Increment reference count for cable plug alternate mode device. Returnshandle to the cable plug alternate mode, or NULL if none is found.
- void
typec_altmode_put_plug(struct typec_altmode * plug)¶ Decrement cable plug alternate mode reference count
Parameters
structtypec_altmode*plug- Handle to the cable plug alternate mode