blob: b0cc422f2ff9dca0c1feae364c48c9df581c3087 [file] [log] [blame]
Li Yang0807c502011-04-18 22:01:59 +02001/*
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/spinlock.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/types.h>
32
33#include "otg_fsm.h"
34
35/* Change USB protocol when there is a protocol change */
36static int otg_set_protocol(struct otg_fsm *fsm, int protocol)
37{
38 int ret = 0;
39
40 if (fsm->protocol != protocol) {
41 VDBG("Changing role fsm->protocol= %d; new protocol= %d\n",
42 fsm->protocol, protocol);
43 /* stop old protocol */
44 if (fsm->protocol == PROTO_HOST)
45 ret = fsm->ops->start_host(fsm, 0);
46 else if (fsm->protocol == PROTO_GADGET)
47 ret = fsm->ops->start_gadget(fsm, 0);
48 if (ret)
49 return ret;
50
51 /* start new protocol */
52 if (protocol == PROTO_HOST)
53 ret = fsm->ops->start_host(fsm, 1);
54 else if (protocol == PROTO_GADGET)
55 ret = fsm->ops->start_gadget(fsm, 1);
56 if (ret)
57 return ret;
58
59 fsm->protocol = protocol;
60 return 0;
61 }
62
63 return 0;
64}
65
66static int state_changed;
67
68/* Called when leaving a state. Do state clean up jobs here */
69void otg_leave_state(struct otg_fsm *fsm, enum usb_otg_state old_state)
70{
71 switch (old_state) {
72 case OTG_STATE_B_IDLE:
73 otg_del_timer(fsm, b_se0_srp_tmr);
74 fsm->b_se0_srp = 0;
75 break;
76 case OTG_STATE_B_SRP_INIT:
77 fsm->b_srp_done = 0;
78 break;
79 case OTG_STATE_B_PERIPHERAL:
80 break;
81 case OTG_STATE_B_WAIT_ACON:
82 otg_del_timer(fsm, b_ase0_brst_tmr);
83 fsm->b_ase0_brst_tmout = 0;
84 break;
85 case OTG_STATE_B_HOST:
86 break;
87 case OTG_STATE_A_IDLE:
88 break;
89 case OTG_STATE_A_WAIT_VRISE:
90 otg_del_timer(fsm, a_wait_vrise_tmr);
91 fsm->a_wait_vrise_tmout = 0;
92 break;
93 case OTG_STATE_A_WAIT_BCON:
94 otg_del_timer(fsm, a_wait_bcon_tmr);
95 fsm->a_wait_bcon_tmout = 0;
96 break;
97 case OTG_STATE_A_HOST:
98 otg_del_timer(fsm, a_wait_enum_tmr);
99 break;
100 case OTG_STATE_A_SUSPEND:
101 otg_del_timer(fsm, a_aidl_bdis_tmr);
102 fsm->a_aidl_bdis_tmout = 0;
103 fsm->a_suspend_req = 0;
104 break;
105 case OTG_STATE_A_PERIPHERAL:
106 break;
107 case OTG_STATE_A_WAIT_VFALL:
108 otg_del_timer(fsm, a_wait_vrise_tmr);
109 break;
110 case OTG_STATE_A_VBUS_ERR:
111 break;
112 default:
113 break;
114 }
115}
116
117/* Called when entering a state */
118int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
119{
120 state_changed = 1;
121 if (fsm->transceiver->state == new_state)
122 return 0;
123 VDBG("Set state: %s\n", otg_state_string(new_state));
124 otg_leave_state(fsm, fsm->transceiver->state);
125 switch (new_state) {
126 case OTG_STATE_B_IDLE:
127 otg_drv_vbus(fsm, 0);
128 otg_chrg_vbus(fsm, 0);
129 otg_loc_conn(fsm, 0);
130 otg_loc_sof(fsm, 0);
131 otg_set_protocol(fsm, PROTO_UNDEF);
132 otg_add_timer(fsm, b_se0_srp_tmr);
133 break;
134 case OTG_STATE_B_SRP_INIT:
135 otg_start_pulse(fsm);
136 otg_loc_sof(fsm, 0);
137 otg_set_protocol(fsm, PROTO_UNDEF);
138 otg_add_timer(fsm, b_srp_fail_tmr);
139 break;
140 case OTG_STATE_B_PERIPHERAL:
141 otg_chrg_vbus(fsm, 0);
142 otg_loc_conn(fsm, 1);
143 otg_loc_sof(fsm, 0);
144 otg_set_protocol(fsm, PROTO_GADGET);
145 break;
146 case OTG_STATE_B_WAIT_ACON:
147 otg_chrg_vbus(fsm, 0);
148 otg_loc_conn(fsm, 0);
149 otg_loc_sof(fsm, 0);
150 otg_set_protocol(fsm, PROTO_HOST);
151 otg_add_timer(fsm, b_ase0_brst_tmr);
152 fsm->a_bus_suspend = 0;
153 break;
154 case OTG_STATE_B_HOST:
155 otg_chrg_vbus(fsm, 0);
156 otg_loc_conn(fsm, 0);
157 otg_loc_sof(fsm, 1);
158 otg_set_protocol(fsm, PROTO_HOST);
159 usb_bus_start_enum(fsm->transceiver->host,
160 fsm->transceiver->host->otg_port);
161 break;
162 case OTG_STATE_A_IDLE:
163 otg_drv_vbus(fsm, 0);
164 otg_chrg_vbus(fsm, 0);
165 otg_loc_conn(fsm, 0);
166 otg_loc_sof(fsm, 0);
167 otg_set_protocol(fsm, PROTO_HOST);
168 break;
169 case OTG_STATE_A_WAIT_VRISE:
170 otg_drv_vbus(fsm, 1);
171 otg_loc_conn(fsm, 0);
172 otg_loc_sof(fsm, 0);
173 otg_set_protocol(fsm, PROTO_HOST);
174 otg_add_timer(fsm, a_wait_vrise_tmr);
175 break;
176 case OTG_STATE_A_WAIT_BCON:
177 otg_drv_vbus(fsm, 1);
178 otg_loc_conn(fsm, 0);
179 otg_loc_sof(fsm, 0);
180 otg_set_protocol(fsm, PROTO_HOST);
181 otg_add_timer(fsm, a_wait_bcon_tmr);
182 break;
183 case OTG_STATE_A_HOST:
184 otg_drv_vbus(fsm, 1);
185 otg_loc_conn(fsm, 0);
186 otg_loc_sof(fsm, 1);
187 otg_set_protocol(fsm, PROTO_HOST);
188 /*
189 * When HNP is triggered while a_bus_req = 0, a_host will
190 * suspend too fast to complete a_set_b_hnp_en
191 */
192 if (!fsm->a_bus_req || fsm->a_suspend_req)
193 otg_add_timer(fsm, a_wait_enum_tmr);
194 break;
195 case OTG_STATE_A_SUSPEND:
196 otg_drv_vbus(fsm, 1);
197 otg_loc_conn(fsm, 0);
198 otg_loc_sof(fsm, 0);
199 otg_set_protocol(fsm, PROTO_HOST);
200 otg_add_timer(fsm, a_aidl_bdis_tmr);
201
202 break;
203 case OTG_STATE_A_PERIPHERAL:
204 otg_loc_conn(fsm, 1);
205 otg_loc_sof(fsm, 0);
206 otg_set_protocol(fsm, PROTO_GADGET);
207 otg_drv_vbus(fsm, 1);
208 break;
209 case OTG_STATE_A_WAIT_VFALL:
210 otg_drv_vbus(fsm, 0);
211 otg_loc_conn(fsm, 0);
212 otg_loc_sof(fsm, 0);
213 otg_set_protocol(fsm, PROTO_HOST);
214 break;
215 case OTG_STATE_A_VBUS_ERR:
216 otg_drv_vbus(fsm, 0);
217 otg_loc_conn(fsm, 0);
218 otg_loc_sof(fsm, 0);
219 otg_set_protocol(fsm, PROTO_UNDEF);
220 break;
221 default:
222 break;
223 }
224
225 fsm->transceiver->state = new_state;
226 return 0;
227}
228
229/* State change judgement */
230int otg_statemachine(struct otg_fsm *fsm)
231{
232 enum usb_otg_state state;
233 unsigned long flags;
234
235 spin_lock_irqsave(&fsm->lock, flags);
236
237 state = fsm->transceiver->state;
238 state_changed = 0;
239 /* State machine state change judgement */
240
241 switch (state) {
242 case OTG_STATE_UNDEFINED:
243 VDBG("fsm->id = %d\n", fsm->id);
244 if (fsm->id)
245 otg_set_state(fsm, OTG_STATE_B_IDLE);
246 else
247 otg_set_state(fsm, OTG_STATE_A_IDLE);
248 break;
249 case OTG_STATE_B_IDLE:
250 if (!fsm->id)
251 otg_set_state(fsm, OTG_STATE_A_IDLE);
252 else if (fsm->b_sess_vld && fsm->transceiver->gadget)
253 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
254 else if (fsm->b_bus_req && fsm->b_sess_end && fsm->b_se0_srp)
255 otg_set_state(fsm, OTG_STATE_B_SRP_INIT);
256 break;
257 case OTG_STATE_B_SRP_INIT:
258 if (!fsm->id || fsm->b_srp_done)
259 otg_set_state(fsm, OTG_STATE_B_IDLE);
260 break;
261 case OTG_STATE_B_PERIPHERAL:
262 if (!fsm->id || !fsm->b_sess_vld)
263 otg_set_state(fsm, OTG_STATE_B_IDLE);
264 else if (fsm->b_bus_req && fsm->transceiver->
265 gadget->b_hnp_enable && fsm->a_bus_suspend)
266 otg_set_state(fsm, OTG_STATE_B_WAIT_ACON);
267 break;
268 case OTG_STATE_B_WAIT_ACON:
269 if (fsm->a_conn)
270 otg_set_state(fsm, OTG_STATE_B_HOST);
271 else if (!fsm->id || !fsm->b_sess_vld)
272 otg_set_state(fsm, OTG_STATE_B_IDLE);
273 else if (fsm->a_bus_resume || fsm->b_ase0_brst_tmout) {
274 fsm->b_ase0_brst_tmout = 0;
275 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
276 }
277 break;
278 case OTG_STATE_B_HOST:
279 if (!fsm->id || !fsm->b_sess_vld)
280 otg_set_state(fsm, OTG_STATE_B_IDLE);
281 else if (!fsm->b_bus_req || !fsm->a_conn)
282 otg_set_state(fsm, OTG_STATE_B_PERIPHERAL);
283 break;
284 case OTG_STATE_A_IDLE:
285 if (fsm->id)
286 otg_set_state(fsm, OTG_STATE_B_IDLE);
287 else if (!fsm->a_bus_drop && (fsm->a_bus_req || fsm->a_srp_det))
288 otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE);
289 break;
290 case OTG_STATE_A_WAIT_VRISE:
291 if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld ||
292 fsm->a_wait_vrise_tmout) {
293 otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
294 }
295 break;
296 case OTG_STATE_A_WAIT_BCON:
297 if (!fsm->a_vbus_vld)
298 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
299 else if (fsm->b_conn)
300 otg_set_state(fsm, OTG_STATE_A_HOST);
301 else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout)
302 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
303 break;
304 case OTG_STATE_A_HOST:
305 if ((!fsm->a_bus_req || fsm->a_suspend_req) &&
306 fsm->transceiver->host->b_hnp_enable)
307 otg_set_state(fsm, OTG_STATE_A_SUSPEND);
308 else if (fsm->id || !fsm->b_conn || fsm->a_bus_drop)
309 otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
310 else if (!fsm->a_vbus_vld)
311 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
312 break;
313 case OTG_STATE_A_SUSPEND:
314 if (!fsm->b_conn && fsm->transceiver->host->b_hnp_enable)
315 otg_set_state(fsm, OTG_STATE_A_PERIPHERAL);
316 else if (!fsm->b_conn && !fsm->transceiver->host->b_hnp_enable)
317 otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
318 else if (fsm->a_bus_req || fsm->b_bus_resume)
319 otg_set_state(fsm, OTG_STATE_A_HOST);
320 else if (fsm->id || fsm->a_bus_drop || fsm->a_aidl_bdis_tmout)
321 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
322 else if (!fsm->a_vbus_vld)
323 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
324 break;
325 case OTG_STATE_A_PERIPHERAL:
326 if (fsm->id || fsm->a_bus_drop)
327 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
328 else if (fsm->b_bus_suspend)
329 otg_set_state(fsm, OTG_STATE_A_WAIT_BCON);
330 else if (!fsm->a_vbus_vld)
331 otg_set_state(fsm, OTG_STATE_A_VBUS_ERR);
332 break;
333 case OTG_STATE_A_WAIT_VFALL:
334 if (fsm->id || fsm->a_bus_req || (!fsm->a_sess_vld &&
335 !fsm->b_conn))
336 otg_set_state(fsm, OTG_STATE_A_IDLE);
337 break;
338 case OTG_STATE_A_VBUS_ERR:
339 if (fsm->id || fsm->a_bus_drop || fsm->a_clr_err)
340 otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL);
341 break;
342 default:
343 break;
344 }
345 spin_unlock_irqrestore(&fsm->lock, flags);
346
347 VDBG("quit statemachine, changed = %d\n", state_changed);
348 return state_changed;
349}