1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright 2020 Google LLC
5 * This driver provides the ability to view and manage Type C ports through the
9 #include <linux/acpi.h>
10 #include <linux/list.h>
11 #include <linux/module.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>
26 #define DRV_NAME "cros-ec-typec"
28 /* Supported alt modes. */
30 CROS_EC_ALTMODE_DP = 0,
35 /* Container for altmode pointer nodes. */
36 struct cros_typec_altmode_node {
37 struct typec_altmode *amode;
38 struct list_head list;
42 struct cros_typec_port {
43 struct typec_port *port;
44 /* Initial capabilities for the port. */
45 struct typec_capability caps;
46 struct typec_partner *partner;
47 /* Port partner PD identity info. */
48 struct usb_pd_identity p_identity;
49 struct typec_switch *ori_sw;
50 struct typec_mux *mux;
51 struct usb_role_switch *role_sw;
53 /* Variables keeping track of switch state. */
54 struct typec_mux_state state;
58 struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX];
60 /* Flag indicating that PD discovery data parsing is completed. */
62 struct ec_response_typec_discovery *sop_disc;
63 struct list_head partner_mode_list;
66 /* Platform-specific data for the Chrome OS EC Type C controller. */
67 struct cros_typec_data {
69 struct cros_ec_device *ec;
71 unsigned int pd_ctrl_ver;
72 /* Array of ports, indexed by port number. */
73 struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
74 struct notifier_block nb;
75 struct work_struct port_work;
76 bool typec_cmd_supported;
79 static int cros_typec_parse_port_props(struct typec_capability *cap,
80 struct fwnode_handle *fwnode,
86 memset(cap, 0, sizeof(*cap));
87 ret = fwnode_property_read_string(fwnode, "power-role", &buf);
89 dev_err(dev, "power-role not found: %d\n", ret);
93 ret = typec_find_port_power_role(buf);
98 ret = fwnode_property_read_string(fwnode, "data-role", &buf);
100 dev_err(dev, "data-role not found: %d\n", ret);
104 ret = typec_find_port_data_role(buf);
109 ret = fwnode_property_read_string(fwnode, "try-power-role", &buf);
111 dev_err(dev, "try-power-role not found: %d\n", ret);
115 ret = typec_find_power_role(buf);
118 cap->prefer_role = ret;
120 cap->fwnode = fwnode;
125 static int cros_typec_get_switch_handles(struct cros_typec_port *port,
126 struct fwnode_handle *fwnode,
129 port->mux = fwnode_typec_mux_get(fwnode, NULL);
130 if (IS_ERR(port->mux)) {
131 dev_dbg(dev, "Mux handle not found.\n");
135 port->ori_sw = fwnode_typec_switch_get(fwnode);
136 if (IS_ERR(port->ori_sw)) {
137 dev_dbg(dev, "Orientation switch handle not found.\n");
141 port->role_sw = fwnode_usb_role_switch_get(fwnode);
142 if (IS_ERR(port->role_sw)) {
143 dev_dbg(dev, "USB role switch handle not found.\n");
150 usb_role_switch_put(port->role_sw);
152 typec_switch_put(port->ori_sw);
154 typec_mux_put(port->mux);
159 static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
162 struct cros_typec_port *port = typec->ports[port_num];
163 struct typec_partner_desc p_desc = {
169 * Fill an initial PD identity, which will then be updated with info
172 p_desc.identity = &port->p_identity;
174 port->partner = typec_register_partner(port->port, &p_desc);
175 if (IS_ERR(port->partner)) {
176 ret = PTR_ERR(port->partner);
177 port->partner = NULL;
183 static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int port_num)
185 struct cros_typec_port *port = typec->ports[port_num];
186 struct cros_typec_altmode_node *node, *tmp;
188 list_for_each_entry_safe(node, tmp, &port->partner_mode_list, list) {
189 list_del(&node->list);
190 typec_unregister_altmode(node->amode);
191 devm_kfree(typec->dev, node);
195 static void cros_typec_remove_partner(struct cros_typec_data *typec,
198 struct cros_typec_port *port = typec->ports[port_num];
200 cros_typec_unregister_altmodes(typec, port_num);
202 port->state.alt = NULL;
203 port->state.mode = TYPEC_STATE_USB;
204 port->state.data = NULL;
206 usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE);
207 typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE);
208 typec_mux_set(port->mux, &port->state);
210 typec_unregister_partner(port->partner);
211 port->partner = NULL;
212 memset(&port->p_identity, 0, sizeof(port->p_identity));
213 port->disc_done = false;
216 static void cros_unregister_ports(struct cros_typec_data *typec)
220 for (i = 0; i < typec->num_ports; i++) {
221 if (!typec->ports[i])
224 if (typec->ports[i]->partner)
225 cros_typec_remove_partner(typec, i);
227 usb_role_switch_put(typec->ports[i]->role_sw);
228 typec_switch_put(typec->ports[i]->ori_sw);
229 typec_mux_put(typec->ports[i]->mux);
230 typec_unregister_port(typec->ports[i]->port);
235 * Fake the alt mode structs until we actually start registering Type C port
236 * and partner alt modes.
238 static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
241 struct cros_typec_port *port = typec->ports[port_num];
243 /* All PD capable CrOS devices are assumed to support DP altmode. */
244 port->p_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
245 port->p_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
248 * Register TBT compatibility alt mode. The EC will not enter the mode
249 * if it doesn't support it, so it's safe to register it unconditionally
252 port->p_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
253 port->p_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
255 port->state.alt = NULL;
256 port->state.mode = TYPEC_STATE_USB;
257 port->state.data = NULL;
260 static int cros_typec_init_ports(struct cros_typec_data *typec)
262 struct device *dev = typec->dev;
263 struct typec_capability *cap;
264 struct fwnode_handle *fwnode;
265 struct cros_typec_port *cros_port;
266 const char *port_prop;
271 nports = device_get_child_node_count(dev);
273 dev_err(dev, "No port entries found.\n");
277 if (nports > typec->num_ports) {
278 dev_err(dev, "More ports listed than can be supported.\n");
282 /* DT uses "reg" to specify port number. */
283 port_prop = dev->of_node ? "reg" : "port-number";
284 device_for_each_child_node(dev, fwnode) {
285 if (fwnode_property_read_u32(fwnode, port_prop, &port_num)) {
287 dev_err(dev, "No port-number for port, aborting.\n");
288 goto unregister_ports;
291 if (port_num >= typec->num_ports) {
292 dev_err(dev, "Invalid port number.\n");
294 goto unregister_ports;
297 dev_dbg(dev, "Registering port %d\n", port_num);
299 cros_port = devm_kzalloc(dev, sizeof(*cros_port), GFP_KERNEL);
302 goto unregister_ports;
305 typec->ports[port_num] = cros_port;
306 cap = &cros_port->caps;
308 ret = cros_typec_parse_port_props(cap, fwnode, dev);
310 goto unregister_ports;
312 cros_port->port = typec_register_port(dev, cap);
313 if (IS_ERR(cros_port->port)) {
314 dev_err(dev, "Failed to register port %d\n", port_num);
315 ret = PTR_ERR(cros_port->port);
316 goto unregister_ports;
319 ret = cros_typec_get_switch_handles(cros_port, fwnode, dev);
321 dev_dbg(dev, "No switch control for port %d\n",
324 cros_typec_register_port_altmodes(typec, port_num);
326 cros_port->sop_disc = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
327 if (!cros_port->sop_disc) {
329 goto unregister_ports;
332 INIT_LIST_HEAD(&cros_port->partner_mode_list);
338 cros_unregister_ports(typec);
342 static int cros_typec_ec_command(struct cros_typec_data *typec,
343 unsigned int version,
344 unsigned int command,
346 unsigned int outsize,
350 struct cros_ec_command *msg;
353 msg = kzalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL);
357 msg->version = version;
358 msg->command = command;
359 msg->outsize = outsize;
360 msg->insize = insize;
363 memcpy(msg->data, outdata, outsize);
365 ret = cros_ec_cmd_xfer_status(typec->ec, msg);
366 if (ret >= 0 && insize)
367 memcpy(indata, msg->data, insize);
373 static int cros_typec_usb_safe_state(struct cros_typec_port *port)
375 port->state.mode = TYPEC_STATE_SAFE;
377 return typec_mux_set(port->mux, &port->state);
381 * Spoof the VDOs that were likely communicated by the partner for TBT alt
384 static int cros_typec_enable_tbt(struct cros_typec_data *typec,
386 struct ec_response_usb_pd_control_v2 *pd_ctrl)
388 struct cros_typec_port *port = typec->ports[port_num];
389 struct typec_thunderbolt_data data;
392 if (typec->pd_ctrl_ver < 2) {
394 "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
398 /* Device Discover Mode VDO */
399 data.device_mode = TBT_MODE;
401 if (pd_ctrl->control_flags & USB_PD_CTRL_TBT_LEGACY_ADAPTER)
402 data.device_mode = TBT_SET_ADAPTER(TBT_ADAPTER_TBT3);
404 /* Cable Discover Mode VDO */
405 data.cable_mode = TBT_MODE;
406 data.cable_mode |= TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
408 if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
409 data.cable_mode |= TBT_CABLE_OPTICAL;
411 if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_LINK_UNIDIR)
412 data.cable_mode |= TBT_CABLE_LINK_TRAINING;
414 data.cable_mode |= TBT_SET_CABLE_ROUNDED(pd_ctrl->cable_gen);
417 data.enter_vdo = TBT_SET_CABLE_SPEED(pd_ctrl->cable_speed);
419 if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
420 data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
422 if (!port->state.alt) {
423 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_TBT];
424 ret = cros_typec_usb_safe_state(port);
429 port->state.data = &data;
430 port->state.mode = TYPEC_TBT_MODE;
432 return typec_mux_set(port->mux, &port->state);
435 /* Spoof the VDOs that were likely communicated by the partner. */
436 static int cros_typec_enable_dp(struct cros_typec_data *typec,
438 struct ec_response_usb_pd_control_v2 *pd_ctrl)
440 struct cros_typec_port *port = typec->ports[port_num];
441 struct typec_displayport_data dp_data;
444 if (typec->pd_ctrl_ver < 2) {
446 "PD_CTRL version too old: %d\n", typec->pd_ctrl_ver);
451 dp_data.status = DP_STATUS_ENABLED;
452 if (port->mux_flags & USB_PD_MUX_HPD_IRQ)
453 dp_data.status |= DP_STATUS_IRQ_HPD;
454 if (port->mux_flags & USB_PD_MUX_HPD_LVL)
455 dp_data.status |= DP_STATUS_HPD_STATE;
457 /* Configuration VDO. */
458 dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
459 if (!port->state.alt) {
460 port->state.alt = &port->p_altmode[CROS_EC_ALTMODE_DP];
461 ret = cros_typec_usb_safe_state(port);
466 port->state.data = &dp_data;
467 port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode));
469 return typec_mux_set(port->mux, &port->state);
472 static int cros_typec_enable_usb4(struct cros_typec_data *typec,
474 struct ec_response_usb_pd_control_v2 *pd_ctrl)
476 struct cros_typec_port *port = typec->ports[port_num];
477 struct enter_usb_data data;
479 data.eudo = EUDO_USB_MODE_USB4 << EUDO_USB_MODE_SHIFT;
482 data.eudo |= pd_ctrl->cable_speed << EUDO_CABLE_SPEED_SHIFT;
485 if (pd_ctrl->control_flags & USB_PD_CTRL_OPTICAL_CABLE)
486 data.eudo |= EUDO_CABLE_TYPE_OPTICAL << EUDO_CABLE_TYPE_SHIFT;
487 else if (pd_ctrl->control_flags & USB_PD_CTRL_ACTIVE_CABLE)
488 data.eudo |= EUDO_CABLE_TYPE_RE_TIMER << EUDO_CABLE_TYPE_SHIFT;
490 data.active_link_training = !!(pd_ctrl->control_flags &
491 USB_PD_CTRL_ACTIVE_LINK_UNIDIR);
493 port->state.alt = NULL;
494 port->state.data = &data;
495 port->state.mode = TYPEC_MODE_USB4;
497 return typec_mux_set(port->mux, &port->state);
500 static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
502 struct ec_response_usb_pd_control_v2 *pd_ctrl)
504 struct cros_typec_port *port = typec->ports[port_num];
505 enum typec_orientation orientation;
511 if (mux_flags & USB_PD_MUX_POLARITY_INVERTED)
512 orientation = TYPEC_ORIENTATION_REVERSE;
514 orientation = TYPEC_ORIENTATION_NORMAL;
516 ret = typec_switch_set(port->ori_sw, orientation);
520 ret = usb_role_switch_set_role(typec->ports[port_num]->role_sw,
521 pd_ctrl->role & PD_CTRL_RESP_ROLE_DATA
522 ? USB_ROLE_HOST : USB_ROLE_DEVICE);
526 if (mux_flags & USB_PD_MUX_USB4_ENABLED) {
527 ret = cros_typec_enable_usb4(typec, port_num, pd_ctrl);
528 } else if (mux_flags & USB_PD_MUX_TBT_COMPAT_ENABLED) {
529 ret = cros_typec_enable_tbt(typec, port_num, pd_ctrl);
530 } else if (mux_flags & USB_PD_MUX_DP_ENABLED) {
531 ret = cros_typec_enable_dp(typec, port_num, pd_ctrl);
532 } else if (mux_flags & USB_PD_MUX_SAFE_MODE) {
533 ret = cros_typec_usb_safe_state(port);
534 } else if (mux_flags & USB_PD_MUX_USB_ENABLED) {
535 port->state.alt = NULL;
536 port->state.mode = TYPEC_STATE_USB;
537 ret = typec_mux_set(port->mux, &port->state);
540 "Unrecognized mode requested, mux flags: %x\n",
547 static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
548 int port_num, struct ec_response_usb_pd_control *resp)
550 struct typec_port *port = typec->ports[port_num]->port;
551 enum typec_orientation polarity;
554 polarity = TYPEC_ORIENTATION_NONE;
555 else if (!resp->polarity)
556 polarity = TYPEC_ORIENTATION_NORMAL;
558 polarity = TYPEC_ORIENTATION_REVERSE;
560 typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
561 typec_set_orientation(port, polarity);
564 static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
565 int port_num, struct ec_response_usb_pd_control_v1 *resp)
567 struct typec_port *port = typec->ports[port_num]->port;
568 enum typec_orientation polarity;
572 if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
573 polarity = TYPEC_ORIENTATION_NONE;
574 else if (!resp->polarity)
575 polarity = TYPEC_ORIENTATION_NORMAL;
577 polarity = TYPEC_ORIENTATION_REVERSE;
578 typec_set_orientation(port, polarity);
579 typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
580 TYPEC_HOST : TYPEC_DEVICE);
581 typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
582 TYPEC_SOURCE : TYPEC_SINK);
583 typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
584 TYPEC_SOURCE : TYPEC_SINK);
586 /* Register/remove partners when a connect/disconnect occurs. */
587 if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
588 if (typec->ports[port_num]->partner)
591 pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
592 ret = cros_typec_add_partner(typec, port_num, pd_en);
595 "Failed to register partner on port: %d\n",
598 if (!typec->ports[port_num]->partner)
600 cros_typec_remove_partner(typec, port_num);
604 static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num,
605 struct ec_response_usb_pd_mux_info *resp)
607 struct ec_params_usb_pd_mux_info req = {
611 return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req,
612 sizeof(req), resp, sizeof(*resp));
615 static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_num)
617 struct cros_typec_port *port = typec->ports[port_num];
618 struct ec_response_typec_discovery *sop_disc = port->sop_disc;
619 struct cros_typec_altmode_node *node;
620 struct typec_altmode_desc desc;
621 struct typec_altmode *amode;
625 for (i = 0; i < sop_disc->svid_count; i++) {
626 for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
627 memset(&desc, 0, sizeof(desc));
628 desc.svid = sop_disc->svids[i].svid;
630 desc.vdo = sop_disc->svids[i].mode_vdo[j];
632 amode = typec_partner_register_altmode(port->partner, &desc);
634 ret = PTR_ERR(amode);
638 /* If no memory is available we should unregister and exit. */
639 node = devm_kzalloc(typec->dev, sizeof(*node), GFP_KERNEL);
642 typec_unregister_altmode(amode);
647 list_add_tail(&node->list, &port->partner_mode_list);
654 cros_typec_unregister_altmodes(typec, port_num);
658 static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_num)
660 struct cros_typec_port *port = typec->ports[port_num];
661 struct ec_response_typec_discovery *sop_disc = port->sop_disc;
662 struct ec_params_typec_discovery req = {
664 .partner_type = TYPEC_PARTNER_SOP,
669 if (!port->partner) {
671 "SOP Discovery received without partner registered, port: %d\n",
677 memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
678 ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
679 sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
681 dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
685 /* First, update the PD identity VDOs for the partner. */
686 if (sop_disc->identity_count > 0)
687 port->p_identity.id_header = sop_disc->discovery_vdo[0];
688 if (sop_disc->identity_count > 1)
689 port->p_identity.cert_stat = sop_disc->discovery_vdo[1];
690 if (sop_disc->identity_count > 2)
691 port->p_identity.product = sop_disc->discovery_vdo[2];
693 /* Copy the remaining identity VDOs till a maximum of 6. */
694 for (i = 3; i < sop_disc->identity_count && i < VDO_MAX_OBJECTS; i++)
695 port->p_identity.vdo[i - 3] = sop_disc->discovery_vdo[i];
697 ret = typec_partner_set_identity(port->partner);
699 dev_err(typec->dev, "Failed to update partner PD identity, port: %d\n", port_num);
703 ret = cros_typec_register_altmodes(typec, port_num);
705 dev_err(typec->dev, "Failed to register partner altmodes, port: %d\n", port_num);
713 static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
715 struct ec_response_typec_status resp;
716 struct ec_params_typec_status req = {
721 ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
722 &resp, sizeof(resp));
724 dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
728 if (typec->ports[port_num]->disc_done)
731 /* Handle any events appropriately. */
732 if (resp.events & PD_STATUS_EVENT_SOP_DISC_DONE) {
733 ret = cros_typec_handle_sop_disc(typec, port_num);
735 dev_err(typec->dev, "Couldn't parse SOP Disc data, port: %d\n", port_num);
739 typec->ports[port_num]->disc_done = true;
743 static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
745 struct ec_params_usb_pd_control req;
746 struct ec_response_usb_pd_control_v2 resp;
747 struct ec_response_usb_pd_mux_info mux_resp;
750 if (port_num < 0 || port_num >= typec->num_ports) {
751 dev_err(typec->dev, "cannot get status for invalid port %d\n",
757 req.role = USB_PD_CTRL_ROLE_NO_CHANGE;
758 req.mux = USB_PD_CTRL_MUX_NO_CHANGE;
759 req.swap = USB_PD_CTRL_SWAP_NONE;
761 ret = cros_typec_ec_command(typec, typec->pd_ctrl_ver,
762 EC_CMD_USB_PD_CONTROL, &req, sizeof(req),
763 &resp, sizeof(resp));
767 dev_dbg(typec->dev, "Enabled %d: 0x%hhx\n", port_num, resp.enabled);
768 dev_dbg(typec->dev, "Role %d: 0x%hhx\n", port_num, resp.role);
769 dev_dbg(typec->dev, "Polarity %d: 0x%hhx\n", port_num, resp.polarity);
770 dev_dbg(typec->dev, "State %d: %s\n", port_num, resp.state);
772 if (typec->pd_ctrl_ver != 0)
773 cros_typec_set_port_params_v1(typec, port_num,
774 (struct ec_response_usb_pd_control_v1 *)&resp);
776 cros_typec_set_port_params_v0(typec, port_num,
777 (struct ec_response_usb_pd_control *) &resp);
779 if (typec->typec_cmd_supported)
780 cros_typec_handle_status(typec, port_num);
782 /* Update the switches if they exist, according to requested state */
783 ret = cros_typec_get_mux_info(typec, port_num, &mux_resp);
786 "Failed to get mux info for port: %d, err = %d\n",
791 /* No change needs to be made, let's exit early. */
792 if (typec->ports[port_num]->mux_flags == mux_resp.flags)
795 typec->ports[port_num]->mux_flags = mux_resp.flags;
796 ret = cros_typec_configure_mux(typec, port_num, mux_resp.flags, &resp);
798 dev_warn(typec->dev, "Configure muxes failed, err = %d\n", ret);
803 static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
805 struct ec_params_get_cmd_versions_v1 req_v1;
806 struct ec_response_get_cmd_versions resp;
809 /* We're interested in the PD control command version. */
810 req_v1.cmd = EC_CMD_USB_PD_CONTROL;
811 ret = cros_typec_ec_command(typec, 1, EC_CMD_GET_CMD_VERSIONS,
812 &req_v1, sizeof(req_v1), &resp,
817 if (resp.version_mask & EC_VER_MASK(2))
818 typec->pd_ctrl_ver = 2;
819 else if (resp.version_mask & EC_VER_MASK(1))
820 typec->pd_ctrl_ver = 1;
822 typec->pd_ctrl_ver = 0;
824 dev_dbg(typec->dev, "PD Control has version mask 0x%hhx\n",
830 /* Check the EC feature flags to see if TYPEC_* commands are supported. */
831 static int cros_typec_cmds_supported(struct cros_typec_data *typec)
833 struct ec_response_get_features resp = {};
836 ret = cros_typec_ec_command(typec, 0, EC_CMD_GET_FEATURES, NULL, 0,
837 &resp, sizeof(resp));
840 "Failed to get features, assuming typec commands unsupported.\n");
844 return resp.flags[EC_FEATURE_TYPEC_CMD / 32] & EC_FEATURE_MASK_1(EC_FEATURE_TYPEC_CMD);
847 static void cros_typec_port_work(struct work_struct *work)
849 struct cros_typec_data *typec = container_of(work, struct cros_typec_data, port_work);
852 for (i = 0; i < typec->num_ports; i++) {
853 ret = cros_typec_port_update(typec, i);
855 dev_warn(typec->dev, "Update failed for port: %d\n", i);
859 static int cros_ec_typec_event(struct notifier_block *nb,
860 unsigned long host_event, void *_notify)
862 struct cros_typec_data *typec = container_of(nb, struct cros_typec_data, nb);
864 schedule_work(&typec->port_work);
870 static const struct acpi_device_id cros_typec_acpi_id[] = {
874 MODULE_DEVICE_TABLE(acpi, cros_typec_acpi_id);
878 static const struct of_device_id cros_typec_of_match[] = {
879 { .compatible = "google,cros-ec-typec", },
882 MODULE_DEVICE_TABLE(of, cros_typec_of_match);
885 static int cros_typec_probe(struct platform_device *pdev)
887 struct device *dev = &pdev->dev;
888 struct cros_typec_data *typec;
889 struct ec_response_usb_pd_ports resp;
892 typec = devm_kzalloc(dev, sizeof(*typec), GFP_KERNEL);
897 typec->ec = dev_get_drvdata(pdev->dev.parent);
898 platform_set_drvdata(pdev, typec);
900 ret = cros_typec_get_cmd_version(typec);
902 dev_err(dev, "failed to get PD command version info\n");
906 typec->typec_cmd_supported = !!cros_typec_cmds_supported(typec);
908 ret = cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
909 &resp, sizeof(resp));
913 typec->num_ports = resp.num_ports;
914 if (typec->num_ports > EC_USB_PD_MAX_PORTS) {
916 "Too many ports reported: %d, limiting to max: %d\n",
917 typec->num_ports, EC_USB_PD_MAX_PORTS);
918 typec->num_ports = EC_USB_PD_MAX_PORTS;
921 ret = cros_typec_init_ports(typec);
925 INIT_WORK(&typec->port_work, cros_typec_port_work);
928 * Safe to call port update here, since we haven't registered the
931 for (i = 0; i < typec->num_ports; i++) {
932 ret = cros_typec_port_update(typec, i);
934 goto unregister_ports;
937 typec->nb.notifier_call = cros_ec_typec_event;
938 ret = cros_usbpd_register_notify(&typec->nb);
940 goto unregister_ports;
945 cros_unregister_ports(typec);
949 static int __maybe_unused cros_typec_suspend(struct device *dev)
951 struct cros_typec_data *typec = dev_get_drvdata(dev);
953 cancel_work_sync(&typec->port_work);
958 static int __maybe_unused cros_typec_resume(struct device *dev)
960 struct cros_typec_data *typec = dev_get_drvdata(dev);
962 /* Refresh port state. */
963 schedule_work(&typec->port_work);
968 static const struct dev_pm_ops cros_typec_pm_ops = {
969 SET_SYSTEM_SLEEP_PM_OPS(cros_typec_suspend, cros_typec_resume)
972 static struct platform_driver cros_typec_driver = {
975 .acpi_match_table = ACPI_PTR(cros_typec_acpi_id),
976 .of_match_table = of_match_ptr(cros_typec_of_match),
977 .pm = &cros_typec_pm_ops,
979 .probe = cros_typec_probe,
982 module_platform_driver(cros_typec_driver);
984 MODULE_AUTHOR("Prashant Malani <pmalani@chromium.org>");
985 MODULE_DESCRIPTION("Chrome OS EC Type C control");
986 MODULE_LICENSE("GPL");