.. | .. |
---|
5 | 5 | |
---|
6 | 6 | #include <linux/bitops.h> |
---|
7 | 7 | #include <linux/device.h> |
---|
| 8 | +#include <linux/power_supply.h> |
---|
8 | 9 | #include <linux/types.h> |
---|
| 10 | +#include <linux/usb/typec.h> |
---|
| 11 | +#include <linux/usb/pd.h> |
---|
| 12 | +#include <linux/usb/role.h> |
---|
| 13 | +#include <linux/usb/pd.h> |
---|
9 | 14 | |
---|
10 | 15 | /* -------------------------------------------------------------------------- */ |
---|
11 | 16 | |
---|
12 | | -/* Command Status and Connector Change Indication (CCI) data structure */ |
---|
13 | | -struct ucsi_cci { |
---|
14 | | - u8:1; /* reserved */ |
---|
15 | | - u8 connector_change:7; |
---|
16 | | - u8 data_length; |
---|
17 | | - u16:9; /* reserved */ |
---|
18 | | - u16 not_supported:1; |
---|
19 | | - u16 cancel_complete:1; |
---|
20 | | - u16 reset_complete:1; |
---|
21 | | - u16 busy:1; |
---|
22 | | - u16 ack_complete:1; |
---|
23 | | - u16 error:1; |
---|
24 | | - u16 cmd_complete:1; |
---|
25 | | -} __packed; |
---|
| 17 | +struct ucsi; |
---|
| 18 | +struct ucsi_altmode; |
---|
26 | 19 | |
---|
27 | | -/* Default fields in CONTROL data structure */ |
---|
28 | | -struct ucsi_command { |
---|
29 | | - u8 cmd; |
---|
30 | | - u8 length; |
---|
31 | | - u64 data:48; |
---|
32 | | -} __packed; |
---|
| 20 | +/* UCSI offsets (Bytes) */ |
---|
| 21 | +#define UCSI_VERSION 0 |
---|
| 22 | +#define UCSI_CCI 4 |
---|
| 23 | +#define UCSI_CONTROL 8 |
---|
| 24 | +#define UCSI_MESSAGE_IN 16 |
---|
| 25 | +#define UCSI_MESSAGE_OUT 32 |
---|
33 | 26 | |
---|
34 | | -/* ACK Command structure */ |
---|
35 | | -struct ucsi_ack_cmd { |
---|
36 | | - u8 cmd; |
---|
37 | | - u8 length; |
---|
38 | | - u8 cci_ack:1; |
---|
39 | | - u8 cmd_ack:1; |
---|
40 | | - u8:6; /* reserved */ |
---|
41 | | -} __packed; |
---|
| 27 | +/* Command Status and Connector Change Indication (CCI) bits */ |
---|
| 28 | +#define UCSI_CCI_CONNECTOR(_c_) (((_c_) & GENMASK(7, 1)) >> 1) |
---|
| 29 | +#define UCSI_CCI_LENGTH(_c_) (((_c_) & GENMASK(15, 8)) >> 8) |
---|
| 30 | +#define UCSI_CCI_NOT_SUPPORTED BIT(25) |
---|
| 31 | +#define UCSI_CCI_CANCEL_COMPLETE BIT(26) |
---|
| 32 | +#define UCSI_CCI_RESET_COMPLETE BIT(27) |
---|
| 33 | +#define UCSI_CCI_BUSY BIT(28) |
---|
| 34 | +#define UCSI_CCI_ACK_COMPLETE BIT(29) |
---|
| 35 | +#define UCSI_CCI_ERROR BIT(30) |
---|
| 36 | +#define UCSI_CCI_COMMAND_COMPLETE BIT(31) |
---|
42 | 37 | |
---|
43 | | -/* Connector Reset Command structure */ |
---|
44 | | -struct ucsi_con_rst { |
---|
45 | | - u8 cmd; |
---|
46 | | - u8 length; |
---|
47 | | - u8 con_num:7; |
---|
48 | | - u8 hard_reset:1; |
---|
49 | | -} __packed; |
---|
50 | | - |
---|
51 | | -/* Set USB Operation Mode Command structure */ |
---|
52 | | -struct ucsi_uor_cmd { |
---|
53 | | - u8 cmd; |
---|
54 | | - u8 length; |
---|
55 | | - u16 con_num:7; |
---|
56 | | - u16 role:3; |
---|
57 | | -#define UCSI_UOR_ROLE_DFP BIT(0) |
---|
58 | | -#define UCSI_UOR_ROLE_UFP BIT(1) |
---|
59 | | -#define UCSI_UOR_ROLE_DRP BIT(2) |
---|
60 | | - u16:6; /* reserved */ |
---|
61 | | -} __packed; |
---|
62 | | - |
---|
63 | | -struct ucsi_control { |
---|
64 | | - union { |
---|
65 | | - u64 raw_cmd; |
---|
66 | | - struct ucsi_command cmd; |
---|
67 | | - struct ucsi_uor_cmd uor; |
---|
68 | | - struct ucsi_ack_cmd ack; |
---|
69 | | - struct ucsi_con_rst con_rst; |
---|
70 | | - }; |
---|
| 38 | +/** |
---|
| 39 | + * struct ucsi_operations - UCSI I/O operations |
---|
| 40 | + * @read: Read operation |
---|
| 41 | + * @sync_write: Blocking write operation |
---|
| 42 | + * @async_write: Non-blocking write operation |
---|
| 43 | + * @update_altmodes: Squashes duplicate DP altmodes |
---|
| 44 | + * |
---|
| 45 | + * Read and write routines for UCSI interface. @sync_write must wait for the |
---|
| 46 | + * Command Completion Event from the PPM before returning, and @async_write must |
---|
| 47 | + * return immediately after sending the data to the PPM. |
---|
| 48 | + */ |
---|
| 49 | +struct ucsi_operations { |
---|
| 50 | + int (*read)(struct ucsi *ucsi, unsigned int offset, |
---|
| 51 | + void *val, size_t val_len); |
---|
| 52 | + int (*sync_write)(struct ucsi *ucsi, unsigned int offset, |
---|
| 53 | + const void *val, size_t val_len); |
---|
| 54 | + int (*async_write)(struct ucsi *ucsi, unsigned int offset, |
---|
| 55 | + const void *val, size_t val_len); |
---|
| 56 | + bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, |
---|
| 57 | + struct ucsi_altmode *updated); |
---|
71 | 58 | }; |
---|
72 | 59 | |
---|
73 | | -#define __UCSI_CMD(_ctrl_, _cmd_) \ |
---|
74 | | -{ \ |
---|
75 | | - (_ctrl_).raw_cmd = 0; \ |
---|
76 | | - (_ctrl_).cmd.cmd = _cmd_; \ |
---|
77 | | -} |
---|
| 60 | +struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops); |
---|
| 61 | +void ucsi_destroy(struct ucsi *ucsi); |
---|
| 62 | +int ucsi_register(struct ucsi *ucsi); |
---|
| 63 | +void ucsi_unregister(struct ucsi *ucsi); |
---|
| 64 | +void *ucsi_get_drvdata(struct ucsi *ucsi); |
---|
| 65 | +void ucsi_set_drvdata(struct ucsi *ucsi, void *data); |
---|
78 | 66 | |
---|
79 | | -/* Helper for preparing ucsi_control for CONNECTOR_RESET command. */ |
---|
80 | | -#define UCSI_CMD_CONNECTOR_RESET(_ctrl_, _con_, _hard_) \ |
---|
81 | | -{ \ |
---|
82 | | - __UCSI_CMD(_ctrl_, UCSI_CONNECTOR_RESET) \ |
---|
83 | | - (_ctrl_).con_rst.con_num = (_con_)->num; \ |
---|
84 | | - (_ctrl_).con_rst.hard_reset = _hard_; \ |
---|
85 | | -} |
---|
| 67 | +void ucsi_connector_change(struct ucsi *ucsi, u8 num); |
---|
86 | 68 | |
---|
87 | | -/* Helper for preparing ucsi_control for ACK_CC_CI command. */ |
---|
88 | | -#define UCSI_CMD_ACK(_ctrl_, _ack_) \ |
---|
89 | | -{ \ |
---|
90 | | - __UCSI_CMD(_ctrl_, UCSI_ACK_CC_CI) \ |
---|
91 | | - (_ctrl_).ack.cci_ack = ((_ack_) == UCSI_ACK_EVENT); \ |
---|
92 | | - (_ctrl_).ack.cmd_ack = ((_ack_) == UCSI_ACK_CMD); \ |
---|
93 | | -} |
---|
94 | | - |
---|
95 | | -/* Helper for preparing ucsi_control for SET_NOTIFY_ENABLE command. */ |
---|
96 | | -#define UCSI_CMD_SET_NTFY_ENABLE(_ctrl_, _ntfys_) \ |
---|
97 | | -{ \ |
---|
98 | | - __UCSI_CMD(_ctrl_, UCSI_SET_NOTIFICATION_ENABLE) \ |
---|
99 | | - (_ctrl_).cmd.data = _ntfys_; \ |
---|
100 | | -} |
---|
101 | | - |
---|
102 | | -/* Helper for preparing ucsi_control for GET_CAPABILITY command. */ |
---|
103 | | -#define UCSI_CMD_GET_CAPABILITY(_ctrl_) \ |
---|
104 | | -{ \ |
---|
105 | | - __UCSI_CMD(_ctrl_, UCSI_GET_CAPABILITY) \ |
---|
106 | | -} |
---|
107 | | - |
---|
108 | | -/* Helper for preparing ucsi_control for GET_CONNECTOR_CAPABILITY command. */ |
---|
109 | | -#define UCSI_CMD_GET_CONNECTOR_CAPABILITY(_ctrl_, _con_) \ |
---|
110 | | -{ \ |
---|
111 | | - __UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_CAPABILITY) \ |
---|
112 | | - (_ctrl_).cmd.data = _con_; \ |
---|
113 | | -} |
---|
114 | | - |
---|
115 | | -/* Helper for preparing ucsi_control for GET_CONNECTOR_STATUS command. */ |
---|
116 | | -#define UCSI_CMD_GET_CONNECTOR_STATUS(_ctrl_, _con_) \ |
---|
117 | | -{ \ |
---|
118 | | - __UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_STATUS) \ |
---|
119 | | - (_ctrl_).cmd.data = _con_; \ |
---|
120 | | -} |
---|
121 | | - |
---|
122 | | -#define __UCSI_ROLE(_ctrl_, _cmd_, _con_num_) \ |
---|
123 | | -{ \ |
---|
124 | | - __UCSI_CMD(_ctrl_, _cmd_) \ |
---|
125 | | - (_ctrl_).uor.con_num = _con_num_; \ |
---|
126 | | - (_ctrl_).uor.role = UCSI_UOR_ROLE_DRP; \ |
---|
127 | | -} |
---|
128 | | - |
---|
129 | | -/* Helper for preparing ucsi_control for SET_UOR command. */ |
---|
130 | | -#define UCSI_CMD_SET_UOR(_ctrl_, _con_, _role_) \ |
---|
131 | | -{ \ |
---|
132 | | - __UCSI_ROLE(_ctrl_, UCSI_SET_UOR, (_con_)->num) \ |
---|
133 | | - (_ctrl_).uor.role |= (_role_) == TYPEC_HOST ? UCSI_UOR_ROLE_DFP : \ |
---|
134 | | - UCSI_UOR_ROLE_UFP; \ |
---|
135 | | -} |
---|
136 | | - |
---|
137 | | -/* Helper for preparing ucsi_control for SET_PDR command. */ |
---|
138 | | -#define UCSI_CMD_SET_PDR(_ctrl_, _con_, _role_) \ |
---|
139 | | -{ \ |
---|
140 | | - __UCSI_ROLE(_ctrl_, UCSI_SET_PDR, (_con_)->num) \ |
---|
141 | | - (_ctrl_).uor.role |= (_role_) == TYPEC_SOURCE ? UCSI_UOR_ROLE_DFP : \ |
---|
142 | | - UCSI_UOR_ROLE_UFP; \ |
---|
143 | | -} |
---|
| 69 | +/* -------------------------------------------------------------------------- */ |
---|
144 | 70 | |
---|
145 | 71 | /* Commands */ |
---|
146 | 72 | #define UCSI_PPM_RESET 0x01 |
---|
.. | .. |
---|
163 | 89 | #define UCSI_GET_CONNECTOR_STATUS 0x12 |
---|
164 | 90 | #define UCSI_GET_ERROR_STATUS 0x13 |
---|
165 | 91 | |
---|
166 | | -/* ACK_CC_CI commands */ |
---|
167 | | -#define UCSI_ACK_EVENT 1 |
---|
168 | | -#define UCSI_ACK_CMD 2 |
---|
| 92 | +#define UCSI_CONNECTOR_NUMBER(_num_) ((u64)(_num_) << 16) |
---|
| 93 | +#define UCSI_COMMAND(_cmd_) ((_cmd_) & 0xff) |
---|
169 | 94 | |
---|
170 | | -/* Bits for SET_NOTIFICATION_ENABLE command */ |
---|
171 | | -#define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(0) |
---|
172 | | -#define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(1) |
---|
173 | | -#define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(2) |
---|
174 | | -#define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(5) |
---|
175 | | -#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(6) |
---|
176 | | -#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(7) |
---|
177 | | -#define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(8) |
---|
178 | | -#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(9) |
---|
179 | | -#define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(11) |
---|
180 | | -#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(12) |
---|
181 | | -#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(14) |
---|
182 | | -#define UCSI_ENABLE_NTFY_ERROR BIT(15) |
---|
183 | | -#define UCSI_ENABLE_NTFY_ALL 0xdbe7 |
---|
| 95 | +/* CONNECTOR_RESET command bits */ |
---|
| 96 | +#define UCSI_CONNECTOR_RESET_HARD BIT(23) /* Deprecated in v1.1 */ |
---|
| 97 | + |
---|
| 98 | +/* ACK_CC_CI bits */ |
---|
| 99 | +#define UCSI_ACK_CONNECTOR_CHANGE BIT(16) |
---|
| 100 | +#define UCSI_ACK_COMMAND_COMPLETE BIT(17) |
---|
| 101 | + |
---|
| 102 | +/* SET_NOTIFICATION_ENABLE command bits */ |
---|
| 103 | +#define UCSI_ENABLE_NTFY_CMD_COMPLETE BIT(16) |
---|
| 104 | +#define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE BIT(17) |
---|
| 105 | +#define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE BIT(18) |
---|
| 106 | +#define UCSI_ENABLE_NTFY_CAP_CHANGE BIT(21) |
---|
| 107 | +#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE BIT(22) |
---|
| 108 | +#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE BIT(23) |
---|
| 109 | +#define UCSI_ENABLE_NTFY_CAM_CHANGE BIT(24) |
---|
| 110 | +#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE BIT(25) |
---|
| 111 | +#define UCSI_ENABLE_NTFY_PARTNER_CHANGE BIT(27) |
---|
| 112 | +#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE BIT(28) |
---|
| 113 | +#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE BIT(30) |
---|
| 114 | +#define UCSI_ENABLE_NTFY_ERROR BIT(31) |
---|
| 115 | +#define UCSI_ENABLE_NTFY_ALL 0xdbe70000 |
---|
| 116 | + |
---|
| 117 | +/* SET_UOR command bits */ |
---|
| 118 | +#define UCSI_SET_UOR_ROLE(_r_) (((_r_) == TYPEC_HOST ? 1 : 2) << 23) |
---|
| 119 | +#define UCSI_SET_UOR_ACCEPT_ROLE_SWAPS BIT(25) |
---|
| 120 | + |
---|
| 121 | +/* SET_PDF command bits */ |
---|
| 122 | +#define UCSI_SET_PDR_ROLE(_r_) (((_r_) == TYPEC_SOURCE ? 1 : 2) << 23) |
---|
| 123 | +#define UCSI_SET_PDR_ACCEPT_ROLE_SWAPS BIT(25) |
---|
| 124 | + |
---|
| 125 | +/* GET_ALTERNATE_MODES command bits */ |
---|
| 126 | +#define UCSI_ALTMODE_RECIPIENT(_r_) (((_r_) >> 16) & 0x7) |
---|
| 127 | +#define UCSI_GET_ALTMODE_RECIPIENT(_r_) ((u64)(_r_) << 16) |
---|
| 128 | +#define UCSI_RECIPIENT_CON 0 |
---|
| 129 | +#define UCSI_RECIPIENT_SOP 1 |
---|
| 130 | +#define UCSI_RECIPIENT_SOP_P 2 |
---|
| 131 | +#define UCSI_RECIPIENT_SOP_PP 3 |
---|
| 132 | +#define UCSI_GET_ALTMODE_CONNECTOR_NUMBER(_r_) ((u64)(_r_) << 24) |
---|
| 133 | +#define UCSI_ALTMODE_OFFSET(_r_) (((_r_) >> 32) & 0xff) |
---|
| 134 | +#define UCSI_GET_ALTMODE_OFFSET(_r_) ((u64)(_r_) << 32) |
---|
| 135 | +#define UCSI_GET_ALTMODE_NUM_ALTMODES(_r_) ((u64)(_r_) << 40) |
---|
| 136 | + |
---|
| 137 | +/* GET_PDOS command bits */ |
---|
| 138 | +#define UCSI_GET_PDOS_PARTNER_PDO(_r_) ((u64)(_r_) << 23) |
---|
| 139 | +#define UCSI_GET_PDOS_PDO_OFFSET(_r_) ((u64)(_r_) << 24) |
---|
| 140 | +#define UCSI_GET_PDOS_NUM_PDOS(_r_) ((u64)(_r_) << 32) |
---|
| 141 | +#define UCSI_MAX_PDOS (4) |
---|
| 142 | +#define UCSI_GET_PDOS_SRC_PDOS ((u64)1 << 34) |
---|
| 143 | + |
---|
| 144 | +/* -------------------------------------------------------------------------- */ |
---|
184 | 145 | |
---|
185 | 146 | /* Error information returned by PPM in response to GET_ERROR_STATUS command. */ |
---|
186 | 147 | #define UCSI_ERROR_UNREGONIZED_CMD BIT(0) |
---|
.. | .. |
---|
190 | 151 | #define UCSI_ERROR_CC_COMMUNICATION_ERR BIT(4) |
---|
191 | 152 | #define UCSI_ERROR_DEAD_BATTERY BIT(5) |
---|
192 | 153 | #define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL BIT(6) |
---|
| 154 | +#define UCSI_ERROR_OVERCURRENT BIT(7) |
---|
| 155 | +#define UCSI_ERROR_UNDEFINED BIT(8) |
---|
| 156 | +#define UCSI_ERROR_PARTNER_REJECTED_SWAP BIT(9) |
---|
| 157 | +#define UCSI_ERROR_HARD_RESET BIT(10) |
---|
| 158 | +#define UCSI_ERROR_PPM_POLICY_CONFLICT BIT(11) |
---|
| 159 | +#define UCSI_ERROR_SWAP_REJECTED BIT(12) |
---|
| 160 | + |
---|
| 161 | +#define UCSI_SET_NEW_CAM_ENTER(x) (((x) >> 23) & 0x1) |
---|
| 162 | +#define UCSI_SET_NEW_CAM_GET_AM(x) (((x) >> 24) & 0xff) |
---|
| 163 | +#define UCSI_SET_NEW_CAM_AM_MASK (0xff << 24) |
---|
| 164 | +#define UCSI_SET_NEW_CAM_SET_AM(x) (((x) & 0xff) << 24) |
---|
| 165 | +#define UCSI_CMD_CONNECTOR_MASK (0x7) |
---|
193 | 166 | |
---|
194 | 167 | /* Data structure filled by PPM in response to GET_CAPABILITY command. */ |
---|
195 | 168 | struct ucsi_capability { |
---|
.. | .. |
---|
201 | 174 | #define UCSI_CAP_ATTR_POWER_AC_SUPPLY BIT(8) |
---|
202 | 175 | #define UCSI_CAP_ATTR_POWER_OTHER BIT(10) |
---|
203 | 176 | #define UCSI_CAP_ATTR_POWER_VBUS BIT(14) |
---|
204 | | - u32 num_connectors:8; |
---|
205 | | - u32 features:24; |
---|
| 177 | + u8 num_connectors; |
---|
| 178 | + u8 features; |
---|
206 | 179 | #define UCSI_CAP_SET_UOM BIT(0) |
---|
207 | 180 | #define UCSI_CAP_SET_PDM BIT(1) |
---|
208 | 181 | #define UCSI_CAP_ALT_MODE_DETAILS BIT(2) |
---|
.. | .. |
---|
211 | 184 | #define UCSI_CAP_CABLE_DETAILS BIT(5) |
---|
212 | 185 | #define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS BIT(6) |
---|
213 | 186 | #define UCSI_CAP_PD_RESET BIT(7) |
---|
| 187 | + u16 reserved_1; |
---|
214 | 188 | u8 num_alt_modes; |
---|
215 | | - u8 reserved; |
---|
| 189 | + u8 reserved_2; |
---|
216 | 190 | u16 bc_version; |
---|
217 | 191 | u16 pd_version; |
---|
218 | 192 | u16 typec_version; |
---|
.. | .. |
---|
229 | 203 | #define UCSI_CONCAP_OPMODE_USB2 BIT(5) |
---|
230 | 204 | #define UCSI_CONCAP_OPMODE_USB3 BIT(6) |
---|
231 | 205 | #define UCSI_CONCAP_OPMODE_ALT_MODE BIT(7) |
---|
232 | | - u8 provider:1; |
---|
233 | | - u8 consumer:1; |
---|
234 | | - u8:6; /* reserved */ |
---|
| 206 | + u8 flags; |
---|
| 207 | +#define UCSI_CONCAP_FLAG_PROVIDER BIT(0) |
---|
| 208 | +#define UCSI_CONCAP_FLAG_CONSUMER BIT(1) |
---|
235 | 209 | } __packed; |
---|
236 | 210 | |
---|
237 | 211 | struct ucsi_altmode { |
---|
.. | .. |
---|
243 | 217 | struct ucsi_cable_property { |
---|
244 | 218 | u16 speed_supported; |
---|
245 | 219 | u8 current_capability; |
---|
246 | | - u8 vbus_in_cable:1; |
---|
247 | | - u8 active_cable:1; |
---|
248 | | - u8 directionality:1; |
---|
249 | | - u8 plug_type:2; |
---|
250 | | -#define UCSI_CABLE_PROPERTY_PLUG_TYPE_A 0 |
---|
251 | | -#define UCSI_CABLE_PROPERTY_PLUG_TYPE_B 1 |
---|
252 | | -#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2 |
---|
253 | | -#define UCSI_CABLE_PROPERTY_PLUG_OTHER 3 |
---|
254 | | - u8 mode_support:1; |
---|
255 | | - u8:2; /* reserved */ |
---|
256 | | - u8 latency:4; |
---|
257 | | - u8:4; /* reserved */ |
---|
| 220 | + u8 flags; |
---|
| 221 | +#define UCSI_CABLE_PROP_FLAG_VBUS_IN_CABLE BIT(0) |
---|
| 222 | +#define UCSI_CABLE_PROP_FLAG_ACTIVE_CABLE BIT(1) |
---|
| 223 | +#define UCSI_CABLE_PROP_FLAG_DIRECTIONALITY BIT(2) |
---|
| 224 | +#define UCSI_CABLE_PROP_FLAG_PLUG_TYPE(_f_) ((_f_) & GENMASK(3, 0)) |
---|
| 225 | +#define UCSI_CABLE_PROPERTY_PLUG_TYPE_A 0 |
---|
| 226 | +#define UCSI_CABLE_PROPERTY_PLUG_TYPE_B 1 |
---|
| 227 | +#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C 2 |
---|
| 228 | +#define UCSI_CABLE_PROPERTY_PLUG_OTHER 3 |
---|
| 229 | +#define UCSI_CABLE_PROP_MODE_SUPPORT BIT(5) |
---|
| 230 | + u8 latency; |
---|
258 | 231 | } __packed; |
---|
259 | 232 | |
---|
260 | 233 | /* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */ |
---|
.. | .. |
---|
271 | 244 | #define UCSI_CONSTAT_POWER_DIR_CHANGE BIT(12) |
---|
272 | 245 | #define UCSI_CONSTAT_CONNECT_CHANGE BIT(14) |
---|
273 | 246 | #define UCSI_CONSTAT_ERROR BIT(15) |
---|
274 | | - u16 pwr_op_mode:3; |
---|
275 | | -#define UCSI_CONSTAT_PWR_OPMODE_NONE 0 |
---|
276 | | -#define UCSI_CONSTAT_PWR_OPMODE_DEFAULT 1 |
---|
277 | | -#define UCSI_CONSTAT_PWR_OPMODE_BC 2 |
---|
278 | | -#define UCSI_CONSTAT_PWR_OPMODE_PD 3 |
---|
279 | | -#define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5 4 |
---|
280 | | -#define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0 5 |
---|
281 | | - u16 connected:1; |
---|
282 | | - u16 pwr_dir:1; |
---|
283 | | - u16 partner_flags:8; |
---|
284 | | -#define UCSI_CONSTAT_PARTNER_FLAG_USB BIT(0) |
---|
285 | | -#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE BIT(1) |
---|
286 | | - u16 partner_type:3; |
---|
287 | | -#define UCSI_CONSTAT_PARTNER_TYPE_DFP 1 |
---|
288 | | -#define UCSI_CONSTAT_PARTNER_TYPE_UFP 2 |
---|
289 | | -#define UCSI_CONSTAT_PARTNER_TYPE_CABLE 3 /* Powered Cable */ |
---|
290 | | -#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */ |
---|
291 | | -#define UCSI_CONSTAT_PARTNER_TYPE_DEBUG 5 |
---|
292 | | -#define UCSI_CONSTAT_PARTNER_TYPE_AUDIO 6 |
---|
| 247 | + u16 flags; |
---|
| 248 | +#define UCSI_CONSTAT_PWR_OPMODE(_f_) ((_f_) & GENMASK(2, 0)) |
---|
| 249 | +#define UCSI_CONSTAT_PWR_OPMODE_NONE 0 |
---|
| 250 | +#define UCSI_CONSTAT_PWR_OPMODE_DEFAULT 1 |
---|
| 251 | +#define UCSI_CONSTAT_PWR_OPMODE_BC 2 |
---|
| 252 | +#define UCSI_CONSTAT_PWR_OPMODE_PD 3 |
---|
| 253 | +#define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5 4 |
---|
| 254 | +#define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0 5 |
---|
| 255 | +#define UCSI_CONSTAT_CONNECTED BIT(3) |
---|
| 256 | +#define UCSI_CONSTAT_PWR_DIR BIT(4) |
---|
| 257 | +#define UCSI_CONSTAT_PARTNER_FLAGS(_f_) (((_f_) & GENMASK(12, 5)) >> 5) |
---|
| 258 | +#define UCSI_CONSTAT_PARTNER_FLAG_USB 1 |
---|
| 259 | +#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE 2 |
---|
| 260 | +#define UCSI_CONSTAT_PARTNER_TYPE(_f_) (((_f_) & GENMASK(15, 13)) >> 13) |
---|
| 261 | +#define UCSI_CONSTAT_PARTNER_TYPE_DFP 1 |
---|
| 262 | +#define UCSI_CONSTAT_PARTNER_TYPE_UFP 2 |
---|
| 263 | +#define UCSI_CONSTAT_PARTNER_TYPE_CABLE 3 /* Powered Cable */ |
---|
| 264 | +#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */ |
---|
| 265 | +#define UCSI_CONSTAT_PARTNER_TYPE_DEBUG 5 |
---|
| 266 | +#define UCSI_CONSTAT_PARTNER_TYPE_AUDIO 6 |
---|
293 | 267 | u32 request_data_obj; |
---|
294 | | - u8 bc_status:2; |
---|
295 | | -#define UCSI_CONSTAT_BC_NOT_CHARGING 0 |
---|
296 | | -#define UCSI_CONSTAT_BC_NOMINAL_CHARGING 1 |
---|
297 | | -#define UCSI_CONSTAT_BC_SLOW_CHARGING 2 |
---|
298 | | -#define UCSI_CONSTAT_BC_TRICKLE_CHARGING 3 |
---|
299 | | - u8 provider_cap_limit_reason:4; |
---|
300 | | -#define UCSI_CONSTAT_CAP_PWR_LOWERED 0 |
---|
301 | | -#define UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT 1 |
---|
302 | | - u8:2; /* reserved */ |
---|
| 268 | + u8 pwr_status; |
---|
| 269 | +#define UCSI_CONSTAT_BC_STATUS(_p_) ((_p_) & GENMASK(2, 0)) |
---|
| 270 | +#define UCSI_CONSTAT_BC_NOT_CHARGING 0 |
---|
| 271 | +#define UCSI_CONSTAT_BC_NOMINAL_CHARGING 1 |
---|
| 272 | +#define UCSI_CONSTAT_BC_SLOW_CHARGING 2 |
---|
| 273 | +#define UCSI_CONSTAT_BC_TRICKLE_CHARGING 3 |
---|
| 274 | +#define UCSI_CONSTAT_PROVIDER_CAP_LIMIT(_p_) (((_p_) & GENMASK(6, 3)) >> 3) |
---|
| 275 | +#define UCSI_CONSTAT_CAP_PWR_LOWERED 0 |
---|
| 276 | +#define UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT 1 |
---|
303 | 277 | } __packed; |
---|
304 | 278 | |
---|
305 | 279 | /* -------------------------------------------------------------------------- */ |
---|
306 | 280 | |
---|
307 | | -struct ucsi; |
---|
308 | | - |
---|
309 | | -struct ucsi_data { |
---|
| 281 | +struct ucsi { |
---|
310 | 282 | u16 version; |
---|
311 | | - u16 reserved; |
---|
312 | | - union { |
---|
313 | | - u32 raw_cci; |
---|
314 | | - struct ucsi_cci cci; |
---|
315 | | - }; |
---|
316 | | - struct ucsi_control ctrl; |
---|
317 | | - u32 message_in[4]; |
---|
318 | | - u32 message_out[4]; |
---|
319 | | -} __packed; |
---|
| 283 | + struct device *dev; |
---|
| 284 | + struct driver_data *driver_data; |
---|
320 | 285 | |
---|
321 | | -/* |
---|
322 | | - * struct ucsi_ppm - Interface to UCSI Platform Policy Manager |
---|
323 | | - * @data: memory location to the UCSI data structures |
---|
324 | | - * @cmd: UCSI command execution routine |
---|
325 | | - * @sync: Refresh UCSI mailbox (the data structures) |
---|
326 | | - */ |
---|
327 | | -struct ucsi_ppm { |
---|
328 | | - struct ucsi_data *data; |
---|
329 | | - int (*cmd)(struct ucsi_ppm *, struct ucsi_control *); |
---|
330 | | - int (*sync)(struct ucsi_ppm *); |
---|
| 286 | + const struct ucsi_operations *ops; |
---|
| 287 | + |
---|
| 288 | + struct ucsi_capability cap; |
---|
| 289 | + struct ucsi_connector *connector; |
---|
| 290 | + |
---|
| 291 | + struct work_struct work; |
---|
| 292 | +#define UCSI_ROLE_SWITCH_RETRY_PER_HZ 10 |
---|
| 293 | +#define UCSI_ROLE_SWITCH_INTERVAL (HZ / UCSI_ROLE_SWITCH_RETRY_PER_HZ) |
---|
| 294 | +#define UCSI_ROLE_SWITCH_WAIT_COUNT (10 * UCSI_ROLE_SWITCH_RETRY_PER_HZ) |
---|
| 295 | + |
---|
| 296 | + /* PPM Communication lock */ |
---|
| 297 | + struct mutex ppm_lock; |
---|
| 298 | + |
---|
| 299 | + /* The latest "Notification Enable" bits (SET_NOTIFICATION_ENABLE) */ |
---|
| 300 | + u64 ntfy; |
---|
| 301 | + |
---|
| 302 | + /* PPM communication flags */ |
---|
| 303 | + unsigned long flags; |
---|
| 304 | +#define EVENT_PENDING 0 |
---|
| 305 | +#define COMMAND_PENDING 1 |
---|
| 306 | +#define ACK_PENDING 2 |
---|
| 307 | +#define EVENT_PROCESSING 3 |
---|
331 | 308 | }; |
---|
332 | 309 | |
---|
333 | | -struct ucsi *ucsi_register_ppm(struct device *dev, struct ucsi_ppm *ppm); |
---|
334 | | -void ucsi_unregister_ppm(struct ucsi *ucsi); |
---|
335 | | -void ucsi_notify(struct ucsi *ucsi); |
---|
| 310 | +/** |
---|
| 311 | + * struct ucsi_android - contains parameters without modifying the format |
---|
| 312 | + * of ucsi struct. |
---|
| 313 | + * @ucsi: contains the ucsi reference. |
---|
| 314 | + * @work: work structure for queuing ucsi_init_work. |
---|
| 315 | + * @work_count: to track the wait count(MAX= UCSI_ROLE_SWITCH_WAIT_COUNT). |
---|
| 316 | + * |
---|
| 317 | + * Required to address Bug: 260537721 |
---|
| 318 | + * If the role switch module probes late the |
---|
| 319 | + * fwnode_usb_role_switch_get() will fail with -EPROBE_DEFER. |
---|
| 320 | + * To recover from this, restart the ucsi_init_work |
---|
| 321 | + * to find the fwnode again using a delayed workqueue. |
---|
| 322 | + */ |
---|
| 323 | +struct ucsi_android { |
---|
| 324 | + struct ucsi ucsi; |
---|
| 325 | + struct delayed_work work; |
---|
| 326 | + int work_count; |
---|
| 327 | +}; |
---|
| 328 | + |
---|
| 329 | +#define UCSI_MAX_SVID 5 |
---|
| 330 | +#define UCSI_MAX_ALTMODES (UCSI_MAX_SVID * 6) |
---|
| 331 | + |
---|
| 332 | +#define UCSI_TYPEC_VSAFE5V 5000 |
---|
| 333 | +#define UCSI_TYPEC_1_5_CURRENT 1500 |
---|
| 334 | +#define UCSI_TYPEC_3_0_CURRENT 3000 |
---|
| 335 | + |
---|
| 336 | +struct ucsi_connector { |
---|
| 337 | + int num; |
---|
| 338 | + |
---|
| 339 | + struct ucsi *ucsi; |
---|
| 340 | + struct mutex lock; /* port lock */ |
---|
| 341 | + struct work_struct work; |
---|
| 342 | + struct completion complete; |
---|
| 343 | + |
---|
| 344 | + struct typec_port *port; |
---|
| 345 | + struct typec_partner *partner; |
---|
| 346 | + |
---|
| 347 | + struct typec_altmode *port_altmode[UCSI_MAX_ALTMODES]; |
---|
| 348 | + struct typec_altmode *partner_altmode[UCSI_MAX_ALTMODES]; |
---|
| 349 | + |
---|
| 350 | + struct typec_capability typec_cap; |
---|
| 351 | + |
---|
| 352 | + u16 unprocessed_changes; |
---|
| 353 | + struct ucsi_connector_status status; |
---|
| 354 | + struct ucsi_connector_capability cap; |
---|
| 355 | + struct power_supply *psy; |
---|
| 356 | + struct power_supply_desc psy_desc; |
---|
| 357 | + u32 rdo; |
---|
| 358 | + u32 src_pdos[PDO_MAX_OBJECTS]; |
---|
| 359 | + int num_pdos; |
---|
| 360 | + |
---|
| 361 | + struct usb_role_switch *usb_role_sw; |
---|
| 362 | +}; |
---|
| 363 | + |
---|
| 364 | +int ucsi_send_command(struct ucsi *ucsi, u64 command, |
---|
| 365 | + void *retval, size_t size); |
---|
| 366 | + |
---|
| 367 | +void ucsi_altmode_update_active(struct ucsi_connector *con); |
---|
| 368 | +int ucsi_resume(struct ucsi *ucsi); |
---|
| 369 | + |
---|
| 370 | +#if IS_ENABLED(CONFIG_POWER_SUPPLY) |
---|
| 371 | +int ucsi_register_port_psy(struct ucsi_connector *con); |
---|
| 372 | +void ucsi_unregister_port_psy(struct ucsi_connector *con); |
---|
| 373 | +void ucsi_port_psy_changed(struct ucsi_connector *con); |
---|
| 374 | +#else |
---|
| 375 | +static inline int ucsi_register_port_psy(struct ucsi_connector *con) { return 0; } |
---|
| 376 | +static inline void ucsi_unregister_port_psy(struct ucsi_connector *con) { } |
---|
| 377 | +static inline void ucsi_port_psy_changed(struct ucsi_connector *con) { } |
---|
| 378 | +#endif /* CONFIG_POWER_SUPPLY */ |
---|
| 379 | + |
---|
| 380 | +#if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE) |
---|
| 381 | +struct typec_altmode * |
---|
| 382 | +ucsi_register_displayport(struct ucsi_connector *con, |
---|
| 383 | + bool override, int offset, |
---|
| 384 | + struct typec_altmode_desc *desc); |
---|
| 385 | + |
---|
| 386 | +void ucsi_displayport_remove_partner(struct typec_altmode *adev); |
---|
| 387 | + |
---|
| 388 | +#else |
---|
| 389 | +static inline struct typec_altmode * |
---|
| 390 | +ucsi_register_displayport(struct ucsi_connector *con, |
---|
| 391 | + bool override, int offset, |
---|
| 392 | + struct typec_altmode_desc *desc) |
---|
| 393 | +{ |
---|
| 394 | + return NULL; |
---|
| 395 | +} |
---|
| 396 | + |
---|
| 397 | +static inline void |
---|
| 398 | +ucsi_displayport_remove_partner(struct typec_altmode *adev) { } |
---|
| 399 | +#endif /* CONFIG_TYPEC_DP_ALTMODE */ |
---|
| 400 | + |
---|
| 401 | +/* |
---|
| 402 | + * NVIDIA VirtualLink (svid 0x955) has two altmode. VirtualLink |
---|
| 403 | + * DP mode with vdo=0x1 and NVIDIA test mode with vdo=0x3 |
---|
| 404 | + */ |
---|
| 405 | +#define USB_TYPEC_NVIDIA_VLINK_DP_VDO 0x1 |
---|
| 406 | +#define USB_TYPEC_NVIDIA_VLINK_DBG_VDO 0x3 |
---|
336 | 407 | |
---|
337 | 408 | #endif /* __DRIVER_USB_TYPEC_UCSI_H */ |
---|