Merge tag 'tag-chrome-platform-for-v5.11' of git://git.kernel.org/pub/scm/linux/kerne...
[platform/kernel/linux-starfive.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/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 /* Supported alt modes. */
29 enum {
30         CROS_EC_ALTMODE_DP = 0,
31         CROS_EC_ALTMODE_TBT,
32         CROS_EC_ALTMODE_MAX,
33 };
34
35 /* Container for altmode pointer nodes. */
36 struct cros_typec_altmode_node {
37         struct typec_altmode *amode;
38         struct list_head list;
39 };
40
41 /* Per port data. */
42 struct cros_typec_port {
43         struct typec_port *port;
44         /* Initial capabilities for the port. */
45         struct typec_capability caps;
46         struct typec_partner *partner;
47         /* Port partner PD identity info. */
48         struct usb_pd_identity p_identity;
49         struct typec_switch *ori_sw;
50         struct typec_mux *mux;
51         struct usb_role_switch *role_sw;
52
53         /* Variables keeping track of switch state. */
54         struct typec_mux_state state;
55         uint8_t mux_flags;
56
57         /* Port alt modes. */
58         struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX];
59
60         /* Flag indicating that PD discovery data parsing is completed. */
61         bool disc_done;
62         struct ec_response_typec_discovery *sop_disc;
63         struct list_head partner_mode_list;
64 };
65
66 /* Platform-specific data for the Chrome OS EC Type C controller. */
67 struct cros_typec_data {
68         struct device *dev;
69         struct cros_ec_device *ec;
70         int num_ports;
71         unsigned int pd_ctrl_ver;
72         /* Array of ports, indexed by port number. */
73         struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
74         struct notifier_block nb;
75         struct work_struct port_work;
76         bool typec_cmd_supported;
77 };
78
79 static int cros_typec_parse_port_props(struct typec_capability *cap,
80                                        struct fwnode_handle *fwnode,
81                                        struct device *dev)
82 {
83         const char *buf;
84         int ret;
85
86         memset(cap, 0, sizeof(*cap));
87         ret = fwnode_property_read_string(fwnode, "power-role", &buf);
88         if (ret) {
89                 dev_err(dev, "power-role not found: %d\n", ret);
90                 return ret;
91         }
92
93         ret = typec_find_port_power_role(buf);
94         if (ret < 0)
95                 return ret;
96         cap->type = ret;
97
98         ret = fwnode_property_read_string(fwnode, "data-role", &buf);
99         if (ret) {
100                 dev_err(dev, "data-role not found: %d\n", ret);
101                 return ret;
102         }
103
104         ret = typec_find_port_data_role(buf);
105         if (ret < 0)
106                 return ret;
107         cap->data = ret;
108
109         ret = fwnode_property_read_string(fwnode, "try-power-role", &buf);
110         if (ret) {
111                 dev_err(dev, "try-power-role not found: %d\n", ret);
112                 return ret;
113         }
114
115         ret = typec_find_power_role(buf);
116         if (ret < 0)
117                 return ret;
118         cap->prefer_role = ret;
119
120         cap->fwnode = fwnode;
121
122         return 0;
123 }
124
125 static int cros_typec_get_switch_handles(struct cros_typec_port *port,
126                                          struct fwnode_handle *fwnode,
127                                          struct device *dev)
128 {
129         port->mux = fwnode_typec_mux_get(fwnode, NULL);
130         if (IS_ERR(port->mux)) {
131                 dev_dbg(dev, "Mux handle not found.\n");
132                 goto mux_err;
133         }
134
135         port->ori_sw = fwnode_typec_switch_get(fwnode);
136         if (IS_ERR(port->ori_sw)) {
137                 dev_dbg(dev, "Orientation switch handle not found.\n");
138                 goto ori_sw_err;
139         }
140
141         port->role_sw = fwnode_usb_role_switch_get(fwnode);
142         if (IS_ERR(port->role_sw)) {
143                 dev_dbg(dev, "USB role switch handle not found.\n");
144                 goto role_sw_err;
145         }
146
147         return 0;
148
149 role_sw_err:
150         usb_role_switch_put(port->role_sw);
151 ori_sw_err:
152         typec_switch_put(port->ori_sw);
153 mux_err:
154         typec_mux_put(port->mux);
155
156         return -ENODEV;
157 }
158
159 static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
160                                   bool pd_en)
161 {
162         struct cros_typec_port *port = typec->ports[port_num];
163         struct typec_partner_desc p_desc = {
164                 .usb_pd = pd_en,
165         };
166         int ret = 0;
167
168         /*
169          * Fill an initial PD identity, which will then be updated with info
170          * from the EC.
171          */
172         p_desc.identity = &port->p_identity;
173
174         port->partner = typec_register_partner(port->port, &p_desc);
175         if (IS_ERR(port->partner)) {
176                 ret = PTR_ERR(port->partner);
177                 port->partner = NULL;
178         }
179
180         return ret;
181 }
182
183 static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int port_num)
184 {
185         struct cros_typec_port *port = typec->ports[port_num];
186         struct cros_typec_altmode_node *node, *tmp;
187
188         list_for_each_entry_safe(node, tmp, &port->partner_mode_list, list) {
189                 list_del(&node->list);
190                 typec_unregister_altmode(node->amode);
191                 devm_kfree(typec->dev, node);
192         }
193 }
194
195 static void cros_typec_remove_partner(struct cros_typec_data *typec,
196                                      int port_num)
197 {
198         struct cros_typec_port *port = typec->ports[port_num];
199
200         cros_typec_unregister_altmodes(typec, port_num);
201
202         port->state.alt = NULL;
203         port->state.mode = TYPEC_STATE_USB;
204         port->state.data = NULL;
205
206         usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
207         typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
208         typec_mux_set(port->mux, &port->state);
209
210         typec_unregister_partner(port->partner);
211         port->partner = NULL;
212         memset(&port->p_identity, 0, sizeof(port->p_identity));
213         port->disc_done = false;
214 }
215
216 static void cros_unregister_ports(struct cros_typec_data *typec)
217 {
218         int i;
219
220         for (i = 0; i < typec->num_ports; i++) {
221                 if (!typec->ports[i])
222                         continue;
223
224                 if (typec->ports[i]->partner)
225                         cros_typec_remove_partner(typec, i);
226
227                 usb_role_switch_put(typec->ports[i]->role_sw);
228                 typec_switch_put(typec->ports[i]->ori_sw);
229                 typec_mux_put(typec->ports[i]->mux);
230                 typec_unregister_port(typec->ports[i]->port);
231         }
232 }
233
234 /*
235  * Fake the alt mode structs until we actually start registering Type C port
236  * and partner alt modes.
237  */
238 static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
239                                               int port_num)
240 {
241         struct cros_typec_port *port = typec->ports[port_num];
242
243         /* All PD capable CrOS devices are assumed to support DP altmode. */
244         port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
245         port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
246
247         /*
248          * Register TBT compatibility alt mode. The EC will not enter the mode
249          * if it doesn't support it, so it's safe to register it unconditionally
250          * here for now.
251          */
252         port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
253         port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
254
255         port->state.alt = NULL;
256         port->state.mode = TYPEC_STATE_USB;
257         port->state.data = NULL;
258 }
259
260 static int cros_typec_init_ports(struct cros_typec_data *typec)
261 {
262         struct device *dev = typec->dev;
263         struct typec_capability *cap;
264         struct fwnode_handle *fwnode;
265         struct cros_typec_port *cros_port;
266         const char *port_prop;
267         int ret;
268         int nports;
269         u32 port_num = 0;
270
271         nports = device_get_child_node_count(dev);
272         if (nports == 0) {
273                 dev_err(dev, "No port entries found.\n");
274                 return -ENODEV;
275         }
276
277         if (nports > typec->num_ports) {
278                 dev_err(dev, "More ports listed than can be supported.\n");
279                 return -EINVAL;
280         }
281
282         /* DT uses "reg" to specify port number. */
283         port_prop = dev->of_node ? "reg" : "port-number";
284         device_for_each_child_node(dev, fwnode) {
285                 if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) {
286                         ret = -EINVAL;
287                         dev_err(dev, "No port-number for port, aborting.\n");
288                         goto unregister_ports;
289                 }
290
291                 if (port_num >= typec->num_ports) {
292                         dev_err(dev, "Invalid port number.\n");
293                         ret = -EINVAL;
294                         goto unregister_ports;
295                 }
296
297                 dev_dbg(dev, "Registering port %d\n", port_num);
298
299                 cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL);
300                 if (!cros_port) {
301                         ret = -ENOMEM;
302                         goto unregister_ports;
303                 }
304
305                 typec->ports[port_num] = cros_port;
306                 cap = &cros_port->caps;
307
308                 ret = cros_typec_parse_port_props(cap, fwnode, dev);
309                 if (ret < 0)
310                         goto unregister_ports;
311
312                 cros_port->port = typec_register_port(dev, cap);
313                 if (IS_ERR(cros_port->port)) {
314                         dev_err(dev, "Failed to register port %d\n", port_num);
315                         ret = PTR_ERR(cros_port->port);
316                         goto unregister_ports;
317                 }
318
319                 ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);
320                 if (ret)
321                         dev_dbg(dev, "No switch control for port %d\n",
322                                 port_num);
323
324                 cros_typec_register_port_altmodes(typec, port_num);
325
326                 cros_port->sop_disc = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
327                 if (!cros_port->sop_disc) {
328                         ret = -ENOMEM;
329                         goto unregister_ports;
330                 }
331
332                 INIT_LIST_HEAD(&cros_port->partner_mode_list);
333         }
334
335         return 0;
336
337 unregister_ports:
338         cros_unregister_ports(typec);
339         return ret;
340 }
341
342 static int cros_typec_ec_command(struct cros_typec_data *typec,
343                                  unsigned int version,
344                                  unsigned int command,
345                                  void *outdata,
346                                  unsigned int outsize,
347                                  void *indata,
348                                  unsigned int insize)
349 {
350         struct cros_ec_command *msg;
351         int ret;
352
353         msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
354         if (!msg)
355                 return -ENOMEM;
356
357         msg->version = version;
358         msg->command = command;
359         msg->outsize = outsize;
360         msg->insize = insize;
361
362         if (outsize)
363                 memcpy(msg->data, outdata, outsize);
364
365         ret = cros_ec_cmd_xfer_status(typec->ec, msg);
366         if (ret >= 0 && insize)
367                 memcpy(indata, msg->data, insize);
368
369         kfree(msg);
370         return ret;
371 }
372
373 static int cros_typec_usb_safe_state(struct cros_typec_port *port)
374 {
375         port->state.mode = TYPEC_STATE_SAFE;
376
377         return typec_mux_set(port->mux, &port->state);
378 }
379
380 /*
381  * Spoof the VDOs that were likely communicated by the partner for TBT alt
382  * mode.
383  */
384 static int cros_typec_enable_tbt(struct cros_typec_data *typec,
385                                  int port_num,
386                                  struct ec_response_usb_pd_control_v2 *pd_ctrl)
387 {
388         struct cros_typec_port *port = typec->ports[port_num];
389         struct typec_thunderbolt_data data;
390         int ret;
391
392         if (typec->pd_ctrl_ver < 2) {
393                 dev_err(typec->dev,
394                         "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
395                 return -ENOTSUPP;
396         }
397
398         /* Device Discover Mode VDO */
399         data.device_mode = TBT_MODE;
400
401         if (pd_ctrl->control_flags & USB_PD_CTRL_TBT_LEGACY_ADAPTER)
402                 data.device_mode = TBT_SET_ADAPTER(TBT_ADAPTER_TBT3);
403
404         /* Cable Discover Mode VDO */
405         data.cable_mode = TBT_MODE;
406         data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
407
408         if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
409                 data.cable_mode |= TBT_CABLE_OPTICAL;
410
411         if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_LINK_UNIDIR)
412                 data.cable_mode |= TBT_CABLE_LINK_TRAINING;
413
414         data.cable_mode |= TBT_SET_CABLE_ROUNDED(pd_ctrl->cable_gen);
415
416         /* Enter Mode VDO */
417         data.enter_vdo = TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
418
419         if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
420                 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
421
422         if (!port->state.alt) {
423                 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];
424                 ret = cros_typec_usb_safe_state(port);
425                 if (ret)
426                         return ret;
427         }
428
429         port->state.data = &data;
430         port->state.mode = TYPEC_TBT_MODE;
431
432         return typec_mux_set(port->mux, &port->state);
433 }
434
435 /* Spoof the VDOs that were likely communicated by the partner. */
436 static int cros_typec_enable_dp(struct cros_typec_data *typec,
437                                 int port_num,
438                                 struct ec_response_usb_pd_control_v2 *pd_ctrl)
439 {
440         struct cros_typec_port *port = typec->ports[port_num];
441         struct typec_displayport_data dp_data;
442         int ret;
443
444         if (typec->pd_ctrl_ver < 2) {
445                 dev_err(typec->dev,
446                         "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
447                 return -ENOTSUPP;
448         }
449
450         /* Status VDO. */
451         dp_data.status = DP_STATUS_ENABLED;
452         if (port->mux_flags & USB_PD_MUX_HPD_IRQ)
453                 dp_data.status |= DP_STATUS_IRQ_HPD;
454         if (port->mux_flags & USB_PD_MUX_HPD_LVL)
455                 dp_data.status |= DP_STATUS_HPD_STATE;
456
457         /* Configuration VDO. */
458         dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
459         if (!port->state.alt) {
460                 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_DP];
461                 ret = cros_typec_usb_safe_state(port);
462                 if (ret)
463                         return ret;
464         }
465
466         port->state.data = &dp_data;
467         port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
468
469         return typec_mux_set(port->mux, &port->state);
470 }
471
472 static int cros_typec_enable_usb4(struct cros_typec_data *typec,
473                                   int port_num,
474                                   struct ec_response_usb_pd_control_v2 *pd_ctrl)
475 {
476         struct cros_typec_port *port = typec->ports[port_num];
477         struct enter_usb_data data;
478
479         data.eudo = EUDO_USB_MODE_USB4 << EUDO_USB_MODE_SHIFT;
480
481         /* Cable Speed */
482         data.eudo |= pd_ctrl->cable_speed << EUDO_CABLE_SPEED_SHIFT;
483
484         /* Cable Type */
485         if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
486                 data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT;
487         else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
488                 data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT;
489
490         data.active_link_training = !!(pd_ctrl->control_flags &
491                                        USB_PD_CTRL_ACTIVE_LINK_UNIDIR);
492
493         port->state.alt = NULL;
494         port->state.data = &data;
495         port->state.mode = TYPEC_MODE_USB4;
496
497         return typec_mux_set(port->mux, &port->state);
498 }
499
500 static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
501                                 uint8_t mux_flags,
502                                 struct ec_response_usb_pd_control_v2 *pd_ctrl)
503 {
504         struct cros_typec_port *port = typec->ports[port_num];
505         enum typec_orientation orientation;
506         int ret;
507
508         if (!port->partner)
509                 return 0;
510
511         if (mux_flags & USB_PD_MUX_POLARITY_INVERTED)
512                 orientation = TYPEC_ORIENTATION_REVERSE;
513         else
514                 orientation = TYPEC_ORIENTATION_NORMAL;
515
516         ret = typec_switch_set(port->ori_sw, orientation);
517         if (ret)
518                 return ret;
519
520         ret = usb_role_switch_set_role(typec->ports[port_num]->role_sw,
521                                         pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA
522                                         ? USB_ROLE_HOST : USB_ROLE_DEVICE);
523         if (ret)
524                 return ret;
525
526         if (mux_flags & USB_PD_MUX_USB4_ENABLED) {
527                 ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl);
528         } else if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
529                 ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
530         } else if (mux_flags & USB_PD_MUX_DP_ENABLED) {
531                 ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
532         } else if (mux_flags & USB_PD_MUX_SAFE_MODE) {
533                 ret = cros_typec_usb_safe_state(port);
534         } else if (mux_flags & USB_PD_MUX_USB_ENABLED) {
535                 port->state.alt = NULL;
536                 port->state.mode = TYPEC_STATE_USB;
537                 ret = typec_mux_set(port->mux, &port->state);
538         } else {
539                 dev_dbg(typec->dev,
540                         "Unrecognized mode requested, mux flags: %x\n",
541                         mux_flags);
542         }
543
544         return ret;
545 }
546
547 static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
548                 int port_num, struct ec_response_usb_pd_control *resp)
549 {
550         struct typec_port *port = typec->ports[port_num]->port;
551         enum typec_orientation polarity;
552
553         if (!resp->enabled)
554                 polarity = TYPEC_ORIENTATION_NONE;
555         else if (!resp->polarity)
556                 polarity = TYPEC_ORIENTATION_NORMAL;
557         else
558                 polarity = TYPEC_ORIENTATION_REVERSE;
559
560         typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
561         typec_set_orientation(port, polarity);
562 }
563
564 static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
565                 int port_num, struct ec_response_usb_pd_control_v1 *resp)
566 {
567         struct typec_port *port = typec->ports[port_num]->port;
568         enum typec_orientation polarity;
569         bool pd_en;
570         int ret;
571
572         if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
573                 polarity = TYPEC_ORIENTATION_NONE;
574         else if (!resp->polarity)
575                 polarity = TYPEC_ORIENTATION_NORMAL;
576         else
577                 polarity = TYPEC_ORIENTATION_REVERSE;
578         typec_set_orientation(port, polarity);
579         typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
580                         TYPEC_HOST : TYPEC_DEVICE);
581         typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
582                         TYPEC_SOURCE : TYPEC_SINK);
583         typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
584                         TYPEC_SOURCE : TYPEC_SINK);
585
586         /* Register/remove partners when a connect/disconnect occurs. */
587         if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
588                 if (typec->ports[port_num]->partner)
589                         return;
590
591                 pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
592                 ret = cros_typec_add_partner(typec, port_num, pd_en);
593                 if (ret)
594                         dev_warn(typec->dev,
595                                  "Failed to register partner on port: %d\n",
596                                  port_num);
597         } else {
598                 if (!typec->ports[port_num]->partner)
599                         return;
600                 cros_typec_remove_partner(typec, port_num);
601         }
602 }
603
604 static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num,
605                                    struct ec_response_usb_pd_mux_info *resp)
606 {
607         struct ec_params_usb_pd_mux_info req = {
608                 .port = port_num,
609         };
610
611         return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req,
612                                      sizeof(req), resp, sizeof(*resp));
613 }
614
615 static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_num)
616 {
617         struct cros_typec_port *port = typec->ports[port_num];
618         struct ec_response_typec_discovery *sop_disc = port->sop_disc;
619         struct cros_typec_altmode_node *node;
620         struct typec_altmode_desc desc;
621         struct typec_altmode *amode;
622         int ret = 0;
623         int i, j;
624
625         for (i = 0; i < sop_disc->svid_count; i++) {
626                 for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
627                         memset(&desc, 0, sizeof(desc));
628                         desc.svid = sop_disc->svids[i].svid;
629                         desc.mode = j;
630                         desc.vdo = sop_disc->svids[i].mode_vdo[j];
631
632                         amode = typec_partner_register_altmode(port->partner, &desc);
633                         if (IS_ERR(amode)) {
634                                 ret = PTR_ERR(amode);
635                                 goto err_cleanup;
636                         }
637
638                         /* If no memory is available we should unregister and exit. */
639                         node = devm_kzalloc(typec->dev, sizeof(*node), GFP_KERNEL);
640                         if (!node) {
641                                 ret = -ENOMEM;
642                                 typec_unregister_altmode(amode);
643                                 goto err_cleanup;
644                         }
645
646                         node->amode = amode;
647                         list_add_tail(&node->list, &port->partner_mode_list);
648                 }
649         }
650
651         return 0;
652
653 err_cleanup:
654         cros_typec_unregister_altmodes(typec, port_num);
655         return ret;
656 }
657
658 static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_num)
659 {
660         struct cros_typec_port *port = typec->ports[port_num];
661         struct ec_response_typec_discovery *sop_disc = port->sop_disc;
662         struct ec_params_typec_discovery req = {
663                 .port = port_num,
664                 .partner_type = TYPEC_PARTNER_SOP,
665         };
666         int ret = 0;
667         int i;
668
669         if (!port->partner) {
670                 dev_err(typec->dev,
671                         "SOP Discovery received without partner registered, port: %d\n",
672                         port_num);
673                 ret = -EINVAL;
674                 goto disc_exit;
675         }
676
677         memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
678         ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
679                                     sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
680         if (ret < 0) {
681                 dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
682                 goto disc_exit;
683         }
684
685         /* First, update the PD identity VDOs for the partner. */
686         if (sop_disc->identity_count > 0)
687                 port->p_identity.id_header = sop_disc->discovery_vdo[0];
688         if (sop_disc->identity_count > 1)
689                 port->p_identity.cert_stat = sop_disc->discovery_vdo[1];
690         if (sop_disc->identity_count > 2)
691                 port->p_identity.product = sop_disc->discovery_vdo[2];
692
693         /* Copy the remaining identity VDOs till a maximum of 6. */
694         for (i = 3; i < sop_disc->identity_count && i < VDO_MAX_OBJECTS; i++)
695                 port->p_identity.vdo[i - 3] = sop_disc->discovery_vdo[i];
696
697         ret = typec_partner_set_identity(port->partner);
698         if (ret < 0) {
699                 dev_err(typec->dev, "Failed to update partner PD identity, port: %d\n", port_num);
700                 goto disc_exit;
701         }
702
703         ret = cros_typec_register_altmodes(typec, port_num);
704         if (ret < 0) {
705                 dev_err(typec->dev, "Failed to register partner altmodes, port: %d\n", port_num);
706                 goto disc_exit;
707         }
708
709 disc_exit:
710         return ret;
711 }
712
713 static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
714 {
715         struct ec_response_typec_status resp;
716         struct ec_params_typec_status req = {
717                 .port = port_num,
718         };
719         int ret;
720
721         ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
722                                     &resp, sizeof(resp));
723         if (ret < 0) {
724                 dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
725                 return;
726         }
727
728         if (typec->ports[port_num]->disc_done)
729                 return;
730
731         /* Handle any events appropriately. */
732         if (resp.events & PD_STATUS_EVENT_SOP_DISC_DONE) {
733                 ret = cros_typec_handle_sop_disc(typec, port_num);
734                 if (ret < 0) {
735                         dev_err(typec->dev, "Couldn't parse SOP Disc data, port: %d\n", port_num);
736                         return;
737                 }
738
739                 typec->ports[port_num]->disc_done = true;
740         }
741 }
742
743 static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
744 {
745         struct ec_params_usb_pd_control req;
746         struct ec_response_usb_pd_control_v2 resp;
747         struct ec_response_usb_pd_mux_info mux_resp;
748         int ret;
749
750         if (port_num < 0 || port_num >= typec->num_ports) {
751                 dev_err(typec->dev, "cannot get status for invalid port %d\n",
752                         port_num);
753                 return -EINVAL;
754         }
755
756         req.port = port_num;
757         req.role = USB_PD_CTRL_ROLE_NO_CHANGE;
758         req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
759         req.swap = USB_PD_CTRL_SWAP_NONE;
760
761         ret = cros_typec_ec_command(typec, typec->pd_ctrl_ver,
762                                     EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
763                                     &resp, sizeof(resp));
764         if (ret < 0)
765                 return ret;
766
767         dev_dbg(typec->dev, "Enabled %d: 0x%hhx\n", port_num, resp.enabled);
768         dev_dbg(typec->dev, "Role %d: 0x%hhx\n", port_num, resp.role);
769         dev_dbg(typec->dev, "Polarity %d: 0x%hhx\n", port_num, resp.polarity);
770         dev_dbg(typec->dev, "State %d: %s\n", port_num, resp.state);
771
772         if (typec->pd_ctrl_ver != 0)
773                 cros_typec_set_port_params_v1(typec, port_num,
774                         (struct ec_response_usb_pd_control_v1 *)&resp);
775         else
776                 cros_typec_set_port_params_v0(typec, port_num,
777                         (struct ec_response_usb_pd_control *) &resp);
778
779         if (typec->typec_cmd_supported)
780                 cros_typec_handle_status(typec, port_num);
781
782         /* Update the switches if they exist, according to requested state */
783         ret = cros_typec_get_mux_info(typec, port_num, &mux_resp);
784         if (ret < 0) {
785                 dev_warn(typec->dev,
786                          "Failed to get mux info for port: %d, err = %d\n",
787                          port_num, ret);
788                 return 0;
789         }
790
791         /* No change needs to be made, let's exit early. */
792         if (typec->ports[port_num]->mux_flags == mux_resp.flags)
793                 return 0;
794
795         typec->ports[port_num]->mux_flags = mux_resp.flags;
796         ret = cros_typec_configure_mux(typec, port_num, mux_resp.flags, &resp);
797         if (ret)
798                 dev_warn(typec->dev, "Configure muxes failed, err = %d\n", ret);
799
800         return ret;
801 }
802
803 static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
804 {
805         struct ec_params_get_cmd_versions_v1 req_v1;
806         struct ec_response_get_cmd_versions resp;
807         int ret;
808
809         /* We're interested in the PD control command version. */
810         req_v1.cmd = EC_CMD_USB_PD_CONTROL;
811         ret = cros_typec_ec_command(typec, 1, EC_CMD_GET_CMD_VERSIONS,
812                                     &req_v1, sizeof(req_v1), &resp,
813                                     sizeof(resp));
814         if (ret < 0)
815                 return ret;
816
817         if (resp.version_mask & EC_VER_MASK(2))
818                 typec->pd_ctrl_ver = 2;
819         else if (resp.version_mask & EC_VER_MASK(1))
820                 typec->pd_ctrl_ver = 1;
821         else
822                 typec->pd_ctrl_ver = 0;
823
824         dev_dbg(typec->dev, "PD Control has version mask 0x%hhx\n",
825                 typec->pd_ctrl_ver);
826
827         return 0;
828 }
829
830 /* Check the EC feature flags to see if TYPEC_* commands are supported. */
831 static int cros_typec_cmds_supported(struct cros_typec_data *typec)
832 {
833         struct ec_response_get_features resp = {};
834         int ret;
835
836         ret = cros_typec_ec_command(typec, 0, EC_CMD_GET_FEATURES, NULL, 0,
837                                     &resp, sizeof(resp));
838         if (ret < 0) {
839                 dev_warn(typec->dev,
840                          "Failed to get features, assuming typec commands unsupported.\n");
841                 return 0;
842         }
843
844         return resp.flags[EC_FEATURE_TYPEC_CMD / 32] & EC_FEATURE_MASK_1(EC_FEATURE_TYPEC_CMD);
845 }
846
847 static void cros_typec_port_work(struct work_struct *work)
848 {
849         struct cros_typec_data *typec = container_of(work, struct cros_typec_data, port_work);
850         int ret, i;
851
852         for (i = 0; i < typec->num_ports; i++) {
853                 ret = cros_typec_port_update(typec, i);
854                 if (ret < 0)
855                         dev_warn(typec->dev, "Update failed for port: %d\n", i);
856         }
857 }
858
859 static int cros_ec_typec_event(struct notifier_block *nb,
860                                unsigned long host_event, void *_notify)
861 {
862         struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
863
864         schedule_work(&typec->port_work);
865
866         return NOTIFY_OK;
867 }
868
869 #ifdef CONFIG_ACPI
870 static const struct acpi_device_id cros_typec_acpi_id[] = {
871         { "GOOG0014", 0 },
872         {}
873 };
874 MODULE_DEVICE_TABLE(acpi, cros_typec_acpi_id);
875 #endif
876
877 #ifdef CONFIG_OF
878 static const struct of_device_id cros_typec_of_match[] = {
879         { .compatible = "google,cros-ec-typec", },
880         {}
881 };
882 MODULE_DEVICE_TABLE(of, cros_typec_of_match);
883 #endif
884
885 static int cros_typec_probe(struct platform_device *pdev)
886 {
887         struct device *dev = &pdev->dev;
888         struct cros_typec_data *typec;
889         struct ec_response_usb_pd_ports resp;
890         int ret, i;
891
892         typec = devm_kzalloc(dev, sizeof(*typec), GFP_KERNEL);
893         if (!typec)
894                 return -ENOMEM;
895
896         typec->dev = dev;
897         typec->ec = dev_get_drvdata(pdev->dev.parent);
898         platform_set_drvdata(pdev, typec);
899
900         ret = cros_typec_get_cmd_version(typec);
901         if (ret < 0) {
902                 dev_err(dev, "failed to get PD command version info\n");
903                 return ret;
904         }
905
906         typec->typec_cmd_supported = !!cros_typec_cmds_supported(typec);
907
908         ret = cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
909                                     &resp, sizeof(resp));
910         if (ret < 0)
911                 return ret;
912
913         typec->num_ports = resp.num_ports;
914         if (typec->num_ports > EC_USB_PD_MAX_PORTS) {
915                 dev_warn(typec->dev,
916                          "Too many ports reported: %d, limiting to max: %d\n",
917                          typec->num_ports, EC_USB_PD_MAX_PORTS);
918                 typec->num_ports = EC_USB_PD_MAX_PORTS;
919         }
920
921         ret = cros_typec_init_ports(typec);
922         if (ret < 0)
923                 return ret;
924
925         INIT_WORK(&typec->port_work, cros_typec_port_work);
926
927         /*
928          * Safe to call port update here, since we haven't registered the
929          * PD notifier yet.
930          */
931         for (i = 0; i < typec->num_ports; i++) {
932                 ret = cros_typec_port_update(typec, i);
933                 if (ret < 0)
934                         goto unregister_ports;
935         }
936
937         typec->nb.notifier_call = cros_ec_typec_event;
938         ret = cros_usbpd_register_notify(&typec->nb);
939         if (ret < 0)
940                 goto unregister_ports;
941
942         return 0;
943
944 unregister_ports:
945         cros_unregister_ports(typec);
946         return ret;
947 }
948
949 static int __maybe_unused cros_typec_suspend(struct device *dev)
950 {
951         struct cros_typec_data *typec = dev_get_drvdata(dev);
952
953         cancel_work_sync(&typec->port_work);
954
955         return 0;
956 }
957
958 static int __maybe_unused cros_typec_resume(struct device *dev)
959 {
960         struct cros_typec_data *typec = dev_get_drvdata(dev);
961
962         /* Refresh port state. */
963         schedule_work(&typec->port_work);
964
965         return 0;
966 }
967
968 static const struct dev_pm_ops cros_typec_pm_ops = {
969         SET_SYSTEM_SLEEP_PM_OPS(cros_typec_suspend, cros_typec_resume)
970 };
971
972 static struct platform_driver cros_typec_driver = {
973         .driver = {
974                 .name = DRV_NAME,
975                 .acpi_match_table = ACPI_PTR(cros_typec_acpi_id),
976                 .of_match_table = of_match_ptr(cros_typec_of_match),
977                 .pm = &cros_typec_pm_ops,
978         },
979         .probe = cros_typec_probe,
980 };
981
982 module_platform_driver(cros_typec_driver);
983
984 MODULE_AUTHOR("Prashant Malani <pmalani@chromium.org>");
985 MODULE_DESCRIPTION("Chrome OS EC Type C control");
986 MODULE_LICENSE("GPL");