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