Sebastian Reichel | 3dd2332 | 2024-10-15 17:26:43 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | /* |
| 3 | * Copyright 2015-2017 Google, Inc |
| 4 | * Copyright 2024 Collabora |
| 5 | */ |
| 6 | |
| 7 | #ifndef __LINUX_USB_TCPM_INTERNAL_H |
| 8 | #define __LINUX_USB_TCPM_INTERNAL_H |
| 9 | |
| 10 | #define FOREACH_TCPM_STATE(S) \ |
| 11 | S(INVALID_STATE), \ |
| 12 | S(TOGGLING), \ |
| 13 | S(SRC_UNATTACHED), \ |
| 14 | S(SRC_ATTACH_WAIT), \ |
| 15 | S(SRC_ATTACHED), \ |
| 16 | S(SRC_STARTUP), \ |
| 17 | S(SRC_SEND_CAPABILITIES), \ |
| 18 | S(SRC_SEND_CAPABILITIES_TIMEOUT), \ |
| 19 | S(SRC_NEGOTIATE_CAPABILITIES), \ |
| 20 | S(SRC_TRANSITION_SUPPLY), \ |
| 21 | S(SRC_READY), \ |
| 22 | S(SRC_WAIT_NEW_CAPABILITIES), \ |
| 23 | \ |
| 24 | S(SNK_UNATTACHED), \ |
| 25 | S(SNK_ATTACH_WAIT), \ |
| 26 | S(SNK_DEBOUNCED), \ |
| 27 | S(SNK_ATTACHED), \ |
| 28 | S(SNK_STARTUP), \ |
| 29 | S(SNK_DISCOVERY), \ |
| 30 | S(SNK_DISCOVERY_DEBOUNCE), \ |
| 31 | S(SNK_DISCOVERY_DEBOUNCE_DONE), \ |
| 32 | S(SNK_WAIT_CAPABILITIES), \ |
| 33 | S(SNK_NEGOTIATE_CAPABILITIES), \ |
| 34 | S(SNK_TRANSITION_SINK), \ |
| 35 | S(SNK_TRANSITION_SINK_VBUS), \ |
| 36 | S(SNK_READY), \ |
| 37 | \ |
| 38 | S(HARD_RESET_SEND), \ |
| 39 | S(HARD_RESET_START), \ |
| 40 | S(SRC_HARD_RESET_VBUS_OFF), \ |
| 41 | S(SRC_HARD_RESET_VBUS_ON), \ |
| 42 | S(SNK_HARD_RESET_SINK_OFF), \ |
| 43 | S(SNK_HARD_RESET_WAIT_VBUS), \ |
| 44 | S(SNK_HARD_RESET_SINK_ON), \ |
| 45 | \ |
| 46 | S(SOFT_RESET), \ |
| 47 | S(SOFT_RESET_SEND), \ |
| 48 | \ |
| 49 | S(DR_SWAP_ACCEPT), \ |
| 50 | S(DR_SWAP_CHANGE_DR), \ |
| 51 | \ |
| 52 | S(ERROR_RECOVERY), \ |
| 53 | S(PORT_RESET), \ |
| 54 | S(PORT_RESET_WAIT_OFF) |
| 55 | |
| 56 | #define GENERATE_TCPM_ENUM(e) e |
| 57 | #define GENERATE_TCPM_STRING(s) #s |
| 58 | #define TCPM_POLL_EVENT_TIME_OUT 2000 |
| 59 | |
| 60 | enum tcpm_state { |
| 61 | FOREACH_TCPM_STATE(GENERATE_TCPM_ENUM) |
| 62 | }; |
| 63 | |
| 64 | enum pd_msg_request { |
| 65 | PD_MSG_NONE = 0, |
| 66 | PD_MSG_CTRL_REJECT, |
| 67 | PD_MSG_CTRL_WAIT, |
| 68 | PD_MSG_CTRL_NOT_SUPP, |
| 69 | PD_MSG_DATA_SINK_CAP, |
| 70 | PD_MSG_DATA_SOURCE_CAP, |
| 71 | }; |
| 72 | |
| 73 | struct tcpm_port { |
| 74 | enum typec_port_type typec_type; |
| 75 | int typec_prefer_role; |
| 76 | |
| 77 | enum typec_role vconn_role; |
| 78 | enum typec_role pwr_role; |
| 79 | enum typec_data_role data_role; |
| 80 | |
| 81 | struct typec_partner *partner; |
| 82 | |
| 83 | enum typec_cc_status cc_req; |
| 84 | enum typec_cc_status cc1; |
| 85 | enum typec_cc_status cc2; |
| 86 | enum typec_cc_polarity polarity; |
| 87 | |
| 88 | bool attached; |
| 89 | bool connected; |
| 90 | int poll_event_cnt; |
| 91 | enum typec_port_type port_type; |
| 92 | |
| 93 | /* |
| 94 | * Set to true when vbus is greater than VSAFE5V min. |
| 95 | * Set to false when vbus falls below vSinkDisconnect max threshold. |
| 96 | */ |
| 97 | bool vbus_present; |
| 98 | |
| 99 | /* |
| 100 | * Set to true when vbus is less than VSAFE0V max. |
| 101 | * Set to false when vbus is greater than VSAFE0V max. |
| 102 | */ |
| 103 | bool vbus_vsafe0v; |
| 104 | |
| 105 | bool vbus_never_low; |
| 106 | bool vbus_source; |
| 107 | bool vbus_charge; |
| 108 | |
| 109 | int try_role; |
| 110 | |
| 111 | enum pd_msg_request queued_message; |
| 112 | |
| 113 | enum tcpm_state enter_state; |
| 114 | enum tcpm_state prev_state; |
| 115 | enum tcpm_state state; |
| 116 | enum tcpm_state delayed_state; |
| 117 | unsigned long delay_ms; |
| 118 | |
| 119 | bool state_machine_running; |
| 120 | |
| 121 | bool tx_complete; |
| 122 | enum tcpm_transmit_status tx_status; |
| 123 | |
| 124 | unsigned int negotiated_rev; |
| 125 | unsigned int message_id; |
| 126 | unsigned int caps_count; |
| 127 | unsigned int hard_reset_count; |
| 128 | bool pd_capable; |
| 129 | bool explicit_contract; |
| 130 | unsigned int rx_msgid; |
| 131 | |
| 132 | /* Partner capabilities/requests */ |
| 133 | u32 sink_request; |
| 134 | u32 source_caps[PDO_MAX_OBJECTS]; |
| 135 | unsigned int nr_source_caps; |
| 136 | u32 sink_caps[PDO_MAX_OBJECTS]; |
| 137 | unsigned int nr_sink_caps; |
| 138 | |
| 139 | /* |
| 140 | * whether to wait for the Type-C device to send the DR_SWAP Message flag |
| 141 | * For Type-C device with Dual-Role Power and Dual-Role Data, the port side |
| 142 | * is used as sink + ufp, then the tcpm framework needs to wait for Type-C |
| 143 | * device to initiate DR_swap Message. |
| 144 | */ |
| 145 | bool wait_dr_swap_message; |
| 146 | |
| 147 | /* Local capabilities */ |
| 148 | u32 src_pdo[PDO_MAX_OBJECTS]; |
| 149 | unsigned int nr_src_pdo; |
| 150 | u32 snk_pdo[PDO_MAX_OBJECTS]; |
| 151 | unsigned int nr_snk_pdo; |
| 152 | |
| 153 | unsigned int operating_snk_mw; |
| 154 | bool update_sink_caps; |
| 155 | |
| 156 | /* Requested current / voltage to the port partner */ |
| 157 | u32 req_current_limit; |
| 158 | u32 req_supply_voltage; |
| 159 | /* Actual current / voltage limit of the local port */ |
| 160 | u32 current_limit; |
| 161 | u32 supply_voltage; |
| 162 | |
| 163 | /* port belongs to a self powered device */ |
| 164 | bool self_powered; |
| 165 | |
| 166 | unsigned long delay_target; |
| 167 | }; |
| 168 | |
| 169 | extern const char * const tcpm_states[]; |
| 170 | |
| 171 | int tcpm_post_probe(struct udevice *dev); |
| 172 | |
| 173 | #endif |