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

Configure Feed

Select the types of activity you want to include in your feed.

usb: typec: tipd: Read USB4, Thunderbolt and DisplayPort status for cd321x

CD321x supports various alternate modes and stores information once
these are entered into separate status registers. Read those when they
are active when reading TPS_DATA_STATUS to prepare supporting these.

Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Neal Gompa <neal@gompa.dev>
Signed-off-by: Sven Peter <sven@kernel.org>
Link: https://lore.kernel.org/r/20250914-apple-usb3-tipd-v1-6-4e99c8649024@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Sven Peter and committed by
Greg Kroah-Hartman
0b31c978 9f36fdfc

+76 -4
+76 -4
drivers/usb/typec/tipd/core.c
··· 35 35 #define TPS_REG_INT_MASK2 0x17 36 36 #define TPS_REG_INT_CLEAR1 0x18 37 37 #define TPS_REG_INT_CLEAR2 0x19 38 - #define TPS_REG_SYSTEM_POWER_STATE 0x20 39 38 #define TPS_REG_STATUS 0x1a 39 + #define TPS_REG_SYSTEM_POWER_STATE 0x20 40 + #define TPS_REG_USB4_STATUS 0x24 40 41 #define TPS_REG_SYSTEM_CONF 0x28 41 42 #define TPS_REG_CTRL_CONF 0x29 42 43 #define TPS_REG_BOOT_STATUS 0x2D 43 44 #define TPS_REG_POWER_STATUS 0x3f 44 45 #define TPS_REG_PD_STATUS 0x40 45 46 #define TPS_REG_RX_IDENTITY_SOP 0x48 47 + #define TPS_REG_CF_VID_STATUS 0x5e 48 + #define TPS_REG_DP_SID_STATUS 0x58 49 + #define TPS_REG_INTEL_VID_STATUS 0x59 46 50 #define TPS_REG_DATA_STATUS 0x5f 47 51 #define TPS_REG_SLEEP_CONF 0x70 48 52 ··· 89 85 struct usb_pd_identity identity; 90 86 } __packed; 91 87 88 + /* TPS_REG_USB4_STATUS */ 89 + struct tps6598x_usb4_status_reg { 90 + u8 mode_status; 91 + __le32 eudo; 92 + __le32 unknown; 93 + } __packed; 94 + 95 + /* TPS_REG_DP_SID_STATUS */ 96 + struct tps6598x_dp_sid_status_reg { 97 + u8 mode_status; 98 + __le32 status_tx; 99 + __le32 status_rx; 100 + __le32 configure; 101 + __le32 mode_data; 102 + } __packed; 103 + 104 + /* TPS_REG_INTEL_VID_STATUS */ 105 + struct tps6598x_intel_vid_status_reg { 106 + u8 mode_status; 107 + __le32 attention_vdo; 108 + __le16 enter_vdo; 109 + __le16 device_mode; 110 + __le16 cable_mode; 111 + } __packed; 112 + 92 113 /* Standard Task return codes */ 93 114 #define TPS_TASK_TIMEOUT 1 94 115 #define TPS_TASK_REJECTED 3 ··· 150 121 int (*apply_patch)(struct tps6598x *tps); 151 122 int (*init)(struct tps6598x *tps); 152 123 int (*switch_power_state)(struct tps6598x *tps, u8 target_state); 124 + bool (*read_data_status)(struct tps6598x *tps); 153 125 int (*reset)(struct tps6598x *tps); 154 126 }; 155 127 ··· 181 151 182 152 struct cd321x { 183 153 struct tps6598x tps; 154 + 155 + struct tps6598x_dp_sid_status_reg dp_sid_status; 156 + struct tps6598x_intel_vid_status_reg intel_vid_status; 157 + struct tps6598x_usb4_status_reg usb4_status; 184 158 }; 185 159 186 160 static enum power_supply_property tps6598x_psy_props[] = { ··· 539 505 return true; 540 506 } 541 507 508 + static bool cd321x_read_data_status(struct tps6598x *tps) 509 + { 510 + struct cd321x *cd321x = container_of(tps, struct cd321x, tps); 511 + int ret; 512 + 513 + ret = tps6598x_read_data_status(tps); 514 + if (ret < 0) 515 + return false; 516 + 517 + if (tps->data_status & TPS_DATA_STATUS_DP_CONNECTION) { 518 + ret = tps6598x_block_read(tps, TPS_REG_DP_SID_STATUS, 519 + &cd321x->dp_sid_status, sizeof(cd321x->dp_sid_status)); 520 + if (ret) 521 + dev_err(tps->dev, "Failed to read DP SID Status: %d\n", 522 + ret); 523 + } 524 + 525 + if (tps->data_status & TPS_DATA_STATUS_TBT_CONNECTION) { 526 + ret = tps6598x_block_read(tps, TPS_REG_INTEL_VID_STATUS, 527 + &cd321x->intel_vid_status, sizeof(cd321x->intel_vid_status)); 528 + if (ret) 529 + dev_err(tps->dev, "Failed to read Intel VID Status: %d\n", ret); 530 + } 531 + 532 + if (tps->data_status & CD321X_DATA_STATUS_USB4_CONNECTION) { 533 + ret = tps6598x_block_read(tps, TPS_REG_USB4_STATUS, 534 + &cd321x->usb4_status, sizeof(cd321x->usb4_status)); 535 + if (ret) 536 + dev_err(tps->dev, 537 + "Failed to read USB4 Status: %d\n", ret); 538 + } 539 + 540 + return true; 541 + } 542 + 542 543 static bool tps6598x_read_power_status(struct tps6598x *tps) 543 544 { 544 545 u16 pwr_status; ··· 634 565 goto err_unlock; 635 566 636 567 if (event & APPLE_CD_REG_INT_DATA_STATUS_UPDATE) 637 - if (!tps6598x_read_data_status(tps)) 568 + if (!tps->data->read_data_status(tps)) 638 569 goto err_unlock; 639 570 640 571 /* Handle plug insert or removal */ ··· 683 614 goto err_clear_ints; 684 615 685 616 if (event[0] & TPS_REG_INT_DATA_STATUS_UPDATE) 686 - if (!tps6598x_read_data_status(tps)) 617 + if (!tps->data->read_data_status(tps)) 687 618 goto err_clear_ints; 688 619 689 620 /* ··· 757 688 goto err_unlock; 758 689 759 690 if ((event1[0] | event2[0]) & TPS_REG_INT_DATA_STATUS_UPDATE) 760 - if (!tps6598x_read_data_status(tps)) 691 + if (!tps->data->read_data_status(tps)) 761 692 goto err_unlock; 762 693 763 694 /* Handle plug insert or removal */ ··· 1603 1534 .trace_power_status = trace_tps6598x_power_status, 1604 1535 .trace_status = trace_tps6598x_status, 1605 1536 .init = cd321x_init, 1537 + .read_data_status = cd321x_read_data_status, 1606 1538 .reset = cd321x_reset, 1607 1539 .switch_power_state = cd321x_switch_power_state, 1608 1540 }; ··· 1620 1550 .trace_status = trace_tps6598x_status, 1621 1551 .apply_patch = tps6598x_apply_patch, 1622 1552 .init = tps6598x_init, 1553 + .read_data_status = tps6598x_read_data_status, 1623 1554 .reset = tps6598x_reset, 1624 1555 }; 1625 1556 ··· 1636 1565 .trace_status = trace_tps25750_status, 1637 1566 .apply_patch = tps25750_apply_patch, 1638 1567 .init = tps25750_init, 1568 + .read_data_status = tps6598x_read_data_status, 1639 1569 .reset = tps25750_reset, 1640 1570 }; 1641 1571