typec_altmode.h (6640B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2 3#ifndef __USB_TYPEC_ALTMODE_H 4#define __USB_TYPEC_ALTMODE_H 5 6#include <linux/mod_devicetable.h> 7#include <linux/usb/typec.h> 8#include <linux/device.h> 9 10#define MODE_DISCOVERY_MAX 6 11 12struct typec_altmode_ops; 13 14/** 15 * struct typec_altmode - USB Type-C alternate mode device 16 * @dev: Driver model's view of this device 17 * @svid: Standard or Vendor ID (SVID) of the alternate mode 18 * @mode: Index of the Mode 19 * @vdo: VDO returned by Discover Modes USB PD command 20 * @active: Tells has the mode been entered or not 21 * @desc: Optional human readable description of the mode 22 * @ops: Operations vector from the driver 23 */ 24struct typec_altmode { 25 struct device dev; 26 u16 svid; 27 int mode; 28 u32 vdo; 29 unsigned int active:1; 30 31 char *desc; 32 const struct typec_altmode_ops *ops; 33}; 34 35#define to_typec_altmode(d) container_of(d, struct typec_altmode, dev) 36 37static inline void typec_altmode_set_drvdata(struct typec_altmode *altmode, 38 void *data) 39{ 40 dev_set_drvdata(&altmode->dev, data); 41} 42 43static inline void *typec_altmode_get_drvdata(struct typec_altmode *altmode) 44{ 45 return dev_get_drvdata(&altmode->dev); 46} 47 48/** 49 * struct typec_altmode_ops - Alternate mode specific operations vector 50 * @enter: Operations to be executed with Enter Mode Command 51 * @exit: Operations to be executed with Exit Mode Command 52 * @attention: Callback for Attention Command 53 * @vdm: Callback for SVID specific commands 54 * @notify: Communication channel for platform and the alternate mode 55 * @activate: User callback for Enter/Exit Mode 56 */ 57struct typec_altmode_ops { 58 int (*enter)(struct typec_altmode *altmode, u32 *vdo); 59 int (*exit)(struct typec_altmode *altmode); 60 void (*attention)(struct typec_altmode *altmode, u32 vdo); 61 int (*vdm)(struct typec_altmode *altmode, const u32 hdr, 62 const u32 *vdo, int cnt); 63 int (*notify)(struct typec_altmode *altmode, unsigned long conf, 64 void *data); 65 int (*activate)(struct typec_altmode *altmode, int activate); 66}; 67 68int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo); 69int typec_altmode_exit(struct typec_altmode *altmode); 70void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo); 71int typec_altmode_vdm(struct typec_altmode *altmode, 72 const u32 header, const u32 *vdo, int count); 73int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf, 74 void *data); 75const struct typec_altmode * 76typec_altmode_get_partner(struct typec_altmode *altmode); 77 78/* 79 * These are the connector states (USB, Safe and Alt Mode) defined in USB Type-C 80 * Specification. SVID specific connector states are expected to follow and 81 * start from the value TYPEC_STATE_MODAL. 82 */ 83enum { 84 TYPEC_STATE_SAFE, /* USB Safe State */ 85 TYPEC_STATE_USB, /* USB Operation */ 86 TYPEC_STATE_MODAL, /* Alternate Modes */ 87}; 88 89/* 90 * For the muxes there is no difference between Accessory Modes and Alternate 91 * Modes, so the Accessory Modes are supplied with specific modal state values 92 * here. Unlike with Alternate Modes, where the mux will be linked with the 93 * alternate mode device, the mux for Accessory Modes will be linked with the 94 * port device instead. 95 * 96 * Port drivers can use TYPEC_MODE_AUDIO and TYPEC_MODE_DEBUG as the mode 97 * value for typec_set_mode() when accessory modes are supported. 98 * 99 * USB4 also requires that the pins on the connector are repurposed, just like 100 * Alternate Modes. USB4 mode is however not entered with the Enter Mode Command 101 * like the Alternate Modes are, but instead with a special Enter_USB Message. 102 * The Enter_USB Message can also be used for setting to connector to operate in 103 * USB 3.2 or in USB 2.0 mode instead of USB4. 104 * 105 * The Enter_USB specific "USB Modes" are also supplied here as special modal 106 * state values, just like the Accessory Modes. 107 */ 108enum { 109 TYPEC_MODE_USB2 = TYPEC_STATE_MODAL, /* USB 2.0 mode */ 110 TYPEC_MODE_USB3, /* USB 3.2 mode */ 111 TYPEC_MODE_USB4, /* USB4 mode */ 112 TYPEC_MODE_AUDIO, /* Audio Accessory */ 113 TYPEC_MODE_DEBUG, /* Debug Accessory */ 114}; 115 116#define TYPEC_MODAL_STATE(_state_) ((_state_) + TYPEC_STATE_MODAL) 117 118struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode, 119 enum typec_plug_index index); 120void typec_altmode_put_plug(struct typec_altmode *plug); 121 122struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes, 123 size_t n, u16 svid, u8 mode); 124 125/** 126 * typec_altmode_get_orientation - Get cable plug orientation 127 * altmode: Handle to the alternate mode 128 */ 129static inline enum typec_orientation 130typec_altmode_get_orientation(struct typec_altmode *altmode) 131{ 132 return typec_get_orientation(typec_altmode2port(altmode)); 133} 134 135/** 136 * typec_altmode_get_svdm_version - Get negotiated SVDM version 137 * @altmode: Handle to the alternate mode 138 */ 139static inline int 140typec_altmode_get_svdm_version(struct typec_altmode *altmode) 141{ 142 return typec_get_negotiated_svdm_version(typec_altmode2port(altmode)); 143} 144 145/** 146 * struct typec_altmode_driver - USB Type-C alternate mode device driver 147 * @id_table: Null terminated array of SVIDs 148 * @probe: Callback for device binding 149 * @remove: Callback for device unbinding 150 * @driver: Device driver model driver 151 * 152 * These drivers will be bind to the partner alternate mode devices. They will 153 * handle all SVID specific communication. 154 */ 155struct typec_altmode_driver { 156 const struct typec_device_id *id_table; 157 int (*probe)(struct typec_altmode *altmode); 158 void (*remove)(struct typec_altmode *altmode); 159 struct device_driver driver; 160}; 161 162#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \ 163 driver) 164 165/** 166 * typec_altmode_register_driver - registers a USB Type-C alternate mode 167 * device driver 168 * @drv: pointer to struct typec_altmode_driver 169 * 170 * These drivers will be bind to the partner alternate mode devices. They will 171 * handle all SVID specific communication. 172 */ 173#define typec_altmode_register_driver(drv) \ 174 __typec_altmode_register_driver(drv, THIS_MODULE) 175int __typec_altmode_register_driver(struct typec_altmode_driver *drv, 176 struct module *module); 177/** 178 * typec_altmode_unregister_driver - unregisters a USB Type-C alternate mode 179 * device driver 180 * @drv: pointer to struct typec_altmode_driver 181 * 182 * These drivers will be bind to the partner alternate mode devices. They will 183 * handle all SVID specific communication. 184 */ 185void typec_altmode_unregister_driver(struct typec_altmode_driver *drv); 186 187#define module_typec_altmode_driver(__typec_altmode_driver) \ 188 module_driver(__typec_altmode_driver, typec_altmode_register_driver, \ 189 typec_altmode_unregister_driver) 190 191#endif /* __USB_TYPEC_ALTMODE_H */