xref: /linux/drivers/platform/chrome/cros_ec_typec.c (revision e5d379e9c3148aaef37909ce6d4c3ca18fad0312)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright 2020 Google LLC
4  *
5  * This driver provides the ability to view and manage Type C ports through the
6  * Chrome OS EC.
7  */
8 
9 #include <linux/acpi.h>
10 #include <linux/array_size.h>
11 #include <linux/delay.h>
12 #include <linux/jiffies.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/overflow.h>
16 #include <linux/platform_data/cros_ec_commands.h>
17 #include <linux/platform_data/cros_usbpd_notify.h>
18 #include <linux/platform_device.h>
19 #include <linux/usb/pd_vdo.h>
20 #include <linux/usb/typec_dp.h>
21 #include <linux/usb/typec_tbt.h>
22 
23 #include "cros_ec_typec.h"
24 #include "cros_typec_vdm.h"
25 #include "cros_typec_altmode.h"
26 
27 #define DRV_NAME "cros-ec-typec"
28 
29 /*
30  * Mirrors PD_ROLE_SWAP_TIMEOUT used by the TCPM port manager: a PR_Swap may
31  * legitimately take seconds when the partner answers with Wait and the
32  * initiator retries.
33  */
34 #define ROLE_SWAP_TIMEOUT_MS	10000
35 #define ROLE_SWAP_DELAY_MS	20
36 
37 #define DP_PORT_VDO	(DP_CAP_DFP_D | DP_CAP_RECEPTACLE | \
38 			 DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | \
39 						BIT(DP_PIN_ASSIGN_D) | \
40 						BIT(DP_PIN_ASSIGN_E)))
41 
cros_typec_role_switch_quirk(struct fwnode_handle * fwnode)42 static void cros_typec_role_switch_quirk(struct fwnode_handle *fwnode)
43 {
44 #ifdef CONFIG_ACPI
45 	struct fwnode_handle *switch_fwnode;
46 
47 	/* Supply the USB role switch with the correct pld_crc if it's missing. */
48 	switch_fwnode = fwnode_find_reference(fwnode, "usb-role-switch", 0);
49 	if (!IS_ERR_OR_NULL(switch_fwnode)) {
50 		struct acpi_device *adev = to_acpi_device_node(switch_fwnode);
51 
52 		if (adev && !adev->pld_crc)
53 			adev->pld_crc = to_acpi_device_node(fwnode)->pld_crc;
54 		fwnode_handle_put(switch_fwnode);
55 	}
56 #endif
57 }
58 
cros_typec_enter_usb_mode(struct typec_port * tc_port,enum usb_mode mode)59 static int cros_typec_enter_usb_mode(struct typec_port *tc_port, enum usb_mode mode)
60 {
61 	struct cros_typec_port *port = typec_get_drvdata(tc_port);
62 	struct ec_params_typec_control req = {
63 		.port = port->port_num,
64 		.command = (mode == USB_MODE_USB4) ?
65 			TYPEC_CONTROL_COMMAND_ENTER_MODE : TYPEC_CONTROL_COMMAND_EXIT_MODES,
66 		.mode_to_enter = CROS_EC_ALTMODE_USB4
67 	};
68 
69 	return cros_ec_cmd(port->typec_data->ec, 0, EC_CMD_TYPEC_CONTROL,
70 			  &req, sizeof(req), NULL, 0);
71 }
72 
73 /*
74  * Decode the role relevant to @swap_type out of an EC_CMD_USB_PD_CONTROL
75  * response.
76  *
77  * Returns a value comparable against the typec class target role
78  * (TYPEC_DEVICE/TYPEC_HOST or TYPEC_SINK/TYPEC_SOURCE), or -EOPNOTSUPP if
79  * @swap_type is not a role swap this driver knows how to track.
80  */
cros_typec_resp_to_role(struct ec_response_usb_pd_control_v2 * resp,u8 swap_type)81 static int cros_typec_resp_to_role(struct ec_response_usb_pd_control_v2 *resp, u8 swap_type)
82 {
83 	switch (swap_type) {
84 	case USB_PD_CTRL_SWAP_DATA:
85 		return (resp->role & PD_CTRL_RESP_ROLE_DATA) ? TYPEC_HOST : TYPEC_DEVICE;
86 	case USB_PD_CTRL_SWAP_POWER:
87 		return (resp->role & PD_CTRL_RESP_ROLE_POWER) ? TYPEC_SOURCE : TYPEC_SINK;
88 	default:
89 		return -EOPNOTSUPP;
90 	}
91 }
92 
cros_typec_perform_role_swap(struct typec_port * tc_port,int target_role,u8 swap_type)93 static int cros_typec_perform_role_swap(struct typec_port *tc_port, int target_role, u8 swap_type)
94 {
95 	struct cros_typec_port *port = typec_get_drvdata(tc_port);
96 	struct cros_typec_data *data = port->typec_data;
97 	struct ec_response_usb_pd_control_v2 resp;
98 	struct ec_params_usb_pd_control req;
99 	unsigned long end;
100 	int role, ret;
101 
102 	/* Must be at least v1 to support role swap. */
103 	if (!data->pd_ctrl_ver)
104 		return -EOPNOTSUPP;
105 
106 	/* First query the state */
107 	req.port = port->port_num;
108 	req.role = USB_PD_CTRL_ROLE_NO_CHANGE;
109 	req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
110 	req.swap = USB_PD_CTRL_SWAP_NONE;
111 
112 	ret = cros_ec_cmd(data->ec, data->pd_ctrl_ver, EC_CMD_USB_PD_CONTROL,
113 				&req, sizeof(req), &resp, sizeof(resp));
114 	if (ret < 0)
115 		return ret;
116 
117 	role = cros_typec_resp_to_role(&resp, swap_type);
118 	if (role < 0) {
119 		dev_warn(data->dev, "Unsupported role swap type %d\n", swap_type);
120 		return role;
121 	}
122 
123 	if (role == target_role)
124 		return 0;
125 
126 	req.swap = swap_type;
127 	ret = cros_ec_cmd(data->ec, data->pd_ctrl_ver, EC_CMD_USB_PD_CONTROL,
128 				&req, sizeof(req), &resp, sizeof(resp));
129 	if (ret < 0)
130 		return ret;
131 
132 	/*
133 	 * Depending on the EC USB-C stack (TCPMv2 vs PDC), EC_CMD_USB_PD_CONTROL
134 	 * may either block until the swap completes or queue the request
135 	 * asynchronously and return the pre-swap role. Poll until the target
136 	 * role is reached while connected, or until the timeout expires.
137 	 */
138 	req.swap = USB_PD_CTRL_SWAP_NONE;
139 	end = jiffies + msecs_to_jiffies(ROLE_SWAP_TIMEOUT_MS);
140 	for (;;) {
141 		if (!(resp.enabled & PD_CTRL_RESP_ENABLED_CONNECTED)) {
142 			dev_warn(data->dev, "Port disconnected during role swap\n");
143 			return -ENOTCONN;
144 		}
145 
146 		if (cros_typec_resp_to_role(&resp, swap_type) == target_role)
147 			break;
148 
149 		if (time_after_eq(jiffies, end)) {
150 			dev_err(data->dev, "Timed out waiting for role swap to complete\n");
151 			return -ETIMEDOUT;
152 		}
153 
154 		msleep(ROLE_SWAP_DELAY_MS);
155 		ret = cros_ec_cmd(data->ec, data->pd_ctrl_ver,
156 				  EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
157 				  &resp, sizeof(resp));
158 		if (ret < 0)
159 			return ret;
160 	}
161 
162 	if (swap_type == USB_PD_CTRL_SWAP_DATA)
163 		typec_set_data_role(tc_port, target_role);
164 	else
165 		typec_set_pwr_role(tc_port, target_role);
166 
167 	return 0;
168 }
169 
cros_typec_dr_swap(struct typec_port * port,enum typec_data_role role)170 static int cros_typec_dr_swap(struct typec_port *port, enum typec_data_role role)
171 {
172 	return cros_typec_perform_role_swap(port, role, USB_PD_CTRL_SWAP_DATA);
173 }
174 
cros_typec_pr_swap(struct typec_port * port,enum typec_role role)175 static int cros_typec_pr_swap(struct typec_port *port, enum typec_role role)
176 {
177 	return cros_typec_perform_role_swap(port, role, USB_PD_CTRL_SWAP_POWER);
178 }
179 
180 static const struct typec_operations cros_typec_usb_mode_ops = {
181 	.enter_usb_mode = cros_typec_enter_usb_mode,
182 	.dr_set = cros_typec_dr_swap,
183 	.pr_set = cros_typec_pr_swap,
184 };
185 
cros_typec_parse_port_props(struct typec_capability * cap,struct fwnode_handle * fwnode,struct device * dev)186 static int cros_typec_parse_port_props(struct typec_capability *cap,
187 				       struct fwnode_handle *fwnode,
188 				       struct device *dev)
189 {
190 	const char *buf;
191 	int ret;
192 
193 	memset(cap, 0, sizeof(*cap));
194 	ret = fwnode_property_read_string(fwnode, "power-role", &buf);
195 	if (ret) {
196 		dev_err(dev, "power-role not found: %d\n", ret);
197 		return ret;
198 	}
199 
200 	ret = typec_find_port_power_role(buf);
201 	if (ret < 0)
202 		return ret;
203 	cap->type = ret;
204 
205 	ret = fwnode_property_read_string(fwnode, "data-role", &buf);
206 	if (ret) {
207 		dev_err(dev, "data-role not found: %d\n", ret);
208 		return ret;
209 	}
210 
211 	ret = typec_find_port_data_role(buf);
212 	if (ret < 0)
213 		return ret;
214 	cap->data = ret;
215 
216 	/* Try-power-role is optional. */
217 	ret = fwnode_property_read_string(fwnode, "try-power-role", &buf);
218 	if (ret) {
219 		dev_warn(dev, "try-power-role not found: %d\n", ret);
220 		cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
221 	} else {
222 		ret = typec_find_power_role(buf);
223 		if (ret < 0)
224 			return ret;
225 		cap->prefer_role = ret;
226 	}
227 
228 	if (fwnode_property_present(fwnode, "usb2-port"))
229 		cap->usb_capability |= USB_CAPABILITY_USB2;
230 	if (fwnode_property_present(fwnode, "usb3-port"))
231 		cap->usb_capability |= USB_CAPABILITY_USB3;
232 	if (fwnode_property_present(fwnode, "usb4-port"))
233 		cap->usb_capability |= USB_CAPABILITY_USB4;
234 
235 	cros_typec_role_switch_quirk(fwnode);
236 
237 	cap->fwnode = fwnode;
238 
239 	return 0;
240 }
241 
cros_typec_get_switch_handles(struct cros_typec_port * port,struct fwnode_handle * fwnode,struct device * dev)242 static int cros_typec_get_switch_handles(struct cros_typec_port *port,
243 					 struct fwnode_handle *fwnode,
244 					 struct device *dev)
245 {
246 	int ret = 0;
247 
248 	port->mux = fwnode_typec_mux_get(fwnode);
249 	if (IS_ERR(port->mux)) {
250 		ret = PTR_ERR(port->mux);
251 		dev_err_probe(dev, ret, "Mux handle not found\n");
252 		goto mux_err;
253 	}
254 
255 	port->retimer = fwnode_typec_retimer_get(fwnode);
256 	if (IS_ERR(port->retimer)) {
257 		ret = PTR_ERR(port->retimer);
258 		dev_err_probe(dev, ret, "Retimer handle not found\n");
259 		goto retimer_sw_err;
260 	}
261 
262 	port->ori_sw = fwnode_typec_switch_get(fwnode);
263 	if (IS_ERR(port->ori_sw)) {
264 		ret = PTR_ERR(port->ori_sw);
265 		dev_err_probe(dev, ret, "Orientation switch handle not found\n");
266 		goto ori_sw_err;
267 	}
268 
269 	port->role_sw = fwnode_usb_role_switch_get(fwnode);
270 	if (IS_ERR(port->role_sw)) {
271 		ret = PTR_ERR(port->role_sw);
272 		dev_err_probe(dev, ret, "USB role switch handle not found\n");
273 		goto role_sw_err;
274 	}
275 
276 	return 0;
277 
278 role_sw_err:
279 	typec_switch_put(port->ori_sw);
280 	port->ori_sw = NULL;
281 ori_sw_err:
282 	typec_retimer_put(port->retimer);
283 	port->retimer = NULL;
284 retimer_sw_err:
285 	typec_mux_put(port->mux);
286 	port->mux = NULL;
287 mux_err:
288 	return ret;
289 }
290 
cros_typec_add_partner(struct cros_typec_data * typec,int port_num,bool pd_en)291 static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
292 				  bool pd_en)
293 {
294 	struct cros_typec_port *port = typec->ports[port_num];
295 	struct typec_partner_desc p_desc = {
296 		.usb_pd = pd_en,
297 	};
298 	int ret = 0;
299 
300 	/*
301 	 * Fill an initial PD identity, which will then be updated with info
302 	 * from the EC.
303 	 */
304 	p_desc.identity = &port->p_identity;
305 
306 	port->partner = typec_register_partner(port->port, &p_desc);
307 	if (IS_ERR(port->partner)) {
308 		ret = PTR_ERR(port->partner);
309 		port->partner = NULL;
310 	}
311 
312 	return ret;
313 }
314 
cros_typec_unregister_altmodes(struct cros_typec_data * typec,int port_num,bool is_partner)315 static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int port_num,
316 					   bool is_partner)
317 {
318 	struct cros_typec_port *port = typec->ports[port_num];
319 	struct cros_typec_altmode_node *node, *tmp;
320 	struct list_head *head;
321 
322 	head = is_partner ? &port->partner_mode_list : &port->plug_mode_list;
323 	list_for_each_entry_safe(node, tmp, head, list) {
324 		list_del(&node->list);
325 		typec_unregister_altmode(node->amode);
326 		devm_kfree(typec->dev, node);
327 	}
328 }
329 
330 /*
331  * Map the Type-C Mux state to retimer state and call the retimer set function. We need this
332  * because we re-use the Type-C mux state for retimers.
333  */
cros_typec_retimer_set(struct typec_retimer * retimer,struct typec_mux_state state)334 static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_mux_state state)
335 {
336 	struct typec_retimer_state rstate = {
337 		.alt = state.alt,
338 		.mode = state.mode,
339 		.data = state.data,
340 	};
341 
342 	return typec_retimer_set(retimer, &rstate);
343 }
344 
cros_typec_usb_disconnect_state(struct cros_typec_port * port)345 static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
346 {
347 	port->state.alt = NULL;
348 	port->state.mode = TYPEC_STATE_USB;
349 	port->state.data = NULL;
350 
351 	usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
352 	typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
353 	cros_typec_retimer_set(port->retimer, port->state);
354 
355 	return typec_mux_set(port->mux, &port->state);
356 }
357 
cros_typec_remove_partner(struct cros_typec_data * typec,int port_num)358 static void cros_typec_remove_partner(struct cros_typec_data *typec,
359 				      int port_num)
360 {
361 	struct cros_typec_port *port = typec->ports[port_num];
362 
363 	if (!port->partner)
364 		return;
365 
366 	cros_typec_unregister_altmodes(typec, port_num, true);
367 
368 	typec_partner_set_usb_power_delivery(port->partner, NULL);
369 	usb_power_delivery_unregister_capabilities(port->partner_sink_caps);
370 	port->partner_sink_caps = NULL;
371 	usb_power_delivery_unregister_capabilities(port->partner_src_caps);
372 	port->partner_src_caps = NULL;
373 	usb_power_delivery_unregister(port->partner_pd);
374 	port->partner_pd = NULL;
375 
376 	cros_typec_usb_disconnect_state(port);
377 	port->mux_flags = USB_PD_MUX_NONE;
378 
379 	typec_unregister_partner(port->partner);
380 	port->partner = NULL;
381 	memset(&port->p_identity, 0, sizeof(port->p_identity));
382 	port->sop_disc_done = false;
383 }
384 
cros_typec_remove_cable(struct cros_typec_data * typec,int port_num)385 static void cros_typec_remove_cable(struct cros_typec_data *typec,
386 				    int port_num)
387 {
388 	struct cros_typec_port *port = typec->ports[port_num];
389 
390 	if (!port->cable)
391 		return;
392 
393 	cros_typec_unregister_altmodes(typec, port_num, false);
394 
395 	typec_unregister_plug(port->plug);
396 	port->plug = NULL;
397 	typec_unregister_cable(port->cable);
398 	port->cable = NULL;
399 	memset(&port->c_identity, 0, sizeof(port->c_identity));
400 	port->sop_prime_disc_done = false;
401 }
402 
cros_typec_unregister_port_altmodes(struct cros_typec_port * port)403 static void cros_typec_unregister_port_altmodes(struct cros_typec_port *port)
404 {
405 	int i;
406 
407 	for (i = 0; i < CROS_EC_ALTMODE_MAX; i++)
408 		typec_unregister_altmode(port->port_altmode[i]);
409 }
410 
cros_unregister_ports(struct cros_typec_data * typec)411 static void cros_unregister_ports(struct cros_typec_data *typec)
412 {
413 	int i;
414 
415 	for (i = 0; i < typec->num_ports; i++) {
416 		if (!typec->ports[i])
417 			continue;
418 
419 		cros_typec_remove_partner(typec, i);
420 		cros_typec_remove_cable(typec, i);
421 
422 		usb_role_switch_put(typec->ports[i]->role_sw);
423 		typec_switch_put(typec->ports[i]->ori_sw);
424 		typec_mux_put(typec->ports[i]->mux);
425 		cros_typec_unregister_port_altmodes(typec->ports[i]);
426 		typec_unregister_port(typec->ports[i]->port);
427 	}
428 }
429 
430 /*
431  * Register port alt modes with known values till we start retrieving
432  * port capabilities from the EC.
433  */
cros_typec_register_port_altmodes(struct cros_typec_data * typec,int port_num)434 static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
435 					      int port_num)
436 {
437 	struct cros_typec_port *port = typec->ports[port_num];
438 	struct typec_altmode_desc desc;
439 	struct typec_altmode *amode;
440 
441 	/* All PD capable CrOS devices are assumed to support DP altmode. */
442 	memset(&desc, 0, sizeof(desc));
443 	desc.svid = USB_TYPEC_DP_SID;
444 	desc.mode = USB_TYPEC_DP_MODE;
445 	desc.vdo = DP_PORT_VDO;
446 	amode = cros_typec_register_displayport(port, &desc,
447 						typec->ap_driven_altmode);
448 	if (IS_ERR(amode))
449 		return PTR_ERR(amode);
450 	port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
451 
452 	/*
453 	 * Register TBT compatibility alt mode. The EC will not enter the mode
454 	 * if it doesn't support it and it will not enter automatically by
455 	 * design so we can use the |ap_driven_altmode| feature to check if we
456 	 * should register it.
457 	 */
458 	if (typec->ap_driven_altmode) {
459 		memset(&desc, 0, sizeof(desc));
460 		desc.svid = USB_TYPEC_TBT_SID;
461 		desc.mode = TBT_MODE;
462 		desc.inactive = true;
463 		amode = cros_typec_register_thunderbolt(port, &desc);
464 		if (IS_ERR(amode))
465 			return PTR_ERR(amode);
466 		port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
467 	}
468 
469 	port->state.alt = NULL;
470 	port->state.mode = TYPEC_STATE_USB;
471 	port->state.data = NULL;
472 
473 	return 0;
474 }
475 
cros_typec_init_ports(struct cros_typec_data * typec)476 static int cros_typec_init_ports(struct cros_typec_data *typec)
477 {
478 	struct device *dev = typec->dev;
479 	struct typec_capability *cap;
480 	struct fwnode_handle *fwnode;
481 	struct cros_typec_port *cros_port;
482 	const char *port_prop;
483 	int ret;
484 	int nports;
485 	u32 port_num = 0;
486 
487 	nports = device_get_child_node_count(dev);
488 	if (nports == 0) {
489 		dev_err(dev, "No port entries found.\n");
490 		return -ENODEV;
491 	}
492 
493 	if (nports > typec->num_ports) {
494 		dev_err(dev, "More ports listed than can be supported.\n");
495 		return -EINVAL;
496 	}
497 
498 	/* DT uses "reg" to specify port number. */
499 	port_prop = dev->of_node ? "reg" : "port-number";
500 	device_for_each_child_node(dev, fwnode) {
501 		if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) {
502 			ret = -EINVAL;
503 			dev_err(dev, "No port-number for port, aborting.\n");
504 			goto unregister_ports;
505 		}
506 
507 		if (port_num >= typec->num_ports) {
508 			dev_err(dev, "Invalid port number.\n");
509 			ret = -EINVAL;
510 			goto unregister_ports;
511 		}
512 
513 		dev_dbg(dev, "Registering port %d\n", port_num);
514 
515 		cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL);
516 		if (!cros_port) {
517 			ret = -ENOMEM;
518 			goto unregister_ports;
519 		}
520 
521 		cros_port->port_num = port_num;
522 		cros_port->typec_data = typec;
523 		typec->ports[port_num] = cros_port;
524 		cap = &cros_port->caps;
525 
526 		ret = cros_typec_parse_port_props(cap, fwnode, dev);
527 		if (ret < 0)
528 			goto unregister_ports;
529 
530 		cap->driver_data = cros_port;
531 		cap->ops = &cros_typec_usb_mode_ops;
532 		cap->no_mode_control = !typec->ap_driven_altmode;
533 
534 		cros_port->port = typec_register_port(dev, cap);
535 		if (IS_ERR(cros_port->port)) {
536 			ret = PTR_ERR(cros_port->port);
537 			dev_err_probe(dev, ret, "Failed to register port %d\n", port_num);
538 			goto unregister_ports;
539 		}
540 
541 		ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);
542 		if (ret) {
543 			dev_dbg(dev, "No switch control for port %d, err: %d\n", port_num, ret);
544 			if (ret == -EPROBE_DEFER)
545 				goto unregister_ports;
546 		}
547 
548 		ret = cros_typec_register_port_altmodes(typec, port_num);
549 		if (ret) {
550 			dev_err(dev, "Failed to register port altmodes\n");
551 			goto unregister_ports;
552 		}
553 
554 		cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
555 		if (!cros_port->disc_data) {
556 			ret = -ENOMEM;
557 			goto unregister_ports;
558 		}
559 
560 		INIT_LIST_HEAD(&cros_port->partner_mode_list);
561 		INIT_LIST_HEAD(&cros_port->plug_mode_list);
562 	}
563 
564 	return 0;
565 
566 unregister_ports:
567 	fwnode_handle_put(fwnode);
568 	cros_unregister_ports(typec);
569 	return ret;
570 }
571 
cros_typec_usb_safe_state(struct cros_typec_port * port)572 static int cros_typec_usb_safe_state(struct cros_typec_port *port)
573 {
574 	int ret;
575 	port->state.mode = TYPEC_STATE_SAFE;
576 
577 	ret = cros_typec_retimer_set(port->retimer, port->state);
578 	if (!ret)
579 		ret = typec_mux_set(port->mux, &port->state);
580 
581 	return ret;
582 }
583 
584 /**
585  * cros_typec_get_cable_vdo() - Get Cable VDO of the connected cable
586  * @port: Type-C port data
587  * @svid: Standard or Vendor ID to match
588  *
589  * Returns the Cable VDO if match is found and returns 0 if match is not found.
590  */
cros_typec_get_cable_vdo(struct cros_typec_port * port,u16 svid)591 static int cros_typec_get_cable_vdo(struct cros_typec_port *port, u16 svid)
592 {
593 	struct list_head *head = &port->plug_mode_list;
594 	struct cros_typec_altmode_node *node;
595 	u32 ret = 0;
596 
597 	list_for_each_entry(node, head, list) {
598 		if (node->amode->svid == svid)
599 			return node->amode->vdo;
600 	}
601 
602 	return ret;
603 }
604 
605 /*
606  * Spoof the VDOs that were likely communicated by the partner for TBT alt
607  * mode.
608  */
cros_typec_enable_tbt(struct cros_typec_data * typec,int port_num,struct ec_response_usb_pd_control_v2 * pd_ctrl)609 static int cros_typec_enable_tbt(struct cros_typec_data *typec,
610 				 int port_num,
611 				 struct ec_response_usb_pd_control_v2 *pd_ctrl)
612 {
613 	struct cros_typec_port *port = typec->ports[port_num];
614 	struct typec_thunderbolt_data data;
615 	int ret;
616 
617 	if (typec->pd_ctrl_ver < 2) {
618 		dev_err(typec->dev,
619 			"PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
620 		return -ENOTSUPP;
621 	}
622 
623 	/* Device Discover Mode VDO */
624 	data.device_mode = TBT_MODE;
625 
626 	if (pd_ctrl->control_flags & USB_PD_CTRL_TBT_LEGACY_ADAPTER)
627 		data.device_mode = TBT_SET_ADAPTER(TBT_ADAPTER_TBT3);
628 
629 	/* Cable Discover Mode VDO */
630 	data.cable_mode = TBT_MODE;
631 
632 	data.cable_mode |= cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID);
633 
634 	data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
635 
636 	if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
637 		data.cable_mode |= TBT_CABLE_OPTICAL;
638 
639 	if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_LINK_UNIDIR)
640 		data.cable_mode |= TBT_CABLE_LINK_TRAINING;
641 
642 	data.cable_mode |= TBT_SET_CABLE_ROUNDED(pd_ctrl->cable_gen);
643 
644 	/* Enter Mode VDO */
645 	data.enter_vdo = TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
646 
647 	if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
648 		data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
649 
650 	if (!port->state.alt) {
651 		port->state.alt = port->port_altmode[CROS_EC_ALTMODE_TBT];
652 		ret = cros_typec_usb_safe_state(port);
653 		if (ret)
654 			return ret;
655 	}
656 
657 	port->state.data = &data;
658 	port->state.mode = TYPEC_TBT_MODE;
659 
660 	return typec_mux_set(port->mux, &port->state);
661 }
662 
663 /* Spoof the VDOs that were likely communicated by the partner. */
cros_typec_enable_dp(struct cros_typec_data * typec,int port_num,struct ec_response_usb_pd_control_v2 * pd_ctrl)664 static int cros_typec_enable_dp(struct cros_typec_data *typec,
665 				int port_num,
666 				struct ec_response_usb_pd_control_v2 *pd_ctrl)
667 {
668 	struct cros_typec_port *port = typec->ports[port_num];
669 	struct typec_displayport_data dp_data;
670 	u32 cable_tbt_vdo;
671 	u32 cable_dp_vdo;
672 	int ret;
673 
674 	if (typec->pd_ctrl_ver < 2) {
675 		dev_err(typec->dev,
676 			"PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
677 		return -ENOTSUPP;
678 	}
679 
680 	if (!pd_ctrl->dp_mode) {
681 		dev_err(typec->dev, "No valid DP mode provided.\n");
682 		return -EINVAL;
683 	}
684 
685 	/* Status VDO. */
686 	dp_data.status = DP_STATUS_ENABLED;
687 	if (port->mux_flags & USB_PD_MUX_HPD_IRQ)
688 		dp_data.status |= DP_STATUS_IRQ_HPD;
689 	if (port->mux_flags & USB_PD_MUX_HPD_LVL)
690 		dp_data.status |= DP_STATUS_HPD_STATE;
691 
692 	/* Configuration VDO. */
693 	dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
694 	if (!port->state.alt) {
695 		port->state.alt = port->port_altmode[CROS_EC_ALTMODE_DP];
696 		ret = cros_typec_usb_safe_state(port);
697 		if (ret)
698 			return ret;
699 	}
700 
701 	port->state.data = &dp_data;
702 	port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
703 
704 	/* Get cable VDO for cables with DPSID to check DPAM2.1 is supported */
705 	cable_dp_vdo = cros_typec_get_cable_vdo(port, USB_TYPEC_DP_SID);
706 
707 	/**
708 	 * Get cable VDO for thunderbolt cables and cables with DPSID but does not
709 	 * support DPAM2.1.
710 	 */
711 	cable_tbt_vdo = cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID);
712 
713 	if (cable_dp_vdo & DP_CAP_DPAM_VERSION) {
714 		dp_data.conf |= cable_dp_vdo;
715 	} else if (cable_tbt_vdo) {
716 		dp_data.conf |=  TBT_CABLE_SPEED(cable_tbt_vdo) << DP_CONF_SIGNALLING_SHIFT;
717 
718 		/* Cable Type */
719 		if (cable_tbt_vdo & TBT_CABLE_OPTICAL)
720 			dp_data.conf |= DP_CONF_CABLE_TYPE_OPTICAL << DP_CONF_CABLE_TYPE_SHIFT;
721 		else if (cable_tbt_vdo & TBT_CABLE_RETIMER)
722 			dp_data.conf |= DP_CONF_CABLE_TYPE_RE_TIMER << DP_CONF_CABLE_TYPE_SHIFT;
723 		else if (cable_tbt_vdo & TBT_CABLE_ACTIVE_PASSIVE)
724 			dp_data.conf |= DP_CONF_CABLE_TYPE_RE_DRIVER << DP_CONF_CABLE_TYPE_SHIFT;
725 	} else if (PD_IDH_PTYPE(port->c_identity.id_header) == IDH_PTYPE_PCABLE) {
726 		dp_data.conf |= VDO_TYPEC_CABLE_SPEED(port->c_identity.vdo[0]) <<
727 				DP_CONF_SIGNALLING_SHIFT;
728 	}
729 
730 	ret = cros_typec_retimer_set(port->retimer, port->state);
731 	if (!ret)
732 		ret = typec_mux_set(port->mux, &port->state);
733 
734 	if (!ret)
735 		ret = cros_typec_displayport_status_update(port->state.alt,
736 							   port->state.data);
737 
738 	return ret;
739 }
740 
cros_typec_enable_usb4(struct cros_typec_data * typec,int port_num,struct ec_response_usb_pd_control_v2 * pd_ctrl)741 static int cros_typec_enable_usb4(struct cros_typec_data *typec,
742 				  int port_num,
743 				  struct ec_response_usb_pd_control_v2 *pd_ctrl)
744 {
745 	struct cros_typec_port *port = typec->ports[port_num];
746 	struct enter_usb_data data;
747 
748 	data.eudo = EUDO_USB_MODE_USB4 << EUDO_USB_MODE_SHIFT;
749 
750 	/* Cable Speed */
751 	data.eudo |= pd_ctrl->cable_speed << EUDO_CABLE_SPEED_SHIFT;
752 
753 	/* Cable Type */
754 	if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
755 		data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT;
756 	else if (cros_typec_get_cable_vdo(port, USB_TYPEC_TBT_SID) & TBT_CABLE_RETIMER)
757 		data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT;
758 	else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
759 		data.eudo |= EUDO_CABLE_TYPE_RE_DRIVER << EUDO_CABLE_TYPE_SHIFT;
760 
761 	data.active_link_training = !!(pd_ctrl->control_flags &
762 				       USB_PD_CTRL_ACTIVE_LINK_UNIDIR);
763 
764 	port->state.alt = NULL;
765 	port->state.data = &data;
766 	port->state.mode = TYPEC_MODE_USB4;
767 
768 	return typec_mux_set(port->mux, &port->state);
769 }
770 
cros_typec_configure_mux(struct cros_typec_data * typec,int port_num,struct ec_response_usb_pd_control_v2 * pd_ctrl)771 static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
772 				struct ec_response_usb_pd_control_v2 *pd_ctrl)
773 {
774 	struct cros_typec_port *port = typec->ports[port_num];
775 	struct ec_response_usb_pd_mux_info resp;
776 	struct ec_params_usb_pd_mux_info req = {
777 		.port = port_num,
778 	};
779 	struct ec_params_usb_pd_mux_ack mux_ack;
780 	enum typec_orientation orientation;
781 	struct cros_typec_altmode_node *node;
782 	int ret;
783 
784 	ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,
785 			  &req, sizeof(req), &resp, sizeof(resp));
786 	if (ret < 0) {
787 		dev_warn(typec->dev, "Failed to get mux info for port: %d, err = %d\n",
788 			 port_num, ret);
789 		return ret;
790 	}
791 
792 	/* No change needs to be made, let's exit early. */
793 	if (port->mux_flags == resp.flags && port->role == pd_ctrl->role)
794 		return 0;
795 
796 	port->mux_flags = resp.flags;
797 	port->role = pd_ctrl->role;
798 
799 	if (port->mux_flags == USB_PD_MUX_NONE) {
800 		ret = cros_typec_usb_disconnect_state(port);
801 		goto mux_ack;
802 	}
803 
804 	if (port->mux_flags & USB_PD_MUX_POLARITY_INVERTED)
805 		orientation = TYPEC_ORIENTATION_REVERSE;
806 	else
807 		orientation = TYPEC_ORIENTATION_NORMAL;
808 
809 	ret = typec_switch_set(port->ori_sw, orientation);
810 	if (ret)
811 		return ret;
812 
813 	ret = usb_role_switch_set_role(typec->ports[port_num]->role_sw,
814 					pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA
815 					? USB_ROLE_HOST : USB_ROLE_DEVICE);
816 	if (ret)
817 		return ret;
818 
819 	if (port->mux_flags & USB_PD_MUX_USB4_ENABLED) {
820 		ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl);
821 	} else if (port->mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
822 		ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
823 	} else if (port->mux_flags & USB_PD_MUX_DP_ENABLED) {
824 		ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
825 	} else if (port->mux_flags & USB_PD_MUX_SAFE_MODE) {
826 		ret = cros_typec_usb_safe_state(port);
827 	} else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) {
828 		port->state.alt = NULL;
829 		port->state.mode = TYPEC_STATE_USB;
830 
831 		ret = cros_typec_retimer_set(port->retimer, port->state);
832 		if (!ret)
833 			ret = typec_mux_set(port->mux, &port->state);
834 	} else {
835 		dev_dbg(typec->dev,
836 			"Unrecognized mode requested, mux flags: %x\n",
837 			port->mux_flags);
838 	}
839 
840 	/* Iterate all partner alt-modes and set the active alternate mode. */
841 	list_for_each_entry(node, &port->partner_mode_list, list) {
842 		typec_altmode_update_active(
843 			node->amode,
844 			port->state.alt &&
845 				node->amode->svid == port->state.alt->svid);
846 	}
847 
848 mux_ack:
849 	if (!typec->needs_mux_ack)
850 		return ret;
851 
852 	/* Sending Acknowledgment to EC */
853 	mux_ack.port = port_num;
854 
855 	if (cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,
856 			sizeof(mux_ack), NULL, 0) < 0)
857 		dev_warn(typec->dev,
858 			 "Failed to send Mux ACK to EC for port: %d\n",
859 			 port_num);
860 
861 	return ret;
862 }
863 
cros_typec_set_port_params_v0(struct cros_typec_data * typec,int port_num,struct ec_response_usb_pd_control * resp)864 static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
865 		int port_num, struct ec_response_usb_pd_control *resp)
866 {
867 	struct typec_port *port = typec->ports[port_num]->port;
868 	enum typec_orientation polarity;
869 
870 	if (!resp->enabled)
871 		polarity = TYPEC_ORIENTATION_NONE;
872 	else if (!resp->polarity)
873 		polarity = TYPEC_ORIENTATION_NORMAL;
874 	else
875 		polarity = TYPEC_ORIENTATION_REVERSE;
876 
877 	typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
878 	typec_set_orientation(port, polarity);
879 }
880 
cros_typec_set_port_params_v1(struct cros_typec_data * typec,int port_num,struct ec_response_usb_pd_control_v1 * resp)881 static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
882 		int port_num, struct ec_response_usb_pd_control_v1 *resp)
883 {
884 	struct typec_port *port = typec->ports[port_num]->port;
885 	enum typec_orientation polarity;
886 	bool pd_en;
887 	int ret;
888 
889 	if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
890 		polarity = TYPEC_ORIENTATION_NONE;
891 	else if (!resp->polarity)
892 		polarity = TYPEC_ORIENTATION_NORMAL;
893 	else
894 		polarity = TYPEC_ORIENTATION_REVERSE;
895 	typec_set_orientation(port, polarity);
896 	typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
897 			TYPEC_HOST : TYPEC_DEVICE);
898 	typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
899 			TYPEC_SOURCE : TYPEC_SINK);
900 	typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
901 			TYPEC_SOURCE : TYPEC_SINK);
902 
903 	/* Register/remove partners when a connect/disconnect occurs. */
904 	if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
905 		if (typec->ports[port_num]->partner)
906 			return;
907 
908 		pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
909 		ret = cros_typec_add_partner(typec, port_num, pd_en);
910 		if (ret)
911 			dev_warn(typec->dev,
912 				 "Failed to register partner on port: %d\n",
913 				 port_num);
914 	} else {
915 		cros_typec_remove_partner(typec, port_num);
916 		cros_typec_remove_cable(typec, port_num);
917 	}
918 }
919 
920 /*
921  * Helper function to register partner/plug altmodes.
922  */
cros_typec_register_altmodes(struct cros_typec_data * typec,int port_num,bool is_partner)923 static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_num,
924 					bool is_partner)
925 {
926 	struct cros_typec_port *port = typec->ports[port_num];
927 	struct ec_response_typec_discovery *sop_disc = port->disc_data;
928 	struct cros_typec_altmode_node *node;
929 	struct typec_altmode_desc desc;
930 	struct typec_altmode *amode;
931 	int num_altmodes = 0;
932 	int ret = 0;
933 	int i, j;
934 
935 	if (struct_size(sop_disc, svids, sop_disc->svid_count) > EC_PROTO2_MAX_RESPONSE_SIZE)
936 		return -EINVAL;
937 
938 	for (i = 0; i < sop_disc->svid_count; i++) {
939 		if (sop_disc->svids[i].mode_count > ARRAY_SIZE(sop_disc->svids[i].mode_vdo)) {
940 			ret = -EINVAL;
941 			goto err_cleanup;
942 		}
943 
944 		for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
945 			memset(&desc, 0, sizeof(desc));
946 			desc.svid = sop_disc->svids[i].svid;
947 			desc.mode = j + 1;
948 			desc.vdo = sop_disc->svids[i].mode_vdo[j];
949 
950 			if (is_partner)
951 				amode = typec_partner_register_altmode(port->partner, &desc);
952 			else
953 				amode = typec_plug_register_altmode(port->plug, &desc);
954 
955 			if (IS_ERR(amode)) {
956 				ret = PTR_ERR(amode);
957 				goto err_cleanup;
958 			}
959 
960 			/* If no memory is available we should unregister and exit. */
961 			node = devm_kzalloc(typec->dev, sizeof(*node), GFP_KERNEL);
962 			if (!node) {
963 				ret = -ENOMEM;
964 				typec_unregister_altmode(amode);
965 				goto err_cleanup;
966 			}
967 
968 			node->amode = amode;
969 
970 			if (is_partner)
971 				list_add_tail(&node->list, &port->partner_mode_list);
972 			else
973 				list_add_tail(&node->list, &port->plug_mode_list);
974 			num_altmodes++;
975 		}
976 	}
977 
978 	if (is_partner)
979 		ret = typec_partner_set_num_altmodes(port->partner, num_altmodes);
980 	else
981 		ret = typec_plug_set_num_altmodes(port->plug, num_altmodes);
982 
983 	if (ret < 0) {
984 		dev_err(typec->dev, "Unable to set %s num_altmodes for port: %d\n",
985 			is_partner ? "partner" : "plug", port_num);
986 		goto err_cleanup;
987 	}
988 
989 	return 0;
990 
991 err_cleanup:
992 	cros_typec_unregister_altmodes(typec, port_num, is_partner);
993 	return ret;
994 }
995 
996 /*
997  * Parse the PD identity data from the EC PD discovery responses and copy that to the supplied
998  * PD identity struct.
999  */
cros_typec_parse_pd_identity(struct usb_pd_identity * id,struct ec_response_typec_discovery * disc)1000 static void cros_typec_parse_pd_identity(struct usb_pd_identity *id,
1001 					 struct ec_response_typec_discovery *disc)
1002 {
1003 	int i;
1004 
1005 	/* First, update the PD identity VDOs for the partner. */
1006 	if (disc->identity_count > 0)
1007 		id->id_header = disc->discovery_vdo[0];
1008 	if (disc->identity_count > 1)
1009 		id->cert_stat = disc->discovery_vdo[1];
1010 	if (disc->identity_count > 2)
1011 		id->product = disc->discovery_vdo[2];
1012 
1013 	/* Copy the remaining identity VDOs till a maximum of 6. */
1014 	for (i = 3; i < disc->identity_count && i < VDO_MAX_OBJECTS; i++)
1015 		id->vdo[i - 3] = disc->discovery_vdo[i];
1016 }
1017 
cros_typec_handle_sop_prime_disc(struct cros_typec_data * typec,int port_num,u16 pd_revision)1018 static int cros_typec_handle_sop_prime_disc(struct cros_typec_data *typec, int port_num, u16 pd_revision)
1019 {
1020 	struct cros_typec_port *port = typec->ports[port_num];
1021 	struct ec_response_typec_discovery *disc = port->disc_data;
1022 	struct typec_cable_desc c_desc = {};
1023 	struct typec_plug_desc p_desc;
1024 	struct ec_params_typec_discovery req = {
1025 		.port = port_num,
1026 		.partner_type = TYPEC_PARTNER_SOP_PRIME,
1027 	};
1028 	u32 cable_plug_type;
1029 	int ret = 0;
1030 
1031 	memset(disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
1032 	ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
1033 			  disc, EC_PROTO2_MAX_RESPONSE_SIZE);
1034 	if (ret < 0) {
1035 		dev_err(typec->dev, "Failed to get SOP' discovery data for port: %d\n", port_num);
1036 		goto sop_prime_disc_exit;
1037 	}
1038 
1039 	/* Parse the PD identity data, even if only 0s were returned. */
1040 	cros_typec_parse_pd_identity(&port->c_identity, disc);
1041 
1042 	if (disc->identity_count != 0) {
1043 		cable_plug_type = VDO_TYPEC_CABLE_TYPE(port->c_identity.vdo[0]);
1044 		switch (cable_plug_type) {
1045 		case CABLE_ATYPE:
1046 			c_desc.type = USB_PLUG_TYPE_A;
1047 			break;
1048 		case CABLE_BTYPE:
1049 			c_desc.type = USB_PLUG_TYPE_B;
1050 			break;
1051 		case CABLE_CTYPE:
1052 			c_desc.type = USB_PLUG_TYPE_C;
1053 			break;
1054 		case CABLE_CAPTIVE:
1055 			c_desc.type = USB_PLUG_CAPTIVE;
1056 			break;
1057 		default:
1058 			c_desc.type = USB_PLUG_NONE;
1059 		}
1060 		c_desc.active = PD_IDH_PTYPE(port->c_identity.id_header) == IDH_PTYPE_ACABLE;
1061 	}
1062 
1063 	c_desc.identity = &port->c_identity;
1064 	c_desc.pd_revision = pd_revision;
1065 
1066 	port->cable = typec_register_cable(port->port, &c_desc);
1067 	if (IS_ERR(port->cable)) {
1068 		ret = PTR_ERR(port->cable);
1069 		port->cable = NULL;
1070 		goto sop_prime_disc_exit;
1071 	}
1072 
1073 	p_desc.index = TYPEC_PLUG_SOP_P;
1074 	port->plug = typec_register_plug(port->cable, &p_desc);
1075 	if (IS_ERR(port->plug)) {
1076 		ret = PTR_ERR(port->plug);
1077 		port->plug = NULL;
1078 		goto sop_prime_disc_exit;
1079 	}
1080 
1081 	ret = cros_typec_register_altmodes(typec, port_num, false);
1082 	if (ret < 0) {
1083 		dev_err(typec->dev, "Failed to register plug altmodes, port: %d\n", port_num);
1084 		goto sop_prime_disc_exit;
1085 	}
1086 
1087 	return 0;
1088 
1089 sop_prime_disc_exit:
1090 	cros_typec_remove_cable(typec, port_num);
1091 	return ret;
1092 }
1093 
cros_typec_handle_sop_disc(struct cros_typec_data * typec,int port_num,u16 pd_revision)1094 static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_num, u16 pd_revision)
1095 {
1096 	struct cros_typec_port *port = typec->ports[port_num];
1097 	struct ec_response_typec_discovery *sop_disc = port->disc_data;
1098 	struct ec_params_typec_discovery req = {
1099 		.port = port_num,
1100 		.partner_type = TYPEC_PARTNER_SOP,
1101 	};
1102 	int ret = 0;
1103 
1104 	if (!port->partner) {
1105 		dev_err(typec->dev,
1106 			"SOP Discovery received without partner registered, port: %d\n",
1107 			port_num);
1108 		ret = -EINVAL;
1109 		goto disc_exit;
1110 	}
1111 
1112 	typec_partner_set_pd_revision(port->partner, pd_revision);
1113 
1114 	memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
1115 	ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
1116 			  sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
1117 	if (ret < 0) {
1118 		dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
1119 		goto disc_exit;
1120 	}
1121 
1122 	cros_typec_parse_pd_identity(&port->p_identity, sop_disc);
1123 
1124 	ret = typec_partner_set_identity(port->partner);
1125 	if (ret < 0) {
1126 		dev_err(typec->dev, "Failed to update partner PD identity, port: %d\n", port_num);
1127 		goto disc_exit;
1128 	}
1129 
1130 	ret = cros_typec_register_altmodes(typec, port_num, true);
1131 	if (ret < 0) {
1132 		dev_err(typec->dev, "Failed to register partner altmodes, port: %d\n", port_num);
1133 		goto disc_exit;
1134 	}
1135 
1136 disc_exit:
1137 	return ret;
1138 }
1139 
cros_typec_send_clear_event(struct cros_typec_data * typec,int port_num,u32 events_mask)1140 static int cros_typec_send_clear_event(struct cros_typec_data *typec, int port_num, u32 events_mask)
1141 {
1142 	struct ec_params_typec_control req = {
1143 		.port = port_num,
1144 		.command = TYPEC_CONTROL_COMMAND_CLEAR_EVENTS,
1145 		.clear_events_mask = events_mask,
1146 	};
1147 
1148 	return cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
1149 			   sizeof(req), NULL, 0);
1150 }
1151 
cros_typec_register_partner_pdos(struct cros_typec_data * typec,struct ec_response_typec_status * resp,int port_num)1152 static void cros_typec_register_partner_pdos(struct cros_typec_data *typec,
1153 					     struct ec_response_typec_status *resp, int port_num)
1154 {
1155 	struct usb_power_delivery_capabilities_desc caps_desc = {};
1156 	struct usb_power_delivery_desc desc = {
1157 		.revision = (le16_to_cpu(resp->sop_revision) & 0xff00) >> 4,
1158 	};
1159 	struct cros_typec_port *port = typec->ports[port_num];
1160 
1161 	if (!port->partner || port->partner_pd)
1162 		return;
1163 
1164 	/* If no caps are available, don't bother creating a device. */
1165 	if (!resp->source_cap_count && !resp->sink_cap_count)
1166 		return;
1167 
1168 	if (resp->source_cap_count > PDO_MAX_OBJECTS ||
1169 	    resp->sink_cap_count > PDO_MAX_OBJECTS) {
1170 		dev_warn(typec->dev, "Invalid PDO count from EC, port: %d\n", port_num);
1171 		return;
1172 	}
1173 
1174 	port->partner_pd = typec_partner_usb_power_delivery_register(port->partner, &desc);
1175 	if (IS_ERR(port->partner_pd)) {
1176 		dev_warn(typec->dev, "Failed to register partner PD device, port: %d\n", port_num);
1177 		return;
1178 	}
1179 
1180 	typec_partner_set_usb_power_delivery(port->partner, port->partner_pd);
1181 
1182 	memcpy(caps_desc.pdo, resp->source_cap_pdos, sizeof(u32) * resp->source_cap_count);
1183 	caps_desc.role = TYPEC_SOURCE;
1184 	port->partner_src_caps = usb_power_delivery_register_capabilities(port->partner_pd,
1185 									  &caps_desc);
1186 	if (IS_ERR(port->partner_src_caps))
1187 		dev_warn(typec->dev, "Failed to register source caps, port: %d\n", port_num);
1188 
1189 	memset(&caps_desc, 0, sizeof(caps_desc));
1190 	memcpy(caps_desc.pdo, resp->sink_cap_pdos, sizeof(u32) * resp->sink_cap_count);
1191 	caps_desc.role = TYPEC_SINK;
1192 	port->partner_sink_caps = usb_power_delivery_register_capabilities(port->partner_pd,
1193 									   &caps_desc);
1194 	if (IS_ERR(port->partner_sink_caps))
1195 		dev_warn(typec->dev, "Failed to register sink caps, port: %d\n", port_num);
1196 }
1197 
cros_typec_handle_status(struct cros_typec_data * typec,int port_num)1198 static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
1199 {
1200 	struct ec_response_typec_status resp;
1201 	struct ec_params_typec_status req = {
1202 		.port = port_num,
1203 	};
1204 	int ret;
1205 
1206 	ret = cros_ec_cmd(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
1207 			  &resp, sizeof(resp));
1208 	if (ret < 0) {
1209 		dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
1210 		return;
1211 	}
1212 
1213 	/* If we got a hard reset, unregister everything and return. */
1214 	if (resp.events & PD_STATUS_EVENT_HARD_RESET) {
1215 		cros_typec_remove_partner(typec, port_num);
1216 		cros_typec_remove_cable(typec, port_num);
1217 
1218 		ret = cros_typec_send_clear_event(typec, port_num,
1219 						  PD_STATUS_EVENT_HARD_RESET);
1220 		if (ret < 0)
1221 			dev_warn(typec->dev,
1222 				 "Failed hard reset event clear, port: %d\n", port_num);
1223 		return;
1224 	}
1225 
1226 	/* Handle any events appropriately. */
1227 	if (resp.events & PD_STATUS_EVENT_SOP_DISC_DONE && !typec->ports[port_num]->sop_disc_done) {
1228 		u16 sop_revision;
1229 
1230 		/* Convert BCD to the format preferred by the TypeC framework */
1231 		sop_revision = (le16_to_cpu(resp.sop_revision) & 0xff00) >> 4;
1232 		ret = cros_typec_handle_sop_disc(typec, port_num, sop_revision);
1233 		if (ret < 0)
1234 			dev_err(typec->dev, "Couldn't parse SOP Disc data, port: %d\n", port_num);
1235 		else {
1236 			typec->ports[port_num]->sop_disc_done = true;
1237 			ret = cros_typec_send_clear_event(typec, port_num,
1238 							  PD_STATUS_EVENT_SOP_DISC_DONE);
1239 			if (ret < 0)
1240 				dev_warn(typec->dev,
1241 					 "Failed SOP Disc event clear, port: %d\n", port_num);
1242 		}
1243 		if (resp.sop_connected)
1244 			typec_set_pwr_opmode(typec->ports[port_num]->port, TYPEC_PWR_MODE_PD);
1245 
1246 		cros_typec_register_partner_pdos(typec, &resp, port_num);
1247 	}
1248 
1249 	if (resp.events & PD_STATUS_EVENT_SOP_PRIME_DISC_DONE &&
1250 	    !typec->ports[port_num]->sop_prime_disc_done) {
1251 		u16 sop_prime_revision;
1252 
1253 		/* Convert BCD to the format preferred by the TypeC framework */
1254 		sop_prime_revision = (le16_to_cpu(resp.sop_prime_revision) & 0xff00) >> 4;
1255 		ret = cros_typec_handle_sop_prime_disc(typec, port_num, sop_prime_revision);
1256 		if (ret < 0)
1257 			dev_err(typec->dev, "Couldn't parse SOP' Disc data, port: %d\n", port_num);
1258 		else {
1259 			typec->ports[port_num]->sop_prime_disc_done = true;
1260 			ret = cros_typec_send_clear_event(typec, port_num,
1261 							  PD_STATUS_EVENT_SOP_PRIME_DISC_DONE);
1262 			if (ret < 0)
1263 				dev_warn(typec->dev,
1264 					 "Failed SOP Disc event clear, port: %d\n", port_num);
1265 		}
1266 	}
1267 
1268 	if (resp.events & PD_STATUS_EVENT_VDM_REQ_REPLY) {
1269 		cros_typec_handle_vdm_response(typec, port_num);
1270 		ret = cros_typec_send_clear_event(typec, port_num, PD_STATUS_EVENT_VDM_REQ_REPLY);
1271 		if (ret < 0)
1272 			dev_warn(typec->dev, "Failed VDM Reply event clear, port: %d\n", port_num);
1273 	}
1274 
1275 	if (resp.events & PD_STATUS_EVENT_VDM_ATTENTION) {
1276 		cros_typec_handle_vdm_attention(typec, port_num);
1277 		ret = cros_typec_send_clear_event(typec, port_num, PD_STATUS_EVENT_VDM_ATTENTION);
1278 		if (ret < 0)
1279 			dev_warn(typec->dev, "Failed VDM attention event clear, port: %d\n",
1280 				 port_num);
1281 	}
1282 }
1283 
cros_typec_port_update(struct cros_typec_data * typec,int port_num)1284 static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
1285 {
1286 	struct ec_params_usb_pd_control req;
1287 	struct ec_response_usb_pd_control_v2 resp;
1288 	int ret;
1289 
1290 	if (port_num < 0 || port_num >= typec->num_ports) {
1291 		dev_err(typec->dev, "cannot get status for invalid port %d\n",
1292 			port_num);
1293 		return -EINVAL;
1294 	}
1295 
1296 	req.port = port_num;
1297 	req.role = USB_PD_CTRL_ROLE_NO_CHANGE;
1298 	req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
1299 	req.swap = USB_PD_CTRL_SWAP_NONE;
1300 
1301 	ret = cros_ec_cmd(typec->ec, typec->pd_ctrl_ver,
1302 			  EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
1303 			  &resp, sizeof(resp));
1304 	if (ret < 0)
1305 		return ret;
1306 
1307 	/* Update the switches if they exist, according to requested state */
1308 	ret = cros_typec_configure_mux(typec, port_num, &resp);
1309 	if (ret)
1310 		dev_warn(typec->dev, "Configure muxes failed, err = %d\n", ret);
1311 
1312 	dev_dbg(typec->dev, "Enabled %d: 0x%hhx\n", port_num, resp.enabled);
1313 	dev_dbg(typec->dev, "Role %d: 0x%hhx\n", port_num, resp.role);
1314 	dev_dbg(typec->dev, "Polarity %d: 0x%hhx\n", port_num, resp.polarity);
1315 	dev_dbg(typec->dev, "State %d: %s\n", port_num, resp.state);
1316 
1317 	if (typec->pd_ctrl_ver != 0)
1318 		cros_typec_set_port_params_v1(typec, port_num,
1319 			(struct ec_response_usb_pd_control_v1 *)&resp);
1320 	else
1321 		cros_typec_set_port_params_v0(typec, port_num,
1322 			(struct ec_response_usb_pd_control *) &resp);
1323 
1324 	if (typec->typec_cmd_supported)
1325 		cros_typec_handle_status(typec, port_num);
1326 
1327 	return 0;
1328 }
1329 
cros_typec_get_cmd_version(struct cros_typec_data * typec)1330 static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
1331 {
1332 	struct ec_params_get_cmd_versions_v1 req_v1;
1333 	struct ec_response_get_cmd_versions resp;
1334 	int ret;
1335 
1336 	/* We're interested in the PD control command version. */
1337 	req_v1.cmd = EC_CMD_USB_PD_CONTROL;
1338 	ret = cros_ec_cmd(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS,
1339 			  &req_v1, sizeof(req_v1), &resp, sizeof(resp));
1340 	if (ret < 0)
1341 		return ret;
1342 
1343 	if (resp.version_mask & EC_VER_MASK(2))
1344 		typec->pd_ctrl_ver = 2;
1345 	else if (resp.version_mask & EC_VER_MASK(1))
1346 		typec->pd_ctrl_ver = 1;
1347 	else
1348 		typec->pd_ctrl_ver = 0;
1349 
1350 	dev_dbg(typec->dev, "PD Control has version mask 0x%02x\n",
1351 		typec->pd_ctrl_ver & 0xff);
1352 
1353 	return 0;
1354 }
1355 
cros_typec_port_work(struct work_struct * work)1356 static void cros_typec_port_work(struct work_struct *work)
1357 {
1358 	struct cros_typec_data *typec = container_of(work, struct cros_typec_data, port_work);
1359 	int ret, i;
1360 
1361 	for (i = 0; i < typec->num_ports; i++) {
1362 		ret = cros_typec_port_update(typec, i);
1363 		if (ret < 0)
1364 			dev_warn(typec->dev, "Update failed for port: %d\n", i);
1365 	}
1366 }
1367 
cros_ec_typec_event(struct notifier_block * nb,unsigned long host_event,void * _notify)1368 static int cros_ec_typec_event(struct notifier_block *nb,
1369 			       unsigned long host_event, void *_notify)
1370 {
1371 	struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
1372 
1373 	flush_work(&typec->port_work);
1374 	schedule_work(&typec->port_work);
1375 
1376 	return NOTIFY_OK;
1377 }
1378 
1379 #ifdef CONFIG_ACPI
1380 static const struct acpi_device_id cros_typec_acpi_id[] = {
1381 	{ "GOOG0014", 0 },
1382 	{}
1383 };
1384 MODULE_DEVICE_TABLE(acpi, cros_typec_acpi_id);
1385 #endif
1386 
1387 #ifdef CONFIG_OF
1388 static const struct of_device_id cros_typec_of_match[] = {
1389 	{ .compatible = "google,cros-ec-typec", },
1390 	{}
1391 };
1392 MODULE_DEVICE_TABLE(of, cros_typec_of_match);
1393 #endif
1394 
cros_typec_probe(struct platform_device * pdev)1395 static int cros_typec_probe(struct platform_device *pdev)
1396 {
1397 	struct cros_ec_dev *ec_dev = NULL;
1398 	struct device *dev = &pdev->dev;
1399 	struct cros_typec_data *typec;
1400 	struct ec_response_usb_pd_ports resp;
1401 	int ret, i;
1402 
1403 	typec = devm_kzalloc(dev, sizeof(*typec), GFP_KERNEL);
1404 	if (!typec)
1405 		return -ENOMEM;
1406 
1407 	typec->dev = dev;
1408 
1409 	typec->ec = dev_get_drvdata(pdev->dev.parent);
1410 	if (!typec->ec || !typec->ec->ec) {
1411 		dev_warn(dev, "couldn't find parent EC device\n");
1412 		return -EPROBE_DEFER;
1413 	}
1414 
1415 	platform_set_drvdata(pdev, typec);
1416 
1417 	ret = cros_typec_get_cmd_version(typec);
1418 	if (ret < 0) {
1419 		dev_err(dev, "failed to get PD command version info\n");
1420 		return ret;
1421 	}
1422 
1423 	ec_dev = dev_get_drvdata(&typec->ec->ec->dev);
1424 	if (!ec_dev)
1425 		return -EPROBE_DEFER;
1426 
1427 	typec->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD);
1428 	typec->needs_mux_ack = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK);
1429 	typec->ap_driven_altmode = cros_ec_check_features(
1430 		ec_dev, EC_FEATURE_TYPEC_REQUIRE_AP_MODE_ENTRY);
1431 
1432 	ret = cros_ec_cmd(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
1433 			  &resp, sizeof(resp));
1434 	if (ret < 0)
1435 		return ret;
1436 
1437 	typec->num_ports = resp.num_ports;
1438 	if (typec->num_ports > EC_USB_PD_MAX_PORTS) {
1439 		dev_warn(typec->dev,
1440 			 "Too many ports reported: %d, limiting to max: %d\n",
1441 			 typec->num_ports, EC_USB_PD_MAX_PORTS);
1442 		typec->num_ports = EC_USB_PD_MAX_PORTS;
1443 	}
1444 
1445 	ret = cros_typec_init_ports(typec);
1446 	if (ret < 0)
1447 		return ret;
1448 
1449 	INIT_WORK(&typec->port_work, cros_typec_port_work);
1450 
1451 	/*
1452 	 * Safe to call port update here, since we haven't registered the
1453 	 * PD notifier yet.
1454 	 */
1455 	for (i = 0; i < typec->num_ports; i++) {
1456 		ret = cros_typec_port_update(typec, i);
1457 		if (ret < 0)
1458 			goto unregister_ports;
1459 	}
1460 
1461 	typec->nb.notifier_call = cros_ec_typec_event;
1462 	ret = cros_usbpd_register_notify(&typec->nb);
1463 	if (ret < 0)
1464 		goto unregister_ports;
1465 
1466 	return 0;
1467 
1468 unregister_ports:
1469 	cros_unregister_ports(typec);
1470 	return ret;
1471 }
1472 
cros_typec_remove(struct platform_device * pdev)1473 static void cros_typec_remove(struct platform_device *pdev)
1474 {
1475 	struct cros_typec_data *typec = platform_get_drvdata(pdev);
1476 
1477 	cros_usbpd_unregister_notify(&typec->nb);
1478 	cancel_work_sync(&typec->port_work);
1479 	cros_unregister_ports(typec);
1480 }
1481 
cros_typec_suspend(struct device * dev)1482 static int __maybe_unused cros_typec_suspend(struct device *dev)
1483 {
1484 	struct cros_typec_data *typec = dev_get_drvdata(dev);
1485 
1486 	cancel_work_sync(&typec->port_work);
1487 
1488 	return 0;
1489 }
1490 
cros_typec_resume(struct device * dev)1491 static int __maybe_unused cros_typec_resume(struct device *dev)
1492 {
1493 	struct cros_typec_data *typec = dev_get_drvdata(dev);
1494 
1495 	/* Refresh port state. */
1496 	schedule_work(&typec->port_work);
1497 
1498 	return 0;
1499 }
1500 
1501 static const struct dev_pm_ops cros_typec_pm_ops = {
1502 	SET_SYSTEM_SLEEP_PM_OPS(cros_typec_suspend, cros_typec_resume)
1503 };
1504 
1505 static struct platform_driver cros_typec_driver = {
1506 	.driver	= {
1507 		.name = DRV_NAME,
1508 		.acpi_match_table = ACPI_PTR(cros_typec_acpi_id),
1509 		.of_match_table = of_match_ptr(cros_typec_of_match),
1510 		.pm = &cros_typec_pm_ops,
1511 	},
1512 	.probe = cros_typec_probe,
1513 	.remove = cros_typec_remove,
1514 };
1515 
1516 module_platform_driver(cros_typec_driver);
1517 
1518 MODULE_AUTHOR("Prashant Malani <pmalani@chromium.org>");
1519 MODULE_DESCRIPTION("Chrome OS EC Type C control");
1520 MODULE_LICENSE("GPL");
1521