Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.11-rc1 348 lines 9.7 kB view raw
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 "phy-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->otg->phy->state == new_state) 121 return 0; 122 VDBG("Set state: %s\n", usb_otg_state_string(new_state)); 123 otg_leave_state(fsm, fsm->otg->phy->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->otg->host, 159 fsm->otg->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->otg->phy->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->otg->phy->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->otg->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->otg-> 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->otg->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->otg->host->b_hnp_enable) 314 otg_set_state(fsm, OTG_STATE_A_PERIPHERAL); 315 else if (!fsm->b_conn && !fsm->otg->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}