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