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