platform/chrome: cros_ec_typec: fix clang -Wformat warning
[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         if (!port->partner)
224                 return;
225
226         cros_typec_unregister_altmodes(typec, port_num, true);
227
228         cros_typec_usb_disconnect_state(port);
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_unregister_ports(struct cros_typec_data *typec)
255 {
256         int i;
257
258         for (i = 0; i < typec->num_ports; i++) {
259                 if (!typec->ports[i])
260                         continue;
261
262                 cros_typec_remove_partner(typec, i);
263                 cros_typec_remove_cable(typec, i);
264
265                 usb_role_switch_put(typec->ports[i]->role_sw);
266                 typec_switch_put(typec->ports[i]->ori_sw);
267                 typec_mux_put(typec->ports[i]->mux);
268                 typec_unregister_port(typec->ports[i]->port);
269         }
270 }
271
272 /*
273  * Fake the alt mode structs until we actually start registering Type C port
274  * and partner alt modes.
275  */
276 static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
277                                               int port_num)
278 {
279         struct cros_typec_port *port = typec->ports[port_num];
280
281         /* All PD capable CrOS devices are assumed to support DP altmode. */
282         port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
283         port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
284
285         /*
286          * Register TBT compatibility alt mode. The EC will not enter the mode
287          * if it doesn't support it, so it's safe to register it unconditionally
288          * here for now.
289          */
290         port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
291         port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
292
293         port->state.alt = NULL;
294         port->state.mode = TYPEC_STATE_USB;
295         port->state.data = NULL;
296 }
297
298 static int cros_typec_init_ports(struct cros_typec_data *typec)
299 {
300         struct device *dev = typec->dev;
301         struct typec_capability *cap;
302         struct fwnode_handle *fwnode;
303         struct cros_typec_port *cros_port;
304         const char *port_prop;
305         int ret;
306         int nports;
307         u32 port_num = 0;
308
309         nports = device_get_child_node_count(dev);
310         if (nports == 0) {
311                 dev_err(dev, "No port entries found.\n");
312                 return -ENODEV;
313         }
314
315         if (nports > typec->num_ports) {
316                 dev_err(dev, "More ports listed than can be supported.\n");
317                 return -EINVAL;
318         }
319
320         /* DT uses "reg" to specify port number. */
321         port_prop = dev->of_node ? "reg" : "port-number";
322         device_for_each_child_node(dev, fwnode) {
323                 if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) {
324                         ret = -EINVAL;
325                         dev_err(dev, "No port-number for port, aborting.\n");
326                         goto unregister_ports;
327                 }
328
329                 if (port_num >= typec->num_ports) {
330                         dev_err(dev, "Invalid port number.\n");
331                         ret = -EINVAL;
332                         goto unregister_ports;
333                 }
334
335                 dev_dbg(dev, "Registering port %d\n", port_num);
336
337                 cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL);
338                 if (!cros_port) {
339                         ret = -ENOMEM;
340                         goto unregister_ports;
341                 }
342
343                 typec->ports[port_num] = cros_port;
344                 cap = &cros_port->caps;
345
346                 ret = cros_typec_parse_port_props(cap, fwnode, dev);
347                 if (ret < 0)
348                         goto unregister_ports;
349
350                 cros_port->port = typec_register_port(dev, cap);
351                 if (IS_ERR(cros_port->port)) {
352                         dev_err(dev, "Failed to register port %d\n", port_num);
353                         ret = PTR_ERR(cros_port->port);
354                         goto unregister_ports;
355                 }
356
357                 ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);
358                 if (ret)
359                         dev_dbg(dev, "No switch control for port %d\n",
360                                 port_num);
361
362                 cros_typec_register_port_altmodes(typec, port_num);
363
364                 cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
365                 if (!cros_port->disc_data) {
366                         ret = -ENOMEM;
367                         goto unregister_ports;
368                 }
369
370                 INIT_LIST_HEAD(&cros_port->partner_mode_list);
371                 INIT_LIST_HEAD(&cros_port->plug_mode_list);
372         }
373
374         return 0;
375
376 unregister_ports:
377         cros_unregister_ports(typec);
378         return ret;
379 }
380
381 static int cros_typec_ec_command(struct cros_typec_data *typec,
382                                  unsigned int version,
383                                  unsigned int command,
384                                  void *outdata,
385                                  unsigned int outsize,
386                                  void *indata,
387                                  unsigned int insize)
388 {
389         struct cros_ec_command *msg;
390         int ret;
391
392         msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
393         if (!msg)
394                 return -ENOMEM;
395
396         msg->version = version;
397         msg->command = command;
398         msg->outsize = outsize;
399         msg->insize = insize;
400
401         if (outsize)
402                 memcpy(msg->data, outdata, outsize);
403
404         ret = cros_ec_cmd_xfer_status(typec->ec, msg);
405         if (ret >= 0 && insize)
406                 memcpy(indata, msg->data, insize);
407
408         kfree(msg);
409         return ret;
410 }
411
412 static int cros_typec_usb_safe_state(struct cros_typec_port *port)
413 {
414         port->state.mode = TYPEC_STATE_SAFE;
415
416         return typec_mux_set(port->mux, &port->state);
417 }
418
419 /*
420  * Spoof the VDOs that were likely communicated by the partner for TBT alt
421  * mode.
422  */
423 static int cros_typec_enable_tbt(struct cros_typec_data *typec,
424                                  int port_num,
425                                  struct ec_response_usb_pd_control_v2 *pd_ctrl)
426 {
427         struct cros_typec_port *port = typec->ports[port_num];
428         struct typec_thunderbolt_data data;
429         int ret;
430
431         if (typec->pd_ctrl_ver < 2) {
432                 dev_err(typec->dev,
433                         "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
434                 return -ENOTSUPP;
435         }
436
437         /* Device Discover Mode VDO */
438         data.device_mode = TBT_MODE;
439
440         if (pd_ctrl->control_flags & USB_PD_CTRL_TBT_LEGACY_ADAPTER)
441                 data.device_mode = TBT_SET_ADAPTER(TBT_ADAPTER_TBT3);
442
443         /* Cable Discover Mode VDO */
444         data.cable_mode = TBT_MODE;
445         data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
446
447         if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
448                 data.cable_mode |= TBT_CABLE_OPTICAL;
449
450         if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_LINK_UNIDIR)
451                 data.cable_mode |= TBT_CABLE_LINK_TRAINING;
452
453         data.cable_mode |= TBT_SET_CABLE_ROUNDED(pd_ctrl->cable_gen);
454
455         /* Enter Mode VDO */
456         data.enter_vdo = TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
457
458         if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
459                 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
460
461         if (!port->state.alt) {
462                 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];
463                 ret = cros_typec_usb_safe_state(port);
464                 if (ret)
465                         return ret;
466         }
467
468         port->state.data = &data;
469         port->state.mode = TYPEC_TBT_MODE;
470
471         return typec_mux_set(port->mux, &port->state);
472 }
473
474 /* Spoof the VDOs that were likely communicated by the partner. */
475 static int cros_typec_enable_dp(struct cros_typec_data *typec,
476                                 int port_num,
477                                 struct ec_response_usb_pd_control_v2 *pd_ctrl)
478 {
479         struct cros_typec_port *port = typec->ports[port_num];
480         struct typec_displayport_data dp_data;
481         int ret;
482
483         if (typec->pd_ctrl_ver < 2) {
484                 dev_err(typec->dev,
485                         "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
486                 return -ENOTSUPP;
487         }
488
489         /* Status VDO. */
490         dp_data.status = DP_STATUS_ENABLED;
491         if (port->mux_flags & USB_PD_MUX_HPD_IRQ)
492                 dp_data.status |= DP_STATUS_IRQ_HPD;
493         if (port->mux_flags & USB_PD_MUX_HPD_LVL)
494                 dp_data.status |= DP_STATUS_HPD_STATE;
495
496         /* Configuration VDO. */
497         dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
498         if (!port->state.alt) {
499                 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_DP];
500                 ret = cros_typec_usb_safe_state(port);
501                 if (ret)
502                         return ret;
503         }
504
505         port->state.data = &dp_data;
506         port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
507
508         return typec_mux_set(port->mux, &port->state);
509 }
510
511 static int cros_typec_enable_usb4(struct cros_typec_data *typec,
512                                   int port_num,
513                                   struct ec_response_usb_pd_control_v2 *pd_ctrl)
514 {
515         struct cros_typec_port *port = typec->ports[port_num];
516         struct enter_usb_data data;
517
518         data.eudo = EUDO_USB_MODE_USB4 << EUDO_USB_MODE_SHIFT;
519
520         /* Cable Speed */
521         data.eudo |= pd_ctrl->cable_speed << EUDO_CABLE_SPEED_SHIFT;
522
523         /* Cable Type */
524         if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
525                 data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT;
526         else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
527                 data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT;
528
529         data.active_link_training = !!(pd_ctrl->control_flags &
530                                        USB_PD_CTRL_ACTIVE_LINK_UNIDIR);
531
532         port->state.alt = NULL;
533         port->state.data = &data;
534         port->state.mode = TYPEC_MODE_USB4;
535
536         return typec_mux_set(port->mux, &port->state);
537 }
538
539 static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
540                                 uint8_t mux_flags,
541                                 struct ec_response_usb_pd_control_v2 *pd_ctrl)
542 {
543         struct cros_typec_port *port = typec->ports[port_num];
544         struct ec_params_usb_pd_mux_ack mux_ack;
545         enum typec_orientation orientation;
546         int ret;
547
548         if (mux_flags == USB_PD_MUX_NONE) {
549                 ret = cros_typec_usb_disconnect_state(port);
550                 goto mux_ack;
551         }
552
553         if (mux_flags & USB_PD_MUX_POLARITY_INVERTED)
554                 orientation = TYPEC_ORIENTATION_REVERSE;
555         else
556                 orientation = TYPEC_ORIENTATION_NORMAL;
557
558         ret = typec_switch_set(port->ori_sw, orientation);
559         if (ret)
560                 return ret;
561
562         ret = usb_role_switch_set_role(typec->ports[port_num]->role_sw,
563                                         pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA
564                                         ? USB_ROLE_HOST : USB_ROLE_DEVICE);
565         if (ret)
566                 return ret;
567
568         if (mux_flags & USB_PD_MUX_USB4_ENABLED) {
569                 ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl);
570         } else if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
571                 ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
572         } else if (mux_flags & USB_PD_MUX_DP_ENABLED) {
573                 ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
574         } else if (mux_flags & USB_PD_MUX_SAFE_MODE) {
575                 ret = cros_typec_usb_safe_state(port);
576         } else if (mux_flags & USB_PD_MUX_USB_ENABLED) {
577                 port->state.alt = NULL;
578                 port->state.mode = TYPEC_STATE_USB;
579                 ret = typec_mux_set(port->mux, &port->state);
580         } else {
581                 dev_dbg(typec->dev,
582                         "Unrecognized mode requested, mux flags: %x\n",
583                         mux_flags);
584         }
585
586 mux_ack:
587         if (!typec->needs_mux_ack)
588                 return ret;
589
590         /* Sending Acknowledgment to EC */
591         mux_ack.port = port_num;
592
593         if (cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_ACK, &mux_ack,
594                                   sizeof(mux_ack), NULL, 0) < 0)
595                 dev_warn(typec->dev,
596                          "Failed to send Mux ACK to EC for port: %d\n",
597                          port_num);
598
599         return ret;
600 }
601
602 static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
603                 int port_num, struct ec_response_usb_pd_control *resp)
604 {
605         struct typec_port *port = typec->ports[port_num]->port;
606         enum typec_orientation polarity;
607
608         if (!resp->enabled)
609                 polarity = TYPEC_ORIENTATION_NONE;
610         else if (!resp->polarity)
611                 polarity = TYPEC_ORIENTATION_NORMAL;
612         else
613                 polarity = TYPEC_ORIENTATION_REVERSE;
614
615         typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
616         typec_set_orientation(port, polarity);
617 }
618
619 static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
620                 int port_num, struct ec_response_usb_pd_control_v1 *resp)
621 {
622         struct typec_port *port = typec->ports[port_num]->port;
623         enum typec_orientation polarity;
624         bool pd_en;
625         int ret;
626
627         if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
628                 polarity = TYPEC_ORIENTATION_NONE;
629         else if (!resp->polarity)
630                 polarity = TYPEC_ORIENTATION_NORMAL;
631         else
632                 polarity = TYPEC_ORIENTATION_REVERSE;
633         typec_set_orientation(port, polarity);
634         typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
635                         TYPEC_HOST : TYPEC_DEVICE);
636         typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
637                         TYPEC_SOURCE : TYPEC_SINK);
638         typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
639                         TYPEC_SOURCE : TYPEC_SINK);
640
641         /* Register/remove partners when a connect/disconnect occurs. */
642         if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
643                 if (typec->ports[port_num]->partner)
644                         return;
645
646                 pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
647                 ret = cros_typec_add_partner(typec, port_num, pd_en);
648                 if (ret)
649                         dev_warn(typec->dev,
650                                  "Failed to register partner on port: %d\n",
651                                  port_num);
652         } else {
653                 cros_typec_remove_partner(typec, port_num);
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%02x\n",
1031                 typec->pd_ctrl_ver & 0xff);
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");