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