Commit | Line | Data |
---|---|---|
5073353a JB |
1 | /* |
2 | * USB PD Driver - Policy Engine | |
3 | */ | |
4 | ||
5 | #include <linux/device.h> | |
6 | #include <linux/workqueue.h> | |
7 | #include <linux/slab.h> | |
8 | #include <linux/sched.h> | |
9 | #include <linux/ccic/usbpd.h> | |
10 | #include <linux/delay.h> | |
11 | #include <linux/completion.h> | |
5073353a JB |
12 | |
13 | #include <linux/muic/muic.h> | |
14 | #if defined(CONFIG_MUIC_NOTIFIER) | |
15 | #include <linux/muic/muic_notifier.h> | |
16 | #endif /* CONFIG_MUIC_NOTIFIER */ | |
17 | ||
18 | #include <linux/usb_notify.h> | |
19 | ||
20 | #if (defined CONFIG_IFCONN_NOTIFIER || defined CONFIG_DUAL_ROLE_USB_INTF) | |
21 | #include <linux/ccic/usbpd_ext.h> | |
22 | #endif | |
23 | ||
24 | #if defined(CONFIG_IFCONN_NOTIFIER) | |
25 | #include <linux/ifconn/ifconn_notifier.h> | |
26 | #endif | |
27 | ||
0ef320fa JB |
28 | #include <linux/ccic/usbpd-s2mu106.h> |
29 | ||
5073353a JB |
30 | #define CHECK_MSG(pd, msg, ret) do {\ |
31 | if (pd->phy_ops.get_status(pd, msg))\ | |
32 | return ret;\ | |
33 | } while (0); | |
34 | ||
35 | #define CHECK_CMD(pd, event, ret) do {\ | |
36 | if (pd->manager.cmd & event) {\ | |
37 | pd->manager.cmd &= ~event; \ | |
38 | return ret;\ | |
39 | } \ | |
40 | } while (0); | |
41 | ||
42 | policy_state usbpd_policy_src_startup(struct policy_data *policy) | |
43 | { | |
44 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
45 | int ret = PE_SRC_Send_Capabilities; |
46 | int ms = 0; | |
5073353a | 47 | |
40798a41 JB |
48 | /********************************************** |
49 | Actions on entry: | |
50 | Reset CapsCounter | |
51 | Reset Protocol Layer | |
52 | Start SwapSourceStartTimer (only after Swap) | |
53 | **********************************************/ | |
54 | ||
55 | /* 1) PD State Inform for AP */ | |
5073353a | 56 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 JB |
57 | |
58 | /* 2) CapsCounter Reset */ | |
5073353a | 59 | pd_data->counter.caps_counter = 0; |
40798a41 JB |
60 | |
61 | /* 3) PD Protocol Initialization */ | |
5073353a JB |
62 | usbpd_init_protocol(pd_data); |
63 | ||
40798a41 JB |
64 | /* 4) Fro tSrcrecover after PE_SRC_Transition_to_default */ |
65 | if (policy->txhardresetflag == 1) { | |
66 | policy->txhardresetflag = 0; | |
67 | ||
68 | usbpd_timer1_start(pd_data); | |
69 | while (1) { | |
70 | if (policy->plug_valid == 0) { | |
71 | ret = PE_SRC_Startup; | |
72 | break; | |
73 | } | |
74 | ms = usbpd_check_time1(pd_data); | |
75 | if (ms >= 200) | |
76 | break; | |
77 | } | |
78 | } | |
79 | ||
80 | /* 5) Configuration Channel On */ | |
5073353a JB |
81 | pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON); |
82 | ||
40798a41 | 83 | return ret; |
5073353a JB |
84 | } |
85 | ||
86 | policy_state usbpd_policy_src_discovery(struct policy_data *policy) | |
87 | { | |
88 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
89 | int ret = 0; |
90 | int ms = 0; | |
91 | ||
92 | /********************************************** | |
93 | Actions on entry: | |
94 | Initialize and run SourceCapabilityTimer | |
95 | **********************************************/ | |
5073353a | 96 | |
40798a41 | 97 | /* 1) PD State Inform for AP */ |
5073353a | 98 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 JB |
99 | |
100 | /* 2) Delay*/ | |
101 | usbpd_timer1_start(pd_data); | |
102 | while (1) { | |
103 | if (policy->plug_valid == 0) { | |
104 | ret = PE_SRC_Discovery; | |
105 | break; | |
106 | } | |
107 | ms = usbpd_check_time1(pd_data); | |
108 | if (ms >= tTypeCSendSourceCap) | |
109 | break; | |
110 | } | |
111 | ||
112 | if (ret == PE_SRC_Discovery) | |
113 | return ret; | |
114 | /* 3) Caps Counter Check */ | |
5073353a JB |
115 | if (pd_data->counter.caps_counter <= USBPD_nCapsCount) |
116 | return PE_SRC_Send_Capabilities; | |
117 | else | |
118 | return PE_SRC_Disabled; | |
119 | } | |
120 | ||
121 | policy_state usbpd_policy_src_send_capabilities(struct policy_data *policy) | |
122 | { | |
123 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
124 | bool received_goodcrc = 0; |
125 | int ret = 0; | |
126 | int ms = 0; | |
127 | ||
128 | /********************************************** | |
129 | Actions on entry: | |
130 | Request present source capabilities from Device Policy Manager | |
131 | Send PD Capabilities message | |
132 | Increment CapsCounter (optional) | |
133 | If GoodCRC received: | |
134 | - stop NoResponseTimer | |
135 | - reset HardResetCounter and CapsCounter | |
136 | - initialize and run SenderResponseTimer | |
137 | **********************************************/ | |
138 | ||
139 | /* 1) PD State Inform for AP */ | |
140 | dev_info(pd_data->dev, "%s\n", __func__); | |
5073353a | 141 | |
40798a41 | 142 | /* 2) Source Capabilities PDO Read & Write */ |
5073353a JB |
143 | policy->tx_msg_header.word = pd_data->source_msg_header.word; |
144 | policy->tx_data_obj[0].object = pd_data->source_data_obj.object; | |
145 | ||
40798a41 JB |
146 | /* 3) Interrupt Status Bit Clear */ |
147 | pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC | MSG_REQUEST | | |
148 | MSG_GET_SNK_CAP); | |
149 | /* 4) Add Caps Counter */ | |
5073353a | 150 | pd_data->counter.caps_counter++; |
5073353a | 151 | |
40798a41 JB |
152 | /* 5) Send Message */ |
153 | usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj); | |
154 | ||
155 | /* 6) Start Timer */ | |
156 | usbpd_timer1_start(pd_data); // Setting 25ms is actual 25 ~ 29ms | |
157 | /* 7) Wait Message or State */ | |
158 | while (1) { | |
159 | if (policy->plug_valid == 0) { | |
160 | ret = PE_SRC_Send_Capabilities; | |
161 | break; | |
162 | } | |
163 | ms = usbpd_check_time1(pd_data); | |
164 | if (pd_data->phy_ops.get_status(pd_data, MSG_REQUEST)) { | |
165 | pd_data->counter.hard_reset_counter = 0; | |
5073353a | 166 | pd_data->counter.caps_counter = 0; |
40798a41 JB |
167 | pd_data->source_request_obj.object |
168 | = policy->rx_data_obj[0].object; | |
169 | dev_info(pd_data->dev, "got Request.\n"); | |
170 | ret = PE_SRC_Negotiate_Capability; | |
171 | break; | |
172 | } | |
5073353a | 173 | |
40798a41 JB |
174 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) |
175 | received_goodcrc = 1; | |
5073353a | 176 | |
40798a41 JB |
177 | if (policy->rx_hardreset) { |
178 | ret = 0; | |
179 | break; | |
180 | } | |
5073353a | 181 | |
40798a41 JB |
182 | /* TD.PD.SRC.E14 Atomic Message Sequence */ |
183 | if (pd_data->phy_ops.get_status(pd_data, MSG_GET_SNK_CAP)) { | |
184 | ret = PE_SRC_Send_Soft_Reset; | |
185 | break; | |
186 | } | |
5073353a | 187 | |
40798a41 JB |
188 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { |
189 | ret = PE_SRC_Discovery; | |
190 | break; | |
191 | } | |
192 | ||
193 | if (pd_data->phy_ops.get_status(pd_data, MSG_PING)) { | |
194 | ret = PE_SRC_Send_Soft_Reset; | |
195 | break; | |
196 | } | |
197 | ||
198 | if (ms >= tSenderResponse) { | |
199 | if (received_goodcrc) { | |
200 | ret = PE_SRC_Hard_Reset; | |
201 | ||
202 | if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount) | |
203 | ret = Error_Recovery; | |
204 | ||
205 | break; | |
5073353a | 206 | } |
5073353a | 207 | } |
5073353a | 208 | |
40798a41 JB |
209 | if (ms >= 100) { |
210 | ret = PE_SRC_Discovery; | |
211 | break; | |
212 | } | |
213 | } | |
5073353a | 214 | |
40798a41 | 215 | return ret; |
5073353a | 216 | } |
40798a41 | 217 | |
5073353a JB |
218 | policy_state usbpd_policy_src_negotiate_capability(struct policy_data *policy) |
219 | { | |
220 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 | 221 | int ret = PE_SRC_Negotiate_Capability; |
99e9c3ca | 222 | int data_role = 0; |
40798a41 JB |
223 | |
224 | /********************************************** | |
225 | Actions on entry: | |
226 | Get Device Policy Manager evaluation of sink request: | |
227 | - Can be met | |
228 | - Can??t be met | |
229 | - Could be met later from Power Reserve | |
230 | If the sink request for Operating Current or Operating Power can be met, | |
231 | but the sink still requires more power Capability Mismatch this | |
232 | information will be passed to Device Policy Manager | |
233 | **********************************************/ | |
234 | ||
235 | /* 1) PD State Inform for AP */ | |
5073353a | 236 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 | 237 | |
99e9c3ca JB |
238 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
239 | ||
240 | mutex_lock(&pd_data->accept_mutex); | |
40798a41 JB |
241 | /* 2) Analysis Received Request Message */ |
242 | if (usbpd_manager_match_request(pd_data) == 0) { | |
99e9c3ca JB |
243 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, |
244 | data_role, USBPD_SOURCE); | |
245 | dev_info(pd_data->dev, "%s sended accept\n", __func__); | |
40798a41 JB |
246 | ret = PE_SRC_Transition_Supply; /* Accept */ |
247 | } else { | |
248 | ret = PE_SRC_Capability_Response; /* Reject */ | |
249 | } | |
99e9c3ca | 250 | mutex_unlock(&pd_data->accept_mutex); |
40798a41 JB |
251 | |
252 | return ret; | |
5073353a JB |
253 | } |
254 | ||
255 | policy_state usbpd_policy_src_transition_supply(struct policy_data *policy) | |
256 | { | |
257 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
258 | int ret = PE_SRC_Ready; |
259 | int ms1 = 0, ms2 = 0; | |
260 | ||
261 | /********************************************** | |
262 | Actions on entry: | |
263 | Initialize and run SourceActivityTimer (see Section 8.3.3.5) | |
264 | If GotoMin send GotoMin message | |
265 | Else send Accept message (within tReceiverResponse) | |
266 | Wait tSrcTransition and request Device Policy Manager to transition Power Supply | |
267 | ||
268 | Actions on exit: | |
269 | Send PS_RDY message | |
270 | **********************************************/ | |
5073353a | 271 | |
40798a41 | 272 | /* 1) PD State Inform for AP */ |
5073353a | 273 | dev_info(pd_data->dev, "%s\n", __func__); |
5073353a | 274 | |
40798a41 JB |
275 | /* 2) Send Message */ |
276 | // Move to PE_SRC_Nego | |
277 | //usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, USBPD_DFP, USBPD_SOURCE); | |
5073353a | 278 | |
40798a41 JB |
279 | /* 3) Start Timer */ |
280 | usbpd_timer1_start(pd_data); | |
281 | ||
282 | /* 4) Wait Message or State */ | |
283 | while (1) { | |
284 | if (policy->plug_valid == 0) { | |
285 | ret = PE_SRC_Transition_Supply; | |
286 | break; | |
287 | } | |
288 | ms1 = usbpd_check_time1(pd_data); | |
289 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
290 | ||
291 | usbpd_timer2_start(pd_data); | |
292 | while (1) { | |
293 | if (policy->plug_valid == 0) { | |
294 | ret = PE_SRC_Transition_Supply; | |
295 | break; | |
296 | } | |
297 | ms2 = usbpd_check_time2(pd_data); | |
298 | if (ms2 > tSrcTransition) | |
299 | break; | |
300 | } | |
301 | ||
302 | if (ret == PE_SRC_Transition_Supply) | |
303 | return ret; | |
304 | ||
305 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_PS_RDY, USBPD_DFP, USBPD_SOURCE); | |
7158ce20 JB |
306 | pd_data->phy_ops.set_rp_control(pd_data, PLUG_CTRL_RP180); |
307 | ||
40798a41 JB |
308 | ret = PE_SRC_Ready; |
309 | break; | |
310 | } | |
311 | ||
312 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
313 | ret = PE_SRC_Send_Soft_Reset; | |
314 | break; | |
315 | } | |
316 | ||
99e9c3ca | 317 | if (ms1 >= 8) { |
40798a41 JB |
318 | ret = PE_SRC_Hard_Reset; |
319 | break; | |
320 | } | |
5073353a | 321 | } |
40798a41 JB |
322 | |
323 | return ret; | |
5073353a JB |
324 | } |
325 | ||
326 | policy_state usbpd_policy_src_ready(struct policy_data *policy) | |
327 | { | |
328 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
329 | int data_role = 0; | |
330 | ||
40798a41 JB |
331 | /********************************************** |
332 | Actions on entry: | |
333 | Initialize and run SourceActivityTimer (see Section 8.3.3.5) | |
334 | Initialize and run DiscoverIdentityTimer | |
335 | **********************************************/ | |
336 | ||
337 | /* 1) PD State Inform for AP */ | |
5073353a | 338 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 | 339 | |
0ef320fa JB |
340 | if (pd_data->pd_support == 0) { |
341 | pd_data->pd_support = 1; | |
342 | pd_data->phy_ops.set_pwr_opmode(pd_data, TYPEC_PWR_MODE_PD); | |
343 | } | |
40798a41 JB |
344 | |
345 | /* 2) Wait Message or State */ | |
5073353a JB |
346 | CHECK_MSG(pd_data, MSG_GET_SRC_CAP, PE_SRC_Give_Source_Cap); |
347 | CHECK_MSG(pd_data, MSG_REQUEST, PE_SRC_Negotiate_Capability); | |
348 | CHECK_MSG(pd_data, MSG_PR_SWAP, PE_PRS_SRC_SNK_Evaluate_Swap); | |
349 | CHECK_MSG(pd_data, MSG_DR_SWAP, PE_DRS_Evaluate_Port); | |
350 | CHECK_MSG(pd_data, MSG_VCONN_SWAP, PE_VCS_Evaluate_Swap); | |
40798a41 JB |
351 | CHECK_MSG(pd_data, MSG_GET_SNK_CAP, PE_DR_SRC_Give_Sink_Cap); |
352 | CHECK_MSG(pd_data, MSG_SOFTRESET, PE_SRC_Soft_Reset); | |
353 | CHECK_MSG(pd_data, MSG_ERROR, PE_SRC_Send_Soft_Reset); | |
99e9c3ca | 354 | CHECK_MSG(pd_data, MSG_BIST, PE_BIST_Receive_Mode); |
0ef320fa | 355 | |
40798a41 | 356 | #if 0 |
5073353a JB |
357 | CHECK_MSG(pd_data, VDM_DISCOVER_IDENTITY, PE_UFP_VDM_Get_Identity); |
358 | CHECK_MSG(pd_data, VDM_DISCOVER_SVID, PE_UFP_VDM_Get_SVIDs); | |
359 | CHECK_MSG(pd_data, VDM_DISCOVER_MODE, PE_UFP_VDM_Get_Modes); | |
360 | CHECK_MSG(pd_data, VDM_ENTER_MODE, PE_UFP_VDM_Evaluate_Mode_Entry); | |
361 | CHECK_MSG(pd_data, VDM_ATTENTION, PE_DFP_VDM_Attention_Request); | |
362 | CHECK_MSG(pd_data, VDM_DP_STATUS_UPDATE, PE_UFP_VDM_Evaluate_Status); | |
363 | CHECK_MSG(pd_data, VDM_DP_CONFIGURE, PE_UFP_VDM_Evaluate_Configure); | |
364 | CHECK_MSG(pd_data, UVDM_MSG, PE_DFP_UVDM_Receive_Message); | |
40798a41 JB |
365 | #endif |
366 | /* 3) Command Check from AP */ | |
5073353a JB |
367 | CHECK_CMD(pd_data, MANAGER_REQ_GET_SNKCAP, PE_SRC_Get_Sink_Cap); |
368 | CHECK_CMD(pd_data, MANAGER_REQ_GOTOMIN, PE_SRC_Transition_Supply); | |
369 | CHECK_CMD(pd_data, MANAGER_REQ_SRCCAP_CHANGE, PE_SRC_Send_Capabilities); | |
370 | CHECK_CMD(pd_data, MANAGER_REQ_PR_SWAP, PE_PRS_SRC_SNK_Send_Swap); | |
371 | CHECK_CMD(pd_data, MANAGER_REQ_DR_SWAP, PE_DRS_Evaluate_Send_Port); | |
372 | CHECK_CMD(pd_data, MANAGER_REQ_VCONN_SWAP, PE_VCS_Send_Swap); | |
373 | CHECK_CMD(pd_data, MANAGER_REQ_UVDM_SEND_MESSAGE, | |
374 | PE_DFP_UVDM_Send_Message); | |
375 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_IDENTITY, PE_DFP_VDM_Identity_Request); | |
376 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_SVID, PE_DFP_VDM_SVIDs_Request); | |
377 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_MODE, PE_DFP_VDM_Modes_Request); | |
378 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_ENTER_MODE, PE_DFP_VDM_Mode_Entry_Request); | |
40798a41 | 379 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_EXIT_MODE, PE_DFP_VDM_Mode_Exit_Request); |
5073353a JB |
380 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_STATUS_UPDATE, PE_DFP_VDM_Status_Update); |
381 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DisplayPort_Configure, PE_DFP_VDM_DisplayPort_Configure); | |
382 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_ATTENTION, PE_UFP_VDM_Attention_Request); | |
383 | ||
40798a41 | 384 | |
5073353a JB |
385 | /* for data role swap test |
386 | if (usbpd_manager_vdm_request_enabled(pd_data)) { | |
387 | msleep(tDiscoverIdentity); | |
388 | return PE_DRS_Evaluate_Send_Port; | |
389 | } | |
390 | */ | |
391 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
392 | ||
40798a41 | 393 | #if 0 |
5073353a JB |
394 | if (data_role == USBPD_DFP) |
395 | usbpd_manager_vdm_request_enabled(pd_data); | |
40798a41 | 396 | #endif |
5073353a JB |
397 | return PE_SRC_Ready; |
398 | } | |
399 | ||
400 | policy_state usbpd_policy_src_disabled(struct policy_data *policy) | |
401 | { | |
402 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
403 | ||
40798a41 JB |
404 | /********************************************** |
405 | Actions on entry: | |
406 | Disable Power Delivery | |
407 | **********************************************/ | |
408 | ||
409 | /* 1) PD State Inform for AP */ | |
5073353a | 410 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 | 411 | |
5073353a JB |
412 | return PE_SRC_Disabled; |
413 | } | |
414 | ||
415 | policy_state usbpd_policy_src_capability_response(struct policy_data *policy) | |
416 | { | |
417 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
418 | int ret = 0; |
419 | int data_role = 0; | |
420 | int ms = 0; | |
5073353a | 421 | |
40798a41 JB |
422 | /********************************************** |
423 | Actions on entry: | |
424 | Send Reject message if request can't be met | |
425 | Send Wait message if request could be met later from the Power | |
426 | Reserve and present Contract is still valid | |
427 | **********************************************/ | |
428 | ||
429 | /* 1) PD State Inform for AP */ | |
5073353a JB |
430 | dev_info(pd_data->dev, "%s\n", __func__); |
431 | ||
40798a41 JB |
432 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
433 | ||
434 | /* 2) Send Message */ | |
435 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Reject, | |
436 | data_role, USBPD_SOURCE); | |
437 | ||
438 | /* 3) Start Timer */ | |
439 | usbpd_timer1_start(pd_data); | |
440 | ||
441 | /* 4) Wait Message or State */ | |
442 | while (1) { | |
443 | if (policy->plug_valid == 0) { | |
444 | ret = PE_SRC_Capability_Response; | |
445 | break; | |
446 | } | |
447 | ms = usbpd_check_time1(pd_data); | |
448 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
449 | ret = PE_SRC_Ready; | |
450 | break; | |
451 | } | |
452 | ||
453 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
454 | ret = PE_SRC_Send_Soft_Reset; | |
455 | break; | |
456 | } | |
457 | if (ms >= 5) { | |
458 | ret = PE_SRC_Hard_Reset; | |
459 | break; | |
460 | } | |
5073353a | 461 | } |
40798a41 JB |
462 | |
463 | return ret; | |
5073353a JB |
464 | } |
465 | ||
466 | policy_state usbpd_policy_src_hard_reset(struct policy_data *policy) | |
467 | { | |
468 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
469 | int ret = PE_SRC_Transition_to_default; |
470 | int ms = 0; | |
5073353a | 471 | |
40798a41 JB |
472 | /********************************************** |
473 | Actions on entry: | |
474 | Generate Hard Reset signalling | |
475 | Start PSHardResetTimer | |
476 | Increment HardResetCounter | |
477 | **********************************************/ | |
5073353a | 478 | |
40798a41 JB |
479 | /* 1) PD State Inform for AP */ |
480 | dev_info(pd_data->dev, "%s\n", __func__); | |
5073353a | 481 | |
40798a41 | 482 | /* 2) Send Hardreset */ |
5073353a | 483 | pd_data->phy_ops.hard_reset(pd_data); |
40798a41 JB |
484 | |
485 | /* 3) Configuration Channel On */ | |
5073353a | 486 | pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_OFF); |
40798a41 JB |
487 | |
488 | /* 4) Set Tx HardReset Flag After SRC_HADRESET */ | |
489 | policy->txhardresetflag = 1; | |
490 | ||
491 | /* 5) Delay : Setting 25 is actual 57.3ms */ | |
492 | usbpd_timer1_start(pd_data); | |
493 | while (1) { | |
494 | if (policy->plug_valid == 0) { | |
495 | ret = PE_SRC_Hard_Reset; | |
496 | break; | |
497 | } | |
498 | ms = usbpd_check_time1(pd_data); | |
499 | if (ms >= tPSHardReset) | |
500 | break; | |
501 | } | |
502 | ||
503 | if (ret == PE_SRC_Hard_Reset) | |
504 | return ret; | |
505 | ||
506 | /* 6) Add Hardreset Counter */ | |
5073353a JB |
507 | pd_data->counter.hard_reset_counter++; |
508 | ||
509 | return PE_SRC_Transition_to_default; | |
510 | } | |
511 | ||
512 | policy_state usbpd_policy_src_hard_reset_received(struct policy_data *policy) | |
513 | { | |
514 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
515 | int ret = PE_SRC_Transition_to_default; |
516 | int ms = 0; | |
517 | ||
518 | /********************************************** | |
519 | Actions on entry: | |
520 | Start PSHardResetTimer | |
521 | **********************************************/ | |
5073353a | 522 | |
40798a41 | 523 | /* 1) PD State Inform for AP */ |
5073353a JB |
524 | dev_info(pd_data->dev, "%s\n", __func__); |
525 | ||
40798a41 JB |
526 | /* 2) Delay */ |
527 | usbpd_timer1_start(pd_data); | |
528 | while (1) { | |
529 | if (policy->plug_valid == 0) { | |
530 | ret = PE_SRC_Hard_Reset_Received; | |
531 | break; | |
532 | } | |
533 | ms = usbpd_check_time1(pd_data); | |
534 | if (ms >= tPSHardReset) | |
535 | break; | |
536 | } | |
537 | ||
538 | if (ret == PE_SRC_Hard_Reset_Received) | |
539 | return ret; | |
540 | ||
541 | /* 3) Set Tx HardReset Flag After SRC_HADRESET */ | |
542 | policy->txhardresetflag = 1; | |
5073353a JB |
543 | |
544 | return PE_SRC_Transition_to_default; | |
545 | } | |
546 | ||
547 | policy_state usbpd_policy_src_transition_to_default(struct policy_data *policy) | |
548 | { | |
549 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
550 | int ret = PE_SRC_Startup; |
551 | int ms = 0; | |
552 | ||
553 | /********************************************** | |
554 | Actions on entry: | |
555 | Request Device Policy Manager to request power | |
556 | supply Hard Resets to vSafe5V via vSafe0V | |
557 | Reset local HW | |
558 | If Type-C request Device Policy Manager to set | |
559 | Port Data Role to DFP and turn off VCONN | |
560 | **********************************************/ | |
5073353a | 561 | |
40798a41 | 562 | /* 1) PD State Inform for AP */ |
5073353a JB |
563 | dev_info(pd_data->dev, "%s\n", __func__); |
564 | ||
40798a41 JB |
565 | /* 2) VBUS Turn off */ |
566 | pd_data->phy_ops.set_otg_control(pd_data, 0); | |
567 | ||
568 | /* 3) Delay */ | |
569 | usbpd_timer1_start(pd_data); | |
570 | while (1) { | |
571 | if (policy->plug_valid == 0) { | |
572 | ret = PE_SRC_Transition_to_default; | |
573 | break; | |
574 | } | |
575 | ms = usbpd_check_time1(pd_data); | |
576 | if (ms >= tSrcRecover) | |
577 | break; | |
578 | } | |
579 | ||
580 | if (ret == PE_SRC_Transition_to_default) | |
581 | return ret; | |
582 | ||
583 | /* 4) initial reset */ | |
5073353a | 584 | pd_data->phy_ops.driver_reset(pd_data); |
40798a41 JB |
585 | |
586 | pd_data->phy_ops.set_otg_control(pd_data, 1); | |
5073353a JB |
587 | /* |
588 | Request Device Policy Manager to request power | |
589 | supply Hard Resets to vSafe5V via vSafe0V | |
590 | ||
591 | If(Type-C request Device Policy Manager to set Port Data Role to DFP) | |
592 | turn off VCONN | |
593 | */ | |
594 | ||
595 | /* | |
596 | Request Device Policy Manager to turn on VCONN | |
597 | Initialize and start NoResponseTimer | |
598 | Inform Protocol Layer Hard Reset complete | |
599 | */ | |
40798a41 JB |
600 | |
601 | /* confirm VBUS ON : done by set_otg_control */ | |
5073353a JB |
602 | return PE_SRC_Startup; |
603 | } | |
604 | ||
605 | policy_state usbpd_policy_src_give_source_cap(struct policy_data *policy) | |
606 | { | |
607 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
608 | int ret = PE_SRC_Give_Source_Cap; |
609 | int data_role = 0; | |
610 | int ms = 0; | |
611 | ||
612 | /********************************************** | |
613 | Action on entry : | |
614 | Request source capabilities from Device Policy Manager | |
615 | Send Capabilities message | |
616 | **********************************************/ | |
5073353a | 617 | |
40798a41 | 618 | /* 1) PD State Inform for AP */ |
5073353a JB |
619 | dev_info(pd_data->dev, "%s\n", __func__); |
620 | ||
40798a41 JB |
621 | /* 2) Read Data Role */ |
622 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
5073353a | 623 | |
40798a41 | 624 | /* 3) Message Setting */ |
5073353a | 625 | policy->tx_msg_header.msg_type = USBPD_Source_Capabilities; |
40798a41 | 626 | policy->tx_msg_header.port_data_role = data_role; |
5073353a JB |
627 | policy->tx_msg_header.port_power_role = USBPD_SOURCE; |
628 | policy->tx_msg_header.num_data_objs = 1; | |
629 | ||
40798a41 JB |
630 | policy->tx_data_obj[0].power_data_obj.max_current = 1500 / 10; |
631 | policy->tx_data_obj[0].power_data_obj.voltage = 5000 / 50; | |
5073353a JB |
632 | policy->tx_data_obj[0].power_data_obj.peak_current = 0; |
633 | policy->tx_data_obj[0].power_data_obj.data_role_swap = 1; | |
634 | policy->tx_data_obj[0].power_data_obj.usb_comm_capable = 1; | |
635 | policy->tx_data_obj[0].power_data_obj.externally_powered = 0; | |
636 | policy->tx_data_obj[0].power_data_obj.usb_suspend_support = 1; | |
637 | policy->tx_data_obj[0].power_data_obj.dual_role_power = 1; | |
638 | policy->tx_data_obj[0].power_data_obj.supply = 0; | |
639 | ||
40798a41 JB |
640 | /* 4) Send Message */ |
641 | usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj); | |
642 | ||
643 | /* 5) Start Timer */ | |
644 | usbpd_timer1_start(pd_data); | |
645 | while (1) { | |
646 | if (policy->plug_valid == 0) { | |
647 | ret = PE_SRC_Give_Source_Cap; | |
648 | break; | |
649 | } | |
650 | ms = usbpd_check_time1(pd_data); | |
651 | if (pd_data->phy_ops.get_status(pd_data, MSG_REQUEST)) { | |
652 | ret = PE_SRC_Negotiate_Capability; | |
653 | break; | |
654 | } | |
655 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
656 | ret = PE_SRC_Send_Soft_Reset; | |
657 | break; | |
658 | } | |
659 | if (ms >= tSenderResponse) { | |
660 | ret = PE_SRC_Hard_Reset; | |
661 | break; | |
662 | } | |
663 | } | |
664 | ||
665 | return ret; | |
5073353a JB |
666 | } |
667 | ||
668 | policy_state usbpd_policy_src_get_sink_cap(struct policy_data *policy) | |
669 | { | |
670 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
671 | int data_role = 0; |
672 | int ret = PE_SRC_Get_Sink_Cap; | |
673 | int ms = 0; | |
674 | ||
675 | /********************************************** | |
676 | Actions on entry: | |
677 | Send Get_Sink_Cap message | |
678 | Initialize and run | |
679 | SenderResponseTimer | |
680 | **********************************************/ | |
5073353a | 681 | |
40798a41 | 682 | /* 1) PD State Inform for AP */ |
5073353a JB |
683 | dev_info(pd_data->dev, "%s\n", __func__); |
684 | ||
40798a41 | 685 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
5073353a | 686 | |
40798a41 JB |
687 | /* 2) Send Message */ |
688 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
689 | USBPD_Get_Sink_Cap, data_role, USBPD_SOURCE); | |
690 | ||
691 | /* 3) Wait Message */ | |
692 | usbpd_timer1_start(pd_data); | |
693 | while (1) { | |
694 | if (policy->plug_valid == 0) | |
695 | break; | |
696 | ms = usbpd_check_time1(pd_data); | |
697 | if (pd_data->phy_ops.get_status(pd_data, MSG_SNK_CAP)) { | |
5073353a | 698 | dev_info(pd_data->dev, "got SinkCap.\n"); |
40798a41 JB |
699 | ret = PE_SRC_Ready; |
700 | break; | |
701 | } | |
702 | if (ms >= tSenderResponse) { | |
703 | ret = PE_SRC_Ready; | |
704 | break; | |
5073353a JB |
705 | } |
706 | } | |
40798a41 JB |
707 | |
708 | return ret; | |
5073353a JB |
709 | } |
710 | ||
711 | policy_state usbpd_policy_src_wait_new_capabilities(struct policy_data *policy) | |
712 | { | |
713 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
714 | ||
40798a41 JB |
715 | /********************************************** |
716 | Actions on entry: | |
717 | Wait for new Source Capabilities | |
718 | **********************************************/ | |
719 | ||
720 | /* 1) PD State Inform for AP */ | |
5073353a JB |
721 | dev_info(pd_data->dev, "%s\n", __func__); |
722 | ||
723 | return PE_SRC_Send_Capabilities; | |
724 | } | |
725 | ||
726 | policy_state usbpd_policy_src_send_soft_reset(struct policy_data *policy) | |
727 | { | |
728 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
729 | int ret = PE_SRC_Send_Soft_Reset; |
730 | int data_role = 0; | |
731 | int ms = 0; | |
732 | ||
733 | /********************************************** | |
734 | Actions on entry: | |
735 | Reset Protocol Layer | |
736 | Send Soft Reset message | |
737 | Initialize and run SenderResponseTimer | |
738 | **********************************************/ | |
5073353a | 739 | |
40798a41 | 740 | /* 1) PD State Inform for AP */ |
5073353a JB |
741 | dev_info(pd_data->dev, "%s\n", __func__); |
742 | ||
40798a41 | 743 | /* 2) USB PD Protocol Initialization */ |
5073353a JB |
744 | usbpd_init_protocol(pd_data); |
745 | ||
40798a41 JB |
746 | /* 3) Read Data Role */ |
747 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
748 | ||
749 | /* 4) Self SoftReset */ | |
750 | pd_data->phy_ops.soft_reset(pd_data); | |
751 | ||
752 | /* 5) Send Message */ | |
753 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Soft_Reset, | |
754 | data_role, USBPD_SOURCE); | |
755 | ||
756 | /* 6) Start Timer */ | |
757 | usbpd_timer1_start(pd_data); | |
758 | while (1) { | |
759 | if (policy->plug_valid == 0) { | |
760 | ret = PE_SRC_Send_Soft_Reset; | |
761 | break; | |
762 | } | |
763 | ms = usbpd_check_time1(pd_data); | |
764 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
765 | ret = PE_SRC_Send_Capabilities; | |
766 | break; | |
767 | } | |
768 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
769 | ret = PE_SRC_Hard_Reset; | |
770 | break; | |
771 | } | |
772 | if (ms >= tSenderResponse) { | |
773 | ret = PE_SRC_Hard_Reset; | |
774 | break; | |
775 | } | |
5073353a | 776 | } |
40798a41 JB |
777 | |
778 | return ret; | |
5073353a JB |
779 | } |
780 | ||
781 | policy_state usbpd_policy_src_soft_reset(struct policy_data *policy) | |
782 | { | |
5073353a | 783 | struct usbpd_data *pd_data = policy_to_usbpd(policy); |
40798a41 JB |
784 | int ret = PE_SRC_Soft_Reset; |
785 | int data_role = 0; | |
786 | int ms = 0; | |
787 | /********************************************** | |
788 | Actions on entry: | |
789 | Reset Protocol Layer | |
790 | Send Accept message | |
791 | **********************************************/ | |
792 | ||
793 | /* 1) PD State Inform for AP */ | |
794 | dev_info(pd_data->dev, "%s\n", __func__); | |
5073353a | 795 | |
40798a41 JB |
796 | /* 2) USB PD Protocol Initialization */ |
797 | usbpd_init_protocol(pd_data); | |
798 | ||
799 | /* 3) Read Data Role */ | |
800 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
801 | ||
802 | /* 4) Self SoftReset */ | |
803 | pd_data->phy_ops.soft_reset(pd_data); | |
804 | ||
805 | /* 5) Send Message */ | |
806 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, data_role, USBPD_SOURCE); | |
807 | ||
808 | /* 6) Start Timer */ | |
809 | usbpd_timer1_start(pd_data); | |
810 | while (1) { | |
811 | if (policy->plug_valid == 0) { | |
812 | ret = PE_SRC_Soft_Reset; | |
813 | break; | |
814 | } | |
815 | ms = usbpd_check_time1(pd_data); | |
816 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
817 | ret = PE_SRC_Send_Capabilities; | |
818 | break; | |
819 | } | |
820 | ||
821 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
822 | ret = PE_SRC_Hard_Reset; | |
823 | break; | |
824 | } | |
825 | if (ms >= 5) { | |
826 | ret = PE_SRC_Ready; | |
827 | break; | |
828 | } | |
829 | } | |
830 | ||
831 | return ret; | |
5073353a JB |
832 | } |
833 | ||
834 | policy_state usbpd_policy_snk_startup(struct policy_data *policy) | |
835 | { | |
836 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
837 | ||
40798a41 JB |
838 | /********************************************** |
839 | Actions on entry: | |
840 | Reset Protocol Layer | |
841 | **********************************************/ | |
842 | ||
843 | /* 1) PD State Inform for AP */ | |
5073353a | 844 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 JB |
845 | |
846 | /* 2) PD Protocol Initialization */ | |
5073353a JB |
847 | usbpd_init_protocol(pd_data); |
848 | ||
40798a41 JB |
849 | /* 3) Configuration Channel On */ |
850 | //pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON); | |
851 | //Move to PE_SNK_Wait_for_Capabilities | |
5073353a JB |
852 | |
853 | return PE_SNK_Discovery; | |
854 | } | |
855 | ||
856 | policy_state usbpd_policy_snk_discovery(struct policy_data *policy) | |
857 | { | |
40798a41 JB |
858 | struct usbpd_data *pd_data = policy_to_usbpd(policy); |
859 | int ret = 0; | |
860 | int vbus_check = 0; | |
861 | int ms = 0; | |
862 | ||
863 | /********************************************** | |
864 | Actions on entry: | |
865 | Wait for VBUS | |
866 | **********************************************/ | |
867 | ||
5073353a JB |
868 | /* TODO: wait vbus */ |
869 | /* if coming from HardReset | |
870 | && NoResponseTimer timeout | |
871 | && HardResetCounter <= nHardResetCount, | |
872 | return(PE_SNK_Hard_Reset) */ | |
40798a41 JB |
873 | |
874 | /* 1) PD State Inform for AP */ | |
875 | dev_info(pd_data->dev, "%s\n", __func__); | |
876 | ||
877 | /* 2) Start Timer */ | |
878 | usbpd_timer1_start(pd_data); | |
879 | ||
880 | /* 3) Wait Message or State */ | |
881 | while (1) { | |
882 | if (policy->plug_valid == 0) { | |
883 | ret = PE_SNK_Discovery; | |
884 | break; | |
885 | } | |
886 | ms = usbpd_check_time1(pd_data); | |
887 | ||
888 | vbus_check = pd_data->phy_ops.vbus_on_check(pd_data); | |
889 | if (vbus_check < 0 || vbus_check > 0) { | |
890 | ret = PE_SNK_Wait_for_Capabilities; | |
891 | break; | |
892 | } | |
893 | ||
894 | /* TimeOver Check */ | |
895 | if (ms >= tNoResponse) { | |
896 | /* HardReset Count Check */ | |
897 | if (pd_data->counter.hard_reset_counter <= USBPD_nHardResetCount) { | |
898 | ret = PE_SNK_Hard_Reset; | |
899 | break; | |
900 | } else { | |
901 | ret = Error_Recovery; | |
902 | break; | |
903 | } | |
904 | } | |
905 | } | |
906 | ||
907 | return ret; | |
5073353a JB |
908 | } |
909 | ||
910 | policy_state usbpd_policy_snk_wait_for_capabilities(struct policy_data *policy) | |
911 | { | |
912 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
913 | int ret = PE_SNK_Wait_for_Capabilities; |
914 | int ms = 0; | |
5073353a | 915 | |
40798a41 JB |
916 | /********************************************** |
917 | Actions on entry: | |
918 | Initialize and run SinkWaitCapTimer | |
919 | **********************************************/ | |
920 | ||
921 | /* 1) PD State Inform for AP */ | |
5073353a JB |
922 | dev_info(pd_data->dev, "%s\n", __func__); |
923 | ||
40798a41 JB |
924 | /* Configuration Channel On */ |
925 | pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_ON); | |
926 | ||
927 | /* Start Timer */ | |
928 | usbpd_timer1_start(pd_data); | |
929 | ||
930 | /* 4) Wait Message or State */ | |
931 | while (1) { | |
932 | if (policy->plug_valid == 0) { | |
933 | ret = PE_SNK_Wait_for_Capabilities; | |
934 | break; | |
935 | } | |
936 | ms = usbpd_check_time1(pd_data); | |
937 | /* Rx Source Capabilities */ | |
938 | if (pd_data->phy_ops.get_status(pd_data, MSG_SRC_CAP)) { | |
939 | ret = PE_SNK_Evaluate_Capability; | |
940 | break; | |
941 | } | |
5073353a | 942 | |
5073353a | 943 | #if !defined(CONFIG_SEC_FACTORY) |
40798a41 JB |
944 | /* TimeOver Check */ |
945 | if (ms >= tTypeCSinkWaitCap) { | |
946 | /* HardReset Count Check */ | |
947 | if (pd_data->counter.hard_reset_counter <= USBPD_nHardResetCount) { | |
948 | ret = PE_SNK_Hard_Reset; | |
949 | break; | |
950 | } else { | |
951 | ret = Error_Recovery; | |
952 | break; | |
953 | } | |
954 | } | |
5073353a | 955 | #endif |
40798a41 JB |
956 | } |
957 | ||
958 | return ret; | |
5073353a JB |
959 | } |
960 | ||
961 | policy_state usbpd_policy_snk_evaluate_capability(struct policy_data *policy) | |
962 | { | |
963 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
964 | int sink_request_obj_num = 0; | |
40798a41 JB |
965 | int ret = PE_SNK_Evaluate_Capability; |
966 | ||
967 | /********************************************** | |
968 | Actions on entry: | |
969 | Reset HardResetCounter to zero. | |
970 | Ask Device Policy Manager to evaluate the options based on supplied | |
971 | capabilities, any Power Reserve that it needs, and respond indicating | |
972 | the selected capability and, optionally, a Capability Mismatch | |
973 | **********************************************/ | |
5073353a | 974 | |
40798a41 | 975 | /* 1) PD State Inform to AP */ |
5073353a JB |
976 | dev_info(pd_data->dev, "%s\n", __func__); |
977 | ||
40798a41 JB |
978 | /* 4) Select PDO */ |
979 | #if defined(CONFIG_IFCONN_NOTIFIER) | |
5073353a JB |
980 | if (pd_noti.sink_status.selected_pdo_num == 0) { |
981 | pd_noti.sink_status.selected_pdo_num = 1; | |
982 | if (policy->sink_cap_received) { | |
983 | policy->send_sink_cap = 1; | |
984 | policy->sink_cap_received = 0; | |
985 | } | |
986 | } | |
987 | #endif | |
40798a41 | 988 | /* 5) Select Object Position */ |
5073353a JB |
989 | sink_request_obj_num = usbpd_manager_evaluate_capability(pd_data); |
990 | ||
40798a41 | 991 | /* 6) Branch */ |
5073353a | 992 | if (sink_request_obj_num > 0) |
40798a41 | 993 | ret = PE_SNK_Select_Capability; |
5073353a | 994 | else |
40798a41 JB |
995 | ret = PE_SNK_Hard_Reset; |
996 | ||
997 | return ret; | |
5073353a JB |
998 | } |
999 | ||
1000 | policy_state usbpd_policy_snk_select_capability(struct policy_data *policy) | |
1001 | { | |
1002 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
1003 | int ret = PE_SNK_Select_Capability; |
1004 | int data_role = 0; | |
1005 | int ms = 0; | |
5073353a | 1006 | |
40798a41 JB |
1007 | /********************************************** |
1008 | Actions on entry: | |
1009 | Send Request based on Device Policy Manager response: | |
1010 | - Request from present capabilities | |
1011 | - Optionally Indicate that other capabilities would be preferred (Capability Mismatch) | |
1012 | Initialize and run SenderResponseTimer | |
1013 | **********************************************/ | |
1014 | ||
1015 | /* 1) PD State Inform to AP */ | |
1016 | //dev_info(pd_data->dev, "%s\n", __func__); | |
5073353a | 1017 | |
40798a41 JB |
1018 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
1019 | ||
1020 | /* 2) Message Header Setting */ | |
5073353a | 1021 | policy->tx_msg_header.msg_type = USBPD_Request; |
40798a41 | 1022 | policy->tx_msg_header.port_data_role = data_role; |
5073353a | 1023 | policy->tx_msg_header.port_power_role = USBPD_SINK; |
40798a41 | 1024 | policy->tx_msg_header.num_data_objs = 1; /* Initial Select PDO = 1 */ |
5073353a | 1025 | |
40798a41 | 1026 | /* 3) Select PDO */ |
5073353a JB |
1027 | policy->tx_data_obj[0] = usbpd_manager_select_capability(pd_data); |
1028 | ||
40798a41 JB |
1029 | /* 4) Send Message*/ |
1030 | usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj); | |
1031 | ||
1032 | /* 5) Start Timer*/ | |
1033 | usbpd_timer1_start(pd_data); | |
1034 | ||
1035 | /* 6) Wait Message or State */ | |
1036 | while (1) { | |
1037 | if (policy->plug_valid == 0) { | |
1038 | ret = PE_SNK_Select_Capability; | |
1039 | break; | |
1040 | } | |
1041 | ms = usbpd_check_time1(pd_data); | |
1042 | if (pd_data->phy_ops.get_status(pd_data, MSG_GET_SNK_CAP)) { | |
1043 | ret = PE_SNK_Send_Soft_Reset; | |
1044 | break; | |
1045 | } | |
1046 | ||
1047 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
1048 | ret = PE_SNK_Transition_Sink; | |
1049 | break; | |
1050 | } | |
1051 | ||
1052 | if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) { | |
1053 | ret = PE_SNK_Ready; | |
1054 | break; | |
1055 | } | |
1056 | ||
1057 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT | MSG_WAIT)) { | |
1058 | /* 1st Power Negotiation Check */ | |
1059 | if (pd_noti.sink_status.selected_pdo_num == 0) | |
1060 | ret = PE_SNK_Wait_for_Capabilities; | |
1061 | else | |
1062 | ret = PE_SNK_Ready; | |
1063 | ||
1064 | break; | |
1065 | } | |
5073353a | 1066 | |
40798a41 JB |
1067 | /* TimeOver Check */ |
1068 | if (ms >= tSenderResponse) { | |
1069 | ret = PE_SNK_Hard_Reset; | |
1070 | break; | |
1071 | } | |
5073353a | 1072 | } |
40798a41 JB |
1073 | |
1074 | return ret; | |
5073353a JB |
1075 | } |
1076 | ||
40798a41 JB |
1077 | uint32_t RX_PS_READY_Message_ID; |
1078 | ||
5073353a JB |
1079 | policy_state usbpd_policy_snk_transition_sink(struct policy_data *policy) |
1080 | { | |
1081 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
1082 | int ret = PE_SNK_Transition_Sink; |
1083 | int ms = 0; | |
1084 | ||
1085 | /********************************************** | |
1086 | Actions on entry: | |
1087 | Initialize and run PSTransitionTimer | |
1088 | **********************************************/ | |
5073353a | 1089 | |
40798a41 | 1090 | /* 1) PD State Inform to AP */ |
5073353a JB |
1091 | dev_info(pd_data->dev, "%s\n", __func__); |
1092 | ||
40798a41 | 1093 | /* 2) Policy Engine State Setting */ |
5073353a | 1094 | policy->state = PE_SNK_Transition_Sink; |
40798a41 JB |
1095 | |
1096 | /* 3) Start Timer */ | |
1097 | usbpd_timer1_start(pd_data); | |
1098 | ||
1099 | /* 4) Wait Message or State */ | |
1100 | while (1) { | |
1101 | if (policy->plug_valid == 0) { | |
1102 | ret = PE_SNK_Transition_Sink; | |
1103 | break; | |
1104 | } | |
1105 | ms = usbpd_check_time1(pd_data); | |
1106 | /* PD Certification(Ellisys) : TD.PD.SNK.E10 GetSinkCap in place of PS_RDY */ | |
1107 | if (pd_data->phy_ops.get_status(pd_data, MSG_GET_SNK_CAP)) { | |
1108 | ret = PE_SNK_Hard_Reset; | |
1109 | break; | |
1110 | } | |
1111 | if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) { | |
1112 | /* Device Information */ | |
1113 | dev_info(pd_data->dev, "got PS_READY.\n"); | |
1114 | ||
1115 | #if defined(CONFIG_IFCONN_NOTIFIER) | |
1116 | pd_noti.sink_status.current_pdo_num = pd_noti.sink_status.selected_pdo_num; | |
5073353a | 1117 | #endif |
0ef320fa JB |
1118 | /* 2) Notify Plug Attach */ |
1119 | usbpd_manager_plug_attach(pd_data->dev); | |
1120 | ||
40798a41 JB |
1121 | ret = PE_SNK_Ready; |
1122 | break; | |
1123 | } | |
5073353a | 1124 | |
40798a41 JB |
1125 | /* TimeOver Check */ |
1126 | if (ms >= tPSTransition) { | |
1127 | ret = PE_SNK_Hard_Reset; | |
1128 | break; | |
1129 | } | |
1130 | } | |
5073353a | 1131 | |
40798a41 | 1132 | return ret; |
5073353a JB |
1133 | } |
1134 | ||
1135 | policy_state usbpd_policy_snk_ready(struct policy_data *policy) | |
1136 | { | |
1137 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1138 | int data_role = 0; | |
1139 | ||
40798a41 JB |
1140 | /********************************************** |
1141 | Actions on entry: | |
1142 | Initialize and run SinkActivityTimer2 | |
1143 | Initialize and run SinkRequestTimer3 (on receiving Wait) | |
1144 | Initialize and run DiscoverIdentityTimer5 | |
1145 | **********************************************/ | |
1146 | ||
1147 | /* 1) PD State Inform to AP */ | |
5073353a JB |
1148 | dev_info(pd_data->dev, "%s\n", __func__); |
1149 | ||
0ef320fa JB |
1150 | if (pd_data->pd_support == 0) { |
1151 | pd_data->pd_support = 1; | |
1152 | pd_data->phy_ops.set_pwr_opmode(pd_data, TYPEC_PWR_MODE_PD); | |
1153 | } | |
5073353a | 1154 | |
40798a41 | 1155 | /* 3) Message Check */ |
5073353a | 1156 | CHECK_MSG(pd_data, MSG_GET_SNK_CAP, PE_SNK_Give_Sink_Cap); |
5073353a JB |
1157 | CHECK_MSG(pd_data, MSG_PR_SWAP, PE_PRS_SNK_SRC_Evaluate_Swap); |
1158 | CHECK_MSG(pd_data, MSG_DR_SWAP, PE_DRS_Evaluate_Port); | |
1159 | CHECK_MSG(pd_data, MSG_VCONN_SWAP, PE_VCS_Evaluate_Swap); | |
40798a41 | 1160 | CHECK_MSG(pd_data, MSG_GET_SRC_CAP, PE_DR_SNK_Give_Source_Cap); |
99e9c3ca | 1161 | CHECK_MSG(pd_data, MSG_BIST, PE_BIST_Receive_Mode); |
9b736c3b | 1162 | CHECK_MSG(pd_data, MSG_SRC_CAP, PE_SNK_Evaluate_Capability); |
40798a41 JB |
1163 | |
1164 | #if 0 | |
5073353a JB |
1165 | CHECK_MSG(pd_data, VDM_DISCOVER_IDENTITY, PE_UFP_VDM_Get_Identity); |
1166 | CHECK_MSG(pd_data, VDM_DISCOVER_SVID, PE_UFP_VDM_Get_SVIDs); | |
1167 | CHECK_MSG(pd_data, VDM_DISCOVER_MODE, PE_UFP_VDM_Get_Modes); | |
1168 | CHECK_MSG(pd_data, VDM_ENTER_MODE, PE_UFP_VDM_Evaluate_Mode_Entry); | |
1169 | CHECK_MSG(pd_data, VDM_ATTENTION, PE_DFP_VDM_Attention_Request); | |
1170 | CHECK_MSG(pd_data, VDM_DP_STATUS_UPDATE, PE_UFP_VDM_Evaluate_Status); | |
1171 | CHECK_MSG(pd_data, VDM_DP_CONFIGURE, PE_UFP_VDM_Evaluate_Configure); | |
1172 | CHECK_MSG(pd_data, UVDM_MSG, PE_DFP_UVDM_Receive_Message); | |
40798a41 | 1173 | #endif |
5073353a | 1174 | |
40798a41 | 1175 | /* 5) Command Check from AP */ |
5073353a JB |
1176 | CHECK_CMD(pd_data, MANAGER_REQ_NEW_POWER_SRC, PE_SNK_Select_Capability); |
1177 | CHECK_CMD(pd_data, MANAGER_REQ_PR_SWAP, PE_PRS_SNK_SRC_Send_Swap); | |
1178 | CHECK_CMD(pd_data, MANAGER_REQ_DR_SWAP, PE_DRS_Evaluate_Send_Port); | |
1179 | CHECK_CMD(pd_data, MANAGER_REQ_VCONN_SWAP, PE_VCS_Send_Swap); | |
1180 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_IDENTITY, PE_DFP_VDM_Identity_Request); | |
1181 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_SVID, PE_DFP_VDM_SVIDs_Request); | |
1182 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DISCOVER_MODE, PE_DFP_VDM_Modes_Request); | |
1183 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_ATTENTION, PE_UFP_VDM_Attention_Request); | |
1184 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_ENTER_MODE, PE_DFP_VDM_Mode_Entry_Request); | |
1185 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_STATUS_UPDATE, PE_DFP_VDM_Status_Update); | |
1186 | CHECK_CMD(pd_data, MANAGER_REQ_VDM_DisplayPort_Configure, PE_DFP_VDM_DisplayPort_Configure); | |
40798a41 | 1187 | CHECK_CMD(pd_data, MANAGER_REQ_UVDM_SEND_MESSAGE, PE_DFP_UVDM_Send_Message); |
5073353a | 1188 | |
40798a41 | 1189 | /* 6) Data Role Check */ |
5073353a JB |
1190 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
1191 | ||
40798a41 | 1192 | #if 0 |
5073353a JB |
1193 | if (data_role == USBPD_DFP) |
1194 | usbpd_manager_vdm_request_enabled(pd_data); | |
40798a41 | 1195 | #endif |
5073353a JB |
1196 | |
1197 | return PE_SNK_Ready; | |
1198 | } | |
1199 | ||
40798a41 JB |
1200 | policy_state usbpd_policy_snk_hard_reset(struct policy_data *policy) |
1201 | { | |
1202 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1203 | ||
1204 | /********************************************** | |
1205 | Actions on entry: | |
1206 | Generate Hard Reset signalling. | |
1207 | Increment HardResetCounter. | |
1208 | **********************************************/ | |
1209 | ||
1210 | /* 1) PD State Inform to AP */ | |
1211 | dev_info(pd_data->dev, "%s\n", __func__); | |
1212 | ||
1213 | pd_data->phy_ops.hard_reset(pd_data); | |
1214 | pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_OFF); | |
1215 | /* increase hard reset counter */ | |
1216 | pd_data->counter.hard_reset_counter++; | |
1217 | ||
1218 | return PE_SNK_Transition_to_default; | |
1219 | } | |
1220 | ||
1221 | policy_state usbpd_policy_snk_transition_to_default(struct policy_data *policy) | |
1222 | { | |
1223 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1224 | int ret = PE_SNK_Startup; | |
1225 | int ms = 0; | |
1226 | ||
1227 | /********************************************** | |
1228 | Hard reset signalling received | |
1229 | ||
1230 | Actions on entry: | |
1231 | Request Device Policy Manager to request power sink transition to default | |
1232 | Reset local HW | |
1233 | If Type-C set Port Data Role to UFP and turn off VCONN | |
1234 | **********************************************/ | |
1235 | ||
1236 | /* 1) PD State Inform to AP */ | |
1237 | dev_info(pd_data->dev, "%s\n", __func__); | |
1238 | ||
1239 | /* 2) Driver Reset */ | |
1240 | pd_data->phy_ops.driver_reset(pd_data); | |
1241 | ||
1242 | /* 3) Vconn Off */ | |
1243 | usbpd_manager_turn_off_vconn(pd_data); | |
1244 | ||
1245 | /* 4) Wait 200ms */ | |
1246 | usbpd_timer1_start(pd_data); | |
1247 | while (1) { | |
1248 | if (policy->plug_valid == 0) { | |
1249 | ret = PE_SNK_Transition_to_default; | |
1250 | break; | |
1251 | } | |
1252 | ms = usbpd_check_time1(pd_data); | |
1253 | if (ms >= 200) | |
1254 | break; | |
1255 | } | |
1256 | ||
1257 | return ret; | |
1258 | } | |
1259 | ||
1260 | policy_state usbpd_policy_snk_give_sink_cap(struct policy_data *policy) | |
1261 | { | |
1262 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1263 | int ret = PE_SNK_Give_Sink_Cap; | |
1264 | int data_role = 0; | |
1265 | int ms = 0; | |
1266 | /********************************************** | |
1267 | Get Sink Cap Message received | |
1268 | ||
1269 | Actions on entry: | |
1270 | Get present sink capabilities from Device Policy Manager | |
1271 | Send Capabilities message (based on Device Policy Manager response) | |
1272 | **********************************************/ | |
1273 | ||
1274 | /* 1) PD State Inform to AP */ | |
1275 | dev_info(pd_data->dev, "%s\n", __func__); | |
1276 | ||
1277 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
1278 | ||
1279 | /* 2) TODO JETSEO ????*/ | |
1280 | #if defined(CONFIG_IFCONN_NOTIFIER) | |
1281 | pd_noti.sink_status.selected_pdo_num = 0; | |
1282 | #endif | |
1283 | ||
1284 | /* 3) Sink Cap Message Setting */ | |
1285 | policy->tx_msg_header.word = pd_data->sink_msg_header.word; | |
1286 | policy->tx_msg_header.port_data_role = data_role; | |
1287 | policy->tx_data_obj[0].object = pd_data->sink_data_obj[0].object; | |
99e9c3ca | 1288 | #if 0 |
40798a41 | 1289 | policy->tx_data_obj[1].object = pd_data->sink_data_obj[1].object; |
99e9c3ca | 1290 | #endif |
40798a41 JB |
1291 | policy->sink_cap_received = 1; |
1292 | ||
1293 | /* 4) Send Message */ | |
1294 | usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj); | |
1295 | ||
1296 | /* 5) Start Timer */ | |
1297 | usbpd_timer1_start(pd_data); | |
1298 | ||
1299 | /* 6) Wait Message or State */ | |
1300 | while (1) { | |
1301 | if (policy->plug_valid == 0) { | |
1302 | ret = PE_SNK_Give_Sink_Cap; | |
1303 | break; | |
1304 | } | |
1305 | ms = usbpd_check_time1(pd_data); | |
1306 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
1307 | dev_info(pd_data->dev, "got snk_give_sink_cap MSG_GOODCRC.\n"); | |
1308 | ret = PE_SNK_Ready; | |
1309 | break; | |
1310 | } | |
1311 | ||
1312 | /* TimeOver Check */ | |
1313 | if (ms >= 5) { | |
1314 | dev_info(pd_data->dev, "got snk_give_sink_cap Timer1_overflag.\n"); | |
1315 | ret = PE_SNK_Send_Soft_Reset; | |
1316 | break; | |
1317 | } | |
1318 | } | |
1319 | ||
1320 | return ret; | |
1321 | } | |
1322 | ||
1323 | policy_state usbpd_policy_snk_get_source_cap(struct policy_data *policy) | |
5073353a JB |
1324 | { |
1325 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
1326 | int ret = PE_SNK_Get_Source_Cap; |
1327 | int data_role = 0; | |
1328 | int ms = 0; | |
1329 | ||
1330 | /********************************************** | |
1331 | Actions on entry: | |
1332 | Send Get_Source_Cap message | |
1333 | **********************************************/ | |
5073353a | 1334 | |
40798a41 | 1335 | /* 1) PD State Inform to AP */ |
5073353a JB |
1336 | dev_info(pd_data->dev, "%s\n", __func__); |
1337 | ||
40798a41 | 1338 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
5073353a | 1339 | |
40798a41 JB |
1340 | /* 2) Send Message*/ |
1341 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1342 | USBPD_Get_Source_Cap, data_role, USBPD_SINK); | |
1343 | ||
1344 | /* 3) Start Timer */ | |
1345 | usbpd_timer1_start(pd_data); | |
1346 | ||
1347 | /* 4) Wait Message or State */ | |
1348 | while (1) { | |
1349 | if (policy->plug_valid == 0) { | |
1350 | ret = PE_SNK_Get_Source_Cap; | |
1351 | break; | |
1352 | } | |
1353 | ms = usbpd_check_time1(pd_data); | |
1354 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
1355 | ret = PE_SNK_Ready; | |
1356 | break; | |
1357 | } | |
1358 | ||
1359 | /* TimeOver Check */ | |
1360 | if (ms >= 5) { | |
1361 | ret = PE_SNK_Get_Source_Cap; | |
1362 | break; | |
1363 | } | |
1364 | } | |
1365 | ||
1366 | return ret; | |
5073353a JB |
1367 | } |
1368 | ||
40798a41 | 1369 | policy_state usbpd_policy_snk_send_soft_reset(struct policy_data *policy) |
5073353a JB |
1370 | { |
1371 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
1372 | int ret = PE_SNK_Send_Soft_Reset; |
1373 | int data_role = 0; | |
1374 | int ms = 0; | |
1375 | /********************************************** | |
1376 | Actions on entry: | |
1377 | Reset Protocol Layer | |
1378 | Send Soft Reset message | |
1379 | Initialize and run SenderResponseTimer | |
1380 | **********************************************/ | |
1381 | ||
1382 | /* 1) PD State Inform for AP */ | |
5073353a JB |
1383 | dev_info(pd_data->dev, "%s\n", __func__); |
1384 | ||
40798a41 JB |
1385 | /* 2) USB PD Protocol Initialization */ |
1386 | usbpd_init_protocol(pd_data); | |
5073353a | 1387 | |
40798a41 JB |
1388 | /* 3) Read Data Role */ |
1389 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
1390 | ||
1391 | /* 4) Self SoftReset */ | |
1392 | pd_data->phy_ops.soft_reset(pd_data); | |
1393 | ||
1394 | /* 5) Send Message */ | |
1395 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Soft_Reset, | |
1396 | data_role, USBPD_SINK); | |
1397 | ||
1398 | /* 6) Start Timer */ | |
1399 | usbpd_timer1_start(pd_data); | |
1400 | ||
1401 | /* 7) Wait Message or State */ | |
1402 | while (1) { | |
1403 | if (policy->plug_valid == 0) { | |
1404 | ret = PE_SNK_Send_Soft_Reset; | |
1405 | break; | |
1406 | } | |
1407 | ms = usbpd_check_time1(pd_data); | |
1408 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
1409 | ret = PE_SNK_Wait_for_Capabilities; | |
1410 | break; | |
1411 | } | |
5073353a | 1412 | |
40798a41 JB |
1413 | /* TimeOver Check */ |
1414 | if (ms >= tSenderResponse) { | |
1415 | ret = PE_SNK_Hard_Reset; | |
1416 | break; | |
1417 | } | |
1418 | } | |
5073353a | 1419 | |
40798a41 | 1420 | return ret; |
5073353a JB |
1421 | } |
1422 | ||
40798a41 | 1423 | policy_state usbpd_policy_snk_soft_reset(struct policy_data *policy) |
5073353a JB |
1424 | { |
1425 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
1426 | int data_role = 0; |
1427 | int ret = PE_SNK_Soft_Reset; | |
1428 | int ms = 0; | |
1429 | ||
1430 | /********************************************** | |
1431 | Soft Reset message received | |
1432 | ||
1433 | Actions on entry: | |
1434 | Reset Protocol Layer | |
1435 | Send Accept message | |
1436 | **********************************************/ | |
5073353a | 1437 | |
40798a41 | 1438 | /* 1) PD State Inform for AP */ |
5073353a JB |
1439 | dev_info(pd_data->dev, "%s\n", __func__); |
1440 | ||
40798a41 JB |
1441 | /* 2) USB PD Protocol Initialization */ |
1442 | usbpd_init_protocol(pd_data); | |
5073353a | 1443 | |
40798a41 JB |
1444 | /* 3) Read Data Role */ |
1445 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
5073353a | 1446 | |
40798a41 JB |
1447 | /* 4) Send Message */ |
1448 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, | |
1449 | data_role, USBPD_SINK); | |
5073353a | 1450 | |
40798a41 JB |
1451 | /* 5) Start Timer */ |
1452 | usbpd_timer1_start(pd_data); | |
5073353a | 1453 | |
40798a41 JB |
1454 | /* 6) Wait Message or State */ |
1455 | while (1) { | |
1456 | if (policy->plug_valid == 0) { | |
1457 | ret = PE_SNK_Soft_Reset; | |
1458 | break; | |
1459 | } | |
1460 | ms = usbpd_check_time1(pd_data); | |
1461 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
1462 | ret = PE_SNK_Wait_for_Capabilities; | |
1463 | break; | |
1464 | } | |
5073353a | 1465 | |
40798a41 JB |
1466 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { |
1467 | ret = PE_SNK_Hard_Reset; | |
1468 | break; | |
1469 | } | |
5073353a | 1470 | |
40798a41 JB |
1471 | if (ms >= 5) { |
1472 | ret = PE_SNK_Ready; | |
1473 | break; | |
1474 | } | |
1475 | } | |
5073353a | 1476 | |
40798a41 | 1477 | return ret; |
5073353a JB |
1478 | } |
1479 | ||
1480 | policy_state usbpd_policy_drs_evaluate_port(struct policy_data *policy) | |
1481 | { | |
1482 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1483 | int data_role = 0; | |
1484 | int power_role = 0; | |
1485 | ||
40798a41 JB |
1486 | /********************************************** |
1487 | **********************************************/ | |
1488 | ||
1489 | /* 1) PD State Inform for AP */ | |
5073353a JB |
1490 | dev_info(pd_data->dev, "%s\n", __func__); |
1491 | ||
1492 | if (policy->modal_operation) { | |
1493 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1494 | ||
1495 | if (power_role == USBPD_SOURCE) | |
1496 | return PE_SRC_Hard_Reset; | |
1497 | else | |
1498 | return PE_SNK_Hard_Reset; | |
1499 | } | |
1500 | ||
1501 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
1502 | ||
1503 | if (data_role == USBPD_DFP) | |
1504 | return PE_DRS_DFP_UFP_Evaluate_DR_Swap; | |
1505 | else | |
1506 | return PE_DRS_UFP_DFP_Evaluate_DR_Swap; | |
1507 | } | |
1508 | ||
1509 | policy_state usbpd_policy_drs_evaluate_send_port(struct policy_data *policy) | |
1510 | { | |
1511 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1512 | int data_role = 0; | |
1513 | int power_role = 0; | |
1514 | ||
40798a41 JB |
1515 | /********************************************** |
1516 | **********************************************/ | |
1517 | ||
1518 | /* 1) PD State Inform for AP */ | |
5073353a JB |
1519 | dev_info(pd_data->dev, "%s\n", __func__); |
1520 | ||
1521 | if (policy->modal_operation) { | |
1522 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1523 | ||
1524 | if (power_role == USBPD_SOURCE) | |
1525 | return PE_SRC_Hard_Reset; | |
1526 | else | |
1527 | return PE_SNK_Hard_Reset; | |
1528 | } | |
1529 | ||
1530 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
1531 | ||
1532 | if (data_role == USBPD_DFP) | |
1533 | return PE_DRS_DFP_UFP_Send_DR_Swap; | |
1534 | else | |
1535 | return PE_DRS_UFP_DFP_Send_DR_Swap; | |
1536 | } | |
1537 | ||
1538 | policy_state usbpd_policy_drs_dfp_ufp_evaluate_dr_swap(struct policy_data *policy) | |
1539 | { | |
1540 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1541 | bool drs_ok; | |
1542 | ||
40798a41 JB |
1543 | /********************************************** |
1544 | DR_Swap message received & not in Modal Operation | |
1545 | ||
1546 | Actions on entry: | |
1547 | Get evaluation of Data Role Swap | |
1548 | request from Device Policy Manager | |
1549 | **********************************************/ | |
1550 | ||
1551 | /* 1) PD State Inform for AP */ | |
5073353a JB |
1552 | dev_info(pd_data->dev, "%s\n", __func__); |
1553 | ||
1554 | drs_ok = usbpd_manager_data_role_swap(pd_data); | |
1555 | ||
1556 | if (drs_ok) | |
1557 | return PE_DRS_DFP_UFP_Accept_DR_Swap; | |
1558 | else | |
1559 | return PE_DRS_DFP_UFP_Reject_DR_Swap; | |
1560 | } | |
1561 | ||
1562 | policy_state usbpd_policy_drs_dfp_ufp_accept_dr_swap(struct policy_data *policy) | |
1563 | { | |
1564 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1565 | int power_role = 0; | |
1566 | ||
40798a41 JB |
1567 | /********************************************** |
1568 | Actions on entry: | |
1569 | Send Accept message | |
1570 | **********************************************/ | |
1571 | ||
5073353a JB |
1572 | dev_info(pd_data->dev, "%s\n", __func__); |
1573 | ||
1574 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1575 | ||
99e9c3ca JB |
1576 | mutex_lock(&pd_data->accept_mutex); |
1577 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1578 | USBPD_Accept, USBPD_DFP, power_role); | |
99e9c3ca JB |
1579 | pd_data->phy_ops.set_data_role(pd_data, USBPD_UFP); |
1580 | mutex_unlock(&pd_data->accept_mutex); | |
5073353a | 1581 | |
99e9c3ca | 1582 | return PE_DRS_DFP_UFP_Change_to_UFP; |
5073353a JB |
1583 | } |
1584 | ||
1585 | policy_state usbpd_policy_drs_dfp_ufp_change_to_ufp(struct policy_data *policy) | |
1586 | { | |
1587 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1588 | int power_role = 0; | |
1589 | ||
40798a41 JB |
1590 | /********************************************** |
1591 | Actions on entry: | |
1592 | Request Device Policy Manager to | |
1593 | change port to UFP | |
1594 | **********************************************/ | |
1595 | ||
5073353a JB |
1596 | dev_info(pd_data->dev, "%s\n", __func__); |
1597 | ||
5073353a JB |
1598 | pd_data->phy_ops.get_power_role(pd_data, &power_role); |
1599 | ||
1600 | if (power_role == USBPD_SOURCE) | |
1601 | return PE_SRC_Ready; | |
1602 | else | |
1603 | return PE_SNK_Ready; | |
1604 | } | |
1605 | ||
1606 | policy_state usbpd_policy_drs_dfp_ufp_send_dr_swap(struct policy_data *policy) | |
1607 | { | |
1608 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1609 | int power_role = 0; | |
40798a41 JB |
1610 | int ret = 0; |
1611 | int ms = 0; | |
1612 | /********************************************** | |
1613 | Actions on entry: | |
1614 | Send Swap DR message | |
1615 | Initialize and run SenderResponseTimer | |
1616 | **********************************************/ | |
5073353a JB |
1617 | |
1618 | dev_info(pd_data->dev, "%s\n", __func__); | |
1619 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1620 | ||
1621 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1622 | USBPD_DR_Swap, USBPD_DFP, power_role)) { | |
40798a41 JB |
1623 | usbpd_timer1_start(pd_data); |
1624 | while (1) { | |
1625 | if (policy->plug_valid == 0) { | |
1626 | ret = PE_DRS_DFP_UFP_Send_DR_Swap; | |
1627 | break; | |
1628 | } | |
1629 | ms = usbpd_check_time1(pd_data); | |
1630 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
1631 | dev_info(pd_data->dev, "%s, got Accept\n", __func__); | |
1632 | ret = PE_DRS_DFP_UFP_Change_to_UFP; | |
0ef320fa | 1633 | pd_data->phy_ops.set_data_role(pd_data, USBPD_UFP); |
40798a41 JB |
1634 | break; |
1635 | } | |
1636 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) { | |
1637 | dev_info(pd_data->dev, "%s, got Reject\n", __func__); | |
1638 | break; | |
1639 | } | |
1640 | if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) { | |
1641 | dev_info(pd_data->dev, "%s, got Wait\n", __func__); | |
1642 | break; | |
1643 | } | |
1644 | if (ms >= tSenderResponse) | |
1645 | break; | |
1646 | } | |
1647 | if (ret > 0) | |
1648 | return ret; | |
5073353a JB |
1649 | } |
1650 | ||
1651 | if (power_role == USBPD_SOURCE) | |
1652 | return PE_SRC_Ready; | |
1653 | else | |
1654 | return PE_SNK_Ready; | |
1655 | } | |
1656 | ||
1657 | policy_state usbpd_policy_drs_dfp_ufp_reject_dr_swap(struct policy_data *policy) | |
1658 | { | |
1659 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1660 | int power_role = 0; | |
1661 | ||
40798a41 JB |
1662 | /********************************************** |
1663 | Actions on entry: | |
1664 | Send Reject or Wait message as appropriate | |
1665 | **********************************************/ | |
1666 | ||
5073353a JB |
1667 | dev_info(pd_data->dev, "%s\n", __func__); |
1668 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1669 | ||
1670 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1671 | USBPD_Reject, USBPD_DFP, power_role)) { | |
1672 | if (power_role == USBPD_SOURCE) | |
1673 | return PE_SRC_Ready; | |
1674 | else | |
1675 | return PE_SNK_Ready; | |
1676 | } | |
1677 | ||
1678 | return PE_DRS_DFP_UFP_Reject_DR_Swap; | |
1679 | } | |
1680 | ||
1681 | policy_state usbpd_policy_drs_ufp_dfp_evaluate_dr_swap(struct policy_data *policy) | |
1682 | { | |
1683 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1684 | bool drs_ok; | |
1685 | ||
40798a41 JB |
1686 | /********************************************** |
1687 | Actions on entry: | |
1688 | Get evaluation of Data Role Swap | |
1689 | request from Device Policy Manager | |
1690 | **********************************************/ | |
1691 | ||
5073353a JB |
1692 | dev_info(pd_data->dev, "%s\n", __func__); |
1693 | ||
1694 | drs_ok = usbpd_manager_data_role_swap(pd_data); | |
1695 | ||
1696 | if (drs_ok) | |
1697 | return PE_DRS_UFP_DFP_Accept_DR_Swap; | |
1698 | else | |
1699 | return PE_DRS_UFP_DFP_Reject_DR_Swap; | |
1700 | } | |
1701 | ||
1702 | policy_state usbpd_policy_drs_ufp_dfp_accept_dr_swap(struct policy_data *policy) | |
1703 | { | |
1704 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1705 | int power_role = 0; | |
1706 | ||
40798a41 JB |
1707 | /********************************************** |
1708 | Actions on entry: | |
1709 | Send Accept message | |
1710 | **********************************************/ | |
1711 | ||
5073353a JB |
1712 | dev_info(pd_data->dev, "%s\n", __func__); |
1713 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1714 | ||
99e9c3ca JB |
1715 | mutex_lock(&pd_data->accept_mutex); |
1716 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1717 | USBPD_Accept, USBPD_UFP, power_role); | |
99e9c3ca JB |
1718 | mutex_unlock(&pd_data->accept_mutex); |
1719 | return PE_DRS_UFP_DFP_Change_to_DFP; | |
5073353a JB |
1720 | } |
1721 | ||
1722 | policy_state usbpd_policy_drs_ufp_dfp_change_to_dfp(struct policy_data *policy) | |
1723 | { | |
1724 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1725 | int power_role = 0; | |
1726 | ||
40798a41 JB |
1727 | /********************************************** |
1728 | Actions on entry: | |
1729 | Request Device Policy Manager to change port to DFP | |
1730 | **********************************************/ | |
1731 | ||
5073353a JB |
1732 | dev_info(pd_data->dev, "%s\n", __func__); |
1733 | ||
0ef320fa | 1734 | pd_data->phy_ops.set_data_role(pd_data, USBPD_DFP); |
5073353a JB |
1735 | pd_data->phy_ops.get_power_role(pd_data, &power_role); |
1736 | ||
1737 | if (power_role == USBPD_SOURCE) | |
1738 | return PE_SRC_Ready; | |
1739 | else | |
1740 | return PE_SNK_Ready; | |
1741 | } | |
1742 | ||
1743 | policy_state usbpd_policy_drs_ufp_dfp_send_dr_swap(struct policy_data *policy) | |
1744 | { | |
1745 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1746 | int power_role = 0; | |
40798a41 JB |
1747 | int ret = 0; |
1748 | int ms = 0; | |
1749 | ||
1750 | /********************************************** | |
1751 | Actions on entry: | |
1752 | Send Swap DR message | |
1753 | Initialize and run SenderResponseTimer | |
1754 | **********************************************/ | |
5073353a JB |
1755 | |
1756 | dev_info(pd_data->dev, "%s\n", __func__); | |
1757 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
1758 | ||
1759 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1760 | USBPD_DR_Swap, USBPD_UFP, power_role)) { | |
40798a41 JB |
1761 | usbpd_timer1_start(pd_data); |
1762 | while (1) { | |
1763 | if (policy->plug_valid == 0) { | |
1764 | ret = PE_DRS_UFP_DFP_Send_DR_Swap; | |
1765 | break; | |
1766 | } | |
1767 | ms = usbpd_check_time1(pd_data); | |
1768 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
1769 | dev_info(pd_data->dev, "%s, got Accept\n", __func__); | |
1770 | ret = PE_DRS_UFP_DFP_Change_to_DFP; | |
1771 | break; | |
1772 | } | |
1773 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) { | |
1774 | dev_info(pd_data->dev, "%s, got Reject\n", __func__); | |
1775 | break; | |
1776 | } | |
1777 | if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) { | |
1778 | dev_info(pd_data->dev, "%s, got Wait\n", __func__); | |
1779 | break; | |
1780 | } | |
1781 | if (ms > tSenderResponse) | |
1782 | break; | |
1783 | } | |
1784 | if (ret > 0) | |
1785 | return ret; | |
5073353a JB |
1786 | } |
1787 | ||
1788 | if (power_role == USBPD_SOURCE) | |
1789 | return PE_SRC_Ready; | |
1790 | else | |
1791 | return PE_SNK_Ready; | |
1792 | } | |
1793 | ||
1794 | policy_state usbpd_policy_drs_ufp_dfp_reject_dr_swap(struct policy_data *policy) | |
1795 | { | |
1796 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1797 | int power_role = 0; | |
40798a41 JB |
1798 | int data_role = 0; |
1799 | ||
1800 | /********************************************** | |
1801 | Actions on entry: | |
1802 | Send Reject or Wait message as appropriate | |
1803 | **********************************************/ | |
5073353a JB |
1804 | |
1805 | dev_info(pd_data->dev, "%s\n", __func__); | |
40798a41 JB |
1806 | |
1807 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
5073353a JB |
1808 | pd_data->phy_ops.get_power_role(pd_data, &power_role); |
1809 | ||
1810 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
40798a41 | 1811 | USBPD_Reject, data_role, USBPD_SINK)) { |
5073353a JB |
1812 | if (power_role == USBPD_SOURCE) |
1813 | return PE_SRC_Ready; | |
1814 | else | |
1815 | return PE_SNK_Ready; | |
1816 | } | |
1817 | ||
1818 | return PE_DRS_UFP_DFP_Reject_DR_Swap; | |
1819 | } | |
1820 | ||
1821 | policy_state usbpd_policy_prs_src_snk_reject_pr_swap(struct policy_data *policy) | |
1822 | { | |
1823 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 | 1824 | int data_role = 0; |
5073353a | 1825 | |
40798a41 JB |
1826 | /********************************************** |
1827 | Actions on entry: | |
1828 | Send Reject or Wait message as appropriate | |
1829 | **********************************************/ | |
1830 | ||
1831 | /* 1) PD State Inform for AP */ | |
5073353a JB |
1832 | dev_info(pd_data->dev, "%s\n", __func__); |
1833 | ||
40798a41 JB |
1834 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
1835 | ||
5073353a | 1836 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, |
40798a41 | 1837 | USBPD_Reject, data_role, USBPD_SOURCE)) |
5073353a JB |
1838 | return PE_SRC_Ready; |
1839 | ||
1840 | return PE_PRS_SRC_SNK_Reject_PR_Swap; | |
1841 | } | |
1842 | ||
1843 | policy_state usbpd_policy_prs_src_snk_evaluate_swap(struct policy_data *policy) | |
1844 | { | |
1845 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1846 | bool prs_ok; | |
1847 | ||
40798a41 JB |
1848 | /********************************************** |
1849 | Actions on entry: | |
1850 | Get evaluation of swap request from Device Policy Manager | |
1851 | **********************************************/ | |
1852 | ||
1853 | /* 1) PD State Inform for AP */ | |
5073353a JB |
1854 | dev_info(pd_data->dev, "%s\n", __func__); |
1855 | ||
40798a41 | 1856 | /* 2) DPM Check to support roleswap */ |
5073353a JB |
1857 | prs_ok = usbpd_manager_power_role_swap(pd_data); |
1858 | ||
40798a41 | 1859 | /* 3) Branch */ |
5073353a JB |
1860 | if (prs_ok) |
1861 | return PE_PRS_SRC_SNK_Accept_Swap; | |
1862 | else | |
1863 | return PE_PRS_SRC_SNK_Reject_PR_Swap; | |
1864 | } | |
1865 | ||
1866 | policy_state usbpd_policy_prs_src_snk_send_swap(struct policy_data *policy) | |
1867 | { | |
1868 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
1869 | int data_role = 0; |
1870 | int ret = PE_SRC_Ready; | |
1871 | int ms = 0; | |
5073353a | 1872 | |
40798a41 JB |
1873 | /********************************************** |
1874 | Actions on entry: | |
1875 | Send PR_Swap message | |
1876 | Initialize and run SenderResponseTimer | |
1877 | **********************************************/ | |
1878 | ||
1879 | /* 1) PD State Inform for AP */ | |
1880 | dev_info(pd_data->dev, "%s\n", __func__); | |
1881 | ||
1882 | /* 2) Read Data Role */ | |
1883 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
1884 | ||
1885 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1886 | USBPD_PR_Swap, data_role, USBPD_SOURCE); | |
1887 | ||
1888 | /* 3) Start Timer */ | |
1889 | usbpd_timer1_start(pd_data); | |
1890 | ||
1891 | while (1) { | |
1892 | if (policy->plug_valid == 0) { | |
1893 | ret = PE_PRS_SRC_SNK_Send_Swap; | |
1894 | break; | |
1895 | } | |
1896 | ms = usbpd_check_time1(pd_data); | |
1897 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
1898 | ret = PE_PRS_SRC_SNK_Transition_off; | |
1899 | break; | |
1900 | } | |
1901 | ||
1902 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) { | |
1903 | ret = PE_SRC_Ready; | |
1904 | break; | |
1905 | } | |
5073353a | 1906 | |
40798a41 JB |
1907 | if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) { |
1908 | ret = PE_SRC_Ready; | |
1909 | break; | |
1910 | } | |
1911 | ||
1912 | /* TimeOver Check */ | |
1913 | if (ms >= tSenderResponse + 5) { | |
1914 | ret = PE_SRC_Ready; | |
1915 | break; | |
1916 | } | |
5073353a | 1917 | |
5073353a | 1918 | } |
40798a41 | 1919 | |
0ef320fa | 1920 | return ret; |
5073353a JB |
1921 | } |
1922 | ||
1923 | policy_state usbpd_policy_prs_src_snk_accept_swap(struct policy_data *policy) | |
1924 | { | |
1925 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 | 1926 | int data_role = 0; |
5073353a | 1927 | |
40798a41 JB |
1928 | /********************************************** |
1929 | Actions on entry: | |
1930 | Send Accept message | |
1931 | **********************************************/ | |
1932 | ||
1933 | /* 1) PD State Inform for AP */ | |
1934 | dev_info(pd_data->dev, "%s\n", __func__); | |
1935 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
1936 | ||
1937 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
1938 | USBPD_Accept, data_role, USBPD_SOURCE); | |
1939 | ||
1940 | return PE_PRS_SRC_SNK_Transition_off; | |
5073353a | 1941 | |
5073353a JB |
1942 | } |
1943 | ||
1944 | policy_state usbpd_policy_prs_src_snk_transition_to_off(struct policy_data *policy) | |
1945 | { | |
1946 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
1947 | struct usbpd_manager_data *manager = &pd_data->manager; | |
40798a41 JB |
1948 | int ret = PE_PRS_SRC_SNK_Assert_Rd; |
1949 | int ms = 0; | |
1950 | ||
1951 | /********************************************** | |
1952 | Actions on entry: | |
1953 | Tell Device Policy Manager to turn off power supply | |
1954 | **********************************************/ | |
1955 | ||
1956 | /* 1) PD State Inform for AP */ | |
1957 | dev_info(pd_data->dev, "%s\n", __func__); | |
5073353a | 1958 | |
40798a41 JB |
1959 | /* 2) Delay */ |
1960 | usbpd_timer1_start(pd_data); | |
1961 | while (1) { | |
1962 | if (policy->plug_valid == 0) { | |
1963 | ret = PE_PRS_SRC_SNK_Transition_off; | |
1964 | break; | |
1965 | } | |
1966 | ms = usbpd_check_time1(pd_data); | |
1967 | if (ms >= tSrcTransition) | |
1968 | break; | |
1969 | } | |
1970 | ||
1971 | if (ret == PE_PRS_SRC_SNK_Transition_off) | |
1972 | return ret; | |
1973 | ||
1974 | pd_data->phy_ops.pr_swap(pd_data, USBPD_SOURCE_OFF); | |
1975 | ||
1976 | /* 3) VBUS off */ | |
5073353a JB |
1977 | pd_data->phy_ops.set_otg_control(pd_data, 0); |
1978 | ||
1979 | pr_info("%s, %d\n", __func__, manager->acc_type); | |
1980 | ||
40798a41 JB |
1981 | usbpd_timer1_start(pd_data); |
1982 | while (1) { | |
1983 | if (policy->plug_valid == 0) { | |
1984 | ret = PE_PRS_SRC_SNK_Transition_off; | |
1985 | break; | |
1986 | } | |
1987 | ms = usbpd_check_time1(pd_data); | |
1988 | if (ms >= 500) | |
1989 | break; | |
1990 | } | |
1991 | #if 0 | |
1992 | /* TODO: svid_0 == 0 confition check? | |
1993 | * based on 004 code 600ms no condition vs here 150ms w/ condition */ | |
5073353a JB |
1994 | /* skip delay when GEARVR is attached */ |
1995 | if (manager->acc_type != CCIC_DOCK_HMT || manager->SVID_0 == 0) | |
40798a41 JB |
1996 | msleep(600); |
1997 | #endif | |
5073353a | 1998 | |
40798a41 | 1999 | return ret; |
5073353a JB |
2000 | } |
2001 | ||
2002 | policy_state usbpd_policy_prs_src_snk_assert_rd(struct policy_data *policy) | |
2003 | { | |
2004 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2005 | ||
40798a41 JB |
2006 | /********************************************** |
2007 | Actions on entry: | |
2008 | Request DPM to assert Rd | |
2009 | **********************************************/ | |
2010 | ||
2011 | /* 1) PD State Inform for AP */ | |
2012 | dev_info(pd_data->dev, "%s\n", __func__); | |
2013 | ||
2014 | /* 2) Asserted Rd */ | |
5073353a JB |
2015 | pd_data->phy_ops.set_power_role(pd_data, USBPD_SINK); |
2016 | ||
2017 | return PE_PRS_SRC_SNK_Wait_Source_on; | |
2018 | } | |
2019 | ||
2020 | policy_state usbpd_policy_prs_src_snk_wait_source_on(struct policy_data *policy) | |
2021 | { | |
2022 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
2023 | int ret = 0; |
2024 | int data_role = 0; | |
2025 | int ms = 0; | |
2026 | /********************************************** | |
2027 | Actions on entry: | |
2028 | Send PS_RDY message | |
2029 | Initialize and run PSSourceOnTimer | |
2030 | **********************************************/ | |
2031 | ||
2032 | /* 1) PD State Inform for AP */ | |
5073353a JB |
2033 | dev_info(pd_data->dev, "%s\n", __func__); |
2034 | ||
40798a41 JB |
2035 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
2036 | ||
2037 | /* 2) Send Message */ | |
2038 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
2039 | USBPD_PS_RDY, data_role, USBPD_SINK); | |
2040 | usbpd_timer1_start(pd_data); | |
2041 | ||
2042 | while (1) { | |
2043 | if (policy->plug_valid == 0) { | |
2044 | ret = PE_PRS_SRC_SNK_Wait_Source_on; | |
2045 | break; | |
2046 | } | |
2047 | ms = usbpd_check_time1(pd_data); | |
2048 | if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) { | |
5073353a | 2049 | dev_info(pd_data->dev, "got PSRDY.\n"); |
40798a41 | 2050 | pd_data->counter.swap_hard_reset_counter = 0; |
0ef320fa | 2051 | pd_data->phy_ops.set_cc_control(pd_data, USBPD_CC_OFF); |
40798a41 JB |
2052 | /* Self SoftReset for Message ID Clear */ |
2053 | pd_data->phy_ops.soft_reset(pd_data); | |
0ef320fa JB |
2054 | msleep(20); |
2055 | pd_data->phy_ops.pr_swap(pd_data, USBPD_PR_DONE); | |
40798a41 JB |
2056 | ret = PE_SNK_Startup; |
2057 | break; | |
2058 | } | |
2059 | if (ms >= tPSSourceOn) { | |
2060 | ret = PE_SNK_Hard_Reset; | |
2061 | if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount) | |
2062 | ret = Error_Recovery; | |
2063 | break; | |
5073353a JB |
2064 | } |
2065 | } | |
5073353a | 2066 | |
40798a41 | 2067 | pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP); |
5073353a | 2068 | |
40798a41 | 2069 | return ret; |
5073353a JB |
2070 | } |
2071 | ||
2072 | policy_state usbpd_policy_prs_snk_src_reject_swap(struct policy_data *policy) | |
2073 | { | |
2074 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2075 | ||
40798a41 JB |
2076 | /********************************************** |
2077 | Actions on entry: | |
2078 | Send Reject or Wait message as appropriate | |
2079 | **********************************************/ | |
2080 | ||
5073353a JB |
2081 | dev_info(pd_data->dev, "%s\n", __func__); |
2082 | ||
2083 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
2084 | USBPD_Reject, USBPD_UFP, USBPD_SINK)) | |
2085 | return PE_SNK_Ready; | |
2086 | ||
2087 | return PE_PRS_SNK_SRC_Reject_Swap; | |
2088 | } | |
2089 | ||
2090 | policy_state usbpd_policy_prs_snk_src_evaluate_swap(struct policy_data *policy) | |
2091 | { | |
2092 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2093 | bool prs_ok; | |
40798a41 JB |
2094 | int ret = PE_PRS_SNK_SRC_Evaluate_Swap; |
2095 | ||
2096 | /********************************************** | |
2097 | Actions on entry: | |
2098 | Get evaluation of swap request from Device Policy Manager | |
2099 | **********************************************/ | |
2100 | ||
2101 | /* 1) PD State Inform to AP */ | |
5073353a JB |
2102 | dev_info(pd_data->dev, "%s\n", __func__); |
2103 | ||
40798a41 | 2104 | /* 2) Power Role Swap Check */ |
5073353a JB |
2105 | prs_ok = usbpd_manager_power_role_swap(pd_data); |
2106 | ||
2107 | if (prs_ok) | |
40798a41 | 2108 | ret = PE_PRS_SNK_SRC_Accept_Swap; |
5073353a | 2109 | else |
40798a41 JB |
2110 | ret = PE_PRS_SNK_SRC_Reject_Swap; |
2111 | ||
2112 | return ret; | |
5073353a JB |
2113 | } |
2114 | ||
2115 | policy_state usbpd_policy_prs_snk_src_send_swap(struct policy_data *policy) | |
2116 | { | |
2117 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
2118 | int data_role = 0; |
2119 | int ret = PE_SNK_Ready; | |
2120 | int ms = 0; | |
5073353a | 2121 | |
40798a41 JB |
2122 | /********************************************** |
2123 | Actions on entry: | |
2124 | Send PR_Swap message | |
2125 | Initialize and run SenderResponseTimer | |
2126 | **********************************************/ | |
2127 | ||
2128 | /* 1) PD State Inform to AP */ | |
5073353a JB |
2129 | dev_info(pd_data->dev, "%s\n", __func__); |
2130 | ||
40798a41 JB |
2131 | pd_data->phy_ops.get_data_role(pd_data, &data_role); |
2132 | ||
2133 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
2134 | USBPD_PR_Swap, data_role, USBPD_SINK); | |
2135 | ||
2136 | usbpd_timer1_start(pd_data); | |
2137 | ||
2138 | while (1) { | |
2139 | if (policy->plug_valid == 0) { | |
2140 | ret = PE_PRS_SNK_SRC_Send_Swap; | |
2141 | break; | |
2142 | } | |
2143 | ms = usbpd_check_time1(pd_data); | |
2144 | if (pd_data->phy_ops.get_status(pd_data, MSG_ACCEPT)) { | |
2145 | ret = PE_PRS_SNK_SRC_Transition_off; | |
0ef320fa | 2146 | pd_data->phy_ops.set_power_role(pd_data, USBPD_SINK); |
40798a41 JB |
2147 | break; |
2148 | } | |
2149 | ||
2150 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) { | |
2151 | ret = PE_SNK_Ready; | |
2152 | break; | |
2153 | } | |
2154 | ||
2155 | if (pd_data->phy_ops.get_status(pd_data, MSG_WAIT)) { | |
2156 | ret = PE_SNK_Ready; | |
2157 | break; | |
2158 | } | |
2159 | ||
2160 | /* TimeOver Check */ | |
2161 | if (ms >= tSenderResponse) { | |
2162 | ret = PE_SNK_Ready; | |
2163 | break; | |
2164 | } | |
5073353a | 2165 | |
5073353a | 2166 | } |
40798a41 JB |
2167 | |
2168 | return ret; | |
5073353a JB |
2169 | } |
2170 | ||
2171 | policy_state usbpd_policy_prs_snk_src_accept_swap(struct policy_data *policy) | |
2172 | { | |
2173 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 | 2174 | int data_role = 0; |
5073353a | 2175 | |
40798a41 JB |
2176 | /********************************************** |
2177 | Actions on entry: | |
2178 | Send Accept message | |
2179 | **********************************************/ | |
2180 | ||
2181 | /* 1) PD State Inform to AP */ | |
5073353a JB |
2182 | dev_info(pd_data->dev, "%s\n", __func__); |
2183 | ||
40798a41 JB |
2184 | /* Send Accept Message */ |
2185 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
0ef320fa | 2186 | |
40798a41 JB |
2187 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Accept, |
2188 | data_role, USBPD_SINK); | |
0ef320fa | 2189 | |
40798a41 | 2190 | pd_data->phy_ops.set_power_role(pd_data, USBPD_SINK); |
5073353a | 2191 | |
40798a41 | 2192 | return PE_PRS_SNK_SRC_Transition_off; |
5073353a JB |
2193 | } |
2194 | ||
2195 | policy_state usbpd_policy_prs_snk_src_transition_to_off(struct policy_data *policy) | |
2196 | { | |
2197 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
2198 | int ret = 0; |
2199 | int ms = 0; | |
2200 | /********************************************** | |
2201 | Actions on entry: | |
2202 | Initialize and run PSSourceOffTimer | |
2203 | Tell Device Policy Manager to turn off Power Sink. | |
2204 | **********************************************/ | |
2205 | ||
2206 | /* 1) PD State Inform to AP */ | |
5073353a JB |
2207 | dev_info(pd_data->dev, "%s\n", __func__); |
2208 | ||
40798a41 | 2209 | pd_data->phy_ops.pr_swap(pd_data, USBPD_SINK_OFF); |
5073353a | 2210 | |
40798a41 JB |
2211 | /* Start Timer 750ms */ |
2212 | usbpd_timer1_start(pd_data); | |
5073353a | 2213 | |
40798a41 JB |
2214 | while (1) { |
2215 | if (policy->plug_valid == 0) { | |
2216 | ret = PE_PRS_SNK_SRC_Transition_off; | |
0ef320fa | 2217 | pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP); |
40798a41 JB |
2218 | break; |
2219 | } | |
2220 | ms = usbpd_check_time1(pd_data); | |
2221 | if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) { | |
2222 | dev_info(pd_data->dev, "got PSRDY.\n"); | |
2223 | ret = PE_PRS_SNK_SRC_Assert_Rp; | |
2224 | break; | |
2225 | } | |
2226 | if (ms >= tPSSourceOff) { | |
2227 | ret = PE_SRC_Hard_Reset; | |
2228 | pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP); | |
2229 | if (pd_data->counter.hard_reset_counter > USBPD_nHardResetCount) | |
2230 | ret = Error_Recovery; | |
2231 | break; | |
2232 | } | |
2233 | } | |
5073353a | 2234 | |
40798a41 | 2235 | return ret; |
5073353a JB |
2236 | } |
2237 | ||
2238 | policy_state usbpd_policy_prs_snk_src_assert_rp(struct policy_data *policy) | |
2239 | { | |
2240 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2241 | ||
40798a41 JB |
2242 | /********************************************** |
2243 | Actions on entry: | |
2244 | Request DPM to assert Rp | |
2245 | **********************************************/ | |
2246 | ||
5073353a JB |
2247 | dev_info(pd_data->dev, "%s\n", __func__); |
2248 | ||
2249 | pd_data->phy_ops.set_power_role(pd_data, USBPD_SOURCE); | |
2250 | ||
2251 | return PE_PRS_SNK_SRC_Source_on; | |
2252 | } | |
2253 | ||
2254 | policy_state usbpd_policy_prs_snk_src_source_on(struct policy_data *policy) | |
2255 | { | |
2256 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
2257 | int data_role = 0; |
2258 | int ret = 0; | |
2259 | int ms = 0; | |
5073353a | 2260 | |
40798a41 JB |
2261 | /********************************************** |
2262 | Actions on entry: | |
2263 | Tell Device Policy Manager to turn on Source | |
2264 | Initialize and run SourceActivityTimer (see Section 8.3.3.6.1.2)1 | |
2265 | **********************************************/ | |
2266 | ||
2267 | /* 1) PD State Inform to AP */ | |
5073353a JB |
2268 | dev_info(pd_data->dev, "%s\n", __func__); |
2269 | ||
40798a41 JB |
2270 | /* 2) Read Data Role */ |
2271 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
2272 | ||
2273 | pd_data->phy_ops.pr_swap(pd_data, USBPD_SOURCE_ON); | |
2274 | ||
2275 | /* 3) VBUS on */ | |
5073353a JB |
2276 | pd_data->phy_ops.set_otg_control(pd_data, 1); |
2277 | ||
40798a41 JB |
2278 | /* 4) Dealy */ |
2279 | usbpd_timer1_start(pd_data); | |
2280 | while (1) { | |
2281 | if (policy->plug_valid == 0) { | |
2282 | ret = PE_PRS_SNK_SRC_Source_on; | |
2283 | break; | |
2284 | } | |
2285 | ms = usbpd_check_time1(pd_data); | |
2286 | if (ms >= 200) | |
2287 | break; | |
2288 | } | |
5073353a | 2289 | |
40798a41 JB |
2290 | if (ret == PE_PRS_SNK_SRC_Source_on) |
2291 | return ret; | |
2292 | ||
2293 | /* 5) send PS_RDY */ | |
5073353a | 2294 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, |
40798a41 | 2295 | USBPD_PS_RDY, data_role, USBPD_SOURCE)) { |
5073353a | 2296 | pd_data->phy_ops.set_power_role(pd_data, USBPD_DRP); |
40798a41 JB |
2297 | usbpd_timer1_start(pd_data); |
2298 | while (1) { | |
2299 | if (policy->plug_valid == 0) { | |
2300 | ret = PE_PRS_SNK_SRC_Source_on; | |
2301 | break; | |
2302 | } | |
2303 | ms = usbpd_check_time1(pd_data); | |
2304 | if (ms >= tSwapSourceStart) | |
2305 | break; | |
2306 | } | |
2307 | ||
2308 | if (ret == PE_PRS_SNK_SRC_Source_on) | |
2309 | return ret; | |
2310 | /* TODO: 4) check GoodCRC : may need to be added for certification */ | |
2311 | ||
2312 | /* Self SoftReset for Message ID Clear */ | |
2313 | pd_data->phy_ops.soft_reset(pd_data); | |
2314 | ||
0ef320fa JB |
2315 | pd_data->phy_ops.pr_swap(pd_data, USBPD_PR_DONE); |
2316 | ||
5073353a JB |
2317 | return PE_SRC_Startup; |
2318 | } | |
40798a41 | 2319 | |
5073353a JB |
2320 | return PE_PRS_SNK_SRC_Source_on; |
2321 | } | |
2322 | ||
2323 | policy_state usbpd_policy_vcs_evaluate_swap(struct policy_data *policy) | |
2324 | { | |
2325 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2326 | bool vcs_ok; | |
2327 | ||
40798a41 JB |
2328 | /********************************************** |
2329 | Actions on entry: | |
2330 | Get evaluation of VCONN swap | |
2331 | request from Device Policy Manager | |
2332 | **********************************************/ | |
2333 | ||
2334 | /* 1) PD State Inform to AP */ | |
5073353a | 2335 | dev_info(pd_data->dev, "%s\n", __func__); |
40798a41 JB |
2336 | |
2337 | /* 2) Request from DPM */ | |
5073353a JB |
2338 | vcs_ok = usbpd_manager_vconn_source_swap(pd_data); |
2339 | ||
2340 | if (vcs_ok) | |
2341 | return PE_VCS_Accept_Swap; | |
2342 | else | |
2343 | return PE_VCS_Reject_VCONN_Swap; | |
2344 | } | |
2345 | ||
2346 | policy_state usbpd_policy_vcs_accept_swap(struct policy_data *policy) | |
2347 | { | |
2348 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2349 | int vconn_source = 0; | |
2350 | int power_role = 0; | |
2351 | int data_role = 0; | |
2352 | ||
40798a41 JB |
2353 | /********************************************** |
2354 | Actions on entry: | |
2355 | Send Accept message | |
2356 | **********************************************/ | |
2357 | ||
5073353a JB |
2358 | pd_data->phy_ops.get_vconn_source(pd_data, &vconn_source); |
2359 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2360 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
2361 | ||
2362 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
2363 | USBPD_Accept, data_role, power_role)) { | |
2364 | if (vconn_source) | |
2365 | return PE_VCS_Wait_for_VCONN; | |
2366 | else | |
2367 | return PE_VCS_Turn_On_VCONN; | |
2368 | } | |
2369 | ||
2370 | return PE_VCS_Accept_Swap; | |
2371 | } | |
2372 | ||
2373 | policy_state usbpd_policy_vcs_send_swap(struct policy_data *policy) | |
2374 | { | |
2375 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2376 | int vconn_source = 0; | |
2377 | int power_role = 0; | |
40798a41 JB |
2378 | int ret = PE_VCS_Send_Swap; |
2379 | int ms = 0; | |
2380 | ||
2381 | /********************************************** | |
2382 | Actions on entry: | |
2383 | Send VCONN_Swap message | |
2384 | Initialize and run SenderResponseTimer | |
2385 | **********************************************/ | |
2386 | ||
5073353a | 2387 | |
40798a41 JB |
2388 | /* 1) PD State Inform for AP */ |
2389 | dev_info(pd_data->dev, "%s\n", __func__); | |
2390 | ||
2391 | /* 2) Get Vconn Source */ | |
5073353a | 2392 | pd_data->phy_ops.get_vconn_source(pd_data, &vconn_source); |
40798a41 JB |
2393 | |
2394 | /* 3) Get Power Role */ | |
5073353a JB |
2395 | pd_data->phy_ops.get_power_role(pd_data, &power_role); |
2396 | ||
40798a41 JB |
2397 | /* 4) Send Vconn Swap */ |
2398 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_VCONN_Swap, USBPD_DFP, power_role); | |
2399 | ||
2400 | /* 5) Start Timer */ | |
2401 | usbpd_timer1_start(pd_data); | |
2402 | ||
2403 | /* 6) Wait Message or State */ | |
2404 | while (1) { | |
2405 | if (policy->plug_valid == 0) { | |
2406 | ret = PE_VCS_Send_Swap; | |
2407 | break; | |
2408 | } | |
2409 | ms = usbpd_check_time1(pd_data); | |
2410 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
2411 | if (vconn_source) | |
2412 | ret = PE_VCS_Wait_for_VCONN; | |
2413 | else | |
2414 | ret = PE_VCS_Turn_On_VCONN; | |
2415 | break; | |
2416 | } | |
2417 | /* TimeOver Check */ | |
2418 | if (ms >= 5) { | |
2419 | if (power_role == USBPD_SINK) | |
2420 | ret = PE_SNK_Hard_Reset; | |
2421 | else | |
2422 | ret = PE_SRC_Hard_Reset; | |
2423 | break; | |
2424 | } | |
5073353a JB |
2425 | } |
2426 | ||
40798a41 | 2427 | return ret; |
5073353a JB |
2428 | } |
2429 | ||
2430 | policy_state usbpd_policy_vcs_wait_for_vconn(struct policy_data *policy) | |
2431 | { | |
2432 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
40798a41 JB |
2433 | int ret = PE_VCS_Wait_for_VCONN; |
2434 | int ms = 0; | |
2435 | /********************************************** | |
2436 | Actions on entry: | |
2437 | Start VCONNOnTimer | |
2438 | **********************************************/ | |
5073353a JB |
2439 | |
2440 | dev_info(pd_data->dev, "%s\n", __func__); | |
2441 | ||
40798a41 JB |
2442 | /* 5) Start Timer */ |
2443 | usbpd_timer1_start(pd_data); | |
5073353a | 2444 | |
40798a41 JB |
2445 | /* 6) Wait Message or State */ |
2446 | while (1) { | |
2447 | if (policy->plug_valid == 0) { | |
2448 | ret = PE_VCS_Wait_for_VCONN; | |
2449 | break; | |
2450 | } | |
2451 | ms = usbpd_check_time1(pd_data); | |
2452 | if (pd_data->phy_ops.get_status(pd_data, MSG_PSRDY)) { | |
2453 | pd_data->counter.swap_hard_reset_counter = 0; | |
2454 | ret = PE_VCS_Turn_Off_VCONN; | |
2455 | break; | |
2456 | } | |
2457 | /* TimeOver Check */ | |
2458 | if (ms >= tVCONNSourceOn) { | |
2459 | if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount) | |
2460 | ret = Error_Recovery; | |
2461 | else | |
2462 | ret = PE_SNK_Hard_Reset; | |
2463 | break; | |
2464 | } | |
2465 | } | |
5073353a | 2466 | |
40798a41 | 2467 | return ret; |
5073353a JB |
2468 | } |
2469 | ||
2470 | policy_state usbpd_policy_vcs_turn_off_vconn(struct policy_data *policy) | |
2471 | { | |
2472 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2473 | int power_role = 0; | |
2474 | ||
40798a41 JB |
2475 | /********************************************** |
2476 | Actions on entry: | |
2477 | Tell Device Policy Manager to turn off VCONN | |
2478 | **********************************************/ | |
2479 | ||
5073353a JB |
2480 | pd_data->phy_ops.get_power_role(pd_data, &power_role); |
2481 | ||
2482 | dev_info(pd_data->dev, "%s\n", __func__); | |
2483 | ||
2484 | pd_data->phy_ops.set_vconn_source(pd_data, USBPD_VCONN_OFF); | |
2485 | ||
2486 | if (power_role == USBPD_SOURCE) | |
2487 | return PE_SRC_Ready; | |
2488 | else | |
2489 | return PE_SNK_Ready; | |
2490 | } | |
2491 | ||
2492 | policy_state usbpd_policy_vcs_turn_on_vconn(struct policy_data *policy) | |
2493 | { | |
2494 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2495 | ||
40798a41 JB |
2496 | /********************************************** |
2497 | Actions on entry: | |
2498 | Tell Device Policy Manager to turn on VCONN | |
2499 | **********************************************/ | |
2500 | ||
5073353a JB |
2501 | dev_info(pd_data->dev, "%s\n", __func__); |
2502 | ||
2503 | pd_data->phy_ops.set_vconn_source(pd_data, USBPD_VCONN_ON); | |
2504 | ||
2505 | return PE_VCS_Send_PS_RDY; | |
2506 | } | |
2507 | ||
2508 | policy_state usbpd_policy_vcs_send_ps_rdy(struct policy_data *policy) | |
2509 | { | |
2510 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2511 | int power_role = 0; | |
2512 | int data_role = 0; | |
2513 | ||
40798a41 JB |
2514 | /********************************************** |
2515 | Actions on entry: | |
2516 | Send PS_RDY message | |
2517 | **********************************************/ | |
2518 | ||
5073353a JB |
2519 | dev_info(pd_data->dev, "%s\n", __func__); |
2520 | ||
2521 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2522 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
2523 | ||
2524 | mdelay(5); | |
2525 | ||
2526 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
2527 | USBPD_PS_RDY, data_role, data_role)) { | |
2528 | if (power_role == USBPD_SOURCE) | |
2529 | return PE_SRC_Ready; | |
2530 | else | |
2531 | return PE_SNK_Ready; | |
2532 | } | |
2533 | ||
2534 | return PE_VCS_Send_PS_RDY; | |
2535 | } | |
2536 | ||
2537 | policy_state usbpd_policy_vcs_reject_vconn_swap(struct policy_data *policy) | |
2538 | { | |
2539 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2540 | int power_role = 0; | |
2541 | ||
40798a41 JB |
2542 | /********************************************** |
2543 | Actions on entry: | |
2544 | Send Reject or Wait message as appropriate | |
2545 | **********************************************/ | |
2546 | ||
5073353a JB |
2547 | dev_info(pd_data->dev, "%s\n", __func__); |
2548 | ||
2549 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2550 | ||
2551 | if (usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
2552 | USBPD_Reject, USBPD_DFP, power_role)) { | |
2553 | if (power_role == USBPD_SOURCE) | |
2554 | return PE_SRC_Ready; | |
2555 | else | |
2556 | return PE_SNK_Ready; | |
2557 | } | |
2558 | ||
2559 | return PE_VCS_Reject_VCONN_Swap; | |
2560 | } | |
2561 | ||
2562 | policy_state usbpd_policy_ufp_vdm_get_identity(struct policy_data *policy) | |
2563 | { | |
40798a41 JB |
2564 | |
2565 | /********************************************** | |
2566 | Actions on entry: | |
2567 | Request Identity information from DPM | |
2568 | **********************************************/ | |
2569 | ||
0ef320fa | 2570 | return PE_UFP_VDM_Send_Identity; |
5073353a JB |
2571 | } |
2572 | ||
2573 | policy_state usbpd_policy_ufp_vdm_send_identity(struct policy_data *policy) | |
2574 | { | |
2575 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2576 | int power_role = 0; | |
2577 | ||
40798a41 JB |
2578 | /********************************************** |
2579 | Actions on entry: | |
2580 | Send Discover Identity ACK | |
2581 | **********************************************/ | |
2582 | ||
5073353a JB |
2583 | dev_info(pd_data->dev, "%s\n", __func__); |
2584 | ||
2585 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2586 | ||
2587 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2588 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2589 | policy->tx_msg_header.port_power_role = power_role; | |
0ef320fa | 2590 | policy->tx_msg_header.num_data_objs = 4; |
5073353a JB |
2591 | |
2592 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2593 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2594 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2595 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2596 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
2597 | policy->tx_data_obj[0].structured_vdm.command = Discover_Identity; | |
2598 | ||
0ef320fa JB |
2599 | policy->tx_data_obj[1].object = 0xD10004E8; |
2600 | policy->tx_data_obj[2].object = 0x0; | |
2601 | policy->tx_data_obj[3].object = 0x68600000; | |
2602 | ||
5073353a JB |
2603 | /* TODO: data object should be prepared from device manager */ |
2604 | ||
2605 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2606 | policy->tx_data_obj)) { | |
2607 | if (power_role == USBPD_SINK) | |
2608 | return PE_SNK_Ready; | |
2609 | else | |
2610 | return PE_SRC_Ready; | |
2611 | } | |
2612 | return PE_UFP_VDM_Send_Identity; | |
2613 | } | |
2614 | ||
2615 | policy_state usbpd_policy_ufp_vdm_get_identity_nak(struct policy_data *policy) | |
2616 | { | |
2617 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2618 | int power_role = 0; | |
2619 | ||
40798a41 JB |
2620 | /********************************************** |
2621 | Actions on entry: NAK | |
2622 | Send Discover Identity NAK/BUSY Command | |
2623 | response as requested | |
2624 | **********************************************/ | |
2625 | ||
5073353a JB |
2626 | dev_info(pd_data->dev, "%s\n", __func__); |
2627 | ||
2628 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2629 | ||
2630 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2631 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2632 | policy->tx_msg_header.port_power_role = power_role; | |
2633 | policy->tx_msg_header.num_data_objs = 1; | |
2634 | ||
2635 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2636 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2637 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2638 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2639 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
2640 | policy->tx_data_obj[0].structured_vdm.command = Discover_Identity; | |
2641 | ||
2642 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2643 | policy->tx_data_obj)) { | |
2644 | if (power_role == USBPD_SINK) | |
2645 | return PE_SNK_Ready; | |
2646 | else | |
2647 | return PE_SRC_Ready; | |
2648 | } | |
2649 | return PE_UFP_VDM_Get_Identity_NAK; | |
2650 | } | |
2651 | ||
2652 | policy_state usbpd_policy_ufp_vdm_get_svids(struct policy_data *policy) | |
2653 | { | |
2654 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2655 | ||
40798a41 JB |
2656 | /********************************************** |
2657 | Actions on entry: | |
2658 | Request SVIDs information from DPM | |
2659 | **********************************************/ | |
2660 | ||
5073353a JB |
2661 | if (usbpd_manager_get_svids(pd_data) == 0) |
2662 | return PE_UFP_VDM_Send_SVIDs; | |
2663 | else | |
2664 | return PE_UFP_VDM_Get_SVIDs_NAK; | |
2665 | ||
2666 | } | |
2667 | ||
2668 | policy_state usbpd_policy_ufp_vdm_send_svids(struct policy_data *policy) | |
2669 | { | |
2670 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2671 | int power_role = 0; | |
2672 | ||
40798a41 JB |
2673 | /********************************************** |
2674 | Actions on entry: | |
2675 | Send Discover SVIDs ACK | |
2676 | **********************************************/ | |
2677 | ||
5073353a JB |
2678 | dev_info(pd_data->dev, "%s\n", __func__); |
2679 | ||
2680 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2681 | ||
2682 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2683 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2684 | policy->tx_msg_header.port_power_role = power_role; | |
2685 | policy->tx_msg_header.num_data_objs = 2; | |
2686 | ||
2687 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2688 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2689 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2690 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2691 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
2692 | policy->tx_data_obj[0].structured_vdm.command = Discover_SVIDs; | |
2693 | ||
2694 | policy->tx_data_obj[1].vdm_svid.svid_0 = PD_SID; | |
2695 | policy->tx_data_obj[1].vdm_svid.svid_1 = 0xFF01; | |
2696 | ||
2697 | /* TODO: data object should be prepared from device manager */ | |
2698 | ||
2699 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2700 | policy->tx_data_obj)) { | |
2701 | if (power_role == USBPD_SINK) | |
2702 | return PE_SNK_Ready; | |
2703 | else | |
2704 | return PE_SRC_Ready; | |
2705 | } | |
2706 | ||
2707 | return PE_UFP_VDM_Send_SVIDs; | |
2708 | } | |
2709 | ||
2710 | policy_state usbpd_policy_ufp_vdm_get_svids_nak(struct policy_data *policy) | |
2711 | { | |
2712 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2713 | int power_role = 0; | |
2714 | ||
40798a41 JB |
2715 | /********************************************** |
2716 | Actions on entry: | |
2717 | Send Discover SVIDs NAK/BUSY Command | |
2718 | response as requested | |
2719 | **********************************************/ | |
2720 | ||
5073353a JB |
2721 | dev_info(pd_data->dev, "%s\n", __func__); |
2722 | ||
2723 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2724 | ||
2725 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2726 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2727 | policy->tx_msg_header.port_power_role = power_role; | |
2728 | policy->tx_msg_header.num_data_objs = 1; | |
2729 | ||
2730 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2731 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2732 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2733 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2734 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
2735 | policy->tx_data_obj[0].structured_vdm.command = Discover_SVIDs; | |
2736 | ||
2737 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2738 | policy->tx_data_obj)) { | |
2739 | if (power_role == USBPD_SINK) | |
2740 | return PE_SNK_Ready; | |
2741 | else | |
2742 | return PE_SRC_Ready; | |
2743 | } | |
2744 | return PE_UFP_VDM_Get_SVIDs_NAK; | |
2745 | } | |
2746 | ||
2747 | policy_state usbpd_policy_ufp_vdm_get_modes(struct policy_data *policy) | |
2748 | { | |
2749 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2750 | ||
40798a41 JB |
2751 | /********************************************** |
2752 | Actions on entry: | |
2753 | Request Modes information from DPM | |
2754 | **********************************************/ | |
2755 | ||
5073353a JB |
2756 | if (usbpd_manager_get_modes(pd_data) == 0) |
2757 | return PE_UFP_VDM_Send_Modes; | |
2758 | else | |
2759 | return PE_UFP_VDM_Get_Modes_NAK; | |
2760 | } | |
2761 | ||
2762 | policy_state usbpd_policy_ufp_vdm_send_modes(struct policy_data *policy) | |
2763 | { | |
2764 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2765 | int power_role = 0; | |
2766 | ||
40798a41 JB |
2767 | /********************************************** |
2768 | Actions on entry: | |
2769 | Send Discover Modes ACK | |
2770 | **********************************************/ | |
2771 | ||
5073353a JB |
2772 | dev_info(pd_data->dev, "%s\n", __func__); |
2773 | ||
2774 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2775 | ||
2776 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2777 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2778 | policy->tx_msg_header.port_power_role = power_role; | |
2779 | policy->tx_msg_header.num_data_objs = 2; | |
2780 | ||
2781 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2782 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2783 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2784 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2785 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
2786 | policy->tx_data_obj[0].structured_vdm.command = Discover_Modes; | |
2787 | ||
2788 | /* TODO: data object should be prepared from device manager */ | |
2789 | ||
2790 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2791 | policy->tx_data_obj)) { | |
2792 | if (power_role == USBPD_SINK) | |
2793 | return PE_SNK_Ready; | |
2794 | else | |
2795 | return PE_SRC_Ready; | |
2796 | } | |
2797 | return PE_UFP_VDM_Send_Modes; | |
2798 | } | |
2799 | ||
2800 | policy_state usbpd_policy_ufp_vdm_get_modes_nak(struct policy_data *policy) | |
2801 | { | |
2802 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2803 | int power_role = 0; | |
2804 | ||
40798a41 JB |
2805 | /********************************************** |
2806 | Actions on entry: | |
2807 | Send Discover Modes NAK/BUSY Command | |
2808 | response as requested | |
2809 | **********************************************/ | |
2810 | ||
5073353a JB |
2811 | dev_info(pd_data->dev, "%s\n", __func__); |
2812 | ||
2813 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2814 | ||
2815 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2816 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2817 | policy->tx_msg_header.port_power_role = power_role; | |
2818 | policy->tx_msg_header.num_data_objs = 1; | |
2819 | ||
2820 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2821 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2822 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2823 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2824 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
2825 | policy->tx_data_obj[0].structured_vdm.command = Discover_Modes; | |
2826 | ||
2827 | /* TODO: data object should be prepared from device manager */ | |
2828 | ||
2829 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2830 | policy->tx_data_obj)) { | |
2831 | if (power_role == USBPD_SINK) | |
2832 | return PE_SNK_Ready; | |
2833 | else | |
2834 | return PE_SRC_Ready; | |
2835 | } | |
2836 | return PE_UFP_VDM_Get_Modes_NAK; | |
2837 | } | |
2838 | ||
2839 | policy_state usbpd_policy_ufp_vdm_evaluate_mode_entry(struct policy_data *policy) | |
2840 | { | |
2841 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2842 | ||
40798a41 JB |
2843 | /********************************************** |
2844 | Actions on entry: | |
2845 | Request DPM to evaluate request to enter a Mode | |
2846 | **********************************************/ | |
2847 | ||
5073353a JB |
2848 | dev_info(pd_data->dev, "%s\n", __func__); |
2849 | ||
40798a41 JB |
2850 | /* Certification: Ellisys: TD.PD.VDMU.E15.Applicability */ |
2851 | if (usbpd_manager_get_svids(pd_data) == 0) | |
2852 | return PE_UFP_VDM_Mode_Entry_ACK; | |
2853 | else | |
2854 | return PE_UFP_VDM_Mode_Entry_NAK; | |
2855 | ||
5073353a JB |
2856 | /* Todo |
2857 | check DPM evaluate request to enter a mode | |
2858 | */ | |
2859 | /* | |
2860 | if (usbpd_manager_enter_mode(pd_data, mode_pos, | |
2861 | mode_vdo) == 0) | |
2862 | return PE_UFP_VDM_Mode_Entry_ACK; | |
2863 | else | |
2864 | return PE_UFP_VDM_Mode_Entry_NAK; | |
2865 | */ | |
2866 | return PE_UFP_VDM_Evaluate_Mode_Entry; | |
2867 | } | |
2868 | ||
2869 | policy_state usbpd_policy_ufp_vdm_mode_entry_ack(struct policy_data *policy) | |
2870 | { | |
2871 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2872 | int power_role = 0; | |
2873 | ||
40798a41 JB |
2874 | /********************************************** |
2875 | Actions on entry: | |
2876 | Send Enter Mode ACK Command | |
2877 | **********************************************/ | |
2878 | ||
5073353a JB |
2879 | dev_info(pd_data->dev, "%s\n", __func__); |
2880 | ||
2881 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2882 | ||
2883 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2884 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2885 | policy->tx_msg_header.port_power_role = power_role; | |
2886 | policy->tx_msg_header.num_data_objs = 1; | |
2887 | ||
2888 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2889 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2890 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2891 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2892 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
2893 | policy->tx_data_obj[0].structured_vdm.command = Enter_Mode; | |
2894 | ||
2895 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2896 | policy->tx_data_obj)) { | |
40798a41 | 2897 | /* TODO: may need to wait a while(5ms) and send status_update */ |
5073353a JB |
2898 | if (power_role == USBPD_SINK) |
2899 | return PE_SNK_Ready; | |
2900 | else | |
2901 | return PE_SRC_Ready; | |
2902 | } | |
2903 | return PE_UFP_VDM_Mode_Entry_ACK; | |
2904 | } | |
2905 | ||
2906 | policy_state usbpd_policy_ufp_vdm_mode_entry_nak(struct policy_data *policy) | |
2907 | { | |
2908 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2909 | int power_role = 0; | |
2910 | ||
40798a41 JB |
2911 | /********************************************** |
2912 | Actions on entry: | |
2913 | Send Enter Mode NAK Command response as requested | |
2914 | **********************************************/ | |
2915 | ||
5073353a JB |
2916 | dev_info(pd_data->dev, "%s\n", __func__); |
2917 | ||
2918 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2919 | ||
2920 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2921 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2922 | policy->tx_msg_header.port_power_role = power_role; | |
2923 | policy->tx_msg_header.num_data_objs = 1; | |
2924 | ||
2925 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2926 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2927 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2928 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2929 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
2930 | policy->tx_data_obj[0].structured_vdm.command = Enter_Mode; | |
2931 | ||
2932 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2933 | policy->tx_data_obj)) { | |
2934 | if (power_role == USBPD_SINK) | |
2935 | return PE_SNK_Ready; | |
2936 | else | |
2937 | return PE_SRC_Ready; | |
2938 | } | |
2939 | return PE_UFP_VDM_Mode_Entry_NAK; | |
2940 | } | |
2941 | ||
2942 | policy_state usbpd_policy_ufp_vdm_mode_exit(struct policy_data *policy) | |
2943 | { | |
2944 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2945 | ||
40798a41 JB |
2946 | /********************************************** |
2947 | Actions on entry: | |
2948 | Request DPM to evaluate request to exit the requested Mode | |
2949 | **********************************************/ | |
2950 | ||
5073353a JB |
2951 | dev_info(pd_data->dev, "%s\n", __func__); |
2952 | ||
2953 | if (pd_data->phy_ops.get_status(pd_data, VDM_EXIT_MODE)) { | |
2954 | if (policy->rx_data_obj[0].structured_vdm.command | |
2955 | == Exit_Mode) { | |
2956 | unsigned mode_pos; | |
2957 | ||
2958 | /* get mode to exit */ | |
2959 | mode_pos = policy->rx_data_obj[0].structured_vdm.obj_pos; | |
2960 | if (usbpd_manager_exit_mode(pd_data, mode_pos) == 0) | |
2961 | return PE_UFP_VDM_Mode_Exit_ACK; | |
2962 | else | |
2963 | return PE_UFP_VDM_Mode_Exit_NAK; | |
2964 | } | |
2965 | } | |
2966 | return PE_UFP_VDM_Mode_Exit; | |
2967 | ||
2968 | } | |
2969 | ||
2970 | policy_state usbpd_policy_ufp_vdm_mode_exit_ack(struct policy_data *policy) | |
2971 | { | |
2972 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
2973 | int power_role = 0; | |
2974 | ||
40798a41 JB |
2975 | /********************************************** |
2976 | Actions on entry: | |
2977 | Send Exit Mode ACK Command | |
2978 | **********************************************/ | |
2979 | ||
5073353a JB |
2980 | dev_info(pd_data->dev, "%s\n", __func__); |
2981 | ||
2982 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
2983 | ||
2984 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
2985 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
2986 | policy->tx_msg_header.port_power_role = power_role; | |
2987 | policy->tx_msg_header.num_data_objs = 1; | |
2988 | ||
2989 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
2990 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
2991 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
2992 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
2993 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
2994 | policy->tx_data_obj[0].structured_vdm.command = Exit_Mode; | |
2995 | ||
2996 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
2997 | policy->tx_data_obj)) { | |
2998 | if (power_role == USBPD_SINK) | |
2999 | return PE_SNK_Ready; | |
3000 | else | |
3001 | return PE_SRC_Ready; | |
3002 | } | |
3003 | return PE_UFP_VDM_Mode_Exit_NAK; | |
3004 | } | |
3005 | ||
3006 | policy_state usbpd_policy_ufp_vdm_mode_exit_nak(struct policy_data *policy) | |
3007 | { | |
3008 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3009 | int power_role = 0; | |
3010 | ||
40798a41 JB |
3011 | /********************************************** |
3012 | Actions on entry: | |
3013 | Send Exit Mode NAK Command | |
3014 | **********************************************/ | |
3015 | ||
5073353a JB |
3016 | dev_info(pd_data->dev, "%s\n", __func__); |
3017 | ||
3018 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3019 | ||
3020 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3021 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
3022 | policy->tx_msg_header.port_power_role = power_role; | |
3023 | policy->tx_msg_header.num_data_objs = 1; | |
3024 | ||
3025 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3026 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3027 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3028 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3029 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
3030 | policy->tx_data_obj[0].structured_vdm.command = Exit_Mode; | |
3031 | ||
3032 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3033 | policy->tx_data_obj)) { | |
3034 | if (power_role == USBPD_SINK) | |
3035 | return PE_SNK_Ready; | |
3036 | else | |
3037 | return PE_SRC_Ready; | |
3038 | } | |
3039 | return PE_UFP_VDM_Mode_Exit_NAK; | |
3040 | } | |
3041 | ||
3042 | policy_state usbpd_policy_ufp_vdm_attention_request(struct policy_data *policy) | |
3043 | { | |
3044 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3045 | int power_role = 0; | |
3046 | ||
40798a41 JB |
3047 | /********************************************** |
3048 | Actions on entry: | |
3049 | Send Attention Command request | |
3050 | **********************************************/ | |
3051 | ||
5073353a JB |
3052 | dev_info(pd_data->dev, "%s\n", __func__); |
3053 | ||
3054 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3055 | ||
3056 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3057 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
3058 | policy->tx_msg_header.port_power_role = power_role; | |
3059 | /* policy->tx_msg_header.num_data_objs = 1; number of objects*/ | |
3060 | ||
3061 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3062 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3063 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3064 | policy->tx_data_obj[0].structured_vdm.obj_pos = 0; | |
3065 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3066 | policy->tx_data_obj[0].structured_vdm.command = Attention; | |
3067 | ||
3068 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3069 | policy->tx_data_obj)) { | |
3070 | if (power_role == USBPD_SINK) | |
3071 | return PE_SNK_Ready; | |
3072 | else | |
3073 | return PE_SRC_Ready; | |
3074 | } | |
3075 | return PE_UFP_VDM_Attention_Request; | |
3076 | ||
3077 | } | |
3078 | ||
3079 | policy_state usbpd_policy_ufp_vdm_evaluate_status(struct policy_data *policy) | |
3080 | { | |
3081 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3082 | int power_role = 0; | |
3083 | ||
40798a41 JB |
3084 | /********************************************** |
3085 | **********************************************/ | |
3086 | ||
5073353a JB |
3087 | dev_info(pd_data->dev, "%s\n", __func__); |
3088 | ||
3089 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3090 | ||
3091 | if (power_role == USBPD_SINK) | |
3092 | return PE_SNK_Ready; | |
3093 | else | |
3094 | return PE_SRC_Ready; | |
3095 | ||
3096 | /* Todo | |
3097 | check DPM evaluate request to inform status | |
3098 | */ | |
3099 | /* | |
3100 | if (usbpd_manager_enter_mode(pd_data, mode_pos, | |
3101 | mode_vdo) == 0) | |
3102 | return PE_UFP_VDM_Mode_Entry_ACK; | |
3103 | else | |
3104 | return PE_UFP_VDM_Mode_Entry_NAK; | |
3105 | */ | |
3106 | } | |
3107 | ||
3108 | policy_state usbpd_policy_ufp_vdm_status_ack(struct policy_data *policy) | |
3109 | { | |
3110 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3111 | int power_role = 0; | |
3112 | ||
40798a41 JB |
3113 | /********************************************** |
3114 | **********************************************/ | |
3115 | ||
5073353a JB |
3116 | dev_info(pd_data->dev, "%s\n", __func__); |
3117 | ||
3118 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3119 | ||
3120 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3121 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
3122 | policy->tx_msg_header.port_power_role = power_role; | |
3123 | policy->tx_msg_header.num_data_objs = 1; | |
3124 | ||
3125 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3126 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3127 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3128 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3129 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
3130 | policy->tx_data_obj[0].structured_vdm.command = DisplayPort_Status_Update; | |
3131 | ||
3132 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3133 | policy->tx_data_obj)) { | |
3134 | if (power_role == USBPD_SINK) | |
3135 | return PE_SNK_Ready; | |
3136 | else | |
3137 | return PE_SRC_Ready; | |
3138 | } | |
3139 | return PE_UFP_VDM_Status_ACK; | |
3140 | } | |
3141 | ||
3142 | policy_state usbpd_policy_ufp_vdm_status_nak(struct policy_data *policy) | |
3143 | { | |
3144 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3145 | int power_role = 0; | |
3146 | ||
40798a41 JB |
3147 | /********************************************** |
3148 | **********************************************/ | |
3149 | ||
5073353a JB |
3150 | dev_info(pd_data->dev, "%s\n", __func__); |
3151 | ||
3152 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3153 | ||
3154 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3155 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
3156 | policy->tx_msg_header.port_power_role = power_role; | |
3157 | policy->tx_msg_header.num_data_objs = 1; | |
3158 | ||
3159 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3160 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3161 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3162 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3163 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
3164 | policy->tx_data_obj[0].structured_vdm.command = DisplayPort_Status_Update; | |
3165 | ||
3166 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3167 | policy->tx_data_obj)) { | |
3168 | if (power_role == USBPD_SINK) | |
3169 | return PE_SNK_Ready; | |
3170 | else | |
3171 | return PE_SRC_Ready; | |
3172 | } | |
3173 | return PE_UFP_VDM_Status_NAK; | |
3174 | } | |
3175 | ||
3176 | policy_state usbpd_policy_ufp_vdm_evaluate_configure(struct policy_data *policy) | |
3177 | { | |
3178 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3179 | int power_role = 0; | |
3180 | ||
40798a41 JB |
3181 | /********************************************** |
3182 | **********************************************/ | |
3183 | ||
5073353a JB |
3184 | dev_info(pd_data->dev, "%s\n", __func__); |
3185 | ||
3186 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3187 | ||
3188 | if (power_role == USBPD_SINK) | |
3189 | return PE_SNK_Ready; | |
3190 | else | |
3191 | return PE_SRC_Ready; | |
3192 | ||
3193 | /* Todo | |
3194 | check DPM evaluate request to inform status | |
3195 | */ | |
3196 | /* | |
3197 | if (usbpd_manager_enter_mode(pd_data, mode_pos, | |
3198 | mode_vdo) == 0) | |
3199 | return PE_UFP_VDM_Mode_Entry_ACK; | |
3200 | else | |
3201 | return PE_UFP_VDM_Mode_Entry_NAK; | |
3202 | */ | |
3203 | } | |
3204 | ||
3205 | policy_state usbpd_policy_ufp_vdm_configure_ack(struct policy_data *policy) | |
3206 | { | |
3207 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3208 | int power_role = 0; | |
3209 | ||
40798a41 JB |
3210 | /********************************************** |
3211 | **********************************************/ | |
3212 | ||
5073353a JB |
3213 | dev_info(pd_data->dev, "%s\n", __func__); |
3214 | ||
3215 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3216 | ||
3217 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3218 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
3219 | policy->tx_msg_header.port_power_role = power_role; | |
3220 | policy->tx_msg_header.num_data_objs = 1; | |
3221 | ||
3222 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3223 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3224 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3225 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3226 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_ACK; | |
3227 | policy->tx_data_obj[0].structured_vdm.command = DisplayPort_Configure; | |
3228 | ||
3229 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3230 | policy->tx_data_obj)) { | |
3231 | if (power_role == USBPD_SINK) | |
3232 | return PE_SNK_Ready; | |
3233 | else | |
3234 | return PE_SRC_Ready; | |
3235 | } | |
3236 | return PE_UFP_VDM_Configure_ACK; | |
3237 | } | |
3238 | ||
3239 | policy_state usbpd_policy_ufp_vdm_configure_nak(struct policy_data *policy) | |
3240 | { | |
3241 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3242 | int power_role = 0; | |
3243 | ||
40798a41 JB |
3244 | /********************************************** |
3245 | **********************************************/ | |
3246 | ||
5073353a JB |
3247 | dev_info(pd_data->dev, "%s\n", __func__); |
3248 | ||
3249 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3250 | ||
3251 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3252 | policy->tx_msg_header.port_data_role = USBPD_UFP; | |
3253 | policy->tx_msg_header.port_power_role = power_role; | |
3254 | policy->tx_msg_header.num_data_objs = 1; | |
3255 | ||
3256 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3257 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3258 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3259 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3260 | policy->tx_data_obj[0].structured_vdm.command_type = Responder_NAK; | |
3261 | policy->tx_data_obj[0].structured_vdm.command = DisplayPort_Configure; | |
3262 | ||
3263 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3264 | policy->tx_data_obj)) { | |
3265 | if (power_role == USBPD_SINK) | |
3266 | return PE_SNK_Ready; | |
3267 | else | |
3268 | return PE_SRC_Ready; | |
3269 | } | |
3270 | return PE_UFP_VDM_Configure_NAK; | |
3271 | } | |
3272 | ||
3273 | /* the end ufp */ | |
3274 | ||
3275 | policy_state usbpd_policy_dfp_vdm_identity_request(struct policy_data *policy) | |
3276 | { | |
3277 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3278 | int power_role = 0; | |
3279 | ||
40798a41 JB |
3280 | /********************************************** |
3281 | Actions on entry: | |
3282 | Send Discover Identity request | |
3283 | Start VDMResponseTimer | |
3284 | **********************************************/ | |
3285 | ||
5073353a JB |
3286 | dev_info(pd_data->dev, "%s\n", __func__); |
3287 | ||
3288 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3289 | ||
3290 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3291 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3292 | policy->tx_msg_header.port_power_role = power_role; | |
3293 | policy->tx_msg_header.num_data_objs = 1; | |
3294 | ||
3295 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3296 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3297 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3298 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3299 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3300 | policy->tx_data_obj[0].structured_vdm.command = Discover_Identity; | |
3301 | ||
3302 | pd_data->counter.discover_identity_counter++; | |
3303 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3304 | policy->tx_data_obj)) { | |
3305 | pd_data->policy.state = PE_DFP_VDM_Identity_Request; | |
3306 | if (usbpd_wait_msg(pd_data, VDM_DISCOVER_IDENTITY, | |
3307 | tVDMSenderResponse)) { | |
3308 | pd_data->counter.discover_identity_counter = 0; | |
3309 | ||
3310 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3311 | == Responder_ACK) | |
3312 | return PE_DFP_VDM_Identity_ACKed; | |
40798a41 JB |
3313 | else if (policy->rx_data_obj[0].structured_vdm.command_type == Responder_NAK |
3314 | || policy->rx_data_obj[0].structured_vdm.command_type == Responder_BUSY) | |
3315 | return PE_DFP_VDM_Identity_NAKed; | |
5073353a JB |
3316 | } |
3317 | } | |
40798a41 JB |
3318 | |
3319 | if (pd_data->counter.swap_hard_reset_counter > USBPD_nHardResetCount) | |
3320 | return Error_Recovery; | |
3321 | ||
3322 | return PE_SRC_Hard_Reset; | |
5073353a JB |
3323 | } |
3324 | ||
3325 | static policy_state usbpd_policy_dfp_vdm_response(struct policy_data *policy, | |
3326 | usbpd_manager_event_type event) | |
3327 | { | |
3328 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3329 | int power_role = 0; | |
3330 | ||
40798a41 JB |
3331 | /********************************************** |
3332 | **********************************************/ | |
3333 | ||
5073353a JB |
3334 | usbpd_manager_inform_event(pd_data, event); |
3335 | ||
3336 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3337 | ||
3338 | if (power_role == USBPD_SINK) | |
3339 | return PE_SNK_Ready; | |
3340 | else | |
3341 | return PE_SRC_Ready; | |
3342 | } | |
3343 | ||
3344 | policy_state usbpd_policy_dfp_vdm_identity_acked(struct policy_data *policy) | |
3345 | { | |
3346 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3347 | ||
40798a41 JB |
3348 | /********************************************** |
3349 | Actions on entry: | |
3350 | Inform DPM of identity | |
3351 | **********************************************/ | |
3352 | ||
5073353a JB |
3353 | dev_info(pd_data->dev, "%s\n", __func__); |
3354 | ||
3355 | return usbpd_policy_dfp_vdm_response(policy, | |
3356 | MANAGER_DISCOVER_IDENTITY_ACKED); | |
3357 | } | |
3358 | ||
3359 | policy_state usbpd_policy_dfp_vdm_identity_naked(struct policy_data *policy) | |
3360 | { | |
3361 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3362 | ||
40798a41 JB |
3363 | /********************************************** |
3364 | Actions on entry: | |
3365 | Inform DPM of result | |
3366 | **********************************************/ | |
3367 | ||
5073353a JB |
3368 | dev_info(pd_data->dev, "%s\n", __func__); |
3369 | ||
3370 | return usbpd_policy_dfp_vdm_response(policy, | |
3371 | MANAGER_DISCOVER_IDENTITY_NAKED); | |
3372 | } | |
3373 | ||
3374 | policy_state usbpd_policy_dfp_vdm_svids_request(struct policy_data *policy) | |
3375 | { | |
3376 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3377 | int power_role = 0; | |
3378 | ||
40798a41 JB |
3379 | /********************************************** |
3380 | Actions on entry: | |
3381 | Send Discover SVIDs request | |
3382 | Start VDMResponseTimer | |
3383 | **********************************************/ | |
3384 | ||
5073353a JB |
3385 | dev_info(pd_data->dev, "%s\n", __func__); |
3386 | ||
3387 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3388 | ||
3389 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3390 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3391 | policy->tx_msg_header.port_power_role = power_role; | |
3392 | policy->tx_msg_header.num_data_objs = 1; | |
3393 | ||
3394 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3395 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3396 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3397 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3398 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3399 | policy->tx_data_obj[0].structured_vdm.command = Discover_SVIDs; | |
3400 | ||
3401 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3402 | policy->tx_data_obj)) { | |
3403 | pd_data->policy.state = PE_DFP_VDM_SVIDs_Request; | |
3404 | if (usbpd_wait_msg(pd_data, VDM_DISCOVER_SVID, | |
3405 | tVDMSenderResponse)) { | |
3406 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3407 | == Responder_ACK) | |
3408 | return PE_DFP_VDM_SVIDs_ACKed; | |
3409 | } | |
3410 | } | |
3411 | return PE_DFP_VDM_SVIDs_NAKed; | |
3412 | } | |
3413 | ||
3414 | policy_state usbpd_policy_dfp_vdm_svids_acked(struct policy_data *policy) | |
3415 | { | |
3416 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3417 | ||
40798a41 JB |
3418 | /********************************************** |
3419 | Actions on entry: | |
3420 | Inform DPM of SVIDs | |
3421 | **********************************************/ | |
3422 | ||
5073353a JB |
3423 | dev_info(pd_data->dev, "%s\n", __func__); |
3424 | ||
3425 | return usbpd_policy_dfp_vdm_response(policy, | |
3426 | MANAGER_DISCOVER_SVID_ACKED); | |
3427 | } | |
3428 | ||
3429 | policy_state usbpd_policy_dfp_vdm_svids_naked(struct policy_data *policy) | |
3430 | { | |
3431 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3432 | ||
40798a41 JB |
3433 | /********************************************** |
3434 | Actions on entry: | |
3435 | Inform DPM of result | |
3436 | **********************************************/ | |
3437 | ||
5073353a JB |
3438 | dev_info(pd_data->dev, "%s\n", __func__); |
3439 | ||
3440 | return usbpd_policy_dfp_vdm_response(policy, | |
3441 | MANAGER_DISCOVER_SVID_NAKED); | |
3442 | } | |
3443 | ||
3444 | policy_state usbpd_policy_dfp_vdm_modes_request(struct policy_data *policy) | |
3445 | { | |
3446 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3447 | struct usbpd_manager_data *manager = &pd_data->manager; | |
3448 | int power_role = 0; | |
3449 | ||
40798a41 JB |
3450 | /********************************************** |
3451 | Actions on entry: | |
3452 | Send Discover Modes request | |
3453 | Start VDMResponseTimer | |
3454 | **********************************************/ | |
3455 | ||
5073353a JB |
3456 | dev_info(pd_data->dev, "%s\n", __func__); |
3457 | ||
3458 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3459 | ||
3460 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3461 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3462 | policy->tx_msg_header.port_power_role = power_role; | |
3463 | policy->tx_msg_header.num_data_objs = 1; | |
3464 | ||
3465 | policy->tx_data_obj[0].structured_vdm.svid = manager->SVID_0; | |
3466 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3467 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3468 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1; | |
3469 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3470 | policy->tx_data_obj[0].structured_vdm.command = Discover_Modes; | |
3471 | ||
3472 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3473 | policy->tx_data_obj)) { | |
3474 | pd_data->policy.state = PE_DFP_VDM_Modes_Request; | |
3475 | if (usbpd_wait_msg(pd_data, VDM_DISCOVER_MODE, | |
3476 | tVDMSenderResponse)) { | |
3477 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3478 | == Responder_ACK) | |
3479 | return PE_DFP_VDM_Modes_ACKed; | |
3480 | } | |
3481 | } | |
3482 | return PE_DFP_VDM_Modes_NAKed; | |
3483 | } | |
3484 | ||
3485 | policy_state usbpd_policy_dfp_vdm_modes_acked(struct policy_data *policy) | |
3486 | { | |
3487 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3488 | ||
40798a41 JB |
3489 | /********************************************** |
3490 | Actions on entry: | |
3491 | Inform DPM of Modes | |
3492 | **********************************************/ | |
3493 | ||
5073353a JB |
3494 | dev_info(pd_data->dev, "%s\n", __func__); |
3495 | ||
3496 | return usbpd_policy_dfp_vdm_response(policy, | |
3497 | MANAGER_DISCOVER_MODE_ACKED); | |
3498 | } | |
3499 | ||
3500 | policy_state usbpd_policy_dfp_vdm_modes_naked(struct policy_data *policy) | |
3501 | { | |
3502 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3503 | ||
40798a41 JB |
3504 | /********************************************** |
3505 | Actions on entry: | |
3506 | Inform DPM of result | |
3507 | **********************************************/ | |
3508 | ||
5073353a JB |
3509 | dev_info(pd_data->dev, "%s\n", __func__); |
3510 | ||
3511 | return usbpd_policy_dfp_vdm_response(policy, | |
3512 | MANAGER_DISCOVER_MODE_NAKED); | |
3513 | } | |
3514 | ||
3515 | policy_state usbpd_policy_dfp_vdm_entry_request(struct policy_data *policy) | |
3516 | { | |
3517 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3518 | struct usbpd_manager_data *manager = &pd_data->manager; | |
3519 | int power_role = 0; | |
3520 | ||
40798a41 JB |
3521 | /********************************************** |
3522 | Actions on entry: | |
3523 | Send Mode Entry request | |
3524 | Start VDMModeEntryTimer | |
3525 | **********************************************/ | |
3526 | ||
5073353a JB |
3527 | dev_info(pd_data->dev, "%s\n", __func__); |
3528 | ||
3529 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3530 | ||
3531 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3532 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3533 | policy->tx_msg_header.port_power_role = power_role; | |
3534 | policy->tx_msg_header.num_data_objs = 1; | |
3535 | ||
3536 | policy->tx_data_obj[0].object = 0; | |
3537 | policy->tx_data_obj[0].structured_vdm.svid = manager->SVID_0; | |
3538 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3539 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3540 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1;/* Todo select which_mode */ | |
3541 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3542 | policy->tx_data_obj[0].structured_vdm.command = Enter_Mode; | |
3543 | ||
3544 | /* TODO: obj_pos , vdo should be set by device manager */ | |
3545 | ||
3546 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3547 | policy->tx_data_obj)) { | |
3548 | pd_data->policy.state = PE_DFP_VDM_Mode_Entry_Request; | |
3549 | if (usbpd_wait_msg(pd_data, VDM_ENTER_MODE, | |
3550 | tVDMWaitModeEntry)) { | |
3551 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3552 | == Responder_ACK) | |
3553 | return PE_DFP_VDM_Mode_Entry_ACKed; | |
3554 | } | |
3555 | } | |
3556 | return PE_DFP_VDM_Mode_Entry_NAKed; | |
3557 | } | |
3558 | ||
3559 | policy_state usbpd_policy_dfp_vdm_entry_acked(struct policy_data *policy) | |
3560 | { | |
3561 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3562 | ||
40798a41 JB |
3563 | /********************************************** |
3564 | Actions on entry: | |
3565 | Request DPM to enter the mode | |
3566 | **********************************************/ | |
3567 | ||
5073353a JB |
3568 | dev_info(pd_data->dev, "%s\n", __func__); |
3569 | ||
3570 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_ENTER_MODE_ACKED); | |
3571 | } | |
3572 | ||
3573 | policy_state usbpd_policy_dfp_vdm_entry_naked(struct policy_data *policy) | |
3574 | { | |
3575 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3576 | ||
40798a41 JB |
3577 | /********************************************** |
3578 | Actions on entry: | |
3579 | Inform DPM of reason for failure | |
3580 | **********************************************/ | |
3581 | ||
5073353a JB |
3582 | dev_info(pd_data->dev, "%s\n", __func__); |
3583 | ||
3584 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_ENTER_MODE_NAKED); | |
3585 | } | |
3586 | ||
3587 | policy_state usbpd_policy_dfp_vdm_exit_request(struct policy_data *policy) | |
3588 | { | |
3589 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3590 | int power_role = 0; | |
3591 | ||
40798a41 JB |
3592 | /********************************************** |
3593 | Actions on entry: | |
3594 | Send Exit Mode request | |
3595 | Start VDMModeExitTimer | |
3596 | **********************************************/ | |
3597 | ||
5073353a JB |
3598 | dev_info(pd_data->dev, "%s\n", __func__); |
3599 | ||
3600 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3601 | ||
3602 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3603 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3604 | policy->tx_msg_header.port_power_role = power_role; | |
3605 | policy->tx_msg_header.num_data_objs = 1; | |
3606 | ||
3607 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID; | |
3608 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3609 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3610 | /* policy->tx_data_obj[0].structured_vdm.obj_pos = which_mode; */ | |
3611 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3612 | policy->tx_data_obj[0].structured_vdm.command = Exit_Mode; | |
3613 | ||
3614 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3615 | policy->tx_data_obj)) { | |
3616 | pd_data->policy.state = PE_DFP_VDM_Mode_Exit_Request; | |
3617 | if (usbpd_wait_msg(pd_data, VDM_EXIT_MODE, | |
3618 | tVDMWaitModeExit)) { | |
3619 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3620 | == Responder_ACK) | |
3621 | return PE_DFP_VDM_Mode_Exit_ACKed; | |
3622 | } | |
3623 | } | |
3624 | return PE_DFP_VDM_Mode_Exit_NAKed; | |
3625 | } | |
3626 | ||
3627 | policy_state usbpd_policy_dfp_vdm_exit_acked(struct policy_data *policy) | |
3628 | { | |
3629 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3630 | ||
40798a41 JB |
3631 | /********************************************** |
3632 | Actions on entry: | |
3633 | Inform DPM of ACK | |
3634 | **********************************************/ | |
3635 | ||
5073353a JB |
3636 | dev_info(pd_data->dev, "%s\n", __func__); |
3637 | ||
3638 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_EXIT_MODE_ACKED); | |
3639 | } | |
3640 | ||
3641 | policy_state usbpd_policy_dfp_vdm_exit_naked(struct policy_data *policy) | |
3642 | { | |
3643 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3644 | ||
40798a41 JB |
3645 | /********************************************** |
3646 | Actions on entry: | |
3647 | Inform DPM of NAK | |
3648 | **********************************************/ | |
3649 | ||
5073353a JB |
3650 | dev_info(pd_data->dev, "%s\n", __func__); |
3651 | ||
3652 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_EXIT_MODE_NAKED); | |
3653 | } | |
3654 | ||
3655 | policy_state usbpd_policy_dfp_vdm_attention_request(struct policy_data *policy) | |
3656 | { | |
3657 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3658 | ||
40798a41 JB |
3659 | /********************************************** |
3660 | Actions on entry: | |
3661 | Inform Device Policy Manager of Attention Command request | |
3662 | **********************************************/ | |
3663 | ||
5073353a JB |
3664 | dev_info(pd_data->dev, "%s\n", __func__); |
3665 | ||
3666 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_ATTENTION_REQUEST); | |
3667 | } | |
3668 | ||
3669 | policy_state usbpd_policy_dfp_vdm_status_update(struct policy_data *policy) | |
3670 | { | |
3671 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3672 | int power_role = 0; | |
3673 | ||
40798a41 JB |
3674 | /********************************************** |
3675 | **********************************************/ | |
3676 | ||
5073353a JB |
3677 | dev_info(pd_data->dev, "%s\n", __func__); |
3678 | ||
3679 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3680 | pd_data->phy_ops.set_check_msg_pass(pd_data, CHECK_MSG_PASS); | |
3681 | ||
3682 | ||
3683 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3684 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3685 | policy->tx_msg_header.port_power_role = power_role; | |
3686 | policy->tx_msg_header.num_data_objs = 2; | |
3687 | ||
3688 | policy->tx_data_obj[0].object = 0; | |
3689 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID_1; | |
3690 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; | |
3691 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3692 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1;/* Todo select which_mode */ | |
3693 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3694 | policy->tx_data_obj[0].structured_vdm.command = DisplayPort_Status_Update; | |
3695 | ||
3696 | /* second object for vdo */ | |
3697 | policy->tx_data_obj[1].object = 0; | |
3698 | policy->tx_data_obj[1].displayport_status.port_connected = 1; | |
3699 | ||
3700 | /* TODO: obj_pos , vdo should be set by device manager */ | |
3701 | ||
3702 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3703 | policy->tx_data_obj)) { | |
3704 | pd_data->policy.state = PE_DFP_VDM_Status_Update; | |
3705 | if (usbpd_wait_msg(pd_data, MSG_PASS, | |
3706 | tVDMWaitModeEntry)) { | |
3707 | pd_data->phy_ops.set_check_msg_pass(pd_data, NONE_CHECK_MSG_PASS); | |
3708 | pr_info("%s : command(%d), command_type(%d), obj_pos(%d), version(%d), vdm_type(%d)\n", | |
3709 | __func__, policy->rx_data_obj[0].structured_vdm.command, | |
3710 | policy->rx_data_obj[0].structured_vdm.command_type, | |
3711 | policy->rx_data_obj[0].structured_vdm.obj_pos, | |
3712 | policy->rx_data_obj[0].structured_vdm.version, | |
3713 | policy->rx_data_obj[0].structured_vdm.vdm_type); | |
3714 | ||
3715 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3716 | == Responder_ACK) | |
3717 | return PE_DFP_VDM_Status_Update_ACKed; | |
3718 | } | |
3719 | } | |
3720 | pd_data->phy_ops.set_check_msg_pass(pd_data, NONE_CHECK_MSG_PASS); | |
3721 | ||
3722 | return PE_DFP_VDM_Status_Update_NAKed; | |
3723 | } | |
3724 | ||
3725 | policy_state usbpd_policy_dfp_vdm_status_update_acked(struct policy_data *policy) | |
3726 | { | |
3727 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3728 | ||
40798a41 JB |
3729 | /********************************************** |
3730 | **********************************************/ | |
3731 | ||
5073353a JB |
3732 | dev_info(pd_data->dev, "%s\n", __func__); |
3733 | ||
3734 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_STATUS_UPDATE_ACKED); | |
3735 | } | |
3736 | ||
3737 | policy_state usbpd_policy_dfp_vdm_status_update_naked(struct policy_data *policy) | |
3738 | { | |
3739 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3740 | ||
40798a41 JB |
3741 | /********************************************** |
3742 | **********************************************/ | |
3743 | ||
5073353a JB |
3744 | dev_info(pd_data->dev, "%s\n", __func__); |
3745 | ||
3746 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_STATUS_UPDATE_NAKED); | |
3747 | } | |
3748 | ||
3749 | policy_state usbpd_policy_dfp_vdm_displayport_configure(struct policy_data *policy) | |
3750 | { | |
3751 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
5073353a JB |
3752 | int power_role = 0; |
3753 | ||
40798a41 JB |
3754 | /********************************************** |
3755 | **********************************************/ | |
3756 | ||
5073353a JB |
3757 | dev_info(pd_data->dev, "%s\n", __func__); |
3758 | ||
3759 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3760 | pd_data->phy_ops.set_check_msg_pass(pd_data, CHECK_MSG_PASS); | |
3761 | ||
3762 | policy->tx_msg_header.msg_type = USBPD_Vendor_Defined; | |
3763 | policy->tx_msg_header.port_data_role = USBPD_DFP; | |
3764 | policy->tx_msg_header.port_power_role = power_role; | |
3765 | policy->tx_msg_header.num_data_objs = 2; | |
3766 | ||
40798a41 | 3767 | policy->tx_data_obj[0].structured_vdm.svid = PD_SID_1; |
5073353a JB |
3768 | policy->tx_data_obj[0].structured_vdm.vdm_type = Structured_VDM; |
3769 | policy->tx_data_obj[0].structured_vdm.version = 0; | |
3770 | policy->tx_data_obj[0].structured_vdm.obj_pos = 1;/* Todo select which_mode */ | |
3771 | policy->tx_data_obj[0].structured_vdm.command_type = Initiator; | |
3772 | policy->tx_data_obj[0].structured_vdm.command = DisplayPort_Configure; | |
3773 | ||
3774 | /* second object for vdo */ | |
3775 | policy->tx_data_obj[1].object = 0; | |
40798a41 JB |
3776 | policy->tx_data_obj[1].displayport_configurations.select_configuration = USB_U_AS_UFP_D; |
3777 | policy->tx_data_obj[1].displayport_configurations.displayport_protocol = DP_V_1_3; | |
3778 | policy->tx_data_obj[1].displayport_configurations.ufp_u_pin_assignment = PIN_ASSIGNMENT_D; | |
5073353a JB |
3779 | |
3780 | /* TODO: obj_pos , vdo should be set by device manager */ | |
3781 | if (usbpd_send_msg(pd_data, &policy->tx_msg_header, | |
3782 | policy->tx_data_obj)) { | |
3783 | pd_data->policy.state = PE_DFP_VDM_DisplayPort_Configure; | |
3784 | if (usbpd_wait_msg(pd_data, MSG_PASS, | |
3785 | tVDMWaitModeEntry)) { | |
3786 | pd_data->phy_ops.set_check_msg_pass(pd_data, NONE_CHECK_MSG_PASS); | |
3787 | if (policy->rx_data_obj[0].structured_vdm.command_type | |
3788 | == Responder_ACK) | |
3789 | return PE_DFP_VDM_DisplayPort_Configure_ACKed; | |
3790 | } | |
3791 | } | |
3792 | pd_data->phy_ops.set_check_msg_pass(pd_data, NONE_CHECK_MSG_PASS); | |
3793 | ||
3794 | return PE_DFP_VDM_DisplayPort_Configure_NAKed; | |
3795 | } | |
3796 | ||
3797 | policy_state usbpd_policy_dfp_vdm_displayport_configure_acked(struct policy_data *policy) | |
3798 | { | |
3799 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3800 | ||
40798a41 JB |
3801 | /********************************************** |
3802 | **********************************************/ | |
3803 | ||
5073353a JB |
3804 | dev_info(pd_data->dev, "%s\n", __func__); |
3805 | ||
3806 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_DisplayPort_Configure_ACKED); | |
3807 | } | |
3808 | ||
3809 | policy_state usbpd_policy_dfp_vdm_displayport_configure_naked(struct policy_data *policy) | |
3810 | { | |
3811 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3812 | ||
40798a41 JB |
3813 | /********************************************** |
3814 | **********************************************/ | |
3815 | ||
5073353a JB |
3816 | dev_info(pd_data->dev, "%s\n", __func__); |
3817 | ||
3818 | return usbpd_policy_dfp_vdm_response(policy, MANAGER_DisplayPort_Configure_NACKED); | |
3819 | } | |
3820 | ||
3821 | policy_state usbpd_policy_dfp_uvdm_send_message(struct policy_data *policy) | |
3822 | { | |
3823 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3824 | struct usbpd_manager_data *manager = &pd_data->manager; | |
3825 | int power_role = 0; | |
3826 | ||
40798a41 JB |
3827 | /********************************************** |
3828 | **********************************************/ | |
3829 | ||
5073353a JB |
3830 | dev_info(pd_data->dev, "%s\n", __func__); |
3831 | ||
3832 | pd_data->phy_ops.set_check_msg_pass(pd_data, CHECK_MSG_PASS); | |
3833 | ||
3834 | usbpd_send_msg(pd_data, &manager->uvdm_msg_header, manager->uvdm_data_obj); | |
3835 | ||
3836 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3837 | ||
3838 | if (power_role == USBPD_SOURCE) | |
3839 | return PE_SRC_Ready; | |
3840 | else | |
3841 | return PE_SNK_Ready; | |
3842 | } | |
3843 | ||
3844 | policy_state usbpd_policy_dfp_uvdm_receive_message(struct policy_data *policy) | |
3845 | { | |
3846 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3847 | int power_role = 0; | |
3848 | ||
40798a41 JB |
3849 | /********************************************** |
3850 | **********************************************/ | |
3851 | ||
5073353a JB |
3852 | dev_info(pd_data->dev, "%s\n", __func__); |
3853 | ||
3854 | usbpd_manager_inform_event(pd_data, MANAGER_UVDM_RECEIVE_MESSAGE); | |
3855 | ||
3856 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
3857 | ||
3858 | if (power_role == USBPD_SOURCE) | |
3859 | return PE_SRC_Ready; | |
3860 | else | |
3861 | return PE_SNK_Ready; | |
3862 | } | |
3863 | ||
40798a41 JB |
3864 | policy_state usbpd_policy_dr_src_get_source_cap(struct policy_data *policy) |
3865 | { | |
3866 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3867 | int ret = PE_DR_SRC_Get_Source_Cap; | |
3868 | int data_role = 0; | |
3869 | int ms = 0; | |
3870 | ||
3871 | /********************************************** | |
3872 | get source capabilities request from Device Policy Manager | |
3873 | ||
3874 | Actions on entry: | |
3875 | Send Get_Source_Cap message | |
3876 | Initialize and run SenderResponseTimer | |
3877 | **********************************************/ | |
3878 | ||
3879 | /* 1) PD State Inform to AP */ | |
3880 | dev_info(pd_data->dev, "%s\n", __func__); | |
3881 | ||
3882 | /* 2) Read Data Role */ | |
3883 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
3884 | ||
3885 | /* 3) Send Message */ | |
3886 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, USBPD_Get_Source_Cap, data_role, USBPD_SOURCE); | |
3887 | ||
3888 | /* 4) Start Timer */ | |
3889 | usbpd_timer1_start(pd_data); | |
3890 | ||
3891 | /* 5) Wait Message or State */ | |
3892 | while (1) { | |
3893 | if (policy->plug_valid == 0) { | |
3894 | ret = PE_DR_SRC_Get_Source_Cap; | |
3895 | break; | |
3896 | } | |
3897 | ms = usbpd_check_time1(pd_data); | |
3898 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
3899 | ret = PE_SRC_Send_Soft_Reset; | |
3900 | break; | |
3901 | } | |
3902 | ||
3903 | if (pd_data->phy_ops.get_status(pd_data, MSG_SRC_CAP)) { | |
3904 | ret = PE_SRC_Ready; | |
3905 | break; | |
3906 | } | |
3907 | ||
3908 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) { | |
3909 | ret = PE_SRC_Ready; | |
3910 | break; | |
3911 | } | |
3912 | ||
3913 | /* TimeOver Check */ | |
3914 | if (ms >= tSenderResponse) { | |
3915 | ret = PE_SRC_Ready; | |
3916 | break; | |
3917 | } | |
3918 | } | |
3919 | ||
3920 | /********************************************** | |
3921 | Actions on exit: | |
3922 | Pass source capabilities/outcome to Device Policy Manager | |
3923 | ||
3924 | Source capabilities message received | |
3925 | | SenderResponseTimer Timeout | Reject message received | |
3926 | **********************************************/ | |
3927 | ||
3928 | return ret; | |
3929 | } | |
3930 | ||
3931 | policy_state usbpd_policy_dr_src_give_sink_cap(struct policy_data *policy) | |
3932 | { | |
3933 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3934 | int data_role = 0; | |
3935 | int ret = PE_DR_SRC_Give_Sink_Cap; | |
3936 | int ms = 0; | |
3937 | ||
3938 | /********************************************** | |
3939 | Actions on entry: | |
3940 | Get present sink capabilities from Device Policy Manager | |
3941 | Send Capabilities message (based on Device Policy Manager response) | |
3942 | **********************************************/ | |
3943 | ||
3944 | /* 1) PD State Inform to AP */ | |
3945 | dev_info(pd_data->dev, "%s\n", __func__); | |
3946 | ||
3947 | /* 2) Read Data Role */ | |
3948 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
3949 | ||
3950 | /* 3) Sink Cap Message Setting */ | |
3951 | policy->tx_msg_header.word = pd_data->sink_msg_header.word; | |
3952 | policy->tx_msg_header.port_data_role = data_role; | |
3953 | policy->tx_data_obj[0].object = pd_data->sink_data_obj[0].object; | |
3954 | policy->tx_data_obj[1].object = pd_data->sink_data_obj[1].object; | |
3955 | ||
3956 | /* 4) Send Message */ | |
3957 | usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj); | |
3958 | ||
3959 | /* 5) Start Timer */ | |
3960 | usbpd_timer1_start(pd_data); | |
3961 | ||
3962 | /* 6) Wait Message or State */ | |
3963 | while (1) { | |
3964 | if (policy->plug_valid == 0) { | |
3965 | ret = PE_DR_SRC_Give_Sink_Cap; | |
3966 | break; | |
3967 | } | |
3968 | ms = usbpd_check_time1(pd_data); | |
3969 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
3970 | dev_info(pd_data->dev, "got dr_src_give_sink_cap MSG_GOODCRC.\n"); | |
3971 | ret = PE_SRC_Ready; | |
3972 | break; | |
3973 | } | |
3974 | ||
3975 | if (ms >= 5) { | |
3976 | ret = PE_SRC_Send_Soft_Reset; | |
3977 | dev_info(pd_data->dev, "got dr_src_give_sink_cap Timer1_overflag.\n"); | |
3978 | break; | |
3979 | } | |
3980 | } | |
3981 | ||
3982 | /* 8) Sink Capabilities message sent */ | |
3983 | return ret; | |
3984 | } | |
3985 | ||
3986 | policy_state usbpd_policy_dr_snk_get_sink_cap(struct policy_data *policy) | |
3987 | { | |
3988 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
3989 | int ret = PE_DR_SNK_Get_Sink_Cap; | |
3990 | int data_role = 0; | |
3991 | int ms = 0; | |
3992 | ||
3993 | /********************************************** | |
3994 | get sink capabilities request from Device Policy Manager | |
3995 | ||
3996 | Actions on entry: | |
3997 | Send Get_Sink_Cap message | |
3998 | Initialize and run | |
3999 | SenderResponseTimer | |
4000 | **********************************************/ | |
4001 | ||
4002 | /* 1) PD State Inform to AP */ | |
4003 | dev_info(pd_data->dev, "%s\n", __func__); | |
4004 | ||
4005 | /* 2) Read Data Role */ | |
4006 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
4007 | ||
4008 | /* 3) Send Message */ | |
4009 | usbpd_send_ctrl_msg(pd_data, &policy->tx_msg_header, | |
4010 | USBPD_Get_Sink_Cap, data_role, USBPD_SINK); | |
4011 | ||
4012 | /* 4) Start Timer */ | |
4013 | usbpd_timer1_start(pd_data); | |
4014 | ||
4015 | /* 5) Wait Message or State */ | |
4016 | while (1) { | |
4017 | if (policy->plug_valid == 0) { | |
4018 | ret = PE_DR_SNK_Get_Sink_Cap; | |
4019 | break; | |
4020 | } | |
4021 | ms = usbpd_check_time1(pd_data); | |
4022 | if (pd_data->phy_ops.get_status(pd_data, MSG_ERROR)) { | |
4023 | ret = PE_SNK_Send_Soft_Reset; | |
4024 | break; | |
4025 | } | |
4026 | ||
4027 | if (pd_data->phy_ops.get_status(pd_data, MSG_SNK_CAP)) { | |
4028 | ret = PE_SNK_Ready; | |
4029 | break; | |
4030 | } | |
4031 | ||
4032 | if (pd_data->phy_ops.get_status(pd_data, MSG_REJECT)) { | |
4033 | ret = PE_SNK_Ready; | |
4034 | break; | |
4035 | } | |
4036 | ||
4037 | /* TimeOver Check */ | |
4038 | if (ms >= tSenderResponse) { | |
4039 | ret = PE_SNK_Ready; | |
4040 | break; | |
4041 | } | |
4042 | } | |
4043 | ||
4044 | /********************************************** | |
4045 | Actions on exit: | |
4046 | Pass sink capabilities/outcome to | |
4047 | Device Policy Manager | |
4048 | ||
4049 | Sink capabilities message received | |
4050 | | SenderResponseTimer Timeout | Reject message received | |
4051 | **********************************************/ | |
4052 | ||
4053 | return ret; | |
4054 | } | |
4055 | ||
4056 | policy_state usbpd_policy_dr_snk_give_source_cap(struct policy_data *policy) | |
4057 | { | |
4058 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
4059 | int ret = PE_DR_SNK_Give_Source_Cap; | |
4060 | int data_role = 0; | |
4061 | int ms = 0; | |
4062 | /********************************************** | |
4063 | Actions on entry: | |
4064 | Request source capabilities from | |
4065 | Device Policy Manager | |
4066 | Send Capabilities message | |
4067 | **********************************************/ | |
4068 | ||
4069 | /* 1) PD State Inform to AP */ | |
4070 | dev_info(pd_data->dev, "%s\n", __func__); | |
4071 | ||
40798a41 JB |
4072 | if (!pd_data->id_matched) |
4073 | return PE_SNK_Ready; | |
4074 | ||
4075 | #if 0 | |
4076 | /* 2) Message ID Check and Ignored */ | |
4077 | if (pd_data->phy_ops.compare_message_id(pd_data) != 0) { | |
4078 | dev_info(pd_data->dev, "After compare_message_id not Match move to PE_SNK_Ready.\n"); | |
4079 | return PE_SNK_Ready; | |
4080 | } else { | |
4081 | dev_info(pd_data->dev, "After compare_message_id Match move to PE_SNK_Ready.\n"); | |
4082 | } | |
4083 | #endif | |
4084 | ||
4085 | /* 3) Read Data Role */ | |
4086 | pd_data->phy_ops.get_data_role(pd_data, &data_role); | |
4087 | ||
4088 | /* 4) Message Setting */ | |
4089 | policy->tx_msg_header.msg_type = USBPD_Source_Capabilities; | |
4090 | policy->tx_msg_header.port_data_role = data_role; | |
4091 | policy->tx_msg_header.port_power_role = USBPD_SINK; | |
4092 | policy->tx_msg_header.num_data_objs = 1; | |
4093 | ||
4094 | policy->tx_data_obj[0].power_data_obj.max_current = 1500 / 10; | |
4095 | policy->tx_data_obj[0].power_data_obj.voltage = 5000 / 50; | |
4096 | policy->tx_data_obj[0].power_data_obj.peak_current = 0; | |
4097 | policy->tx_data_obj[0].power_data_obj.rsvd = 0; | |
4098 | policy->tx_data_obj[0].power_data_obj.data_role_swap = 1; | |
4099 | policy->tx_data_obj[0].power_data_obj.usb_comm_capable = 1; | |
4100 | policy->tx_data_obj[0].power_data_obj.externally_powered = 0; | |
4101 | policy->tx_data_obj[0].power_data_obj.usb_suspend_support = 1; | |
4102 | policy->tx_data_obj[0].power_data_obj.dual_role_power = 1; | |
4103 | policy->tx_data_obj[0].power_data_obj.supply = 0; | |
4104 | ||
4105 | /* 5) Send Message */ | |
4106 | usbpd_send_msg(pd_data, &policy->tx_msg_header, policy->tx_data_obj); | |
4107 | ||
4108 | /* 6) Start Timer */ | |
4109 | usbpd_timer1_start(pd_data); | |
4110 | ||
4111 | /* 7) Wait Message or State */ | |
4112 | while (1) { | |
4113 | if (policy->plug_valid == 0) | |
4114 | break; | |
4115 | ms = usbpd_check_time1(pd_data); | |
4116 | if (pd_data->phy_ops.get_status(pd_data, MSG_GOODCRC)) { | |
4117 | ret = PE_SNK_Ready; | |
4118 | break; | |
4119 | } | |
4120 | ||
4121 | if (ms >= 5) { | |
4122 | ret = PE_SNK_Send_Soft_Reset; | |
4123 | break; | |
4124 | } | |
4125 | } | |
4126 | ||
4127 | return ret; | |
4128 | } | |
4129 | #if 1 //JETSEO | |
4130 | policy_state usbpd_policy_bist_receive_mode(struct policy_data *policy) | |
4131 | { | |
4132 | ||
4133 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
4134 | int ret = PE_BIST_Receive_Mode; | |
4135 | ||
4136 | /********************************************** | |
4137 | Actions on entry: | |
4138 | Tell Protocol Layer to go to BIST | |
4139 | Receive Mode | |
4140 | **********************************************/ | |
4141 | ||
4142 | /* 1) PD State Inform to AP */ | |
4143 | dev_info(pd_data->dev, "%s\n", __func__); | |
4144 | ||
4145 | /* 2) Interrupt Status All Mask */ | |
4146 | ||
4147 | /********************************************** | |
4148 | Actions on exit: | |
4149 | Goto bist frame received state | |
4150 | or Hard Reset signaling received | |
4151 | **********************************************/ | |
4152 | ret = PE_BIST_Frame_Received; | |
4153 | ||
4154 | return ret; | |
4155 | ||
4156 | } | |
4157 | ||
4158 | policy_state usbpd_policy_bist_frame_received(struct policy_data *policy) | |
4159 | { | |
4160 | ||
4161 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
4162 | int ret = PE_BIST_Frame_Received; | |
4163 | ||
4164 | /********************************************** | |
4165 | Actions on entry: | |
4166 | Consume Frame | |
4167 | **********************************************/ | |
4168 | ||
4169 | /* 1) PD State Inform to AP */ | |
4170 | dev_info(pd_data->dev, "%s\n", __func__); | |
4171 | ||
4172 | /********************************************** | |
4173 | Actions on exit: | |
4174 | Detach | |
4175 | or Hard Reset signaling received | |
4176 | **********************************************/ | |
4177 | ||
4178 | return ret; | |
4179 | ||
4180 | } | |
4181 | #endif | |
5073353a JB |
4182 | policy_state usbpd_error_recovery(struct policy_data *policy) |
4183 | { | |
4184 | struct usbpd_data *pd_data = policy_to_usbpd(policy); | |
4185 | ||
40798a41 JB |
4186 | /********************************************** |
4187 | **********************************************/ | |
4188 | ||
5073353a JB |
4189 | dev_err(pd_data->dev, "%s\n", __func__); |
4190 | ||
4191 | return Error_Recovery; | |
4192 | } | |
4193 | ||
4194 | void usbpd_policy_work(struct work_struct *work) | |
4195 | { | |
4196 | struct usbpd_data *pd_data = container_of(work, struct usbpd_data, | |
4197 | worker); | |
4198 | struct policy_data *policy = &pd_data->policy; | |
4199 | int power_role = 0; | |
4200 | policy_state next_state = policy->state; | |
4201 | policy_state saved_state; | |
4202 | ||
4203 | do { | |
4204 | if (!policy->plug_valid) { | |
4205 | pr_info("%s : usbpd cable is empty\n", __func__); | |
4206 | break; | |
4207 | } | |
4208 | ||
4209 | if (policy->rx_hardreset || policy->rx_softreset | |
4210 | || policy->plug) { | |
4211 | saved_state = 0; | |
4212 | next_state = 0; /* default */ | |
4213 | } | |
4214 | saved_state = next_state; | |
4215 | switch (next_state) { | |
4216 | case PE_SRC_Startup: | |
4217 | next_state = usbpd_policy_src_startup(policy); | |
40798a41 | 4218 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4219 | break; |
4220 | case PE_SRC_Discovery: | |
4221 | next_state = usbpd_policy_src_discovery(policy); | |
4222 | break; | |
4223 | case PE_SRC_Send_Capabilities: | |
4224 | next_state = usbpd_policy_src_send_capabilities(policy); | |
4225 | break; | |
4226 | case PE_SRC_Negotiate_Capability: | |
4227 | next_state = usbpd_policy_src_negotiate_capability(policy); | |
4228 | break; | |
4229 | case PE_SRC_Transition_Supply: | |
4230 | next_state = usbpd_policy_src_transition_supply(policy); | |
4231 | break; | |
4232 | case PE_SRC_Ready: | |
4233 | next_state = usbpd_policy_src_ready(policy); | |
40798a41 | 4234 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4235 | break; |
4236 | case PE_SRC_Disabled: | |
4237 | next_state = usbpd_policy_src_disabled(policy); | |
40798a41 | 4238 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4239 | break; |
4240 | case PE_SRC_Capability_Response: | |
4241 | next_state = usbpd_policy_src_capability_response(policy); | |
4242 | break; | |
4243 | case PE_SRC_Hard_Reset: | |
4244 | next_state = usbpd_policy_src_hard_reset(policy); | |
40798a41 | 4245 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4246 | break; |
4247 | case PE_SRC_Hard_Reset_Received: | |
4248 | next_state = usbpd_policy_src_hard_reset_received(policy); | |
40798a41 | 4249 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4250 | break; |
4251 | case PE_SRC_Transition_to_default: | |
4252 | next_state = usbpd_policy_src_transition_to_default(policy); | |
4253 | break; | |
4254 | case PE_SRC_Give_Source_Cap: | |
4255 | next_state = usbpd_policy_src_give_source_cap(policy); | |
4256 | break; | |
4257 | case PE_SRC_Get_Sink_Cap: | |
4258 | next_state = usbpd_policy_src_get_sink_cap(policy); | |
4259 | break; | |
4260 | case PE_SRC_Wait_New_Capabilities: | |
4261 | next_state = usbpd_policy_src_wait_new_capabilities(policy); | |
4262 | break; | |
4263 | case PE_SRC_Send_Soft_Reset: | |
4264 | next_state = usbpd_policy_src_send_soft_reset(policy); | |
4265 | break; | |
4266 | case PE_SRC_Soft_Reset: | |
4267 | next_state = usbpd_policy_src_soft_reset(policy); | |
40798a41 | 4268 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4269 | break; |
4270 | ||
4271 | case PE_SNK_Startup: | |
4272 | next_state = usbpd_policy_snk_startup(policy); | |
40798a41 | 4273 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4274 | break; |
4275 | case PE_SNK_Discovery: | |
4276 | next_state = usbpd_policy_snk_discovery(policy); | |
4277 | break; | |
4278 | case PE_SNK_Wait_for_Capabilities: | |
4279 | next_state = usbpd_policy_snk_wait_for_capabilities(policy); | |
4280 | break; | |
4281 | case PE_SNK_Evaluate_Capability: | |
4282 | next_state = usbpd_policy_snk_evaluate_capability(policy); | |
4283 | break; | |
4284 | case PE_SNK_Select_Capability: | |
4285 | next_state = usbpd_policy_snk_select_capability(policy); | |
4286 | break; | |
4287 | case PE_SNK_Transition_Sink: | |
4288 | next_state = usbpd_policy_snk_transition_sink(policy); | |
4289 | break; | |
4290 | case PE_SNK_Ready: | |
4291 | next_state = usbpd_policy_snk_ready(policy); | |
40798a41 | 4292 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4293 | break; |
4294 | case PE_SNK_Hard_Reset: | |
4295 | next_state = usbpd_policy_snk_hard_reset(policy); | |
40798a41 | 4296 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4297 | break; |
4298 | case PE_SNK_Transition_to_default: | |
4299 | next_state = usbpd_policy_snk_transition_to_default(policy); | |
40798a41 | 4300 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4301 | break; |
4302 | case PE_SNK_Give_Sink_Cap: | |
4303 | next_state = usbpd_policy_snk_give_sink_cap(policy); | |
4304 | break; | |
4305 | case PE_SNK_Get_Source_Cap: | |
4306 | next_state = usbpd_policy_snk_get_source_cap(policy); | |
4307 | break; | |
40798a41 JB |
4308 | case PE_SNK_Send_Soft_Reset: |
4309 | next_state = usbpd_policy_snk_send_soft_reset(policy); | |
4310 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); | |
4311 | break; | |
5073353a JB |
4312 | case PE_SNK_Soft_Reset: |
4313 | next_state = usbpd_policy_snk_soft_reset(policy); | |
40798a41 | 4314 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a | 4315 | break; |
5073353a JB |
4316 | case PE_DRS_Evaluate_Port: |
4317 | next_state = usbpd_policy_drs_evaluate_port(policy); | |
4318 | break; | |
4319 | case PE_DRS_Evaluate_Send_Port: | |
4320 | next_state = usbpd_policy_drs_evaluate_send_port(policy); | |
4321 | break; | |
4322 | case PE_DRS_DFP_UFP_Evaluate_DR_Swap: | |
4323 | next_state = usbpd_policy_drs_dfp_ufp_evaluate_dr_swap(policy); | |
4324 | break; | |
4325 | case PE_DRS_DFP_UFP_Accept_DR_Swap: | |
4326 | next_state = usbpd_policy_drs_dfp_ufp_accept_dr_swap(policy); | |
40798a41 | 4327 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4328 | break; |
4329 | case PE_DRS_DFP_UFP_Change_to_UFP: | |
4330 | next_state = usbpd_policy_drs_dfp_ufp_change_to_ufp(policy); | |
4331 | break; | |
4332 | case PE_DRS_DFP_UFP_Send_DR_Swap: | |
4333 | next_state = usbpd_policy_drs_dfp_ufp_send_dr_swap(policy); | |
40798a41 | 4334 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4335 | break; |
4336 | case PE_DRS_DFP_UFP_Reject_DR_Swap: | |
4337 | next_state = usbpd_policy_drs_dfp_ufp_reject_dr_swap(policy); | |
4338 | break; | |
4339 | case PE_DRS_UFP_DFP_Evaluate_DR_Swap: | |
4340 | next_state = usbpd_policy_drs_ufp_dfp_evaluate_dr_swap(policy); | |
4341 | break; | |
4342 | case PE_DRS_UFP_DFP_Accept_DR_Swap: | |
4343 | next_state = usbpd_policy_drs_ufp_dfp_accept_dr_swap(policy); | |
40798a41 | 4344 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4345 | break; |
4346 | case PE_DRS_UFP_DFP_Change_to_DFP: | |
4347 | next_state = usbpd_policy_drs_ufp_dfp_change_to_dfp(policy); | |
4348 | break; | |
4349 | case PE_DRS_UFP_DFP_Send_DR_Swap: | |
4350 | next_state = usbpd_policy_drs_ufp_dfp_send_dr_swap(policy); | |
40798a41 | 4351 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4352 | break; |
4353 | case PE_DRS_UFP_DFP_Reject_DR_Swap: | |
4354 | next_state = usbpd_policy_drs_ufp_dfp_reject_dr_swap(policy); | |
4355 | break; | |
4356 | ||
4357 | case PE_PRS_SRC_SNK_Reject_PR_Swap: | |
4358 | next_state = usbpd_policy_prs_src_snk_reject_pr_swap(policy); | |
4359 | break; | |
4360 | case PE_PRS_SRC_SNK_Evaluate_Swap: | |
4361 | next_state = usbpd_policy_prs_src_snk_evaluate_swap(policy); | |
4362 | break; | |
4363 | case PE_PRS_SRC_SNK_Send_Swap: | |
4364 | next_state = usbpd_policy_prs_src_snk_send_swap(policy); | |
40798a41 | 4365 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4366 | break; |
4367 | case PE_PRS_SRC_SNK_Accept_Swap: | |
4368 | next_state = usbpd_policy_prs_src_snk_accept_swap(policy); | |
40798a41 | 4369 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4370 | break; |
4371 | case PE_PRS_SRC_SNK_Transition_off: | |
4372 | next_state = usbpd_policy_prs_src_snk_transition_to_off(policy); | |
4373 | break; | |
4374 | case PE_PRS_SRC_SNK_Assert_Rd: | |
4375 | next_state = usbpd_policy_prs_src_snk_assert_rd(policy); | |
4376 | break; | |
4377 | case PE_PRS_SRC_SNK_Wait_Source_on: | |
4378 | next_state = usbpd_policy_prs_src_snk_wait_source_on(policy); | |
4379 | break; | |
4380 | case PE_PRS_SNK_SRC_Reject_Swap: | |
4381 | next_state = usbpd_policy_prs_snk_src_reject_swap(policy); | |
4382 | break; | |
4383 | case PE_PRS_SNK_SRC_Evaluate_Swap: | |
4384 | next_state = usbpd_policy_prs_snk_src_evaluate_swap(policy); | |
4385 | break; | |
4386 | case PE_PRS_SNK_SRC_Send_Swap: | |
4387 | next_state = usbpd_policy_prs_snk_src_send_swap(policy); | |
40798a41 | 4388 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4389 | break; |
4390 | case PE_PRS_SNK_SRC_Accept_Swap: | |
4391 | next_state = usbpd_policy_prs_snk_src_accept_swap(policy); | |
40798a41 | 4392 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4393 | break; |
4394 | case PE_PRS_SNK_SRC_Transition_off: | |
4395 | next_state = usbpd_policy_prs_snk_src_transition_to_off(policy); | |
4396 | break; | |
4397 | case PE_PRS_SNK_SRC_Assert_Rp: | |
4398 | next_state = usbpd_policy_prs_snk_src_assert_rp(policy); | |
4399 | break; | |
4400 | case PE_PRS_SNK_SRC_Source_on: | |
4401 | next_state = usbpd_policy_prs_snk_src_source_on(policy); | |
4402 | break; | |
4403 | case PE_VCS_Evaluate_Swap: | |
4404 | next_state = usbpd_policy_vcs_evaluate_swap(policy); | |
4405 | break; | |
4406 | case PE_VCS_Accept_Swap: | |
4407 | next_state = usbpd_policy_vcs_accept_swap(policy); | |
4408 | break; | |
4409 | case PE_VCS_Wait_for_VCONN: | |
4410 | next_state = usbpd_policy_vcs_wait_for_vconn(policy); | |
4411 | break; | |
4412 | case PE_VCS_Turn_Off_VCONN: | |
4413 | next_state = usbpd_policy_vcs_turn_off_vconn(policy); | |
4414 | break; | |
4415 | case PE_VCS_Turn_On_VCONN: | |
4416 | next_state = usbpd_policy_vcs_turn_on_vconn(policy); | |
4417 | break; | |
4418 | case PE_VCS_Send_PS_RDY: | |
4419 | next_state = usbpd_policy_vcs_send_ps_rdy(policy); | |
4420 | break; | |
4421 | case PE_VCS_Send_Swap: | |
4422 | next_state = usbpd_policy_vcs_send_swap(policy); | |
4423 | break; | |
4424 | case PE_VCS_Reject_VCONN_Swap: | |
4425 | next_state = usbpd_policy_vcs_reject_vconn_swap(policy); | |
4426 | break; | |
4427 | ||
4428 | case PE_UFP_VDM_Get_Identity: | |
4429 | next_state = usbpd_policy_ufp_vdm_get_identity(policy); | |
4430 | break; | |
4431 | case PE_UFP_VDM_Send_Identity: | |
4432 | next_state = usbpd_policy_ufp_vdm_send_identity(policy); | |
4433 | break; | |
4434 | case PE_UFP_VDM_Get_Identity_NAK: | |
4435 | next_state = usbpd_policy_ufp_vdm_get_identity_nak(policy); | |
4436 | break; | |
4437 | case PE_UFP_VDM_Get_SVIDs: | |
4438 | next_state = usbpd_policy_ufp_vdm_get_svids(policy); | |
4439 | break; | |
4440 | case PE_UFP_VDM_Send_SVIDs: | |
4441 | next_state = usbpd_policy_ufp_vdm_send_svids(policy); | |
4442 | break; | |
4443 | case PE_UFP_VDM_Get_SVIDs_NAK: | |
4444 | next_state = usbpd_policy_ufp_vdm_get_svids_nak(policy); | |
4445 | break; | |
4446 | case PE_UFP_VDM_Get_Modes: | |
4447 | next_state = usbpd_policy_ufp_vdm_get_modes(policy); | |
4448 | break; | |
4449 | case PE_UFP_VDM_Send_Modes: | |
4450 | next_state = usbpd_policy_ufp_vdm_send_modes(policy); | |
4451 | break; | |
4452 | case PE_UFP_VDM_Get_Modes_NAK: | |
4453 | next_state = usbpd_policy_ufp_vdm_get_modes_nak(policy); | |
4454 | break; | |
4455 | case PE_UFP_VDM_Evaluate_Mode_Entry: | |
4456 | next_state = usbpd_policy_ufp_vdm_evaluate_mode_entry(policy); | |
4457 | break; | |
4458 | case PE_UFP_VDM_Mode_Entry_ACK: | |
4459 | next_state = usbpd_policy_ufp_vdm_mode_entry_ack(policy); | |
4460 | break; | |
4461 | case PE_UFP_VDM_Mode_Entry_NAK: | |
4462 | next_state = usbpd_policy_ufp_vdm_mode_entry_nak(policy); | |
4463 | break; | |
4464 | case PE_UFP_VDM_Mode_Exit: | |
4465 | next_state = usbpd_policy_ufp_vdm_mode_exit(policy); | |
4466 | break; | |
4467 | case PE_UFP_VDM_Mode_Exit_ACK: | |
4468 | next_state = usbpd_policy_ufp_vdm_mode_exit_ack(policy); | |
4469 | break; | |
4470 | case PE_UFP_VDM_Mode_Exit_NAK: | |
4471 | next_state = usbpd_policy_ufp_vdm_mode_exit_nak(policy); | |
4472 | break; | |
4473 | case PE_UFP_VDM_Attention_Request: | |
4474 | next_state = usbpd_policy_ufp_vdm_attention_request(policy); | |
4475 | break; | |
4476 | case PE_UFP_VDM_Evaluate_Status: | |
4477 | next_state = usbpd_policy_ufp_vdm_evaluate_status(policy); | |
4478 | break; | |
4479 | case PE_UFP_VDM_Status_ACK: | |
4480 | next_state = usbpd_policy_ufp_vdm_status_ack(policy); | |
4481 | break; | |
4482 | case PE_UFP_VDM_Status_NAK: | |
4483 | next_state = usbpd_policy_ufp_vdm_status_nak(policy); | |
4484 | break; | |
4485 | case PE_UFP_VDM_Evaluate_Configure: | |
4486 | next_state = usbpd_policy_ufp_vdm_evaluate_configure(policy); | |
4487 | break; | |
4488 | case PE_UFP_VDM_Configure_ACK: | |
4489 | next_state = usbpd_policy_ufp_vdm_configure_ack(policy); | |
4490 | break; | |
4491 | case PE_UFP_VDM_Configure_NAK: | |
4492 | next_state = usbpd_policy_ufp_vdm_configure_nak(policy); | |
4493 | break; | |
4494 | case PE_DFP_VDM_Identity_Request: | |
4495 | next_state = usbpd_policy_dfp_vdm_identity_request(policy); | |
4496 | break; | |
4497 | case PE_DFP_VDM_Identity_ACKed: | |
4498 | next_state = usbpd_policy_dfp_vdm_identity_acked(policy); | |
4499 | break; | |
4500 | case PE_DFP_VDM_Identity_NAKed: | |
4501 | next_state = usbpd_policy_dfp_vdm_identity_naked(policy); | |
4502 | break; | |
4503 | case PE_DFP_VDM_SVIDs_Request: | |
4504 | next_state = usbpd_policy_dfp_vdm_svids_request(policy); | |
4505 | break; | |
4506 | case PE_DFP_VDM_SVIDs_ACKed: | |
4507 | next_state = usbpd_policy_dfp_vdm_svids_acked(policy); | |
4508 | break; | |
4509 | case PE_DFP_VDM_SVIDs_NAKed: | |
4510 | next_state = usbpd_policy_dfp_vdm_svids_naked(policy); | |
4511 | break; | |
4512 | case PE_DFP_VDM_Modes_Request: | |
4513 | next_state = usbpd_policy_dfp_vdm_modes_request(policy); | |
4514 | break; | |
4515 | case PE_DFP_VDM_Modes_ACKed: | |
4516 | next_state = usbpd_policy_dfp_vdm_modes_acked(policy); | |
4517 | break; | |
4518 | case PE_DFP_VDM_Modes_NAKed: | |
4519 | next_state = usbpd_policy_dfp_vdm_modes_naked(policy); | |
4520 | break; | |
4521 | case PE_DFP_VDM_Mode_Entry_Request: | |
4522 | next_state = usbpd_policy_dfp_vdm_entry_request(policy); | |
4523 | break; | |
4524 | case PE_DFP_VDM_Mode_Entry_ACKed: | |
4525 | next_state = usbpd_policy_dfp_vdm_entry_acked(policy); | |
4526 | break; | |
4527 | case PE_DFP_VDM_Mode_Entry_NAKed: | |
4528 | next_state = usbpd_policy_dfp_vdm_entry_naked(policy); | |
4529 | break; | |
4530 | case PE_DFP_VDM_Mode_Exit_Request: | |
4531 | next_state = usbpd_policy_dfp_vdm_exit_request(policy); | |
4532 | break; | |
4533 | case PE_DFP_VDM_Mode_Exit_ACKed: | |
4534 | next_state = usbpd_policy_dfp_vdm_exit_acked(policy); | |
4535 | break; | |
4536 | case PE_DFP_VDM_Mode_Exit_NAKed: | |
4537 | next_state = usbpd_policy_dfp_vdm_exit_naked(policy); | |
4538 | break; | |
4539 | case PE_DFP_VDM_Attention_Request: | |
4540 | next_state = usbpd_policy_dfp_vdm_attention_request(policy); | |
4541 | break; | |
4542 | case PE_DFP_VDM_Status_Update: | |
4543 | next_state = usbpd_policy_dfp_vdm_status_update(policy); | |
4544 | break; | |
4545 | case PE_DFP_VDM_Status_Update_ACKed: | |
4546 | next_state = usbpd_policy_dfp_vdm_status_update_acked(policy); | |
4547 | break; | |
4548 | case PE_DFP_VDM_Status_Update_NAKed: | |
4549 | next_state = usbpd_policy_dfp_vdm_status_update_naked(policy); | |
4550 | break; | |
4551 | case PE_DFP_VDM_DisplayPort_Configure: | |
4552 | next_state = usbpd_policy_dfp_vdm_displayport_configure(policy); | |
4553 | break; | |
4554 | case PE_DFP_VDM_DisplayPort_Configure_ACKed: | |
4555 | next_state = usbpd_policy_dfp_vdm_displayport_configure_acked(policy); | |
4556 | break; | |
4557 | case PE_DFP_VDM_DisplayPort_Configure_NAKed: | |
4558 | next_state = usbpd_policy_dfp_vdm_displayport_configure_naked(policy); | |
4559 | break; | |
4560 | case PE_DFP_UVDM_Send_Message: | |
4561 | next_state = usbpd_policy_dfp_uvdm_send_message(policy); | |
4562 | break; | |
4563 | case PE_DFP_UVDM_Receive_Message: | |
4564 | next_state = usbpd_policy_dfp_uvdm_receive_message(policy); | |
4565 | break; | |
40798a41 JB |
4566 | case PE_DR_SRC_Get_Source_Cap: |
4567 | next_state = usbpd_policy_dr_src_get_source_cap(policy); | |
4568 | break; | |
4569 | case PE_DR_SRC_Give_Sink_Cap: | |
4570 | next_state = usbpd_policy_dr_src_give_sink_cap(policy); | |
4571 | break; | |
4572 | case PE_DR_SNK_Get_Sink_Cap: | |
4573 | next_state = usbpd_policy_dr_snk_get_sink_cap(policy); | |
4574 | break; | |
4575 | case PE_DR_SNK_Give_Source_Cap: | |
4576 | next_state = usbpd_policy_dr_snk_give_source_cap(policy); | |
4577 | break; | |
4578 | #if 1 //JETSEO | |
4579 | case PE_BIST_Receive_Mode: | |
4580 | next_state = usbpd_policy_bist_receive_mode(policy); | |
4581 | break; | |
4582 | case PE_BIST_Frame_Received: | |
4583 | next_state = usbpd_policy_bist_frame_received(policy); | |
4584 | break; | |
4585 | #endif | |
5073353a JB |
4586 | case Error_Recovery: |
4587 | next_state = usbpd_error_recovery(policy); | |
40798a41 | 4588 | store_usblog_notify(NOTIFY_FUNCSTATE, (void *)&next_state, NULL); |
5073353a JB |
4589 | break; |
4590 | ||
4591 | default: | |
4592 | pd_data->phy_ops.get_power_role(pd_data, &power_role); | |
4593 | pr_info("%s, %d\n", __func__, power_role); | |
4594 | ||
4595 | if (power_role == USBPD_SINK) { | |
4596 | pr_info("%s, SINK\n", __func__); | |
4597 | if (policy->rx_hardreset) { | |
4598 | policy->rx_hardreset = 0; | |
4599 | next_state = PE_SNK_Transition_to_default; | |
4600 | } else if (policy->rx_softreset) { | |
4601 | policy->rx_softreset = 0; | |
4602 | next_state = PE_SNK_Soft_Reset; | |
4603 | } else if (policy->plug) { | |
4604 | policy->plug = 0; | |
4605 | next_state = PE_SNK_Startup; | |
4606 | } else { | |
4607 | next_state = PE_SNK_Startup; | |
4608 | } | |
4609 | } else { | |
4610 | pr_info("%s, SOURCE\n", __func__); | |
4611 | if (policy->rx_hardreset) { | |
4612 | policy->rx_hardreset = 0; | |
4613 | next_state = PE_SRC_Hard_Reset_Received; | |
4614 | } else if (policy->rx_softreset) { | |
4615 | policy->rx_softreset = 0; | |
4616 | next_state = PE_SRC_Soft_Reset; | |
4617 | } else if (policy->plug) { | |
4618 | policy->plug = 0; | |
4619 | next_state = PE_SRC_Startup; | |
4620 | } else { | |
4621 | next_state = PE_SRC_Startup; | |
4622 | } | |
4623 | } | |
40798a41 | 4624 | |
5073353a JB |
4625 | break; |
4626 | } | |
4627 | dev_info(pd_data->dev, "%s saved state %x next_state %x \n", __func__, saved_state, next_state); | |
4628 | } while (saved_state != next_state); | |
4629 | ||
4630 | policy->state = next_state; | |
4631 | dev_info(pd_data->dev, "%s Finished\n", __func__); | |
4632 | } | |
4633 | ||
4634 | void usbpd_init_policy(struct usbpd_data *pd_data) | |
4635 | { | |
4636 | int i; | |
4637 | struct policy_data *policy = &pd_data->policy; | |
4638 | ||
4639 | policy->state = 0; | |
4640 | policy->rx_hardreset = 0; | |
4641 | policy->rx_softreset = 0; | |
4642 | policy->plug = 0; | |
4643 | policy->rx_msg_header.word = 0; | |
4644 | policy->tx_msg_header.word = 0; | |
4645 | policy->modal_operation = 0; | |
4646 | policy->sink_cap_received = 0; | |
4647 | policy->send_sink_cap = 0; | |
40798a41 JB |
4648 | policy->txhardresetflag = 0; |
4649 | policy->pd_support = 0; | |
5073353a JB |
4650 | for (i = 0; i < USBPD_MAX_COUNT_MSG_OBJECT; i++) { |
4651 | policy->rx_data_obj[i].object = 0; | |
4652 | policy->tx_data_obj[i].object = 0; | |
4653 | } | |
4654 | } | |
4655 | ||
4656 | void usbpd_kick_policy_work(struct device *dev) | |
4657 | { | |
4658 | struct usbpd_data *pd_data = dev_get_drvdata(dev); | |
4659 | ||
40798a41 JB |
4660 | if (pd_data->policy_wqueue) |
4661 | queue_work(pd_data->policy_wqueue, &pd_data->worker); | |
4662 | else | |
4663 | schedule_work(&pd_data->worker); | |
5073353a JB |
4664 | } |
4665 | ||
40798a41 JB |
4666 | void usbpd_cancel_policy_work(struct device *dev) |
4667 | { | |
4668 | struct usbpd_data *pd_data = dev_get_drvdata(dev); | |
4669 | ||
4670 | if (pd_data->policy_wqueue) | |
4671 | flush_workqueue(pd_data->policy_wqueue); | |
4672 | } |