1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef __LINUX_USB_TYPEC_H
4 #define __LINUX_USB_TYPEC_H
5
6 #include <linux/types.h>
7 #include <linux/android_kabi.h>
8
9 /* USB Type-C Specification releases */
10 #define USB_TYPEC_REV_1_0 0x100 /* 1.0 */
11 #define USB_TYPEC_REV_1_1 0x110 /* 1.1 */
12 #define USB_TYPEC_REV_1_2 0x120 /* 1.2 */
13 #define USB_TYPEC_REV_1_3 0x130 /* 1.3 */
14 #define USB_TYPEC_REV_1_4 0x140 /* 1.4 */
15 #define USB_TYPEC_REV_2_0 0x200 /* 2.0 */
16
17 struct typec_partner;
18 struct typec_cable;
19 struct typec_plug;
20 struct typec_port;
21 struct typec_altmode_ops;
22 struct typec_cable_ops;
23
24 struct fwnode_handle;
25 struct device;
26
27 struct usb_power_delivery;
28 struct usb_power_delivery_desc;
29
30 enum typec_port_type {
31 TYPEC_PORT_SRC,
32 TYPEC_PORT_SNK,
33 TYPEC_PORT_DRP,
34 };
35
36 enum typec_port_data {
37 TYPEC_PORT_DFP,
38 TYPEC_PORT_UFP,
39 TYPEC_PORT_DRD,
40 };
41
42 enum typec_plug_type {
43 USB_PLUG_NONE,
44 USB_PLUG_TYPE_A,
45 USB_PLUG_TYPE_B,
46 USB_PLUG_TYPE_C,
47 USB_PLUG_CAPTIVE,
48 };
49
50 enum typec_data_role {
51 TYPEC_DEVICE,
52 TYPEC_HOST,
53 };
54
55 enum typec_role {
56 TYPEC_SINK,
57 TYPEC_SOURCE,
58 };
59
is_sink(enum typec_role role)60 static inline int is_sink(enum typec_role role)
61 {
62 return role == TYPEC_SINK;
63 }
64
is_source(enum typec_role role)65 static inline int is_source(enum typec_role role)
66 {
67 return role == TYPEC_SOURCE;
68 }
69
70 enum typec_pwr_opmode {
71 TYPEC_PWR_MODE_USB,
72 TYPEC_PWR_MODE_1_5A,
73 TYPEC_PWR_MODE_3_0A,
74 TYPEC_PWR_MODE_PD,
75 };
76
77 enum typec_accessory {
78 TYPEC_ACCESSORY_NONE,
79 TYPEC_ACCESSORY_AUDIO,
80 TYPEC_ACCESSORY_DEBUG,
81 };
82
83 #define TYPEC_MAX_ACCESSORY 3
84
85 enum typec_orientation {
86 TYPEC_ORIENTATION_NONE,
87 TYPEC_ORIENTATION_NORMAL,
88 TYPEC_ORIENTATION_REVERSE,
89 };
90
91 /*
92 * struct enter_usb_data - Enter_USB Message details
93 * @eudo: Enter_USB Data Object
94 * @active_link_training: Active Cable Plug Link Training
95 *
96 * @active_link_training is a flag that should be set with uni-directional SBRX
97 * communication, and left 0 with passive cables and with bi-directional SBRX
98 * communication.
99 */
100 struct enter_usb_data {
101 u32 eudo;
102 unsigned char active_link_training:1;
103 };
104
105 /*
106 * struct usb_pd_identity - USB Power Delivery identity data
107 * @id_header: ID Header VDO
108 * @cert_stat: Cert Stat VDO
109 * @product: Product VDO
110 * @vdo: Product Type Specific VDOs
111 *
112 * USB power delivery Discover Identity command response data.
113 *
114 * REVISIT: This is USB Power Delivery specific information, so this structure
115 * probable belongs to USB Power Delivery header file once we have them.
116 */
117 struct usb_pd_identity {
118 u32 id_header;
119 u32 cert_stat;
120 u32 product;
121 u32 vdo[3];
122 };
123
124 int typec_partner_set_identity(struct typec_partner *partner);
125 int typec_cable_set_identity(struct typec_cable *cable);
126
127 /*
128 * struct typec_altmode_desc - USB Type-C Alternate Mode Descriptor
129 * @svid: Standard or Vendor ID
130 * @mode: Index of the Mode
131 * @vdo: VDO returned by Discover Modes USB PD command
132 * @roles: Only for ports. DRP if the mode is available in both roles
133 *
134 * Description of an Alternate Mode which a connector, cable plug or partner
135 * supports.
136 */
137 struct typec_altmode_desc {
138 u16 svid;
139 u8 mode;
140 u32 vdo;
141 /* Only used with ports */
142 enum typec_port_data roles;
143 };
144
145 void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_revision);
146 int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmodes);
147 struct typec_altmode
148 *typec_partner_register_altmode(struct typec_partner *partner,
149 const struct typec_altmode_desc *desc);
150 int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes);
151 struct typec_altmode
152 *typec_plug_register_altmode(struct typec_plug *plug,
153 const struct typec_altmode_desc *desc);
154 struct typec_altmode
155 *typec_port_register_altmode(struct typec_port *port,
156 const struct typec_altmode_desc *desc);
157
158 void typec_port_register_altmodes(struct typec_port *port,
159 const struct typec_altmode_ops *ops, void *drvdata,
160 struct typec_altmode **altmodes, size_t n);
161
162 void typec_port_register_cable_ops(struct typec_altmode **altmodes, int max_altmodes,
163 const struct typec_cable_ops *ops);
164
165 void typec_unregister_altmode(struct typec_altmode *altmode);
166
167 struct typec_port *typec_altmode2port(struct typec_altmode *alt);
168
169 void typec_altmode_update_active(struct typec_altmode *alt, bool active);
170
171 void typec_altmode_set_ops(struct typec_altmode *alt,
172 const struct typec_altmode_ops *ops);
173
174 enum typec_plug_index {
175 TYPEC_PLUG_SOP_P,
176 TYPEC_PLUG_SOP_PP,
177 };
178
179 /*
180 * struct typec_plug_desc - USB Type-C Cable Plug Descriptor
181 * @index: SOP Prime for the plug connected to DFP and SOP Double Prime for the
182 * plug connected to UFP
183 *
184 * Represents USB Type-C Cable Plug.
185 */
186 struct typec_plug_desc {
187 enum typec_plug_index index;
188 };
189
190 /*
191 * struct typec_cable_desc - USB Type-C Cable Descriptor
192 * @type: The plug type from USB PD Cable VDO
193 * @active: Is the cable active or passive
194 * @identity: Result of Discover Identity command
195 * @pd_revision: USB Power Delivery Specification revision if supported
196 *
197 * Represents USB Type-C Cable attached to USB Type-C port.
198 */
199 struct typec_cable_desc {
200 enum typec_plug_type type;
201 unsigned int active:1;
202 struct usb_pd_identity *identity;
203 u16 pd_revision; /* 0300H = "3.0" */
204
205 };
206
207 /*
208 * struct typec_partner_desc - USB Type-C Partner Descriptor
209 * @usb_pd: USB Power Delivery support
210 * @accessory: Audio, Debug or none.
211 * @identity: Discover Identity command data
212 * @pd_revision: USB Power Delivery Specification Revision if supported
213 * @attach: Notification about attached USB device
214 * @deattach: Notification about removed USB device
215 *
216 * Details about a partner that is attached to USB Type-C port. If @identity
217 * member exists when partner is registered, a directory named "identity" is
218 * created to sysfs for the partner device.
219 *
220 * @pd_revision is based on the setting of the "Specification Revision" field
221 * in the message header on the initial "Source Capabilities" message received
222 * from the partner, or a "Request" message received from the partner, depending
223 * on whether our port is a Sink or a Source.
224 */
225 struct typec_partner_desc {
226 unsigned int usb_pd:1;
227 enum typec_accessory accessory;
228 struct usb_pd_identity *identity;
229 u16 pd_revision; /* 0300H = "3.0" */
230
231 void (*attach)(struct typec_partner *partner, struct device *dev);
232 void (*deattach)(struct typec_partner *partner, struct device *dev);
233 };
234
235 /**
236 * struct typec_operations - USB Type-C Port Operations
237 * @try_role: Set data role preference for DRP port
238 * @dr_set: Set Data Role
239 * @pr_set: Set Power Role
240 * @vconn_set: Source VCONN
241 * @port_type_set: Set port type
242 * @pd_get: Get available USB Power Delivery Capabilities.
243 * @pd_set: Set USB Power Delivery Capabilities.
244 */
245 struct typec_operations {
246 int (*try_role)(struct typec_port *port, int role);
247 int (*dr_set)(struct typec_port *port, enum typec_data_role role);
248 int (*pr_set)(struct typec_port *port, enum typec_role role);
249 int (*vconn_set)(struct typec_port *port, enum typec_role role);
250 int (*port_type_set)(struct typec_port *port,
251 enum typec_port_type type);
252 struct usb_power_delivery **(*pd_get)(struct typec_port *port);
253 int (*pd_set)(struct typec_port *port, struct usb_power_delivery *pd);
254
255 ANDROID_KABI_RESERVE(1);
256 ANDROID_KABI_RESERVE(2);
257 };
258
259 enum usb_pd_svdm_ver {
260 SVDM_VER_1_0 = 0,
261 SVDM_VER_2_0 = 1,
262 SVDM_VER_MAX = SVDM_VER_2_0,
263 };
264
265 /*
266 * struct typec_capability - USB Type-C Port Capabilities
267 * @type: Supported power role of the port
268 * @data: Supported data role of the port
269 * @revision: USB Type-C Specification release. Binary coded decimal
270 * @pd_revision: USB Power Delivery Specification revision if supported
271 * @svdm_version: USB PD Structured VDM version if supported
272 * @prefer_role: Initial role preference (DRP ports).
273 * @accessory: Supported Accessory Modes
274 * @fwnode: Optional fwnode of the port
275 * @driver_data: Private pointer for driver specific info
276 * @pd: Optional USB Power Delivery Support
277 * @ops: Port operations vector
278 *
279 * Static capabilities of a single USB Type-C port.
280 */
281 struct typec_capability {
282 enum typec_port_type type;
283 enum typec_port_data data;
284 u16 revision; /* 0120H = "1.2" */
285 u16 pd_revision; /* 0300H = "3.0" */
286 enum usb_pd_svdm_ver svdm_version;
287 int prefer_role;
288 enum typec_accessory accessory[TYPEC_MAX_ACCESSORY];
289 unsigned int orientation_aware:1;
290
291 struct fwnode_handle *fwnode;
292 void *driver_data;
293
294 struct usb_power_delivery *pd;
295
296 const struct typec_operations *ops;
297
298 ANDROID_KABI_RESERVE(1);
299 ANDROID_KABI_RESERVE(2);
300 };
301
302 /* Specific to try_role(). Indicates the user want's to clear the preference. */
303 #define TYPEC_NO_PREFERRED_ROLE (-1)
304
305 struct typec_port *typec_register_port(struct device *parent,
306 const struct typec_capability *cap);
307 void typec_unregister_port(struct typec_port *port);
308
309 struct typec_partner *typec_register_partner(struct typec_port *port,
310 struct typec_partner_desc *desc);
311 void typec_unregister_partner(struct typec_partner *partner);
312
313 struct typec_cable *typec_register_cable(struct typec_port *port,
314 struct typec_cable_desc *desc);
315 void typec_unregister_cable(struct typec_cable *cable);
316
317 struct typec_cable *typec_cable_get(struct typec_port *port);
318 void typec_cable_put(struct typec_cable *cable);
319 int typec_cable_is_active(struct typec_cable *cable);
320
321 struct typec_plug *typec_register_plug(struct typec_cable *cable,
322 struct typec_plug_desc *desc);
323 void typec_unregister_plug(struct typec_plug *plug);
324
325 void typec_set_data_role(struct typec_port *port, enum typec_data_role role);
326 void typec_set_pwr_role(struct typec_port *port, enum typec_role role);
327 void typec_set_vconn_role(struct typec_port *port, enum typec_role role);
328 void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode);
329
330 int typec_set_orientation(struct typec_port *port,
331 enum typec_orientation orientation);
332 enum typec_orientation typec_get_orientation(struct typec_port *port);
333 int typec_set_mode(struct typec_port *port, int mode);
334
335 void *typec_get_drvdata(struct typec_port *port);
336
337 int typec_get_fw_cap(struct typec_capability *cap,
338 struct fwnode_handle *fwnode);
339
340 int typec_find_pwr_opmode(const char *name);
341 int typec_find_orientation(const char *name);
342 int typec_find_port_power_role(const char *name);
343 int typec_find_power_role(const char *name);
344 int typec_find_port_data_role(const char *name);
345
346 void typec_partner_set_svdm_version(struct typec_partner *partner,
347 enum usb_pd_svdm_ver svdm_version);
348 int typec_get_negotiated_svdm_version(struct typec_port *port);
349
350 int typec_get_cable_svdm_version(struct typec_port *port);
351 void typec_cable_set_svdm_version(struct typec_cable *cable, enum usb_pd_svdm_ver svdm_version);
352
353 struct usb_power_delivery *typec_partner_usb_power_delivery_register(struct typec_partner *partner,
354 struct usb_power_delivery_desc *desc);
355
356 int typec_port_set_usb_power_delivery(struct typec_port *port, struct usb_power_delivery *pd);
357 int typec_partner_set_usb_power_delivery(struct typec_partner *partner,
358 struct usb_power_delivery *pd);
359
360 /**
361 * struct typec_connector - Representation of Type-C port for external drivers
362 * @attach: notification about device removal
363 * @deattach: notification about device removal
364 *
365 * Drivers that control the USB and other ports (DisplayPorts, etc.), that are
366 * connected to the Type-C connectors, can use these callbacks to inform the
367 * Type-C connector class about connections and disconnections. That information
368 * can then be used by the typec-port drivers to power on or off parts that are
369 * needed or not needed - as an example, in USB mode if USB2 device is
370 * enumerated, USB3 components (retimers, phys, and what have you) do not need
371 * to be powered on.
372 *
373 * The attached (enumerated) devices will be liked with the typec-partner device.
374 */
375 struct typec_connector {
376 void (*attach)(struct typec_connector *con, struct device *dev);
377 void (*deattach)(struct typec_connector *con, struct device *dev);
378 };
379
typec_attach(struct typec_connector * con,struct device * dev)380 static inline void typec_attach(struct typec_connector *con, struct device *dev)
381 {
382 if (con && con->attach)
383 con->attach(con, dev);
384 }
385
typec_deattach(struct typec_connector * con,struct device * dev)386 static inline void typec_deattach(struct typec_connector *con, struct device *dev)
387 {
388 if (con && con->deattach)
389 con->deattach(con, dev);
390 }
391
392 #endif /* __LINUX_USB_TYPEC_H */
393