1
2
3
4
5
6
7
8
9#include <linux/acpi.h>
10#include <linux/list.h>
11#include <linux/module.h>
12#include <linux/of.h>
13#include <linux/platform_data/cros_ec_commands.h>
14#include <linux/platform_data/cros_ec_proto.h>
15#include <linux/platform_data/cros_usbpd_notify.h>
16#include <linux/platform_device.h>
17#include <linux/usb/pd.h>
18#include <linux/usb/pd_vdo.h>
19#include <linux/usb/typec.h>
20#include <linux/usb/typec_altmode.h>
21#include <linux/usb/typec_dp.h>
22#include <linux/usb/typec_mux.h>
23#include <linux/usb/typec_tbt.h>
24#include <linux/usb/role.h>
25
26#define DRV_NAME "cros-ec-typec"
27
28
29enum {
30 CROS_EC_ALTMODE_DP = 0,
31 CROS_EC_ALTMODE_TBT,
32 CROS_EC_ALTMODE_MAX,
33};
34
35
36struct cros_typec_altmode_node {
37 struct typec_altmode *amode;
38 struct list_head list;
39};
40
41
42struct cros_typec_port {
43 struct typec_port *port;
44
45 struct typec_capability caps;
46 struct typec_partner *partner;
47 struct typec_cable *cable;
48
49 struct typec_plug *plug;
50
51 struct usb_pd_identity p_identity;
52
53 struct usb_pd_identity c_identity;
54 struct typec_switch *ori_sw;
55 struct typec_mux *mux;
56 struct usb_role_switch *role_sw;
57
58
59 struct typec_mux_state state;
60 uint8_t mux_flags;
61 uint8_t role;
62
63
64 struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX];
65
66
67 bool sop_disc_done;
68 bool sop_prime_disc_done;
69 struct ec_response_typec_discovery *disc_data;
70 struct list_head partner_mode_list;
71 struct list_head plug_mode_list;
72};
73
74
75struct cros_typec_data {
76 struct device *dev;
77 struct cros_ec_device *ec;
78 int num_ports;
79 unsigned int pd_ctrl_ver;
80
81 struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
82 struct notifier_block nb;
83 struct work_struct port_work;
84 bool typec_cmd_supported;
85 bool needs_mux_ack;
86};
87
88static int cros_typec_parse_port_props(struct typec_capability *cap,
89 struct fwnode_handle *fwnode,
90 struct device *dev)
91{
92 const char *buf;
93 int ret;
94
95 memset(cap, 0, sizeof(*cap));
96 ret = fwnode_property_read_string(fwnode, "power-role", &buf);
97 if (ret) {
98 dev_err(dev, "power-role not found: %d\n", ret);
99 return ret;
100 }
101
102 ret = typec_find_port_power_role(buf);
103 if (ret < 0)
104 return ret;
105 cap->type = ret;
106
107 ret = fwnode_property_read_string(fwnode, "data-role", &buf);
108 if (ret) {
109 dev_err(dev, "data-role not found: %d\n", ret);
110 return ret;
111 }
112
113 ret = typec_find_port_data_role(buf);
114 if (ret < 0)
115 return ret;
116 cap->data = ret;
117
118
119 ret = fwnode_property_read_string(fwnode, "try-power-role", &buf);
120 if (ret) {
121 dev_warn(dev, "try-power-role not found: %d\n", ret);
122 cap->prefer_role = TYPEC_NO_PREFERRED_ROLE;
123 } else {
124 ret = typec_find_power_role(buf);
125 if (ret < 0)
126 return ret;
127 cap->prefer_role = ret;
128 }
129
130 cap->fwnode = fwnode;
131
132 return 0;
133}
134
135static int cros_typec_get_switch_handles(struct cros_typec_port *port,
136 struct fwnode_handle *fwnode,
137 struct device *dev)
138{
139 port->mux = fwnode_typec_mux_get(fwnode, NULL);
140 if (IS_ERR(port->mux)) {
141 dev_dbg(dev, "Mux handle not found.\n");
142 goto mux_err;
143 }
144
145 port->ori_sw = fwnode_typec_switch_get(fwnode);
146 if (IS_ERR(port->ori_sw)) {
147 dev_dbg(dev, "Orientation switch handle not found.\n");
148 goto ori_sw_err;
149 }
150
151 port->role_sw = fwnode_usb_role_switch_get(fwnode);
152 if (IS_ERR(port->role_sw)) {
153 dev_dbg(dev, "USB role switch handle not found.\n");
154 goto role_sw_err;
155 }
156
157 return 0;
158
159role_sw_err:
160 usb_role_switch_put(port->role_sw);
161ori_sw_err:
162 typec_switch_put(port->ori_sw);
163mux_err:
164 typec_mux_put(port->mux);
165
166 return -ENODEV;
167}
168
169static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
170 bool pd_en)
171{
172 struct cros_typec_port *port = typec->ports[port_num];
173 struct typec_partner_desc p_desc = {
174 .usb_pd = pd_en,
175 };
176 int ret = 0;
177
178
179
180
181
182 p_desc.identity = &port->p_identity;
183
184 port->partner = typec_register_partner(port->port, &p_desc);
185 if (IS_ERR(port->partner)) {
186 ret = PTR_ERR(port->partner);
187 port->partner = NULL;
188 }
189
190 return ret;
191}
192
193static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int port_num,
194 bool is_partner)
195{
196 struct cros_typec_port *port = typec->ports[port_num];
197 struct cros_typec_altmode_node *node, *tmp;
198 struct list_head *head;
199
200 head = is_partner ? &port->partner_mode_list : &port->plug_mode_list;
201 list_for_each_entry_safe(node, tmp, head, list) {
202 list_del(&node->list);
203 typec_unregister_altmode(node->amode);
204 devm_kfree(typec->dev, node);
205 }
206}
207
208static int cros_typec_usb_disconnect_state(struct cros_typec_port *port)
209{
210 port->state.alt = NULL;
211 port->state.mode = TYPEC_STATE_USB;
212 port->state.data = NULL;
213
214 usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
215 typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
216
217 return typec_mux_set(port->mux, &port->state);
218}
219
220static void cros_typec_remove_partner(struct cros_typec_data *typec,
221 int port_num)
222{
223 struct cros_typec_port *port = typec->ports[port_num];
224
225 if (!port->partner)
226 return;
227
228 cros_typec_unregister_altmodes(typec, port_num, true);
229
230 cros_typec_usb_disconnect_state(port);
231 port->mux_flags = USB_PD_MUX_NONE;
232
233 typec_unregister_partner(port->partner);
234 port->partner = NULL;
235 memset(&port->p_identity, 0, sizeof(port->p_identity));
236 port->sop_disc_done = false;
237}
238
239static void cros_typec_remove_cable(struct cros_typec_data *typec,
240 int port_num)
241{
242 struct cros_typec_port *port = typec->ports[port_num];
243
244 if (!port->cable)
245 return;
246
247 cros_typec_unregister_altmodes(typec, port_num, false);
248
249 typec_unregister_plug(port->plug);
250 port->plug = NULL;
251 typec_unregister_cable(port->cable);
252 port->cable = NULL;
253 memset(&port->c_identity, 0, sizeof(port->c_identity));
254 port->sop_prime_disc_done = false;
255}
256
257static void cros_unregister_ports(struct cros_typec_data *typec)
258{
259 int i;
260
261 for (i = 0; i < typec->num_ports; i++) {
262 if (!typec->ports[i])
263 continue;
264
265 cros_typec_remove_partner(typec, i);
266 cros_typec_remove_cable(typec, i);
267
268 usb_role_switch_put(typec->ports[i]->role_sw);
269 typec_switch_put(typec->ports[i]->ori_sw);
270 typec_mux_put(typec->ports[i]->mux);
271 typec_unregister_port(typec->ports[i]->port);
272 }
273}
274
275
276
277
278
279static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
280 int port_num)
281{
282 struct cros_typec_port *port = typec->ports[port_num];
283
284
285 port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
286 port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
287
288
289
290
291
292
293 port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
294 port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
295
296 port->state.alt = NULL;
297 port->state.mode = TYPEC_STATE_USB;
298 port->state.data = NULL;
299}
300
301static int cros_typec_init_ports(struct cros_typec_data *typec)
302{
303 struct device *dev = typec->dev;
304 struct typec_capability *cap;
305 struct fwnode_handle *fwnode;
306 struct cros_typec_port *cros_port;
307 const char *port_prop;
308 int ret;
309 int nports;
310 u32 port_num = 0;
311
312 nports = device_get_child_node_count(dev);
313 if (nports == 0) {
314 dev_err(dev, "No port entries found.\n");
315 return -ENODEV;
316 }
317
318 if (nports > typec->num_ports) {
319 dev_err(dev, "More ports listed than can be supported.\n");
320 return -EINVAL;
321 }
322
323
324 port_prop = dev->of_node ? "reg" : "port-number";
325 device_for_each_child_node(dev, fwnode) {
326 if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) {
327 ret = -EINVAL;
328 dev_err(dev, "No port-number for port, aborting.\n");
329 goto unregister_ports;
330 }
331
332 if (port_num >= typec->num_ports) {
333 dev_err(dev, "Invalid port number.\n");
334 ret = -EINVAL;
335 goto unregister_ports;
336 }
337
338 dev_dbg(dev, "Registering port %d\n", port_num);
339
340 cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL);
341 if (!cros_port) {
342 ret = -ENOMEM;
343 goto unregister_ports;
344 }
345
346 typec->ports[port_num] = cros_port;
347 cap = &cros_port->caps;
348
349 ret = cros_typec_parse_port_props(cap, fwnode, dev);
350 if (ret < 0)
351 goto unregister_ports;
352
353 cros_port->port = typec_register_port(dev, cap);
354 if (IS_ERR(cros_port->port)) {
355 dev_err(dev, "Failed to register port %d\n", port_num);
356 ret = PTR_ERR(cros_port->port);
357 goto unregister_ports;
358 }
359
360 ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);
361 if (ret)
362 dev_dbg(dev, "No switch control for port %d\n",
363 port_num);
364
365 cros_typec_register_port_altmodes(typec, port_num);
366
367 cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
368 if (!cros_port->disc_data) {
369 ret = -ENOMEM;
370 goto unregister_ports;
371 }
372
373 INIT_LIST_HEAD(&cros_port->partner_mode_list);
374 INIT_LIST_HEAD(&cros_port->plug_mode_list);
375 }
376
377 return 0;
378
379unregister_ports:
380 cros_unregister_ports(typec);
381 return ret;
382}
383
384static int cros_typec_usb_safe_state(struct cros_typec_port *port)
385{
386 port->state.mode = TYPEC_STATE_SAFE;
387
388 return typec_mux_set(port->mux, &port->state);
389}
390
391
392
393
394
395static int cros_typec_enable_tbt(struct cros_typec_data *typec,
396 int port_num,
397 struct ec_response_usb_pd_control_v2 *pd_ctrl)
398{
399 struct cros_typec_port *port = typec->ports[port_num];
400 struct typec_thunderbolt_data data;
401 int ret;
402
403 if (typec->pd_ctrl_ver < 2) {
404 dev_err(typec->dev,
405 "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
406 return -ENOTSUPP;
407 }
408
409
410 data.device_mode = TBT_MODE;
411
412 if (pd_ctrl->control_flags & USB_PD_CTRL_TBT_LEGACY_ADAPTER)
413 data.device_mode = TBT_SET_ADAPTER(TBT_ADAPTER_TBT3);
414
415
416 data.cable_mode = TBT_MODE;
417 data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
418
419 if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
420 data.cable_mode |= TBT_CABLE_OPTICAL;
421
422 if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_LINK_UNIDIR)
423 data.cable_mode |= TBT_CABLE_LINK_TRAINING;
424
425 data.cable_mode |= TBT_SET_CABLE_ROUNDED(pd_ctrl->cable_gen);
426
427
428 data.enter_vdo = TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
429
430 if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
431 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
432
433 if (!port->state.alt) {
434 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];
435 ret = cros_typec_usb_safe_state(port);
436 if (ret)
437 return ret;
438 }
439
440 port->state.data = &data;
441 port->state.mode = TYPEC_TBT_MODE;
442
443 return typec_mux_set(port->mux, &port->state);
444}
445
446
447static int cros_typec_enable_dp(struct cros_typec_data *typec,
448 int port_num,
449 struct ec_response_usb_pd_control_v2 *pd_ctrl)
450{
451 struct cros_typec_port *port = typec->ports[port_num];
452 struct typec_displayport_data dp_data;
453 int ret;
454
455 if (typec->pd_ctrl_ver < 2) {
456 dev_err(typec->dev,
457 "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
458 return -ENOTSUPP;
459 }
460
461 if (!pd_ctrl->dp_mode) {
462 dev_err(typec->dev, "No valid DP mode provided.\n");
463 return -EINVAL;
464 }
465
466
467 dp_data.status = DP_STATUS_ENABLED;
468 if (port->mux_flags & USB_PD_MUX_HPD_IRQ)
469 dp_data.status |= DP_STATUS_IRQ_HPD;
470 if (port->mux_flags & USB_PD_MUX_HPD_LVL)
471 dp_data.status |= DP_STATUS_HPD_STATE;
472
473
474 dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
475 if (!port->state.alt) {
476 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_DP];
477 ret = cros_typec_usb_safe_state(port);
478 if (ret)
479 return ret;
480 }
481
482 port->state.data = &dp_data;
483 port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
484
485 return typec_mux_set(port->mux, &port->state);
486}
487
488static int cros_typec_enable_usb4(struct cros_typec_data *typec,
489 int port_num,
490 struct ec_response_usb_pd_control_v2 *pd_ctrl)
491{
492 struct cros_typec_port *port = typec->ports[port_num];
493 struct enter_usb_data data;
494
495 data.eudo = EUDO_USB_MODE_USB4 << EUDO_USB_MODE_SHIFT;
496
497
498 data.eudo |= pd_ctrl->cable_speed << EUDO_CABLE_SPEED_SHIFT;
499
500
501 if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
502 data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT;
503 else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
504 data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT;
505
506 data.active_link_training = !!(pd_ctrl->control_flags &
507 USB_PD_CTRL_ACTIVE_LINK_UNIDIR);
508
509 port->state.alt = NULL;
510 port->state.data = &data;
511 port->state.mode = TYPEC_MODE_USB4;
512
513 return typec_mux_set(port->mux, &port->state);
514}
515
516static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
517 struct ec_response_usb_pd_control_v2 *pd_ctrl)
518{
519 struct cros_typec_port *port = typec->ports[port_num];
520 struct ec_response_usb_pd_mux_info resp;
521 struct ec_params_usb_pd_mux_info req = {
522 .port = port_num,
523 };
524 struct ec_params_usb_pd_mux_ack mux_ack;
525 enum typec_orientation orientation;
526 int ret;
527
528 ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_INFO,
529 &req, sizeof(req), &resp, sizeof(resp));
530 if (ret < 0) {
531 dev_warn(typec->dev, "Failed to get mux info for port: %d, err = %d\n",
532 port_num, ret);
533 return ret;
534 }
535
536
537 if (port->mux_flags == resp.flags && port->role == pd_ctrl->role)
538 return 0;
539
540 port->mux_flags = resp.flags;
541 port->role = pd_ctrl->role;
542
543 if (port->mux_flags == USB_PD_MUX_NONE) {
544 ret = cros_typec_usb_disconnect_state(port);
545 goto mux_ack;
546 }
547
548 if (port->mux_flags & USB_PD_MUX_POLARITY_INVERTED)
549 orientation = TYPEC_ORIENTATION_REVERSE;
550 else
551 orientation = TYPEC_ORIENTATION_NORMAL;
552
553 ret = typec_switch_set(port->ori_sw, orientation);
554 if (ret)
555 return ret;
556
557 ret = usb_role_switch_set_role(typec->ports[port_num]->role_sw,
558 pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA
559 ? USB_ROLE_HOST : USB_ROLE_DEVICE);
560 if (ret)
561 return ret;
562
563 if (port->mux_flags & USB_PD_MUX_USB4_ENABLED) {
564 ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl);
565 } else if (port->mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
566 ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
567 } else if (port->mux_flags & USB_PD_MUX_DP_ENABLED) {
568 ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
569 } else if (port->mux_flags & USB_PD_MUX_SAFE_MODE) {
570 ret = cros_typec_usb_safe_state(port);
571 } else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) {
572 port->state.alt = NULL;
573 port->state.mode = TYPEC_STATE_USB;
574 ret = typec_mux_set(port->mux, &port->state);
575 } else {
576 dev_dbg(typec->dev,
577 "Unrecognized mode requested, mux flags: %x\n",
578 port->mux_flags);
579 }
580
581mux_ack:
582 if (!typec->needs_mux_ack)
583 return ret;
584
585
586 mux_ack.port = port_num;
587
588 if (cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,
589 sizeof(mux_ack), NULL, 0) < 0)
590 dev_warn(typec->dev,
591 "Failed to send Mux ACK to EC for port: %d\n",
592 port_num);
593
594 return ret;
595}
596
597static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
598 int port_num, struct ec_response_usb_pd_control *resp)
599{
600 struct typec_port *port = typec->ports[port_num]->port;
601 enum typec_orientation polarity;
602
603 if (!resp->enabled)
604 polarity = TYPEC_ORIENTATION_NONE;
605 else if (!resp->polarity)
606 polarity = TYPEC_ORIENTATION_NORMAL;
607 else
608 polarity = TYPEC_ORIENTATION_REVERSE;
609
610 typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
611 typec_set_orientation(port, polarity);
612}
613
614static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
615 int port_num, struct ec_response_usb_pd_control_v1 *resp)
616{
617 struct typec_port *port = typec->ports[port_num]->port;
618 enum typec_orientation polarity;
619 bool pd_en;
620 int ret;
621
622 if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
623 polarity = TYPEC_ORIENTATION_NONE;
624 else if (!resp->polarity)
625 polarity = TYPEC_ORIENTATION_NORMAL;
626 else
627 polarity = TYPEC_ORIENTATION_REVERSE;
628 typec_set_orientation(port, polarity);
629 typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
630 TYPEC_HOST : TYPEC_DEVICE);
631 typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
632 TYPEC_SOURCE : TYPEC_SINK);
633 typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
634 TYPEC_SOURCE : TYPEC_SINK);
635
636
637 if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
638 if (typec->ports[port_num]->partner)
639 return;
640
641 pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
642 ret = cros_typec_add_partner(typec, port_num, pd_en);
643 if (ret)
644 dev_warn(typec->dev,
645 "Failed to register partner on port: %d\n",
646 port_num);
647 } else {
648 cros_typec_remove_partner(typec, port_num);
649 cros_typec_remove_cable(typec, port_num);
650 }
651}
652
653
654
655
656static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_num,
657 bool is_partner)
658{
659 struct cros_typec_port *port = typec->ports[port_num];
660 struct ec_response_typec_discovery *sop_disc = port->disc_data;
661 struct cros_typec_altmode_node *node;
662 struct typec_altmode_desc desc;
663 struct typec_altmode *amode;
664 int num_altmodes = 0;
665 int ret = 0;
666 int i, j;
667
668 for (i = 0; i < sop_disc->svid_count; i++) {
669 for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
670 memset(&desc, 0, sizeof(desc));
671 desc.svid = sop_disc->svids[i].svid;
672 desc.mode = j;
673 desc.vdo = sop_disc->svids[i].mode_vdo[j];
674
675 if (is_partner)
676 amode = typec_partner_register_altmode(port->partner, &desc);
677 else
678 amode = typec_plug_register_altmode(port->plug, &desc);
679
680 if (IS_ERR(amode)) {
681 ret = PTR_ERR(amode);
682 goto err_cleanup;
683 }
684
685
686 node = devm_kzalloc(typec->dev, sizeof(*node), GFP_KERNEL);
687 if (!node) {
688 ret = -ENOMEM;
689 typec_unregister_altmode(amode);
690 goto err_cleanup;
691 }
692
693 node->amode = amode;
694
695 if (is_partner)
696 list_add_tail(&node->list, &port->partner_mode_list);
697 else
698 list_add_tail(&node->list, &port->plug_mode_list);
699 num_altmodes++;
700 }
701 }
702
703 if (is_partner)
704 ret = typec_partner_set_num_altmodes(port->partner, num_altmodes);
705 else
706 ret = typec_plug_set_num_altmodes(port->plug, num_altmodes);
707
708 if (ret < 0) {
709 dev_err(typec->dev, "Unable to set %s num_altmodes for port: %d\n",
710 is_partner ? "partner" : "plug", port_num);
711 goto err_cleanup;
712 }
713
714 return 0;
715
716err_cleanup:
717 cros_typec_unregister_altmodes(typec, port_num, is_partner);
718 return ret;
719}
720
721
722
723
724
725static void cros_typec_parse_pd_identity(struct usb_pd_identity *id,
726 struct ec_response_typec_discovery *disc)
727{
728 int i;
729
730
731 if (disc->identity_count > 0)
732 id->id_header = disc->discovery_vdo[0];
733 if (disc->identity_count > 1)
734 id->cert_stat = disc->discovery_vdo[1];
735 if (disc->identity_count > 2)
736 id->product = disc->discovery_vdo[2];
737
738
739 for (i = 3; i < disc->identity_count && i < VDO_MAX_OBJECTS; i++)
740 id->vdo[i - 3] = disc->discovery_vdo[i];
741}
742
743static int cros_typec_handle_sop_prime_disc(struct cros_typec_data *typec, int port_num, u16 pd_revision)
744{
745 struct cros_typec_port *port = typec->ports[port_num];
746 struct ec_response_typec_discovery *disc = port->disc_data;
747 struct typec_cable_desc c_desc = {};
748 struct typec_plug_desc p_desc;
749 struct ec_params_typec_discovery req = {
750 .port = port_num,
751 .partner_type = TYPEC_PARTNER_SOP_PRIME,
752 };
753 u32 cable_plug_type;
754 int ret = 0;
755
756 memset(disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
757 ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
758 disc, EC_PROTO2_MAX_RESPONSE_SIZE);
759 if (ret < 0) {
760 dev_err(typec->dev, "Failed to get SOP' discovery data for port: %d\n", port_num);
761 goto sop_prime_disc_exit;
762 }
763
764
765 cros_typec_parse_pd_identity(&port->c_identity, disc);
766
767 if (disc->identity_count != 0) {
768 cable_plug_type = VDO_TYPEC_CABLE_TYPE(port->c_identity.vdo[0]);
769 switch (cable_plug_type) {
770 case CABLE_ATYPE:
771 c_desc.type = USB_PLUG_TYPE_A;
772 break;
773 case CABLE_BTYPE:
774 c_desc.type = USB_PLUG_TYPE_B;
775 break;
776 case CABLE_CTYPE:
777 c_desc.type = USB_PLUG_TYPE_C;
778 break;
779 case CABLE_CAPTIVE:
780 c_desc.type = USB_PLUG_CAPTIVE;
781 break;
782 default:
783 c_desc.type = USB_PLUG_NONE;
784 }
785 c_desc.active = PD_IDH_PTYPE(port->c_identity.id_header) == IDH_PTYPE_ACABLE;
786 }
787
788 c_desc.identity = &port->c_identity;
789 c_desc.pd_revision = pd_revision;
790
791 port->cable = typec_register_cable(port->port, &c_desc);
792 if (IS_ERR(port->cable)) {
793 ret = PTR_ERR(port->cable);
794 port->cable = NULL;
795 goto sop_prime_disc_exit;
796 }
797
798 p_desc.index = TYPEC_PLUG_SOP_P;
799 port->plug = typec_register_plug(port->cable, &p_desc);
800 if (IS_ERR(port->plug)) {
801 ret = PTR_ERR(port->plug);
802 port->plug = NULL;
803 goto sop_prime_disc_exit;
804 }
805
806 ret = cros_typec_register_altmodes(typec, port_num, false);
807 if (ret < 0) {
808 dev_err(typec->dev, "Failed to register plug altmodes, port: %d\n", port_num);
809 goto sop_prime_disc_exit;
810 }
811
812 return 0;
813
814sop_prime_disc_exit:
815 cros_typec_remove_cable(typec, port_num);
816 return ret;
817}
818
819static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_num, u16 pd_revision)
820{
821 struct cros_typec_port *port = typec->ports[port_num];
822 struct ec_response_typec_discovery *sop_disc = port->disc_data;
823 struct ec_params_typec_discovery req = {
824 .port = port_num,
825 .partner_type = TYPEC_PARTNER_SOP,
826 };
827 int ret = 0;
828
829 if (!port->partner) {
830 dev_err(typec->dev,
831 "SOP Discovery received without partner registered, port: %d\n",
832 port_num);
833 ret = -EINVAL;
834 goto disc_exit;
835 }
836
837 typec_partner_set_pd_revision(port->partner, pd_revision);
838
839 memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
840 ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
841 sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
842 if (ret < 0) {
843 dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
844 goto disc_exit;
845 }
846
847 cros_typec_parse_pd_identity(&port->p_identity, sop_disc);
848
849 ret = typec_partner_set_identity(port->partner);
850 if (ret < 0) {
851 dev_err(typec->dev, "Failed to update partner PD identity, port: %d\n", port_num);
852 goto disc_exit;
853 }
854
855 ret = cros_typec_register_altmodes(typec, port_num, true);
856 if (ret < 0) {
857 dev_err(typec->dev, "Failed to register partner altmodes, port: %d\n", port_num);
858 goto disc_exit;
859 }
860
861disc_exit:
862 return ret;
863}
864
865static int cros_typec_send_clear_event(struct cros_typec_data *typec, int port_num, u32 events_mask)
866{
867 struct ec_params_typec_control req = {
868 .port = port_num,
869 .command = TYPEC_CONTROL_COMMAND_CLEAR_EVENTS,
870 .clear_events_mask = events_mask,
871 };
872
873 return cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_CONTROL, &req,
874 sizeof(req), NULL, 0);
875}
876
877static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
878{
879 struct ec_response_typec_status resp;
880 struct ec_params_typec_status req = {
881 .port = port_num,
882 };
883 int ret;
884
885 ret = cros_ec_command(typec->ec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
886 &resp, sizeof(resp));
887 if (ret < 0) {
888 dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
889 return;
890 }
891
892
893 if (resp.events & PD_STATUS_EVENT_HARD_RESET) {
894 cros_typec_remove_partner(typec, port_num);
895 cros_typec_remove_cable(typec, port_num);
896
897 ret = cros_typec_send_clear_event(typec, port_num,
898 PD_STATUS_EVENT_HARD_RESET);
899 if (ret < 0)
900 dev_warn(typec->dev,
901 "Failed hard reset event clear, port: %d\n", port_num);
902 return;
903 }
904
905
906 if (resp.events & PD_STATUS_EVENT_SOP_DISC_DONE && !typec->ports[port_num]->sop_disc_done) {
907 u16 sop_revision;
908
909
910 sop_revision = (le16_to_cpu(resp.sop_revision) & 0xff00) >> 4;
911 ret = cros_typec_handle_sop_disc(typec, port_num, sop_revision);
912 if (ret < 0)
913 dev_err(typec->dev, "Couldn't parse SOP Disc data, port: %d\n", port_num);
914 else {
915 typec->ports[port_num]->sop_disc_done = true;
916 ret = cros_typec_send_clear_event(typec, port_num,
917 PD_STATUS_EVENT_SOP_DISC_DONE);
918 if (ret < 0)
919 dev_warn(typec->dev,
920 "Failed SOP Disc event clear, port: %d\n", port_num);
921 }
922 if (resp.sop_connected)
923 typec_set_pwr_opmode(typec->ports[port_num]->port, TYPEC_PWR_MODE_PD);
924 }
925
926 if (resp.events & PD_STATUS_EVENT_SOP_PRIME_DISC_DONE &&
927 !typec->ports[port_num]->sop_prime_disc_done) {
928 u16 sop_prime_revision;
929
930
931 sop_prime_revision = (le16_to_cpu(resp.sop_prime_revision) & 0xff00) >> 4;
932 ret = cros_typec_handle_sop_prime_disc(typec, port_num, sop_prime_revision);
933 if (ret < 0)
934 dev_err(typec->dev, "Couldn't parse SOP' Disc data, port: %d\n", port_num);
935 else {
936 typec->ports[port_num]->sop_prime_disc_done = true;
937 ret = cros_typec_send_clear_event(typec, port_num,
938 PD_STATUS_EVENT_SOP_PRIME_DISC_DONE);
939 if (ret < 0)
940 dev_warn(typec->dev,
941 "Failed SOP Disc event clear, port: %d\n", port_num);
942 }
943 }
944}
945
946static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
947{
948 struct ec_params_usb_pd_control req;
949 struct ec_response_usb_pd_control_v2 resp;
950 int ret;
951
952 if (port_num < 0 || port_num >= typec->num_ports) {
953 dev_err(typec->dev, "cannot get status for invalid port %d\n",
954 port_num);
955 return -EINVAL;
956 }
957
958 req.port = port_num;
959 req.role = USB_PD_CTRL_ROLE_NO_CHANGE;
960 req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
961 req.swap = USB_PD_CTRL_SWAP_NONE;
962
963 ret = cros_ec_command(typec->ec, typec->pd_ctrl_ver,
964 EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
965 &resp, sizeof(resp));
966 if (ret < 0)
967 return ret;
968
969
970 ret = cros_typec_configure_mux(typec, port_num, &resp);
971 if (ret)
972 dev_warn(typec->dev, "Configure muxes failed, err = %d\n", ret);
973
974 dev_dbg(typec->dev, "Enabled %d: 0x%hhx\n", port_num, resp.enabled);
975 dev_dbg(typec->dev, "Role %d: 0x%hhx\n", port_num, resp.role);
976 dev_dbg(typec->dev, "Polarity %d: 0x%hhx\n", port_num, resp.polarity);
977 dev_dbg(typec->dev, "State %d: %s\n", port_num, resp.state);
978
979 if (typec->pd_ctrl_ver != 0)
980 cros_typec_set_port_params_v1(typec, port_num,
981 (struct ec_response_usb_pd_control_v1 *)&resp);
982 else
983 cros_typec_set_port_params_v0(typec, port_num,
984 (struct ec_response_usb_pd_control *) &resp);
985
986 if (typec->typec_cmd_supported)
987 cros_typec_handle_status(typec, port_num);
988
989 return 0;
990}
991
992static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
993{
994 struct ec_params_get_cmd_versions_v1 req_v1;
995 struct ec_response_get_cmd_versions resp;
996 int ret;
997
998
999 req_v1.cmd = EC_CMD_USB_PD_CONTROL;
1000 ret = cros_ec_command(typec->ec, 1, EC_CMD_GET_CMD_VERSIONS,
1001 &req_v1, sizeof(req_v1), &resp,
1002 sizeof(resp));
1003 if (ret < 0)
1004 return ret;
1005
1006 if (resp.version_mask & EC_VER_MASK(2))
1007 typec->pd_ctrl_ver = 2;
1008 else if (resp.version_mask & EC_VER_MASK(1))
1009 typec->pd_ctrl_ver = 1;
1010 else
1011 typec->pd_ctrl_ver = 0;
1012
1013 dev_dbg(typec->dev, "PD Control has version mask 0x%02x\n",
1014 typec->pd_ctrl_ver & 0xff);
1015
1016 return 0;
1017}
1018
1019static void cros_typec_port_work(struct work_struct *work)
1020{
1021 struct cros_typec_data *typec = container_of(work, struct cros_typec_data, port_work);
1022 int ret, i;
1023
1024 for (i = 0; i < typec->num_ports; i++) {
1025 ret = cros_typec_port_update(typec, i);
1026 if (ret < 0)
1027 dev_warn(typec->dev, "Update failed for port: %d\n", i);
1028 }
1029}
1030
1031static int cros_ec_typec_event(struct notifier_block *nb,
1032 unsigned long host_event, void *_notify)
1033{
1034 struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
1035
1036 flush_work(&typec->port_work);
1037 schedule_work(&typec->port_work);
1038
1039 return NOTIFY_OK;
1040}
1041
1042#ifdef CONFIG_ACPI
1043static const struct acpi_device_id cros_typec_acpi_id[] = {
1044 { "GOOG0014", 0 },
1045 {}
1046};
1047MODULE_DEVICE_TABLE(acpi, cros_typec_acpi_id);
1048#endif
1049
1050#ifdef CONFIG_OF
1051static const struct of_device_id cros_typec_of_match[] = {
1052 { .compatible = "google,cros-ec-typec", },
1053 {}
1054};
1055MODULE_DEVICE_TABLE(of, cros_typec_of_match);
1056#endif
1057
1058static int cros_typec_probe(struct platform_device *pdev)
1059{
1060 struct cros_ec_dev *ec_dev = NULL;
1061 struct device *dev = &pdev->dev;
1062 struct cros_typec_data *typec;
1063 struct ec_response_usb_pd_ports resp;
1064 int ret, i;
1065
1066 typec = devm_kzalloc(dev, sizeof(*typec), GFP_KERNEL);
1067 if (!typec)
1068 return -ENOMEM;
1069
1070 typec->dev = dev;
1071
1072 typec->ec = dev_get_drvdata(pdev->dev.parent);
1073 if (!typec->ec) {
1074 dev_err(dev, "couldn't find parent EC device\n");
1075 return -ENODEV;
1076 }
1077
1078 platform_set_drvdata(pdev, typec);
1079
1080 ret = cros_typec_get_cmd_version(typec);
1081 if (ret < 0) {
1082 dev_err(dev, "failed to get PD command version info\n");
1083 return ret;
1084 }
1085
1086 ec_dev = dev_get_drvdata(&typec->ec->ec->dev);
1087 if (!ec_dev)
1088 return -EPROBE_DEFER;
1089
1090 typec->typec_cmd_supported = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_CMD);
1091 typec->needs_mux_ack = cros_ec_check_features(ec_dev, EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK);
1092
1093 ret = cros_ec_command(typec->ec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
1094 &resp, sizeof(resp));
1095 if (ret < 0)
1096 return ret;
1097
1098 typec->num_ports = resp.num_ports;
1099 if (typec->num_ports > EC_USB_PD_MAX_PORTS) {
1100 dev_warn(typec->dev,
1101 "Too many ports reported: %d, limiting to max: %d\n",
1102 typec->num_ports, EC_USB_PD_MAX_PORTS);
1103 typec->num_ports = EC_USB_PD_MAX_PORTS;
1104 }
1105
1106 ret = cros_typec_init_ports(typec);
1107 if (ret < 0)
1108 return ret;
1109
1110 INIT_WORK(&typec->port_work, cros_typec_port_work);
1111
1112
1113
1114
1115
1116 for (i = 0; i < typec->num_ports; i++) {
1117 ret = cros_typec_port_update(typec, i);
1118 if (ret < 0)
1119 goto unregister_ports;
1120 }
1121
1122 typec->nb.notifier_call = cros_ec_typec_event;
1123 ret = cros_usbpd_register_notify(&typec->nb);
1124 if (ret < 0)
1125 goto unregister_ports;
1126
1127 return 0;
1128
1129unregister_ports:
1130 cros_unregister_ports(typec);
1131 return ret;
1132}
1133
1134static int __maybe_unused cros_typec_suspend(struct device *dev)
1135{
1136 struct cros_typec_data *typec = dev_get_drvdata(dev);
1137
1138 cancel_work_sync(&typec->port_work);
1139
1140 return 0;
1141}
1142
1143static int __maybe_unused cros_typec_resume(struct device *dev)
1144{
1145 struct cros_typec_data *typec = dev_get_drvdata(dev);
1146
1147
1148 schedule_work(&typec->port_work);
1149
1150 return 0;
1151}
1152
1153static const struct dev_pm_ops cros_typec_pm_ops = {
1154 SET_SYSTEM_SLEEP_PM_OPS(cros_typec_suspend, cros_typec_resume)
1155};
1156
1157static struct platform_driver cros_typec_driver = {
1158 .driver = {
1159 .name = DRV_NAME,
1160 .acpi_match_table = ACPI_PTR(cros_typec_acpi_id),
1161 .of_match_table = of_match_ptr(cros_typec_of_match),
1162 .pm = &cros_typec_pm_ops,
1163 },
1164 .probe = cros_typec_probe,
1165};
1166
1167module_platform_driver(cros_typec_driver);
1168
1169MODULE_AUTHOR("Prashant Malani <pmalani@chromium.org>");
1170MODULE_DESCRIPTION("Chrome OS EC Type C control");
1171MODULE_LICENSE("GPL");
1172