otg-fsm.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /* Copyright (C) 2007,2008 Freescale Semiconductor, Inc.
  2. *
  3. * This program is free software; you can redistribute it and/or modify it
  4. * under the terms of the GNU General Public License as published by the
  5. * Free Software Foundation; either version 2 of the License, or (at your
  6. * option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along
  14. * with this program; if not, write to the Free Software Foundation, Inc.,
  15. * 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifndef __LINUX_USB_OTG_FSM_H
  18. #define __LINUX_USB_OTG_FSM_H
  19. #include <linux/mutex.h>
  20. #include <linux/errno.h>
  21. #define PROTO_UNDEF (0)
  22. #define PROTO_HOST (1)
  23. #define PROTO_GADGET (2)
  24. #define OTG_STS_SELECTOR 0xF000 /* OTG status selector, according to
  25. * OTG and EH 2.0 Chapter 6.2.3
  26. * Table:6-4
  27. */
  28. #define HOST_REQUEST_FLAG 1 /* Host request flag, according to
  29. * OTG and EH 2.0 Charpter 6.2.3
  30. * Table:6-5
  31. */
  32. #define T_HOST_REQ_POLL (1500) /* 1500ms, HNP polling interval */
  33. enum otg_fsm_timer {
  34. /* Standard OTG timers */
  35. A_WAIT_VRISE,
  36. A_WAIT_VFALL,
  37. A_WAIT_BCON,
  38. A_AIDL_BDIS,
  39. B_ASE0_BRST,
  40. A_BIDL_ADIS,
  41. B_AIDL_BDIS,
  42. /* Auxiliary timers */
  43. B_SE0_SRP,
  44. B_SRP_FAIL,
  45. A_WAIT_ENUM,
  46. B_DATA_PLS,
  47. B_SSEND_SRP,
  48. NUM_OTG_FSM_TIMERS,
  49. };
  50. /**
  51. * struct otg_fsm - OTG state machine according to the OTG spec
  52. *
  53. * OTG hardware Inputs
  54. *
  55. * Common inputs for A and B device
  56. * @id: TRUE for B-device, FALSE for A-device.
  57. * @adp_change: TRUE when current ADP measurement (n) value, compared to the
  58. * ADP measurement taken at n-2, differs by more than CADP_THR
  59. * @power_up: TRUE when the OTG device first powers up its USB system and
  60. * ADP measurement taken if ADP capable
  61. *
  62. * A-Device state inputs
  63. * @a_srp_det: TRUE if the A-device detects SRP
  64. * @a_vbus_vld: TRUE when VBUS voltage is in regulation
  65. * @b_conn: TRUE if the A-device detects connection from the B-device
  66. * @a_bus_resume: TRUE when the B-device detects that the A-device is signaling
  67. * a resume (K state)
  68. * B-Device state inputs
  69. * @a_bus_suspend: TRUE when the B-device detects that the A-device has put the
  70. * bus into suspend
  71. * @a_conn: TRUE if the B-device detects a connection from the A-device
  72. * @b_se0_srp: TRUE when the line has been at SE0 for more than the minimum
  73. * time before generating SRP
  74. * @b_ssend_srp: TRUE when the VBUS has been below VOTG_SESS_VLD for more than
  75. * the minimum time before generating SRP
  76. * @b_sess_vld: TRUE when the B-device detects that the voltage on VBUS is
  77. * above VOTG_SESS_VLD
  78. * @test_device: TRUE when the B-device switches to B-Host and detects an OTG
  79. * test device. This must be set by host/hub driver
  80. *
  81. * Application inputs (A-Device)
  82. * @a_bus_drop: TRUE when A-device application needs to power down the bus
  83. * @a_bus_req: TRUE when A-device application wants to use the bus.
  84. * FALSE to suspend the bus
  85. *
  86. * Application inputs (B-Device)
  87. * @b_bus_req: TRUE during the time that the Application running on the
  88. * B-device wants to use the bus
  89. *
  90. * Auxilary inputs (OTG v1.3 only. Obsolete now.)
  91. * @a_sess_vld: TRUE if the A-device detects that VBUS is above VA_SESS_VLD
  92. * @b_bus_suspend: TRUE when the A-device detects that the B-device has put
  93. * the bus into suspend
  94. * @b_bus_resume: TRUE when the A-device detects that the B-device is signaling
  95. * resume on the bus
  96. *
  97. * OTG Output status. Read only for users. Updated by OTG FSM helpers defined
  98. * in this file
  99. *
  100. * Outputs for Both A and B device
  101. * @drv_vbus: TRUE when A-device is driving VBUS
  102. * @loc_conn: TRUE when the local device has signaled that it is connected
  103. * to the bus
  104. * @loc_sof: TRUE when the local device is generating activity on the bus
  105. * @adp_prb: TRUE when the local device is in the process of doing
  106. * ADP probing
  107. *
  108. * Outputs for B-device state
  109. * @adp_sns: TRUE when the B-device is in the process of carrying out
  110. * ADP sensing
  111. * @data_pulse: TRUE when the B-device is performing data line pulsing
  112. *
  113. * Internal Variables
  114. *
  115. * a_set_b_hnp_en: TRUE when the A-device has successfully set the
  116. * b_hnp_enable bit in the B-device.
  117. * Unused as OTG fsm uses otg->host->b_hnp_enable instead
  118. * b_srp_done: TRUE when the B-device has completed initiating SRP
  119. * b_hnp_enable: TRUE when the B-device has accepted the
  120. * SetFeature(b_hnp_enable) B-device.
  121. * Unused as OTG fsm uses otg->gadget->b_hnp_enable instead
  122. * a_clr_err: Asserted (by application ?) to clear a_vbus_err due to an
  123. * overcurrent condition and causes the A-device to transition
  124. * to a_wait_vfall
  125. */
  126. struct otg_fsm {
  127. /* Input */
  128. int id;
  129. int adp_change;
  130. int power_up;
  131. int a_srp_det;
  132. int a_vbus_vld;
  133. int b_conn;
  134. int a_bus_resume;
  135. int a_bus_suspend;
  136. int a_conn;
  137. int b_se0_srp;
  138. int b_ssend_srp;
  139. int b_sess_vld;
  140. int test_device;
  141. int a_bus_drop;
  142. int a_bus_req;
  143. int b_bus_req;
  144. /* Auxilary inputs */
  145. int a_sess_vld;
  146. int b_bus_resume;
  147. int b_bus_suspend;
  148. /* Output */
  149. int drv_vbus;
  150. int loc_conn;
  151. int loc_sof;
  152. int adp_prb;
  153. int adp_sns;
  154. int data_pulse;
  155. /* Internal variables */
  156. int a_set_b_hnp_en;
  157. int b_srp_done;
  158. int b_hnp_enable;
  159. int a_clr_err;
  160. /* Informative variables. All unused as of now */
  161. int a_bus_drop_inf;
  162. int a_bus_req_inf;
  163. int a_clr_err_inf;
  164. int b_bus_req_inf;
  165. /* Auxilary informative variables */
  166. int a_suspend_req_inf;
  167. /* Timeout indicator for timers */
  168. int a_wait_vrise_tmout;
  169. int a_wait_vfall_tmout;
  170. int a_wait_bcon_tmout;
  171. int a_aidl_bdis_tmout;
  172. int b_ase0_brst_tmout;
  173. int a_bidl_adis_tmout;
  174. struct otg_fsm_ops *ops;
  175. struct usb_otg *otg;
  176. /* Current usb protocol used: 0:undefine; 1:host; 2:client */
  177. int protocol;
  178. struct mutex lock;
  179. u8 *host_req_flag;
  180. struct delayed_work hnp_polling_work;
  181. bool state_changed;
  182. };
  183. struct otg_fsm_ops {
  184. void (*chrg_vbus)(struct otg_fsm *fsm, int on);
  185. void (*drv_vbus)(struct otg_fsm *fsm, int on);
  186. void (*loc_conn)(struct otg_fsm *fsm, int on);
  187. void (*loc_sof)(struct otg_fsm *fsm, int on);
  188. void (*start_pulse)(struct otg_fsm *fsm);
  189. void (*start_adp_prb)(struct otg_fsm *fsm);
  190. void (*start_adp_sns)(struct otg_fsm *fsm);
  191. void (*add_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
  192. void (*del_timer)(struct otg_fsm *fsm, enum otg_fsm_timer timer);
  193. int (*start_host)(struct otg_fsm *fsm, int on);
  194. int (*start_gadget)(struct otg_fsm *fsm, int on);
  195. };
  196. static inline int otg_chrg_vbus(struct otg_fsm *fsm, int on)
  197. {
  198. if (!fsm->ops->chrg_vbus)
  199. return -EOPNOTSUPP;
  200. fsm->ops->chrg_vbus(fsm, on);
  201. return 0;
  202. }
  203. static inline int otg_drv_vbus(struct otg_fsm *fsm, int on)
  204. {
  205. if (!fsm->ops->drv_vbus)
  206. return -EOPNOTSUPP;
  207. if (fsm->drv_vbus != on) {
  208. fsm->drv_vbus = on;
  209. fsm->ops->drv_vbus(fsm, on);
  210. }
  211. return 0;
  212. }
  213. static inline int otg_loc_conn(struct otg_fsm *fsm, int on)
  214. {
  215. if (!fsm->ops->loc_conn)
  216. return -EOPNOTSUPP;
  217. if (fsm->loc_conn != on) {
  218. fsm->loc_conn = on;
  219. fsm->ops->loc_conn(fsm, on);
  220. }
  221. return 0;
  222. }
  223. static inline int otg_loc_sof(struct otg_fsm *fsm, int on)
  224. {
  225. if (!fsm->ops->loc_sof)
  226. return -EOPNOTSUPP;
  227. if (fsm->loc_sof != on) {
  228. fsm->loc_sof = on;
  229. fsm->ops->loc_sof(fsm, on);
  230. }
  231. return 0;
  232. }
  233. static inline int otg_start_pulse(struct otg_fsm *fsm)
  234. {
  235. if (!fsm->ops->start_pulse)
  236. return -EOPNOTSUPP;
  237. if (!fsm->data_pulse) {
  238. fsm->data_pulse = 1;
  239. fsm->ops->start_pulse(fsm);
  240. }
  241. return 0;
  242. }
  243. static inline int otg_start_adp_prb(struct otg_fsm *fsm)
  244. {
  245. if (!fsm->ops->start_adp_prb)
  246. return -EOPNOTSUPP;
  247. if (!fsm->adp_prb) {
  248. fsm->adp_sns = 0;
  249. fsm->adp_prb = 1;
  250. fsm->ops->start_adp_prb(fsm);
  251. }
  252. return 0;
  253. }
  254. static inline int otg_start_adp_sns(struct otg_fsm *fsm)
  255. {
  256. if (!fsm->ops->start_adp_sns)
  257. return -EOPNOTSUPP;
  258. if (!fsm->adp_sns) {
  259. fsm->adp_sns = 1;
  260. fsm->ops->start_adp_sns(fsm);
  261. }
  262. return 0;
  263. }
  264. static inline int otg_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
  265. {
  266. if (!fsm->ops->add_timer)
  267. return -EOPNOTSUPP;
  268. fsm->ops->add_timer(fsm, timer);
  269. return 0;
  270. }
  271. static inline int otg_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer timer)
  272. {
  273. if (!fsm->ops->del_timer)
  274. return -EOPNOTSUPP;
  275. fsm->ops->del_timer(fsm, timer);
  276. return 0;
  277. }
  278. static inline int otg_start_host(struct otg_fsm *fsm, int on)
  279. {
  280. if (!fsm->ops->start_host)
  281. return -EOPNOTSUPP;
  282. return fsm->ops->start_host(fsm, on);
  283. }
  284. static inline int otg_start_gadget(struct otg_fsm *fsm, int on)
  285. {
  286. if (!fsm->ops->start_gadget)
  287. return -EOPNOTSUPP;
  288. return fsm->ops->start_gadget(fsm, on);
  289. }
  290. int otg_statemachine(struct otg_fsm *fsm);
  291. #endif /* __LINUX_USB_OTG_FSM_H */