Linux Audio

Check our new training course

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