xref: /openbmc/linux/drivers/usb/typec/ucsi/ucsi.h (revision 33786a28)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 
3 #ifndef __DRIVER_USB_TYPEC_UCSI_H
4 #define __DRIVER_USB_TYPEC_UCSI_H
5 
6 #include <linux/bitops.h>
7 #include <linux/device.h>
8 #include <linux/types.h>
9 #include <linux/usb/typec.h>
10 
11 /* -------------------------------------------------------------------------- */
12 
13 struct ucsi;
14 
15 /* UCSI offsets (Bytes) */
16 #define UCSI_VERSION			0
17 #define UCSI_CCI			4
18 #define UCSI_CONTROL			8
19 #define UCSI_MESSAGE_IN			16
20 #define UCSI_MESSAGE_OUT		32
21 
22 /* Command Status and Connector Change Indication (CCI) bits */
23 #define UCSI_CCI_CONNECTOR(_c_)		(((_c_) & GENMASK(7, 0)) >> 1)
24 #define UCSI_CCI_LENGTH(_c_)		(((_c_) & GENMASK(15, 8)) >> 8)
25 #define UCSI_CCI_NOT_SUPPORTED		BIT(25)
26 #define UCSI_CCI_CANCEL_COMPLETE	BIT(26)
27 #define UCSI_CCI_RESET_COMPLETE		BIT(27)
28 #define UCSI_CCI_BUSY			BIT(28)
29 #define UCSI_CCI_ACK_COMPLETE		BIT(29)
30 #define UCSI_CCI_ERROR			BIT(30)
31 #define UCSI_CCI_COMMAND_COMPLETE	BIT(31)
32 
33 /**
34  * struct ucsi_operations - UCSI I/O operations
35  * @read: Read operation
36  * @sync_write: Blocking write operation
37  * @async_write: Non-blocking write operation
38  *
39  * Read and write routines for UCSI interface. @sync_write must wait for the
40  * Command Completion Event from the PPM before returning, and @async_write must
41  * return immediately after sending the data to the PPM.
42  */
43 struct ucsi_operations {
44 	int (*read)(struct ucsi *ucsi, unsigned int offset,
45 		    void *val, size_t val_len);
46 	int (*sync_write)(struct ucsi *ucsi, unsigned int offset,
47 			  const void *val, size_t val_len);
48 	int (*async_write)(struct ucsi *ucsi, unsigned int offset,
49 			   const void *val, size_t val_len);
50 };
51 
52 struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops);
53 void ucsi_destroy(struct ucsi *ucsi);
54 int ucsi_register(struct ucsi *ucsi);
55 void ucsi_unregister(struct ucsi *ucsi);
56 void *ucsi_get_drvdata(struct ucsi *ucsi);
57 void ucsi_set_drvdata(struct ucsi *ucsi, void *data);
58 
59 void ucsi_connector_change(struct ucsi *ucsi, u8 num);
60 
61 /* -------------------------------------------------------------------------- */
62 
63 /* Commands */
64 #define UCSI_PPM_RESET			0x01
65 #define UCSI_CANCEL			0x02
66 #define UCSI_CONNECTOR_RESET		0x03
67 #define UCSI_ACK_CC_CI			0x04
68 #define UCSI_SET_NOTIFICATION_ENABLE	0x05
69 #define UCSI_GET_CAPABILITY		0x06
70 #define UCSI_GET_CONNECTOR_CAPABILITY	0x07
71 #define UCSI_SET_UOM			0x08
72 #define UCSI_SET_UOR			0x09
73 #define UCSI_SET_PDM			0x0a
74 #define UCSI_SET_PDR			0x0b
75 #define UCSI_GET_ALTERNATE_MODES	0x0c
76 #define UCSI_GET_CAM_SUPPORTED		0x0d
77 #define UCSI_GET_CURRENT_CAM		0x0e
78 #define UCSI_SET_NEW_CAM		0x0f
79 #define UCSI_GET_PDOS			0x10
80 #define UCSI_GET_CABLE_PROPERTY		0x11
81 #define UCSI_GET_CONNECTOR_STATUS	0x12
82 #define UCSI_GET_ERROR_STATUS		0x13
83 
84 #define UCSI_CONNECTOR_NUMBER(_num_)		((u64)(_num_) << 16)
85 
86 /* CONNECTOR_RESET command bits */
87 #define UCSI_CONNECTOR_RESET_HARD		BIT(23) /* Deprecated in v1.1 */
88 
89 /* ACK_CC_CI bits */
90 #define UCSI_ACK_CONNECTOR_CHANGE		BIT(16)
91 #define UCSI_ACK_COMMAND_COMPLETE		BIT(17)
92 
93 /* SET_NOTIFICATION_ENABLE command bits */
94 #define UCSI_ENABLE_NTFY_CMD_COMPLETE		BIT(16)
95 #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE	BIT(17)
96 #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE	BIT(18)
97 #define UCSI_ENABLE_NTFY_CAP_CHANGE		BIT(21)
98 #define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE	BIT(22)
99 #define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE	BIT(23)
100 #define UCSI_ENABLE_NTFY_CAM_CHANGE		BIT(24)
101 #define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE	BIT(25)
102 #define UCSI_ENABLE_NTFY_PARTNER_CHANGE		BIT(27)
103 #define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE		BIT(28)
104 #define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE	BIT(30)
105 #define UCSI_ENABLE_NTFY_ERROR			BIT(31)
106 #define UCSI_ENABLE_NTFY_ALL			0xdbe70000
107 
108 /* SET_UOR command bits */
109 #define UCSI_SET_UOR_ROLE(_r_)		(((_r_) == TYPEC_HOST ? 1 : 2) << 23)
110 #define UCSI_SET_UOR_ACCEPT_ROLE_SWAPS		BIT(25)
111 
112 /* SET_PDF command bits */
113 #define UCSI_SET_PDR_ROLE(_r_)		(((_r_) == TYPEC_SOURCE ? 1 : 2) << 23)
114 #define UCSI_SET_PDR_ACCEPT_ROLE_SWAPS		BIT(25)
115 
116 /* GET_ALTERNATE_MODES command bits */
117 #define UCSI_GET_ALTMODE_RECIPIENT(_r_)		((u64)(_r_) << 16)
118 #define   UCSI_RECIPIENT_CON			0
119 #define   UCSI_RECIPIENT_SOP			1
120 #define   UCSI_RECIPIENT_SOP_P			2
121 #define   UCSI_RECIPIENT_SOP_PP			3
122 #define UCSI_GET_ALTMODE_CONNECTOR_NUMBER(_r_)	((u64)(_r_) << 24)
123 #define UCSI_GET_ALTMODE_OFFSET(_r_)		((u64)(_r_) << 32)
124 #define UCSI_GET_ALTMODE_NUM_ALTMODES(_r_)	((u64)(_r_) << 40)
125 
126 /* -------------------------------------------------------------------------- */
127 
128 /* Error information returned by PPM in response to GET_ERROR_STATUS command. */
129 #define UCSI_ERROR_UNREGONIZED_CMD		BIT(0)
130 #define UCSI_ERROR_INVALID_CON_NUM		BIT(1)
131 #define UCSI_ERROR_INVALID_CMD_ARGUMENT		BIT(2)
132 #define UCSI_ERROR_INCOMPATIBLE_PARTNER		BIT(3)
133 #define UCSI_ERROR_CC_COMMUNICATION_ERR		BIT(4)
134 #define UCSI_ERROR_DEAD_BATTERY			BIT(5)
135 #define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL	BIT(6)
136 #define UCSI_ERROR_OVERCURRENT			BIT(7)
137 #define UCSI_ERROR_UNDEFINED			BIT(8)
138 #define UCSI_ERROR_PARTNER_REJECTED_SWAP	BIT(9)
139 #define UCSI_ERROR_HARD_RESET			BIT(10)
140 #define UCSI_ERROR_PPM_POLICY_CONFLICT		BIT(11)
141 #define UCSI_ERROR_SWAP_REJECTED		BIT(12)
142 
143 /* Data structure filled by PPM in response to GET_CAPABILITY command. */
144 struct ucsi_capability {
145 	u32 attributes;
146 #define UCSI_CAP_ATTR_DISABLE_STATE		BIT(0)
147 #define UCSI_CAP_ATTR_BATTERY_CHARGING		BIT(1)
148 #define UCSI_CAP_ATTR_USB_PD			BIT(2)
149 #define UCSI_CAP_ATTR_TYPEC_CURRENT		BIT(6)
150 #define UCSI_CAP_ATTR_POWER_AC_SUPPLY		BIT(8)
151 #define UCSI_CAP_ATTR_POWER_OTHER		BIT(10)
152 #define UCSI_CAP_ATTR_POWER_VBUS		BIT(14)
153 	u8 num_connectors;
154 	u8 features;
155 #define UCSI_CAP_SET_UOM			BIT(0)
156 #define UCSI_CAP_SET_PDM			BIT(1)
157 #define UCSI_CAP_ALT_MODE_DETAILS		BIT(2)
158 #define UCSI_CAP_ALT_MODE_OVERRIDE		BIT(3)
159 #define UCSI_CAP_PDO_DETAILS			BIT(4)
160 #define UCSI_CAP_CABLE_DETAILS			BIT(5)
161 #define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS	BIT(6)
162 #define UCSI_CAP_PD_RESET			BIT(7)
163 	u16 reserved_1;
164 	u8 num_alt_modes;
165 	u8 reserved_2;
166 	u16 bc_version;
167 	u16 pd_version;
168 	u16 typec_version;
169 } __packed;
170 
171 /* Data structure filled by PPM in response to GET_CONNECTOR_CAPABILITY cmd. */
172 struct ucsi_connector_capability {
173 	u8 op_mode;
174 #define UCSI_CONCAP_OPMODE_DFP			BIT(0)
175 #define UCSI_CONCAP_OPMODE_UFP			BIT(1)
176 #define UCSI_CONCAP_OPMODE_DRP			BIT(2)
177 #define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY	BIT(3)
178 #define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY	BIT(4)
179 #define UCSI_CONCAP_OPMODE_USB2			BIT(5)
180 #define UCSI_CONCAP_OPMODE_USB3			BIT(6)
181 #define UCSI_CONCAP_OPMODE_ALT_MODE		BIT(7)
182 	u8 flags;
183 #define UCSI_CONCAP_FLAG_PROVIDER		BIT(0)
184 #define UCSI_CONCAP_FLAG_CONSUMER		BIT(1)
185 } __packed;
186 
187 struct ucsi_altmode {
188 	u16 svid;
189 	u32 mid;
190 } __packed;
191 
192 /* Data structure filled by PPM in response to GET_CABLE_PROPERTY command. */
193 struct ucsi_cable_property {
194 	u16 speed_supported;
195 	u8 current_capability;
196 	u8 flags;
197 #define UCSI_CABLE_PROP_FLAG_VBUS_IN_CABLE	BIT(0)
198 #define UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE	BIT(1)
199 #define UCSI_CABLE_PROP_FLAG_DIRECTIONALITY	BIT(2)
200 #define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_)	((_f_) & GENMASK(3, 0))
201 #define   UCSI_CABLE_PROPERTY_PLUG_TYPE_A	0
202 #define   UCSI_CABLE_PROPERTY_PLUG_TYPE_B	1
203 #define   UCSI_CABLE_PROPERTY_PLUG_TYPE_C	2
204 #define   UCSI_CABLE_PROPERTY_PLUG_OTHER	3
205 #define UCSI_CABLE_PROP_MODE_SUPPORT		BIT(5)
206 	u8 latency;
207 } __packed;
208 
209 /* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */
210 struct ucsi_connector_status {
211 	u16 change;
212 #define UCSI_CONSTAT_EXT_SUPPLY_CHANGE		BIT(1)
213 #define UCSI_CONSTAT_POWER_OPMODE_CHANGE	BIT(2)
214 #define UCSI_CONSTAT_PDOS_CHANGE		BIT(5)
215 #define UCSI_CONSTAT_POWER_LEVEL_CHANGE		BIT(6)
216 #define UCSI_CONSTAT_PD_RESET_COMPLETE		BIT(7)
217 #define UCSI_CONSTAT_CAM_CHANGE			BIT(8)
218 #define UCSI_CONSTAT_BC_CHANGE			BIT(9)
219 #define UCSI_CONSTAT_PARTNER_CHANGE		BIT(11)
220 #define UCSI_CONSTAT_POWER_DIR_CHANGE		BIT(12)
221 #define UCSI_CONSTAT_CONNECT_CHANGE		BIT(14)
222 #define UCSI_CONSTAT_ERROR			BIT(15)
223 	u16 flags;
224 #define UCSI_CONSTAT_PWR_OPMODE(_f_)		((_f_) & GENMASK(2, 0))
225 #define   UCSI_CONSTAT_PWR_OPMODE_NONE		0
226 #define   UCSI_CONSTAT_PWR_OPMODE_DEFAULT	1
227 #define   UCSI_CONSTAT_PWR_OPMODE_BC		2
228 #define   UCSI_CONSTAT_PWR_OPMODE_PD		3
229 #define   UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5	4
230 #define   UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0	5
231 #define UCSI_CONSTAT_CONNECTED			BIT(3)
232 #define UCSI_CONSTAT_PWR_DIR			BIT(4)
233 #define UCSI_CONSTAT_PARTNER_FLAGS(_f_)		(((_f_) & GENMASK(12, 5)) >> 5)
234 #define   UCSI_CONSTAT_PARTNER_FLAG_USB		1
235 #define   UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE	2
236 #define UCSI_CONSTAT_PARTNER_TYPE(_f_)		(((_f_) & GENMASK(15, 13)) >> 13)
237 #define   UCSI_CONSTAT_PARTNER_TYPE_DFP		1
238 #define   UCSI_CONSTAT_PARTNER_TYPE_UFP		2
239 #define   UCSI_CONSTAT_PARTNER_TYPE_CABLE	3 /* Powered Cable */
240 #define   UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP	4 /* Powered Cable */
241 #define   UCSI_CONSTAT_PARTNER_TYPE_DEBUG	5
242 #define   UCSI_CONSTAT_PARTNER_TYPE_AUDIO	6
243 	u32 request_data_obj;
244 	u8 pwr_status;
245 #define UCSI_CONSTAT_BC_STATUS(_p_)		((_p_) & GENMASK(2, 0))
246 #define   UCSI_CONSTAT_BC_NOT_CHARGING		0
247 #define   UCSI_CONSTAT_BC_NOMINAL_CHARGING	1
248 #define   UCSI_CONSTAT_BC_SLOW_CHARGING		2
249 #define   UCSI_CONSTAT_BC_TRICKLE_CHARGING	3
250 #define UCSI_CONSTAT_PROVIDER_CAP_LIMIT(_p_)	(((_p_) & GENMASK(6, 3)) >> 3)
251 #define   UCSI_CONSTAT_CAP_PWR_LOWERED		0
252 #define   UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT	1
253 } __packed;
254 
255 /* -------------------------------------------------------------------------- */
256 
257 struct ucsi {
258 	u16 version;
259 	struct device *dev;
260 	struct driver_data *driver_data;
261 
262 	const struct ucsi_operations *ops;
263 
264 	struct ucsi_capability cap;
265 	struct ucsi_connector *connector;
266 
267 	struct work_struct work;
268 
269 	/* PPM Communication lock */
270 	struct mutex ppm_lock;
271 
272 	/* PPM communication flags */
273 	unsigned long flags;
274 #define EVENT_PENDING	0
275 #define COMMAND_PENDING	1
276 #define ACK_PENDING	2
277 };
278 
279 #define UCSI_MAX_SVID		5
280 #define UCSI_MAX_ALTMODES	(UCSI_MAX_SVID * 6)
281 
282 struct ucsi_connector {
283 	int num;
284 
285 	struct ucsi *ucsi;
286 	struct mutex lock; /* port lock */
287 	struct work_struct work;
288 	struct completion complete;
289 
290 	struct typec_port *port;
291 	struct typec_partner *partner;
292 
293 	struct typec_altmode *port_altmode[UCSI_MAX_ALTMODES];
294 	struct typec_altmode *partner_altmode[UCSI_MAX_ALTMODES];
295 
296 	struct typec_capability typec_cap;
297 
298 	struct ucsi_connector_status status;
299 	struct ucsi_connector_capability cap;
300 };
301 
302 int ucsi_send_command(struct ucsi *ucsi, u64 command,
303 		      void *retval, size_t size);
304 
305 void ucsi_altmode_update_active(struct ucsi_connector *con);
306 int ucsi_resume(struct ucsi *ucsi);
307 
308 #if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE)
309 struct typec_altmode *
310 ucsi_register_displayport(struct ucsi_connector *con,
311 			  bool override, int offset,
312 			  struct typec_altmode_desc *desc);
313 
314 void ucsi_displayport_remove_partner(struct typec_altmode *adev);
315 
316 #else
317 static inline struct typec_altmode *
318 ucsi_register_displayport(struct ucsi_connector *con,
319 			  bool override, int offset,
320 			  struct typec_altmode_desc *desc)
321 {
322 	return NULL;
323 }
324 
325 static inline void
326 ucsi_displayport_remove_partner(struct typec_altmode *adev) { }
327 #endif /* CONFIG_TYPEC_DP_ALTMODE */
328 
329 #endif /* __DRIVER_USB_TYPEC_UCSI_H */
330