Commit 1dfa91aa5ba9650acf59b6310d8e78a162d56410
Committed by
Greg Kroah-Hartman
1 parent
f4cbd33fd5
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
usb: common: rename phy-fsm-usb.c to usb-otg-fsm.c
Since usb otg fsm implementation is not related to usb phy. We move it from usb/phy/ to usb/common/, and rename it to reflect its real meaning. Cc: Felipe Balbi <balbi@ti.com> Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 6 changed files with 377 additions and 377 deletions Side-by-side Diff
drivers/usb/common/Makefile
drivers/usb/common/usb-otg-fsm.c
1 | +/* | |
2 | + * OTG Finite State Machine from OTG spec | |
3 | + * | |
4 | + * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. | |
5 | + * | |
6 | + * Author: Li Yang <LeoLi@freescale.com> | |
7 | + * Jerry Huang <Chang-Ming.Huang@freescale.com> | |
8 | + * | |
9 | + * This program is free software; you can redistribute it and/or modify it | |
10 | + * under the terms of the GNU General Public License as published by the | |
11 | + * Free Software Foundation; either version 2 of the License, or (at your | |
12 | + * option) any later version. | |
13 | + * | |
14 | + * This program is distributed in the hope that it will be useful, but | |
15 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | + * General Public License for more details. | |
18 | + * | |
19 | + * You should have received a copy of the GNU General Public License along | |
20 | + * with this program; if not, write to the Free Software Foundation, Inc., | |
21 | + * 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 | + */ | |
23 | + | |
24 | +#include <linux/kernel.h> | |
25 | +#include <linux/types.h> | |
26 | +#include <linux/mutex.h> | |
27 | +#include <linux/delay.h> | |
28 | +#include <linux/usb.h> | |
29 | +#include <linux/usb/gadget.h> | |
30 | +#include <linux/usb/otg.h> | |
31 | +#include <linux/usb/otg-fsm.h> | |
32 | + | |
33 | +/* Change USB protocol when there is a protocol change */ | |
34 | +static int otg_set_protocol(struct otg_fsm *fsm, int protocol) | |
35 | +{ | |
36 | + int ret = 0; | |
37 | + | |
38 | + if (fsm->protocol != protocol) { | |
39 | + VDBG("Changing role fsm->protocol= %d; new protocol= %d\n", | |
40 | + fsm->protocol, protocol); | |
41 | + /* stop old protocol */ | |
42 | + if (fsm->protocol == PROTO_HOST) | |
43 | + ret = otg_start_host(fsm, 0); | |
44 | + else if (fsm->protocol == PROTO_GADGET) | |
45 | + ret = otg_start_gadget(fsm, 0); | |
46 | + if (ret) | |
47 | + return ret; | |
48 | + | |
49 | + /* start new protocol */ | |
50 | + if (protocol == PROTO_HOST) | |
51 | + ret = otg_start_host(fsm, 1); | |
52 | + else if (protocol == PROTO_GADGET) | |
53 | + ret = otg_start_gadget(fsm, 1); | |
54 | + if (ret) | |
55 | + return ret; | |
56 | + | |
57 | + fsm->protocol = protocol; | |
58 | + return 0; | |
59 | + } | |
60 | + | |
61 | + return 0; | |
62 | +} | |
63 | + | |
64 | +static int state_changed; | |
65 | + | |
66 | +/* Called when leaving a state. Do state clean up jobs here */ | |
67 | +static void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) | |
68 | +{ | |
69 | + switch (old_state) { | |
70 | + case OTG_STATE_B_IDLE: | |
71 | + otg_del_timer(fsm, B_SE0_SRP); | |
72 | + fsm->b_se0_srp = 0; | |
73 | + fsm->adp_sns = 0; | |
74 | + fsm->adp_prb = 0; | |
75 | + break; | |
76 | + case OTG_STATE_B_SRP_INIT: | |
77 | + fsm->data_pulse = 0; | |
78 | + fsm->b_srp_done = 0; | |
79 | + break; | |
80 | + case OTG_STATE_B_PERIPHERAL: | |
81 | + break; | |
82 | + case OTG_STATE_B_WAIT_ACON: | |
83 | + otg_del_timer(fsm, B_ASE0_BRST); | |
84 | + fsm->b_ase0_brst_tmout = 0; | |
85 | + break; | |
86 | + case OTG_STATE_B_HOST: | |
87 | + break; | |
88 | + case OTG_STATE_A_IDLE: | |
89 | + fsm->adp_prb = 0; | |
90 | + break; | |
91 | + case OTG_STATE_A_WAIT_VRISE: | |
92 | + otg_del_timer(fsm, A_WAIT_VRISE); | |
93 | + fsm->a_wait_vrise_tmout = 0; | |
94 | + break; | |
95 | + case OTG_STATE_A_WAIT_BCON: | |
96 | + otg_del_timer(fsm, A_WAIT_BCON); | |
97 | + fsm->a_wait_bcon_tmout = 0; | |
98 | + break; | |
99 | + case OTG_STATE_A_HOST: | |
100 | + otg_del_timer(fsm, A_WAIT_ENUM); | |
101 | + break; | |
102 | + case OTG_STATE_A_SUSPEND: | |
103 | + otg_del_timer(fsm, A_AIDL_BDIS); | |
104 | + fsm->a_aidl_bdis_tmout = 0; | |
105 | + fsm->a_suspend_req_inf = 0; | |
106 | + break; | |
107 | + case OTG_STATE_A_PERIPHERAL: | |
108 | + otg_del_timer(fsm, A_BIDL_ADIS); | |
109 | + fsm->a_bidl_adis_tmout = 0; | |
110 | + break; | |
111 | + case OTG_STATE_A_WAIT_VFALL: | |
112 | + otg_del_timer(fsm, A_WAIT_VFALL); | |
113 | + fsm->a_wait_vfall_tmout = 0; | |
114 | + otg_del_timer(fsm, A_WAIT_VRISE); | |
115 | + break; | |
116 | + case OTG_STATE_A_VBUS_ERR: | |
117 | + break; | |
118 | + default: | |
119 | + break; | |
120 | + } | |
121 | +} | |
122 | + | |
123 | +/* Called when entering a state */ | |
124 | +static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) | |
125 | +{ | |
126 | + state_changed = 1; | |
127 | + if (fsm->otg->phy->state == new_state) | |
128 | + return 0; | |
129 | + VDBG("Set state: %s\n", usb_otg_state_string(new_state)); | |
130 | + otg_leave_state(fsm, fsm->otg->phy->state); | |
131 | + switch (new_state) { | |
132 | + case OTG_STATE_B_IDLE: | |
133 | + otg_drv_vbus(fsm, 0); | |
134 | + otg_chrg_vbus(fsm, 0); | |
135 | + otg_loc_conn(fsm, 0); | |
136 | + otg_loc_sof(fsm, 0); | |
137 | + /* | |
138 | + * Driver is responsible for starting ADP probing | |
139 | + * if ADP sensing times out. | |
140 | + */ | |
141 | + otg_start_adp_sns(fsm); | |
142 | + otg_set_protocol(fsm, PROTO_UNDEF); | |
143 | + otg_add_timer(fsm, B_SE0_SRP); | |
144 | + break; | |
145 | + case OTG_STATE_B_SRP_INIT: | |
146 | + otg_start_pulse(fsm); | |
147 | + otg_loc_sof(fsm, 0); | |
148 | + otg_set_protocol(fsm, PROTO_UNDEF); | |
149 | + otg_add_timer(fsm, B_SRP_FAIL); | |
150 | + break; | |
151 | + case OTG_STATE_B_PERIPHERAL: | |
152 | + otg_chrg_vbus(fsm, 0); | |
153 | + otg_loc_conn(fsm, 1); | |
154 | + otg_loc_sof(fsm, 0); | |
155 | + otg_set_protocol(fsm, PROTO_GADGET); | |
156 | + break; | |
157 | + case OTG_STATE_B_WAIT_ACON: | |
158 | + otg_chrg_vbus(fsm, 0); | |
159 | + otg_loc_conn(fsm, 0); | |
160 | + otg_loc_sof(fsm, 0); | |
161 | + otg_set_protocol(fsm, PROTO_HOST); | |
162 | + otg_add_timer(fsm, B_ASE0_BRST); | |
163 | + fsm->a_bus_suspend = 0; | |
164 | + break; | |
165 | + case OTG_STATE_B_HOST: | |
166 | + otg_chrg_vbus(fsm, 0); | |
167 | + otg_loc_conn(fsm, 0); | |
168 | + otg_loc_sof(fsm, 1); | |
169 | + otg_set_protocol(fsm, PROTO_HOST); | |
170 | + usb_bus_start_enum(fsm->otg->host, | |
171 | + fsm->otg->host->otg_port); | |
172 | + break; | |
173 | + case OTG_STATE_A_IDLE: | |
174 | + otg_drv_vbus(fsm, 0); | |
175 | + otg_chrg_vbus(fsm, 0); | |
176 | + otg_loc_conn(fsm, 0); | |
177 | + otg_loc_sof(fsm, 0); | |
178 | + otg_start_adp_prb(fsm); | |
179 | + otg_set_protocol(fsm, PROTO_HOST); | |
180 | + break; | |
181 | + case OTG_STATE_A_WAIT_VRISE: | |
182 | + otg_drv_vbus(fsm, 1); | |
183 | + otg_loc_conn(fsm, 0); | |
184 | + otg_loc_sof(fsm, 0); | |
185 | + otg_set_protocol(fsm, PROTO_HOST); | |
186 | + otg_add_timer(fsm, A_WAIT_VRISE); | |
187 | + break; | |
188 | + case OTG_STATE_A_WAIT_BCON: | |
189 | + otg_drv_vbus(fsm, 1); | |
190 | + otg_loc_conn(fsm, 0); | |
191 | + otg_loc_sof(fsm, 0); | |
192 | + otg_set_protocol(fsm, PROTO_HOST); | |
193 | + otg_add_timer(fsm, A_WAIT_BCON); | |
194 | + break; | |
195 | + case OTG_STATE_A_HOST: | |
196 | + otg_drv_vbus(fsm, 1); | |
197 | + otg_loc_conn(fsm, 0); | |
198 | + otg_loc_sof(fsm, 1); | |
199 | + otg_set_protocol(fsm, PROTO_HOST); | |
200 | + /* | |
201 | + * When HNP is triggered while a_bus_req = 0, a_host will | |
202 | + * suspend too fast to complete a_set_b_hnp_en | |
203 | + */ | |
204 | + if (!fsm->a_bus_req || fsm->a_suspend_req_inf) | |
205 | + otg_add_timer(fsm, A_WAIT_ENUM); | |
206 | + break; | |
207 | + case OTG_STATE_A_SUSPEND: | |
208 | + otg_drv_vbus(fsm, 1); | |
209 | + otg_loc_conn(fsm, 0); | |
210 | + otg_loc_sof(fsm, 0); | |
211 | + otg_set_protocol(fsm, PROTO_HOST); | |
212 | + otg_add_timer(fsm, A_AIDL_BDIS); | |
213 | + | |
214 | + break; | |
215 | + case OTG_STATE_A_PERIPHERAL: | |
216 | + otg_loc_conn(fsm, 1); | |
217 | + otg_loc_sof(fsm, 0); | |
218 | + otg_set_protocol(fsm, PROTO_GADGET); | |
219 | + otg_drv_vbus(fsm, 1); | |
220 | + otg_add_timer(fsm, A_BIDL_ADIS); | |
221 | + break; | |
222 | + case OTG_STATE_A_WAIT_VFALL: | |
223 | + otg_drv_vbus(fsm, 0); | |
224 | + otg_loc_conn(fsm, 0); | |
225 | + otg_loc_sof(fsm, 0); | |
226 | + otg_set_protocol(fsm, PROTO_HOST); | |
227 | + otg_add_timer(fsm, A_WAIT_VFALL); | |
228 | + break; | |
229 | + case OTG_STATE_A_VBUS_ERR: | |
230 | + otg_drv_vbus(fsm, 0); | |
231 | + otg_loc_conn(fsm, 0); | |
232 | + otg_loc_sof(fsm, 0); | |
233 | + otg_set_protocol(fsm, PROTO_UNDEF); | |
234 | + break; | |
235 | + default: | |
236 | + break; | |
237 | + } | |
238 | + | |
239 | + fsm->otg->phy->state = new_state; | |
240 | + return 0; | |
241 | +} | |
242 | + | |
243 | +/* State change judgement */ | |
244 | +int otg_statemachine(struct otg_fsm *fsm) | |
245 | +{ | |
246 | + enum usb_otg_state state; | |
247 | + | |
248 | + mutex_lock(&fsm->lock); | |
249 | + | |
250 | + state = fsm->otg->phy->state; | |
251 | + state_changed = 0; | |
252 | + /* State machine state change judgement */ | |
253 | + | |
254 | + switch (state) { | |
255 | + case OTG_STATE_UNDEFINED: | |
256 | + VDBG("fsm->id = %d\n", fsm->id); | |
257 | + if (fsm->id) | |
258 | + otg_set_state(fsm, OTG_STATE_B_IDLE); | |
259 | + else | |
260 | + otg_set_state(fsm, OTG_STATE_A_IDLE); | |
261 | + break; | |
262 | + case OTG_STATE_B_IDLE: | |
263 | + if (!fsm->id) | |
264 | + otg_set_state(fsm, OTG_STATE_A_IDLE); | |
265 | + else if (fsm->b_sess_vld && fsm->otg->gadget) | |
266 | + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); | |
267 | + else if ((fsm->b_bus_req || fsm->adp_change || fsm->power_up) && | |
268 | + fsm->b_ssend_srp && fsm->b_se0_srp) | |
269 | + otg_set_state(fsm, OTG_STATE_B_SRP_INIT); | |
270 | + break; | |
271 | + case OTG_STATE_B_SRP_INIT: | |
272 | + if (!fsm->id || fsm->b_srp_done) | |
273 | + otg_set_state(fsm, OTG_STATE_B_IDLE); | |
274 | + break; | |
275 | + case OTG_STATE_B_PERIPHERAL: | |
276 | + if (!fsm->id || !fsm->b_sess_vld) | |
277 | + otg_set_state(fsm, OTG_STATE_B_IDLE); | |
278 | + else if (fsm->b_bus_req && fsm->otg-> | |
279 | + gadget->b_hnp_enable && fsm->a_bus_suspend) | |
280 | + otg_set_state(fsm, OTG_STATE_B_WAIT_ACON); | |
281 | + break; | |
282 | + case OTG_STATE_B_WAIT_ACON: | |
283 | + if (fsm->a_conn) | |
284 | + otg_set_state(fsm, OTG_STATE_B_HOST); | |
285 | + else if (!fsm->id || !fsm->b_sess_vld) | |
286 | + otg_set_state(fsm, OTG_STATE_B_IDLE); | |
287 | + else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) { | |
288 | + fsm->b_ase0_brst_tmout = 0; | |
289 | + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); | |
290 | + } | |
291 | + break; | |
292 | + case OTG_STATE_B_HOST: | |
293 | + if (!fsm->id || !fsm->b_sess_vld) | |
294 | + otg_set_state(fsm, OTG_STATE_B_IDLE); | |
295 | + else if (!fsm->b_bus_req || !fsm->a_conn || fsm->test_device) | |
296 | + otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); | |
297 | + break; | |
298 | + case OTG_STATE_A_IDLE: | |
299 | + if (fsm->id) | |
300 | + otg_set_state(fsm, OTG_STATE_B_IDLE); | |
301 | + else if (!fsm->a_bus_drop && (fsm->a_bus_req || | |
302 | + fsm->a_srp_det || fsm->adp_change || fsm->power_up)) | |
303 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); | |
304 | + break; | |
305 | + case OTG_STATE_A_WAIT_VRISE: | |
306 | + if (fsm->a_vbus_vld) | |
307 | + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
308 | + else if (fsm->id || fsm->a_bus_drop || | |
309 | + fsm->a_wait_vrise_tmout) | |
310 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
311 | + break; | |
312 | + case OTG_STATE_A_WAIT_BCON: | |
313 | + if (!fsm->a_vbus_vld) | |
314 | + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
315 | + else if (fsm->b_conn) | |
316 | + otg_set_state(fsm, OTG_STATE_A_HOST); | |
317 | + else if (fsm->id || fsm->a_bus_drop || fsm->a_wait_bcon_tmout) | |
318 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
319 | + break; | |
320 | + case OTG_STATE_A_HOST: | |
321 | + if (fsm->id || fsm->a_bus_drop) | |
322 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
323 | + else if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) && | |
324 | + fsm->otg->host->b_hnp_enable) | |
325 | + otg_set_state(fsm, OTG_STATE_A_SUSPEND); | |
326 | + else if (!fsm->b_conn) | |
327 | + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
328 | + else if (!fsm->a_vbus_vld) | |
329 | + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
330 | + break; | |
331 | + case OTG_STATE_A_SUSPEND: | |
332 | + if (!fsm->b_conn && fsm->otg->host->b_hnp_enable) | |
333 | + otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); | |
334 | + else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable) | |
335 | + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
336 | + else if (fsm->a_bus_req || fsm->b_bus_resume) | |
337 | + otg_set_state(fsm, OTG_STATE_A_HOST); | |
338 | + else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout) | |
339 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
340 | + else if (!fsm->a_vbus_vld) | |
341 | + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
342 | + break; | |
343 | + case OTG_STATE_A_PERIPHERAL: | |
344 | + if (fsm->id || fsm->a_bus_drop) | |
345 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
346 | + else if (fsm->a_bidl_adis_tmout || fsm->b_bus_suspend) | |
347 | + otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
348 | + else if (!fsm->a_vbus_vld) | |
349 | + otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
350 | + break; | |
351 | + case OTG_STATE_A_WAIT_VFALL: | |
352 | + if (fsm->a_wait_vfall_tmout) | |
353 | + otg_set_state(fsm, OTG_STATE_A_IDLE); | |
354 | + break; | |
355 | + case OTG_STATE_A_VBUS_ERR: | |
356 | + if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err) | |
357 | + otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
358 | + break; | |
359 | + default: | |
360 | + break; | |
361 | + } | |
362 | + mutex_unlock(&fsm->lock); | |
363 | + | |
364 | + VDBG("quit statemachine, changed = %d\n", state_changed); | |
365 | + return state_changed; | |
366 | +} | |
367 | +EXPORT_SYMBOL_GPL(otg_statemachine); |
drivers/usb/core/Kconfig
... | ... | @@ -80,4 +80,13 @@ |
80 | 80 | external hubs. OTG hosts are allowed to reduce hardware |
81 | 81 | and software costs by not supporting external hubs. So |
82 | 82 | are "Embedded Hosts" that don't offer OTG support. |
83 | + | |
84 | +config USB_OTG_FSM | |
85 | + tristate "USB 2.0 OTG FSM implementation" | |
86 | + depends on USB | |
87 | + select USB_OTG | |
88 | + select USB_PHY | |
89 | + help | |
90 | + Implements OTG Finite State Machine as specified in On-The-Go | |
91 | + and Embedded Host Supplement to the USB Revision 2.0 Specification. |
drivers/usb/phy/Kconfig
... | ... | @@ -6,15 +6,6 @@ |
6 | 6 | config USB_PHY |
7 | 7 | def_bool n |
8 | 8 | |
9 | -config USB_OTG_FSM | |
10 | - tristate "USB 2.0 OTG FSM implementation" | |
11 | - depends on USB | |
12 | - select USB_OTG | |
13 | - select USB_PHY | |
14 | - help | |
15 | - Implements OTG Final State Machine as specified in On-The-Go | |
16 | - and Embedded Host Supplement to the USB Revision 2.0 Specification. | |
17 | - | |
18 | 9 | # |
19 | 10 | # USB Transceiver Drivers |
20 | 11 | # |
drivers/usb/phy/Makefile
drivers/usb/phy/phy-fsm-usb.c
1 | -/* | |
2 | - * OTG Finite State Machine from OTG spec | |
3 | - * | |
4 | - * Copyright (C) 2007,2008 Freescale Semiconductor, Inc. | |
5 | - * | |
6 | - * Author: Li Yang <LeoLi@freescale.com> | |
7 | - * Jerry Huang <Chang-Ming.Huang@freescale.com> | |
8 | - * | |
9 | - * This program is free software; you can redistribute it and/or modify it | |
10 | - * under the terms of the GNU General Public License as published by the | |
11 | - * Free Software Foundation; either version 2 of the License, or (at your | |
12 | - * option) any later version. | |
13 | - * | |
14 | - * This program is distributed in the hope that it will be useful, but | |
15 | - * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | - * General Public License for more details. | |
18 | - * | |
19 | - * You should have received a copy of the GNU General Public License along | |
20 | - * with this program; if not, write to the Free Software Foundation, Inc., | |
21 | - * 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 | - */ | |
23 | - | |
24 | -#include <linux/kernel.h> | |
25 | -#include <linux/types.h> | |
26 | -#include <linux/mutex.h> | |
27 | -#include <linux/delay.h> | |
28 | -#include <linux/usb.h> | |
29 | -#include <linux/usb/gadget.h> | |
30 | -#include <linux/usb/otg.h> | |
31 | -#include <linux/usb/otg-fsm.h> | |
32 | - | |
33 | -/* Change USB protocol when there is a protocol change */ | |
34 | -static int otg_set_protocol(struct otg_fsm *fsm, int protocol) | |
35 | -{ | |
36 | - int ret = 0; | |
37 | - | |
38 | - if (fsm->protocol != protocol) { | |
39 | - VDBG("Changing role fsm->protocol= %d; new protocol= %d\n", | |
40 | - fsm->protocol, protocol); | |
41 | - /* stop old protocol */ | |
42 | - if (fsm->protocol == PROTO_HOST) | |
43 | - ret = otg_start_host(fsm, 0); | |
44 | - else if (fsm->protocol == PROTO_GADGET) | |
45 | - ret = otg_start_gadget(fsm, 0); | |
46 | - if (ret) | |
47 | - return ret; | |
48 | - | |
49 | - /* start new protocol */ | |
50 | - if (protocol == PROTO_HOST) | |
51 | - ret = otg_start_host(fsm, 1); | |
52 | - else if (protocol == PROTO_GADGET) | |
53 | - ret = otg_start_gadget(fsm, 1); | |
54 | - if (ret) | |
55 | - return ret; | |
56 | - | |
57 | - fsm->protocol = protocol; | |
58 | - return 0; | |
59 | - } | |
60 | - | |
61 | - return 0; | |
62 | -} | |
63 | - | |
64 | -static int state_changed; | |
65 | - | |
66 | -/* Called when leaving a state. Do state clean up jobs here */ | |
67 | -static void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state) | |
68 | -{ | |
69 | - switch (old_state) { | |
70 | - case OTG_STATE_B_IDLE: | |
71 | - otg_del_timer(fsm, B_SE0_SRP); | |
72 | - fsm->b_se0_srp = 0; | |
73 | - fsm->adp_sns = 0; | |
74 | - fsm->adp_prb = 0; | |
75 | - break; | |
76 | - case OTG_STATE_B_SRP_INIT: | |
77 | - fsm->data_pulse = 0; | |
78 | - fsm->b_srp_done = 0; | |
79 | - break; | |
80 | - case OTG_STATE_B_PERIPHERAL: | |
81 | - break; | |
82 | - case OTG_STATE_B_WAIT_ACON: | |
83 | - otg_del_timer(fsm, B_ASE0_BRST); | |
84 | - fsm->b_ase0_brst_tmout = 0; | |
85 | - break; | |
86 | - case OTG_STATE_B_HOST: | |
87 | - break; | |
88 | - case OTG_STATE_A_IDLE: | |
89 | - fsm->adp_prb = 0; | |
90 | - break; | |
91 | - case OTG_STATE_A_WAIT_VRISE: | |
92 | - otg_del_timer(fsm, A_WAIT_VRISE); | |
93 | - fsm->a_wait_vrise_tmout = 0; | |
94 | - break; | |
95 | - case OTG_STATE_A_WAIT_BCON: | |
96 | - otg_del_timer(fsm, A_WAIT_BCON); | |
97 | - fsm->a_wait_bcon_tmout = 0; | |
98 | - break; | |
99 | - case OTG_STATE_A_HOST: | |
100 | - otg_del_timer(fsm, A_WAIT_ENUM); | |
101 | - break; | |
102 | - case OTG_STATE_A_SUSPEND: | |
103 | - otg_del_timer(fsm, A_AIDL_BDIS); | |
104 | - fsm->a_aidl_bdis_tmout = 0; | |
105 | - fsm->a_suspend_req_inf = 0; | |
106 | - break; | |
107 | - case OTG_STATE_A_PERIPHERAL: | |
108 | - otg_del_timer(fsm, A_BIDL_ADIS); | |
109 | - fsm->a_bidl_adis_tmout = 0; | |
110 | - break; | |
111 | - case OTG_STATE_A_WAIT_VFALL: | |
112 | - otg_del_timer(fsm, A_WAIT_VFALL); | |
113 | - fsm->a_wait_vfall_tmout = 0; | |
114 | - otg_del_timer(fsm, A_WAIT_VRISE); | |
115 | - break; | |
116 | - case OTG_STATE_A_VBUS_ERR: | |
117 | - break; | |
118 | - default: | |
119 | - break; | |
120 | - } | |
121 | -} | |
122 | - | |
123 | -/* Called when entering a state */ | |
124 | -static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state) | |
125 | -{ | |
126 | - state_changed = 1; | |
127 | - if (fsm->otg->phy->state == new_state) | |
128 | - return 0; | |
129 | - VDBG("Set state: %s\n", usb_otg_state_string(new_state)); | |
130 | - otg_leave_state(fsm, fsm->otg->phy->state); | |
131 | - switch (new_state) { | |
132 | - case OTG_STATE_B_IDLE: | |
133 | - otg_drv_vbus(fsm, 0); | |
134 | - otg_chrg_vbus(fsm, 0); | |
135 | - otg_loc_conn(fsm, 0); | |
136 | - otg_loc_sof(fsm, 0); | |
137 | - /* | |
138 | - * Driver is responsible for starting ADP probing | |
139 | - * if ADP sensing times out. | |
140 | - */ | |
141 | - otg_start_adp_sns(fsm); | |
142 | - otg_set_protocol(fsm, PROTO_UNDEF); | |
143 | - otg_add_timer(fsm, B_SE0_SRP); | |
144 | - break; | |
145 | - case OTG_STATE_B_SRP_INIT: | |
146 | - otg_start_pulse(fsm); | |
147 | - otg_loc_sof(fsm, 0); | |
148 | - otg_set_protocol(fsm, PROTO_UNDEF); | |
149 | - otg_add_timer(fsm, B_SRP_FAIL); | |
150 | - break; | |
151 | - case OTG_STATE_B_PERIPHERAL: | |
152 | - otg_chrg_vbus(fsm, 0); | |
153 | - otg_loc_conn(fsm, 1); | |
154 | - otg_loc_sof(fsm, 0); | |
155 | - otg_set_protocol(fsm, PROTO_GADGET); | |
156 | - break; | |
157 | - case OTG_STATE_B_WAIT_ACON: | |
158 | - otg_chrg_vbus(fsm, 0); | |
159 | - otg_loc_conn(fsm, 0); | |
160 | - otg_loc_sof(fsm, 0); | |
161 | - otg_set_protocol(fsm, PROTO_HOST); | |
162 | - otg_add_timer(fsm, B_ASE0_BRST); | |
163 | - fsm->a_bus_suspend = 0; | |
164 | - break; | |
165 | - case OTG_STATE_B_HOST: | |
166 | - otg_chrg_vbus(fsm, 0); | |
167 | - otg_loc_conn(fsm, 0); | |
168 | - otg_loc_sof(fsm, 1); | |
169 | - otg_set_protocol(fsm, PROTO_HOST); | |
170 | - usb_bus_start_enum(fsm->otg->host, | |
171 | - fsm->otg->host->otg_port); | |
172 | - break; | |
173 | - case OTG_STATE_A_IDLE: | |
174 | - otg_drv_vbus(fsm, 0); | |
175 | - otg_chrg_vbus(fsm, 0); | |
176 | - otg_loc_conn(fsm, 0); | |
177 | - otg_loc_sof(fsm, 0); | |
178 | - otg_start_adp_prb(fsm); | |
179 | - otg_set_protocol(fsm, PROTO_HOST); | |
180 | - break; | |
181 | - case OTG_STATE_A_WAIT_VRISE: | |
182 | - otg_drv_vbus(fsm, 1); | |
183 | - otg_loc_conn(fsm, 0); | |
184 | - otg_loc_sof(fsm, 0); | |
185 | - otg_set_protocol(fsm, PROTO_HOST); | |
186 | - otg_add_timer(fsm, A_WAIT_VRISE); | |
187 | - break; | |
188 | - case OTG_STATE_A_WAIT_BCON: | |
189 | - otg_drv_vbus(fsm, 1); | |
190 | - otg_loc_conn(fsm, 0); | |
191 | - otg_loc_sof(fsm, 0); | |
192 | - otg_set_protocol(fsm, PROTO_HOST); | |
193 | - otg_add_timer(fsm, A_WAIT_BCON); | |
194 | - break; | |
195 | - case OTG_STATE_A_HOST: | |
196 | - otg_drv_vbus(fsm, 1); | |
197 | - otg_loc_conn(fsm, 0); | |
198 | - otg_loc_sof(fsm, 1); | |
199 | - otg_set_protocol(fsm, PROTO_HOST); | |
200 | - /* | |
201 | - * When HNP is triggered while a_bus_req = 0, a_host will | |
202 | - * suspend too fast to complete a_set_b_hnp_en | |
203 | - */ | |
204 | - if (!fsm->a_bus_req || fsm->a_suspend_req_inf) | |
205 | - otg_add_timer(fsm, A_WAIT_ENUM); | |
206 | - break; | |
207 | - case OTG_STATE_A_SUSPEND: | |
208 | - otg_drv_vbus(fsm, 1); | |
209 | - otg_loc_conn(fsm, 0); | |
210 | - otg_loc_sof(fsm, 0); | |
211 | - otg_set_protocol(fsm, PROTO_HOST); | |
212 | - otg_add_timer(fsm, A_AIDL_BDIS); | |
213 | - | |
214 | - break; | |
215 | - case OTG_STATE_A_PERIPHERAL: | |
216 | - otg_loc_conn(fsm, 1); | |
217 | - otg_loc_sof(fsm, 0); | |
218 | - otg_set_protocol(fsm, PROTO_GADGET); | |
219 | - otg_drv_vbus(fsm, 1); | |
220 | - otg_add_timer(fsm, A_BIDL_ADIS); | |
221 | - break; | |
222 | - case OTG_STATE_A_WAIT_VFALL: | |
223 | - otg_drv_vbus(fsm, 0); | |
224 | - otg_loc_conn(fsm, 0); | |
225 | - otg_loc_sof(fsm, 0); | |
226 | - otg_set_protocol(fsm, PROTO_HOST); | |
227 | - otg_add_timer(fsm, A_WAIT_VFALL); | |
228 | - break; | |
229 | - case OTG_STATE_A_VBUS_ERR: | |
230 | - otg_drv_vbus(fsm, 0); | |
231 | - otg_loc_conn(fsm, 0); | |
232 | - otg_loc_sof(fsm, 0); | |
233 | - otg_set_protocol(fsm, PROTO_UNDEF); | |
234 | - break; | |
235 | - default: | |
236 | - break; | |
237 | - } | |
238 | - | |
239 | - fsm->otg->phy->state = new_state; | |
240 | - return 0; | |
241 | -} | |
242 | - | |
243 | -/* State change judgement */ | |
244 | -int otg_statemachine(struct otg_fsm *fsm) | |
245 | -{ | |
246 | - enum usb_otg_state state; | |
247 | - | |
248 | - mutex_lock(&fsm->lock); | |
249 | - | |
250 | - state = fsm->otg->phy->state; | |
251 | - state_changed = 0; | |
252 | - /* State machine state change judgement */ | |
253 | - | |
254 | - switch (state) { | |
255 | - case OTG_STATE_UNDEFINED: | |
256 | - VDBG("fsm->id = %d\n", fsm->id); | |
257 | - if (fsm->id) | |
258 | - otg_set_state(fsm, OTG_STATE_B_IDLE); | |
259 | - else | |
260 | - otg_set_state(fsm, OTG_STATE_A_IDLE); | |
261 | - break; | |
262 | - case OTG_STATE_B_IDLE: | |
263 | - if (!fsm->id) | |
264 | - otg_set_state(fsm, OTG_STATE_A_IDLE); | |
265 | - else if (fsm->b_sess_vld && fsm->otg->gadget) | |
266 | - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); | |
267 | - else if ((fsm->b_bus_req || fsm->adp_change || fsm->power_up) && | |
268 | - fsm->b_ssend_srp && fsm->b_se0_srp) | |
269 | - otg_set_state(fsm, OTG_STATE_B_SRP_INIT); | |
270 | - break; | |
271 | - case OTG_STATE_B_SRP_INIT: | |
272 | - if (!fsm->id || fsm->b_srp_done) | |
273 | - otg_set_state(fsm, OTG_STATE_B_IDLE); | |
274 | - break; | |
275 | - case OTG_STATE_B_PERIPHERAL: | |
276 | - if (!fsm->id || !fsm->b_sess_vld) | |
277 | - otg_set_state(fsm, OTG_STATE_B_IDLE); | |
278 | - else if (fsm->b_bus_req && fsm->otg-> | |
279 | - gadget->b_hnp_enable && fsm->a_bus_suspend) | |
280 | - otg_set_state(fsm, OTG_STATE_B_WAIT_ACON); | |
281 | - break; | |
282 | - case OTG_STATE_B_WAIT_ACON: | |
283 | - if (fsm->a_conn) | |
284 | - otg_set_state(fsm, OTG_STATE_B_HOST); | |
285 | - else if (!fsm->id || !fsm->b_sess_vld) | |
286 | - otg_set_state(fsm, OTG_STATE_B_IDLE); | |
287 | - else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) { | |
288 | - fsm->b_ase0_brst_tmout = 0; | |
289 | - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); | |
290 | - } | |
291 | - break; | |
292 | - case OTG_STATE_B_HOST: | |
293 | - if (!fsm->id || !fsm->b_sess_vld) | |
294 | - otg_set_state(fsm, OTG_STATE_B_IDLE); | |
295 | - else if (!fsm->b_bus_req || !fsm->a_conn || fsm->test_device) | |
296 | - otg_set_state(fsm, OTG_STATE_B_PERIPHERAL); | |
297 | - break; | |
298 | - case OTG_STATE_A_IDLE: | |
299 | - if (fsm->id) | |
300 | - otg_set_state(fsm, OTG_STATE_B_IDLE); | |
301 | - else if (!fsm->a_bus_drop && (fsm->a_bus_req || | |
302 | - fsm->a_srp_det || fsm->adp_change || fsm->power_up)) | |
303 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); | |
304 | - break; | |
305 | - case OTG_STATE_A_WAIT_VRISE: | |
306 | - if (fsm->a_vbus_vld) | |
307 | - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
308 | - else if (fsm->id || fsm->a_bus_drop || | |
309 | - fsm->a_wait_vrise_tmout) | |
310 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
311 | - break; | |
312 | - case OTG_STATE_A_WAIT_BCON: | |
313 | - if (!fsm->a_vbus_vld) | |
314 | - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
315 | - else if (fsm->b_conn) | |
316 | - otg_set_state(fsm, OTG_STATE_A_HOST); | |
317 | - else if (fsm->id || fsm->a_bus_drop || fsm->a_wait_bcon_tmout) | |
318 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
319 | - break; | |
320 | - case OTG_STATE_A_HOST: | |
321 | - if (fsm->id || fsm->a_bus_drop) | |
322 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
323 | - else if ((!fsm->a_bus_req || fsm->a_suspend_req_inf) && | |
324 | - fsm->otg->host->b_hnp_enable) | |
325 | - otg_set_state(fsm, OTG_STATE_A_SUSPEND); | |
326 | - else if (!fsm->b_conn) | |
327 | - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
328 | - else if (!fsm->a_vbus_vld) | |
329 | - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
330 | - break; | |
331 | - case OTG_STATE_A_SUSPEND: | |
332 | - if (!fsm->b_conn && fsm->otg->host->b_hnp_enable) | |
333 | - otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); | |
334 | - else if (!fsm->b_conn && !fsm->otg->host->b_hnp_enable) | |
335 | - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
336 | - else if (fsm->a_bus_req || fsm->b_bus_resume) | |
337 | - otg_set_state(fsm, OTG_STATE_A_HOST); | |
338 | - else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout) | |
339 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
340 | - else if (!fsm->a_vbus_vld) | |
341 | - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
342 | - break; | |
343 | - case OTG_STATE_A_PERIPHERAL: | |
344 | - if (fsm->id || fsm->a_bus_drop) | |
345 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
346 | - else if (fsm->a_bidl_adis_tmout || fsm->b_bus_suspend) | |
347 | - otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | |
348 | - else if (!fsm->a_vbus_vld) | |
349 | - otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | |
350 | - break; | |
351 | - case OTG_STATE_A_WAIT_VFALL: | |
352 | - if (fsm->a_wait_vfall_tmout) | |
353 | - otg_set_state(fsm, OTG_STATE_A_IDLE); | |
354 | - break; | |
355 | - case OTG_STATE_A_VBUS_ERR: | |
356 | - if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err) | |
357 | - otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | |
358 | - break; | |
359 | - default: | |
360 | - break; | |
361 | - } | |
362 | - mutex_unlock(&fsm->lock); | |
363 | - | |
364 | - VDBG("quit statemachine, changed = %d\n", state_changed); | |
365 | - return state_changed; | |
366 | -} | |
367 | -EXPORT_SYMBOL_GPL(otg_statemachine); |