Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'tag-chrome-platform-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux

Pull chrome platform updates from Benson Leung:
"cros_ec_typec:

- A series from Prashant for Type-C to implement TYPEC_STATUS,
parsing USB PD Partner ID VDOs, and registering partner altmodes.

cros_ec misc:

- Don't treat RTC events as wakeup sources in cros_ec_proto"

* tag 'tag-chrome-platform-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux:
platform/chrome: cros_ec_typec: Tolerate unrecognized mux flags
platform/chrome: cros_ec_typec: Register partner altmodes
platform/chrome: cros_ec_typec: Parse partner PD ID VDOs
platform/chrome: cros_ec_typec: Introduce TYPEC_STATUS
platform/chrome: cros_ec: Import Type C host commands
platform/chrome: cros_ec_typec: Clear partner identity on device removal
platform/chrome: cros_ec_typec: Fix remove partner logic
platform/chrome: cros_ec_typec: Relocate set_port_params_v*() functions
platform/chrome: Don't treat RTC events as wakeup sources

+427 -78
+9 -5
drivers/platform/chrome/cros_ec_proto.c
··· 742 742 * Sensor events need to be parsed by the sensor sub-device. 743 743 * Defer them, and don't report the wakeup here. 744 744 */ 745 - if (event_type == EC_MKBP_EVENT_SENSOR_FIFO) 745 + if (event_type == EC_MKBP_EVENT_SENSOR_FIFO) { 746 746 *wake_event = false; 747 - /* Masked host-events should not count as wake events. */ 748 - else if (host_event && 749 - !(host_event & ec_dev->host_event_wake_mask)) 750 - *wake_event = false; 747 + } else if (host_event) { 748 + /* rtc_update_irq() already handles wakeup events. */ 749 + if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC)) 750 + *wake_event = false; 751 + /* Masked host-events should not count as wake events. */ 752 + if (!(host_event & ec_dev->host_event_wake_mask)) 753 + *wake_event = false; 754 + } 751 755 } 752 756 753 757 return ret;
+263 -73
drivers/platform/chrome/cros_ec_typec.c
··· 7 7 */ 8 8 9 9 #include <linux/acpi.h> 10 + #include <linux/list.h> 10 11 #include <linux/module.h> 11 12 #include <linux/of.h> 12 13 #include <linux/platform_data/cros_ec_commands.h> ··· 15 14 #include <linux/platform_data/cros_usbpd_notify.h> 16 15 #include <linux/platform_device.h> 17 16 #include <linux/usb/pd.h> 17 + #include <linux/usb/pd_vdo.h> 18 18 #include <linux/usb/typec.h> 19 19 #include <linux/usb/typec_altmode.h> 20 20 #include <linux/usb/typec_dp.h> ··· 30 28 CROS_EC_ALTMODE_DP = 0, 31 29 CROS_EC_ALTMODE_TBT, 32 30 CROS_EC_ALTMODE_MAX, 31 + }; 32 + 33 + /* Container for altmode pointer nodes. */ 34 + struct cros_typec_altmode_node { 35 + struct typec_altmode *amode; 36 + struct list_head list; 33 37 }; 34 38 35 39 /* Per port data. */ ··· 56 48 57 49 /* Port alt modes. */ 58 50 struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX]; 51 + 52 + /* Flag indicating that PD discovery data parsing is completed. */ 53 + bool disc_done; 54 + struct ec_response_typec_discovery *sop_disc; 55 + struct list_head partner_mode_list; 59 56 }; 60 57 61 58 /* Platform-specific data for the Chrome OS EC Type C controller. */ ··· 73 60 struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS]; 74 61 struct notifier_block nb; 75 62 struct work_struct port_work; 63 + bool typec_cmd_supported; 76 64 }; 77 65 78 66 static int cros_typec_parse_port_props(struct typec_capability *cap, ··· 180 166 return ret; 181 167 } 182 168 169 + static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int port_num) 170 + { 171 + struct cros_typec_port *port = typec->ports[port_num]; 172 + struct cros_typec_altmode_node *node, *tmp; 173 + 174 + list_for_each_entry_safe(node, tmp, &port->partner_mode_list, list) { 175 + list_del(&node->list); 176 + typec_unregister_altmode(node->amode); 177 + devm_kfree(typec->dev, node); 178 + } 179 + } 180 + 183 181 static void cros_typec_remove_partner(struct cros_typec_data *typec, 184 182 int port_num) 185 183 { 186 184 struct cros_typec_port *port = typec->ports[port_num]; 185 + 186 + cros_typec_unregister_altmodes(typec, port_num); 187 187 188 188 port->state.alt = NULL; 189 189 port->state.mode = TYPEC_STATE_USB; ··· 209 181 210 182 typec_unregister_partner(port->partner); 211 183 port->partner = NULL; 184 + memset(&port->p_identity, 0, sizeof(port->p_identity)); 185 + port->disc_done = false; 212 186 } 213 187 214 188 static void cros_unregister_ports(struct cros_typec_data *typec) ··· 220 190 for (i = 0; i < typec->num_ports; i++) { 221 191 if (!typec->ports[i]) 222 192 continue; 223 - cros_typec_remove_partner(typec, i); 193 + 194 + if (typec->ports[i]->partner) 195 + cros_typec_remove_partner(typec, i); 196 + 224 197 usb_role_switch_put(typec->ports[i]->role_sw); 225 198 typec_switch_put(typec->ports[i]->ori_sw); 226 199 typec_mux_put(typec->ports[i]->mux); ··· 322 289 port_num); 323 290 324 291 cros_typec_register_port_altmodes(typec, port_num); 292 + 293 + cros_port->sop_disc = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL); 294 + if (!cros_port->sop_disc) { 295 + ret = -ENOMEM; 296 + goto unregister_ports; 297 + } 298 + 299 + INIT_LIST_HEAD(&cros_port->partner_mode_list); 325 300 } 326 301 327 302 return 0; ··· 368 327 369 328 kfree(msg); 370 329 return ret; 371 - } 372 - 373 - static void cros_typec_set_port_params_v0(struct cros_typec_data *typec, 374 - int port_num, struct ec_response_usb_pd_control *resp) 375 - { 376 - struct typec_port *port = typec->ports[port_num]->port; 377 - enum typec_orientation polarity; 378 - 379 - if (!resp->enabled) 380 - polarity = TYPEC_ORIENTATION_NONE; 381 - else if (!resp->polarity) 382 - polarity = TYPEC_ORIENTATION_NORMAL; 383 - else 384 - polarity = TYPEC_ORIENTATION_REVERSE; 385 - 386 - typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK); 387 - typec_set_orientation(port, polarity); 388 - } 389 - 390 - static void cros_typec_set_port_params_v1(struct cros_typec_data *typec, 391 - int port_num, struct ec_response_usb_pd_control_v1 *resp) 392 - { 393 - struct typec_port *port = typec->ports[port_num]->port; 394 - enum typec_orientation polarity; 395 - bool pd_en; 396 - int ret; 397 - 398 - if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED)) 399 - polarity = TYPEC_ORIENTATION_NONE; 400 - else if (!resp->polarity) 401 - polarity = TYPEC_ORIENTATION_NORMAL; 402 - else 403 - polarity = TYPEC_ORIENTATION_REVERSE; 404 - typec_set_orientation(port, polarity); 405 - typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ? 406 - TYPEC_HOST : TYPEC_DEVICE); 407 - typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ? 408 - TYPEC_SOURCE : TYPEC_SINK); 409 - typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ? 410 - TYPEC_SOURCE : TYPEC_SINK); 411 - 412 - /* Register/remove partners when a connect/disconnect occurs. */ 413 - if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) { 414 - if (typec->ports[port_num]->partner) 415 - return; 416 - 417 - pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE; 418 - ret = cros_typec_add_partner(typec, port_num, pd_en); 419 - if (ret) 420 - dev_warn(typec->dev, 421 - "Failed to register partner on port: %d\n", 422 - port_num); 423 - } else { 424 - if (!typec->ports[port_num]->partner) 425 - return; 426 - cros_typec_remove_partner(typec, port_num); 427 - } 428 - } 429 - 430 - static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num, 431 - struct ec_response_usb_pd_mux_info *resp) 432 - { 433 - struct ec_params_usb_pd_mux_info req = { 434 - .port = port_num, 435 - }; 436 - 437 - return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req, 438 - sizeof(req), resp, sizeof(*resp)); 439 330 } 440 331 441 332 static int cros_typec_usb_safe_state(struct cros_typec_port *port) ··· 536 563 port->state.mode = TYPEC_STATE_USB; 537 564 ret = typec_mux_set(port->mux, &port->state); 538 565 } else { 539 - dev_info(typec->dev, 540 - "Unsupported mode requested, mux flags: %x\n", 541 - mux_flags); 542 - ret = -ENOTSUPP; 566 + dev_dbg(typec->dev, 567 + "Unrecognized mode requested, mux flags: %x\n", 568 + mux_flags); 543 569 } 544 570 545 571 return ret; 572 + } 573 + 574 + static void cros_typec_set_port_params_v0(struct cros_typec_data *typec, 575 + int port_num, struct ec_response_usb_pd_control *resp) 576 + { 577 + struct typec_port *port = typec->ports[port_num]->port; 578 + enum typec_orientation polarity; 579 + 580 + if (!resp->enabled) 581 + polarity = TYPEC_ORIENTATION_NONE; 582 + else if (!resp->polarity) 583 + polarity = TYPEC_ORIENTATION_NORMAL; 584 + else 585 + polarity = TYPEC_ORIENTATION_REVERSE; 586 + 587 + typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK); 588 + typec_set_orientation(port, polarity); 589 + } 590 + 591 + static void cros_typec_set_port_params_v1(struct cros_typec_data *typec, 592 + int port_num, struct ec_response_usb_pd_control_v1 *resp) 593 + { 594 + struct typec_port *port = typec->ports[port_num]->port; 595 + enum typec_orientation polarity; 596 + bool pd_en; 597 + int ret; 598 + 599 + if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED)) 600 + polarity = TYPEC_ORIENTATION_NONE; 601 + else if (!resp->polarity) 602 + polarity = TYPEC_ORIENTATION_NORMAL; 603 + else 604 + polarity = TYPEC_ORIENTATION_REVERSE; 605 + typec_set_orientation(port, polarity); 606 + typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ? 607 + TYPEC_HOST : TYPEC_DEVICE); 608 + typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ? 609 + TYPEC_SOURCE : TYPEC_SINK); 610 + typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ? 611 + TYPEC_SOURCE : TYPEC_SINK); 612 + 613 + /* Register/remove partners when a connect/disconnect occurs. */ 614 + if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) { 615 + if (typec->ports[port_num]->partner) 616 + return; 617 + 618 + pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE; 619 + ret = cros_typec_add_partner(typec, port_num, pd_en); 620 + if (ret) 621 + dev_warn(typec->dev, 622 + "Failed to register partner on port: %d\n", 623 + port_num); 624 + } else { 625 + if (!typec->ports[port_num]->partner) 626 + return; 627 + cros_typec_remove_partner(typec, port_num); 628 + } 629 + } 630 + 631 + static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num, 632 + struct ec_response_usb_pd_mux_info *resp) 633 + { 634 + struct ec_params_usb_pd_mux_info req = { 635 + .port = port_num, 636 + }; 637 + 638 + return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req, 639 + sizeof(req), resp, sizeof(*resp)); 640 + } 641 + 642 + static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_num) 643 + { 644 + struct cros_typec_port *port = typec->ports[port_num]; 645 + struct ec_response_typec_discovery *sop_disc = port->sop_disc; 646 + struct cros_typec_altmode_node *node; 647 + struct typec_altmode_desc desc; 648 + struct typec_altmode *amode; 649 + int ret = 0; 650 + int i, j; 651 + 652 + for (i = 0; i < sop_disc->svid_count; i++) { 653 + for (j = 0; j < sop_disc->svids[i].mode_count; j++) { 654 + memset(&desc, 0, sizeof(desc)); 655 + desc.svid = sop_disc->svids[i].svid; 656 + desc.mode = j; 657 + desc.vdo = sop_disc->svids[i].mode_vdo[j]; 658 + 659 + amode = typec_partner_register_altmode(port->partner, &desc); 660 + if (IS_ERR(amode)) { 661 + ret = PTR_ERR(amode); 662 + goto err_cleanup; 663 + } 664 + 665 + /* If no memory is available we should unregister and exit. */ 666 + node = devm_kzalloc(typec->dev, sizeof(*node), GFP_KERNEL); 667 + if (!node) { 668 + ret = -ENOMEM; 669 + typec_unregister_altmode(amode); 670 + goto err_cleanup; 671 + } 672 + 673 + node->amode = amode; 674 + list_add_tail(&node->list, &port->partner_mode_list); 675 + } 676 + } 677 + 678 + return 0; 679 + 680 + err_cleanup: 681 + cros_typec_unregister_altmodes(typec, port_num); 682 + return ret; 683 + } 684 + 685 + static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_num) 686 + { 687 + struct cros_typec_port *port = typec->ports[port_num]; 688 + struct ec_response_typec_discovery *sop_disc = port->sop_disc; 689 + struct ec_params_typec_discovery req = { 690 + .port = port_num, 691 + .partner_type = TYPEC_PARTNER_SOP, 692 + }; 693 + int ret = 0; 694 + int i; 695 + 696 + if (!port->partner) { 697 + dev_err(typec->dev, 698 + "SOP Discovery received without partner registered, port: %d\n", 699 + port_num); 700 + ret = -EINVAL; 701 + goto disc_exit; 702 + } 703 + 704 + memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE); 705 + ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req), 706 + sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE); 707 + if (ret < 0) { 708 + dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num); 709 + goto disc_exit; 710 + } 711 + 712 + /* First, update the PD identity VDOs for the partner. */ 713 + if (sop_disc->identity_count > 0) 714 + port->p_identity.id_header = sop_disc->discovery_vdo[0]; 715 + if (sop_disc->identity_count > 1) 716 + port->p_identity.cert_stat = sop_disc->discovery_vdo[1]; 717 + if (sop_disc->identity_count > 2) 718 + port->p_identity.product = sop_disc->discovery_vdo[2]; 719 + 720 + /* Copy the remaining identity VDOs till a maximum of 6. */ 721 + for (i = 3; i < sop_disc->identity_count && i < VDO_MAX_OBJECTS; i++) 722 + port->p_identity.vdo[i - 3] = sop_disc->discovery_vdo[i]; 723 + 724 + ret = typec_partner_set_identity(port->partner); 725 + if (ret < 0) { 726 + dev_err(typec->dev, "Failed to update partner PD identity, port: %d\n", port_num); 727 + goto disc_exit; 728 + } 729 + 730 + ret = cros_typec_register_altmodes(typec, port_num); 731 + if (ret < 0) { 732 + dev_err(typec->dev, "Failed to register partner altmodes, port: %d\n", port_num); 733 + goto disc_exit; 734 + } 735 + 736 + disc_exit: 737 + return ret; 738 + } 739 + 740 + static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num) 741 + { 742 + struct ec_response_typec_status resp; 743 + struct ec_params_typec_status req = { 744 + .port = port_num, 745 + }; 746 + int ret; 747 + 748 + ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req), 749 + &resp, sizeof(resp)); 750 + if (ret < 0) { 751 + dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num); 752 + return; 753 + } 754 + 755 + if (typec->ports[port_num]->disc_done) 756 + return; 757 + 758 + /* Handle any events appropriately. */ 759 + if (resp.events & PD_STATUS_EVENT_SOP_DISC_DONE) { 760 + ret = cros_typec_handle_sop_disc(typec, port_num); 761 + if (ret < 0) { 762 + dev_err(typec->dev, "Couldn't parse SOP Disc data, port: %d\n", port_num); 763 + return; 764 + } 765 + 766 + typec->ports[port_num]->disc_done = true; 767 + } 546 768 } 547 769 548 770 static int cros_typec_port_update(struct cros_typec_data *typec, int port_num) ··· 775 607 else 776 608 cros_typec_set_port_params_v0(typec, port_num, 777 609 (struct ec_response_usb_pd_control *) &resp); 610 + 611 + if (typec->typec_cmd_supported) 612 + cros_typec_handle_status(typec, port_num); 778 613 779 614 /* Update the switches if they exist, according to requested state */ 780 615 ret = cros_typec_get_mux_info(typec, port_num, &mux_resp); ··· 825 654 typec->pd_ctrl_ver); 826 655 827 656 return 0; 657 + } 658 + 659 + /* Check the EC feature flags to see if TYPEC_* commands are supported. */ 660 + static int cros_typec_cmds_supported(struct cros_typec_data *typec) 661 + { 662 + struct ec_response_get_features resp = {}; 663 + int ret; 664 + 665 + ret = cros_typec_ec_command(typec, 0, EC_CMD_GET_FEATURES, NULL, 0, 666 + &resp, sizeof(resp)); 667 + if (ret < 0) { 668 + dev_warn(typec->dev, 669 + "Failed to get features, assuming typec commands unsupported.\n"); 670 + return 0; 671 + } 672 + 673 + return resp.flags[EC_FEATURE_TYPEC_CMD / 32] & EC_FEATURE_MASK_1(EC_FEATURE_TYPEC_CMD); 828 674 } 829 675 830 676 static void cros_typec_port_work(struct work_struct *work) ··· 902 714 dev_err(dev, "failed to get PD command version info\n"); 903 715 return ret; 904 716 } 717 + 718 + typec->typec_cmd_supported = !!cros_typec_cmds_supported(typec); 905 719 906 720 ret = cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_PORTS, NULL, 0, 907 721 &resp, sizeof(resp));
+155
include/linux/platform_data/cros_ec_commands.h
··· 1284 1284 EC_FEATURE_SCP = 39, 1285 1285 /* The MCU is an Integrated Sensor Hub */ 1286 1286 EC_FEATURE_ISH = 40, 1287 + /* New TCPMv2 TYPEC_ prefaced commands supported */ 1288 + EC_FEATURE_TYPEC_CMD = 41, 1287 1289 }; 1288 1290 1289 1291 #define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32) ··· 5529 5527 struct ec_response_regulator_get_voltage { 5530 5528 uint32_t voltage_mv; 5531 5529 } __ec_align4; 5530 + 5531 + /* 5532 + * Gather all discovery information for the given port and partner type. 5533 + * 5534 + * Note that if discovery has not yet completed, only the currently completed 5535 + * responses will be filled in. If the discovery data structures are changed 5536 + * in the process of the command running, BUSY will be returned. 5537 + * 5538 + * VDO field sizes are set to the maximum possible number of VDOs a VDM may 5539 + * contain, while the number of SVIDs here is selected to fit within the PROTO2 5540 + * maximum parameter size. 5541 + */ 5542 + #define EC_CMD_TYPEC_DISCOVERY 0x0131 5543 + 5544 + enum typec_partner_type { 5545 + TYPEC_PARTNER_SOP = 0, 5546 + TYPEC_PARTNER_SOP_PRIME = 1, 5547 + }; 5548 + 5549 + struct ec_params_typec_discovery { 5550 + uint8_t port; 5551 + uint8_t partner_type; /* enum typec_partner_type */ 5552 + } __ec_align1; 5553 + 5554 + struct svid_mode_info { 5555 + uint16_t svid; 5556 + uint16_t mode_count; /* Number of modes partner sent */ 5557 + uint32_t mode_vdo[6]; /* Max VDOs allowed after VDM header is 6 */ 5558 + }; 5559 + 5560 + struct ec_response_typec_discovery { 5561 + uint8_t identity_count; /* Number of identity VDOs partner sent */ 5562 + uint8_t svid_count; /* Number of SVIDs partner sent */ 5563 + uint16_t reserved; 5564 + uint32_t discovery_vdo[6]; /* Max VDOs allowed after VDM header is 6 */ 5565 + struct svid_mode_info svids[0]; 5566 + } __ec_align1; 5567 + 5568 + /* 5569 + * Gather all status information for a port. 5570 + * 5571 + * Note: this covers many of the return fields from the deprecated 5572 + * EC_CMD_USB_PD_CONTROL command, except those that are redundant with the 5573 + * discovery data. The "enum pd_cc_states" is defined with the deprecated 5574 + * EC_CMD_USB_PD_CONTROL command. 5575 + * 5576 + * This also combines in the EC_CMD_USB_PD_MUX_INFO flags. 5577 + */ 5578 + #define EC_CMD_TYPEC_STATUS 0x0133 5579 + 5580 + /* 5581 + * Power role. 5582 + * 5583 + * Note this is also used for PD header creation, and values align to those in 5584 + * the Power Delivery Specification Revision 3.0 (See 5585 + * 6.2.1.1.4 Port Power Role). 5586 + */ 5587 + enum pd_power_role { 5588 + PD_ROLE_SINK = 0, 5589 + PD_ROLE_SOURCE = 1 5590 + }; 5591 + 5592 + /* 5593 + * Data role. 5594 + * 5595 + * Note this is also used for PD header creation, and the first two values 5596 + * align to those in the Power Delivery Specification Revision 3.0 (See 5597 + * 6.2.1.1.6 Port Data Role). 5598 + */ 5599 + enum pd_data_role { 5600 + PD_ROLE_UFP = 0, 5601 + PD_ROLE_DFP = 1, 5602 + PD_ROLE_DISCONNECTED = 2, 5603 + }; 5604 + 5605 + enum pd_vconn_role { 5606 + PD_ROLE_VCONN_OFF = 0, 5607 + PD_ROLE_VCONN_SRC = 1, 5608 + }; 5609 + 5610 + /* 5611 + * Note: BIT(0) may be used to determine whether the polarity is CC1 or CC2, 5612 + * regardless of whether a debug accessory is connected. 5613 + */ 5614 + enum tcpc_cc_polarity { 5615 + /* 5616 + * _CCx: is used to indicate the polarity while not connected to 5617 + * a Debug Accessory. Only one CC line will assert a resistor and 5618 + * the other will be open. 5619 + */ 5620 + POLARITY_CC1 = 0, 5621 + POLARITY_CC2 = 1, 5622 + 5623 + /* 5624 + * _CCx_DTS is used to indicate the polarity while connected to a 5625 + * SRC Debug Accessory. Assert resistors on both lines. 5626 + */ 5627 + POLARITY_CC1_DTS = 2, 5628 + POLARITY_CC2_DTS = 3, 5629 + 5630 + /* 5631 + * The current TCPC code relies on these specific POLARITY values. 5632 + * Adding in a check to verify if the list grows for any reason 5633 + * that this will give a hint that other places need to be 5634 + * adjusted. 5635 + */ 5636 + POLARITY_COUNT 5637 + }; 5638 + 5639 + #define PD_STATUS_EVENT_SOP_DISC_DONE BIT(0) 5640 + #define PD_STATUS_EVENT_SOP_PRIME_DISC_DONE BIT(1) 5641 + 5642 + struct ec_params_typec_status { 5643 + uint8_t port; 5644 + } __ec_align1; 5645 + 5646 + struct ec_response_typec_status { 5647 + uint8_t pd_enabled; /* PD communication enabled - bool */ 5648 + uint8_t dev_connected; /* Device connected - bool */ 5649 + uint8_t sop_connected; /* Device is SOP PD capable - bool */ 5650 + uint8_t source_cap_count; /* Number of Source Cap PDOs */ 5651 + 5652 + uint8_t power_role; /* enum pd_power_role */ 5653 + uint8_t data_role; /* enum pd_data_role */ 5654 + uint8_t vconn_role; /* enum pd_vconn_role */ 5655 + uint8_t sink_cap_count; /* Number of Sink Cap PDOs */ 5656 + 5657 + uint8_t polarity; /* enum tcpc_cc_polarity */ 5658 + uint8_t cc_state; /* enum pd_cc_states */ 5659 + uint8_t dp_pin; /* DP pin mode (MODE_DP_IN_[A-E]) */ 5660 + uint8_t mux_state; /* USB_PD_MUX* - encoded mux state */ 5661 + 5662 + char tc_state[32]; /* TC state name */ 5663 + 5664 + uint32_t events; /* PD_STATUS_EVENT bitmask */ 5665 + 5666 + /* 5667 + * BCD PD revisions for partners 5668 + * 5669 + * The format has the PD major reversion in the upper nibble, and PD 5670 + * minor version in the next nibble. Following two nibbles are 5671 + * currently 0. 5672 + * ex. PD 3.2 would map to 0x3200 5673 + * 5674 + * PD major/minor will be 0 if no PD device is connected. 5675 + */ 5676 + uint16_t sop_revision; 5677 + uint16_t sop_prime_revision; 5678 + 5679 + uint32_t source_cap_pdos[7]; /* Max 7 PDOs can be present */ 5680 + 5681 + uint32_t sink_cap_pdos[7]; /* Max 7 PDOs can be present */ 5682 + } __ec_align1; 5532 5683 5533 5684 /*****************************************************************************/ 5534 5685 /* The command range 0x200-0x2FF is reserved for Rotor. */