usb20_otg_if.c 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/sched.h>
  4. #include <linux/slab.h>
  5. #include <linux/init.h>
  6. #include <linux/list.h>
  7. #include <linux/kobject.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/io.h>
  10. /* #include <asm/system.h> */
  11. #include <linux/miscdevice.h>
  12. #include <asm/uaccess.h>
  13. #include <linux/completion.h>
  14. #include <mach/eint.h>
  15. #include <linux/gpio.h>
  16. #include "musb_core.h"
  17. #ifdef CONFIG_OF
  18. #include <linux/of_address.h>
  19. #endif
  20. #define DRIVER_AUTHOR "Mediatek"
  21. #define DRIVER_DESC "driver for OTG USB-IF test"
  22. #define MUSB_OTG_CSR0 0x102
  23. #define MUSB_OTG_COUNT0 0x108
  24. #define TEST_DRIVER_NAME "mt_otg_test"
  25. #define DX_DBG
  26. #define TEST_IS_STOP 0xfff1
  27. #define DEV_NOT_CONNECT 0xfff2
  28. #define DEV_HNP_TIMEOUT 0xfff3
  29. #define DEV_NOT_RESET 0xfff4
  30. MODULE_AUTHOR(DRIVER_AUTHOR);
  31. MODULE_LICENSE("GPL");
  32. /*for USB-IF OTG test*/
  33. /*when this func is called in EM, it will reset the USB hw.
  34. and tester should not connet the uut to PC or connect a A-cable to it*/
  35. /*macro for USB-IF for OTG driver*/
  36. #define OTG_CMD_E_ENABLE_VBUS 0x00
  37. #define OTG_CMD_E_ENABLE_SRP 0x01
  38. #define OTG_CMD_E_START_DET_SRP 0x02
  39. #define OTG_CMD_E_START_DET_VBUS 0x03
  40. #define OTG_CMD_P_A_UUT 0x04
  41. #define OTG_CMD_P_B_UUT 0x05
  42. #define HOST_CMD_TEST_SE0_NAK 0x6
  43. #define HOST_CMD_TEST_J 0x7
  44. #define HOST_CMD_TEST_K 0x8
  45. #define HOST_CMD_TEST_PACKET 0x9
  46. #define HOST_CMD_SUSPEND_RESUME 0xa
  47. #define HOST_CMD_GET_DESCRIPTOR 0xb
  48. #define HOST_CMD_SET_FEATURE 0xc
  49. #define OTG_CMD_P_B_UUT_TD59 0xd
  50. #define HOST_CMD_ENV_INIT 0xe
  51. #define HOST_CMD_ENV_EXIT 0xf
  52. #define OTG_MSG_DEV_NOT_SUPPORT 0x01
  53. #define OTG_MSG_DEV_NOT_RESPONSE 0x02
  54. #define OTG_MSG_HUB_NOT_SUPPORT 0x03
  55. #define OTG_STOP_CMD 0x10
  56. #define OTG_INIT_MSG 0x20
  57. typedef struct {
  58. spinlock_t lock;
  59. unsigned int msg;
  60. } otg_message;
  61. static otg_message g_otg_message;
  62. int volatile g_exec = 0;
  63. unsigned long usb_l1intm_store;
  64. unsigned short usb_intrrxe_store;
  65. unsigned short usb_intrtxe_store;
  66. unsigned char usb_intrusbe_store;
  67. unsigned long pericfg_base;
  68. bool device_enumed = false;
  69. bool set_hnp = false;
  70. bool high_speed = false;
  71. bool is_td_59 = false;
  72. struct completion stop_event;
  73. void musb_otg_reset_usb(void)
  74. {
  75. /* reset all of the USB IP, including PHY and MAC */
  76. unsigned int usb_reset;
  77. usb_reset = __raw_readl((void __iomem *)pericfg_base);
  78. usb_reset |= 1 << 29;
  79. __raw_writel(usb_reset, (void __iomem *)pericfg_base);
  80. mdelay(10);
  81. usb_reset &= ~(1 << 29);
  82. __raw_writel(usb_reset, (void __iomem *)pericfg_base);
  83. /* power on the USB */
  84. usb_phy_poweron();
  85. /* enable interrupt */
  86. musb_writel(mtk_musb->mregs, USB_L1INTM, 0x105);
  87. musb_writew(mtk_musb->mregs, MUSB_INTRTXE, 1);
  88. musb_writeb(mtk_musb->mregs, MUSB_INTRUSBE, 0xf7);
  89. }
  90. int musb_otg_env_init(void)
  91. {
  92. u8 power;
  93. /* u8 intrusb; */
  94. /* step1: mask the PMU/PMIC EINT */
  95. mtk_musb->usb_if = true;
  96. mtk_musb->is_host = true; /* workaround for PMIC charger detection */
  97. /* mt65xx_eint_mask(EINT_CHR_DET_NUM); */
  98. pmic_chrdet_int_en(0);
  99. mt_usb_init_drvvbus();
  100. /* step5: make sure to power on the USB module */
  101. if (mtk_musb->power)
  102. mtk_musb->power = FALSE;
  103. musb_platform_enable(mtk_musb);
  104. /* step6: clear session bit */
  105. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0);
  106. /* step7: disable and enable usb interrupt */
  107. usb_l1intm_store = musb_readl(mtk_musb->mregs, USB_L1INTM);
  108. usb_intrrxe_store = musb_readw(mtk_musb->mregs, MUSB_INTRRXE);
  109. usb_intrtxe_store = musb_readw(mtk_musb->mregs, MUSB_INTRTXE);
  110. usb_intrusbe_store = musb_readb(mtk_musb->mregs, MUSB_INTRUSBE);
  111. musb_writel(mtk_musb->mregs, USB_L1INTM, 0);
  112. musb_writew(mtk_musb->mregs, MUSB_INTRRXE, 0);
  113. musb_writew(mtk_musb->mregs, MUSB_INTRTXE, 0);
  114. musb_writeb(mtk_musb->mregs, MUSB_INTRUSBE, 0);
  115. musb_writew(mtk_musb->mregs, MUSB_INTRRX, 0xffff);
  116. musb_writew(mtk_musb->mregs, MUSB_INTRTX, 0xffff);
  117. musb_writeb(mtk_musb->mregs, MUSB_INTRUSB, 0xff);
  118. free_irq(mtk_musb->nIrq, mtk_musb);
  119. musb_writel(mtk_musb->mregs, USB_L1INTM, 0x105);
  120. musb_writew(mtk_musb->mregs, MUSB_INTRTXE, 1);
  121. musb_writeb(mtk_musb->mregs, MUSB_INTRUSBE, 0xf7);
  122. /* setp8: set the index to 0 for ep0, maybe no need.
  123. Designers said it is better not to use the index register. */
  124. musb_writeb(mtk_musb->mregs, MUSB_INDEX, 0);
  125. /* setp9: init message */
  126. g_otg_message.msg = 0;
  127. spin_lock_init(&g_otg_message.lock);
  128. init_completion(&stop_event);
  129. #ifdef DX_DBG
  130. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  131. DBG(0, "start the USB-IF test in EM,power=0x%x!\n", power);
  132. #endif
  133. return 0;
  134. }
  135. int musb_otg_env_exit(void)
  136. {
  137. DBG(0, "stop the USB-IF test in EM!\n");
  138. musb_writel(mtk_musb->mregs, USB_L1INTM, 0);
  139. musb_writew(mtk_musb->mregs, MUSB_INTRRXE, 0);
  140. musb_writew(mtk_musb->mregs, MUSB_INTRTXE, 0);
  141. musb_writeb(mtk_musb->mregs, MUSB_INTRUSBE, 0);
  142. musb_writew(mtk_musb->mregs, MUSB_INTRRX, 0xffff);
  143. musb_writew(mtk_musb->mregs, MUSB_INTRTX, 0xffff);
  144. musb_writeb(mtk_musb->mregs, MUSB_INTRUSB, 0xff);
  145. musb_writel(mtk_musb->mregs, USB_L1INTM, usb_l1intm_store);
  146. musb_writew(mtk_musb->mregs, MUSB_INTRRXE, usb_intrrxe_store);
  147. musb_writew(mtk_musb->mregs, MUSB_INTRTXE, usb_intrtxe_store);
  148. musb_writeb(mtk_musb->mregs, MUSB_INTRUSBE, usb_intrusbe_store);
  149. mtk_musb->usb_if = false;
  150. mtk_musb->is_host = false;
  151. pmic_chrdet_int_en(1);
  152. return 0;
  153. }
  154. void musb_otg_write_fifo(u16 len, u8 *buf)
  155. {
  156. int i;
  157. DBG(0, "musb_otg_write_fifo,len=%d\n", len);
  158. for (i = 0; i < len; i++)
  159. musb_writeb(mtk_musb->mregs, 0x20, *(buf + i));
  160. }
  161. void musb_otg_read_fifo(u16 len, u8 *buf)
  162. {
  163. int i;
  164. DBG(0, "musb_otg_read_fifo,len=%d\n", len);
  165. for (i = 0; i < len; i++)
  166. *(buf + i) = musb_readb(mtk_musb->mregs, 0x20);
  167. }
  168. unsigned int musb_polling_ep0_interrupt(void)
  169. {
  170. unsigned short intrtx;
  171. DBG(0, "polling ep0 interrupt\n");
  172. do {
  173. intrtx = musb_readw(mtk_musb->mregs, MUSB_INTRTX);
  174. mb();
  175. musb_writew(mtk_musb->mregs, MUSB_INTRTX, intrtx);
  176. if (intrtx & 0x1) { /* ep0 interrupt happen */
  177. DBG(0, "get ep0 interrupt,csr0=0x%x\n",
  178. musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0));
  179. break;
  180. }
  181. DBG(0, "polling ep0 interrupt,csr0=0x%x\n",
  182. musb_readb(mtk_musb->mregs, MUSB_OTG_CSR0));
  183. wait_for_completion_timeout(&stop_event, 1);
  184. if (!g_exec)
  185. return TEST_IS_STOP;
  186. } while (g_exec);
  187. return 0;
  188. }
  189. void musb_h_setup(struct usb_ctrlrequest *setup)
  190. {
  191. unsigned short csr0;
  192. DBG(0, "musb_h_setup++\n");
  193. musb_otg_write_fifo(sizeof(struct usb_ctrlrequest), (u8 *) setup);
  194. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  195. DBG(0, "musb_h_setup,csr0=0x%x\n", csr0);
  196. csr0 |= MUSB_CSR0_H_SETUPPKT | MUSB_CSR0_TXPKTRDY;
  197. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  198. /* polling the Tx interrupt */
  199. if (musb_polling_ep0_interrupt())
  200. return;
  201. DBG(0, "musb_h_setup--\n");
  202. }
  203. void musb_h_in_data(unsigned char *buf, u16 len)
  204. {
  205. /* will receive all of the data in this transfer. */
  206. unsigned short csr0;
  207. u16 received = 0;
  208. bool bshort = false;
  209. DBG(0, "musb_h_in_data++\n");
  210. while ((received < len) && (!bshort)) {
  211. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  212. csr0 |= MUSB_CSR0_H_REQPKT;
  213. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  214. if (musb_polling_ep0_interrupt())
  215. return;
  216. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  217. DBG(0, "csr0 = 0x%x!\n", csr0);
  218. if (csr0 & MUSB_CSR0_RXPKTRDY) {
  219. /* get the data from ep fifo */
  220. u8 count = musb_readb(mtk_musb->mregs, MUSB_OTG_COUNT0);
  221. if (count < 64)
  222. bshort = true;
  223. musb_otg_read_fifo(count, buf + received);
  224. received += count;
  225. csr0 &= ~MUSB_CSR0_RXPKTRDY;
  226. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  227. } else
  228. DBG(0, "error, not receive the rxpktrdy interrupt!\n");
  229. DBG(0, "musb_h_in_data--\n");
  230. }
  231. }
  232. void musb_h_in_status(void)
  233. {
  234. unsigned short csr0;
  235. DBG(0, "musb_h_in_status++\n");
  236. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  237. csr0 |= MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
  238. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  239. if (musb_polling_ep0_interrupt())
  240. return;
  241. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  242. DBG(0, "csr0 = 0x%x!\n", csr0);
  243. if (csr0 & MUSB_CSR0_RXPKTRDY) {
  244. csr0 &= ~MUSB_CSR0_RXPKTRDY;
  245. /* whether this bit will be cleared auto, need to clear by sw?? */
  246. if (csr0 & MUSB_CSR0_H_STATUSPKT)
  247. csr0 &= ~MUSB_CSR0_H_STATUSPKT;
  248. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  249. } else if (csr0 & MUSB_CSR0_H_RXSTALL) {
  250. DBG(0, "stall!\n");
  251. if (set_hnp) {
  252. DBG(0, "will pop up:DEV_NOT_RESPONSE!\n");
  253. g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE;
  254. set_hnp = false;
  255. msleep(1000);
  256. }
  257. }
  258. DBG(0, "musb_h_in_status--\n");
  259. }
  260. void musb_h_out_status(void)
  261. {
  262. unsigned short csr0;
  263. DBG(0, "musb_h_out_status++\n");
  264. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  265. csr0 |= MUSB_CSR0_H_STATUSPKT | MUSB_CSR0_TXPKTRDY;
  266. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  267. if (musb_polling_ep0_interrupt())
  268. return;
  269. #ifdef DX_DBG
  270. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  271. DBG(0, "csr0 = 0x%x!\n", csr0);
  272. #endif
  273. DBG(0, "musb_h_out_status--\n");
  274. }
  275. void musb_d_reset(void)
  276. {
  277. unsigned short swrst;
  278. swrst = musb_readw(mtk_musb->mregs, 0x74);
  279. swrst |= 0x2;
  280. musb_writew(mtk_musb->mregs, 0x74, swrst);
  281. }
  282. void musb_d_setup(struct usb_ctrlrequest *setup_packet, u16 len)
  283. {
  284. musb_otg_read_fifo(len, (u8 *) setup_packet);
  285. DBG(0, "receive setup packet:0x%x 0x%x 0x%x 0x%x 0x%x\n", setup_packet->bRequest,
  286. setup_packet->bRequestType, setup_packet->wIndex, setup_packet->wValue,
  287. setup_packet->wLength);
  288. }
  289. void musb_d_out_data(struct usb_ctrlrequest *setup_packet)
  290. {
  291. unsigned short csr0;
  292. static struct usb_device_descriptor device_descriptor = {
  293. 0x12,
  294. 0x01,
  295. 0x0200,
  296. 0x00,
  297. 0x00,
  298. 0x00,
  299. 0x40,
  300. 0x0951,
  301. 0x1603,
  302. 0x0200,
  303. 0x01,
  304. 0x02,
  305. 0x03,
  306. 0x01
  307. };
  308. static struct usb_config_descriptor configuration_descriptor = {
  309. 0x09,
  310. 0x02,
  311. 0x0023,
  312. 0x01,
  313. 0x01,
  314. 0x00,
  315. 0x80,
  316. 0x32
  317. };
  318. static struct usb_interface_descriptor interface_descriptor = {
  319. 0x09,
  320. 0x04,
  321. 0x00,
  322. 0x00,
  323. 0x02,
  324. 0x08,
  325. 0x06,
  326. 0x50,
  327. 0x00
  328. };
  329. static struct usb_endpoint_descriptor endpoint_descriptor_in = {
  330. 0x07,
  331. 0x05,
  332. 0x81,
  333. 0x02,
  334. 0x0200,
  335. 0x00
  336. };
  337. static struct usb_endpoint_descriptor endpoint_descriptor_out = {
  338. 0x07,
  339. 0x05,
  340. 0x02,
  341. 0x02,
  342. 0x0200,
  343. 0x00
  344. };
  345. static struct usb_otg_descriptor usb_otg_descriptor = {
  346. 0x03,
  347. 0x09,
  348. 0x03
  349. };
  350. if (setup_packet->wValue == 0x0100) {
  351. musb_otg_write_fifo(sizeof(struct usb_device_descriptor),
  352. (u8 *) &device_descriptor);
  353. } else if (setup_packet->wValue == 0x0200) {
  354. if (setup_packet->wLength == 9) {
  355. musb_otg_write_fifo(sizeof(struct usb_config_descriptor),
  356. (u8 *) &configuration_descriptor);
  357. } else {
  358. musb_otg_write_fifo(sizeof(struct usb_config_descriptor),
  359. (u8 *) &configuration_descriptor);
  360. musb_otg_write_fifo(sizeof(struct usb_interface_descriptor),
  361. (u8 *) &interface_descriptor);
  362. musb_otg_write_fifo(7, (u8 *) &endpoint_descriptor_in);
  363. musb_otg_write_fifo(7, (u8 *) &endpoint_descriptor_out);
  364. musb_otg_write_fifo(sizeof(struct usb_otg_descriptor),
  365. (u8 *) &usb_otg_descriptor);
  366. }
  367. }
  368. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  369. csr0 |= MUSB_CSR0_TXPKTRDY | MUSB_CSR0_P_DATAEND;
  370. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  371. if (musb_polling_ep0_interrupt())
  372. return;
  373. }
  374. unsigned int musb_polling_bus_interrupt(unsigned int intr)
  375. {
  376. unsigned char intrusb;
  377. unsigned long timeout;
  378. if (MUSB_INTR_CONNECT == intr)
  379. timeout = jiffies + 15 * HZ;
  380. if ((MUSB_INTR_CONNECT | MUSB_INTR_RESUME) == intr)
  381. timeout = jiffies + 1;
  382. if (MUSB_INTR_RESET == intr)
  383. timeout = jiffies + 2 * HZ;
  384. do {
  385. intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB);
  386. mb();
  387. musb_writeb(mtk_musb->mregs, MUSB_INTRUSB, intrusb);
  388. if (intrusb & intr) {
  389. DBG(0, "interrupt happen, intrusb=0x%x, intr=0x%x\n", intrusb, intr);
  390. break;
  391. }
  392. /* DBG(0,"still polling,intrusb=0x%x,power=0x%x,devctl=0x%x\n",
  393. intrusb,musb_readb(mtk_musb->mregs,MUSB_POWER),musb_readb(mtk_musb->mregs,MUSB_DEVCTL)); */
  394. /* check the timeout */
  395. if ((MUSB_INTR_CONNECT == intr) && time_after(jiffies, timeout)) {
  396. DBG(0, "time out for MUSB_INTR_CONNECT\n");
  397. return DEV_NOT_CONNECT;
  398. }
  399. if (((MUSB_INTR_CONNECT | MUSB_INTR_RESUME) == intr)
  400. && time_after(jiffies, timeout)) {
  401. DBG(0, "time out for MUSB_INTR_CONNECT|MUSB_INTR_RESUME\n");
  402. return DEV_HNP_TIMEOUT;
  403. }
  404. if ((MUSB_INTR_RESET == intr) && time_after(jiffies, timeout)) {
  405. DBG(0, "time out for MUSB_INTR_RESET\n");
  406. return DEV_NOT_RESET;
  407. }
  408. /* delay for the interrupt */
  409. if (intr != MUSB_INTR_RESET) {
  410. wait_for_completion_timeout(&stop_event, 1);
  411. if (!g_exec)
  412. break;
  413. }
  414. } while (g_exec);
  415. if (!g_exec) {
  416. DBG(0, "TEST_IS_STOP\n");
  417. return TEST_IS_STOP;
  418. }
  419. if (intrusb & MUSB_INTR_RESUME) { /* for TD.4.8, remote wakeup */
  420. DBG(0, "MUSB_INTR_RESUME\n");
  421. return MUSB_INTR_RESUME;
  422. } else {
  423. return intrusb;
  424. }
  425. }
  426. void musb_h_suspend(void)
  427. {
  428. unsigned char power;
  429. /* before suspend, should to send SOF for a while (USB-IF plan need) */
  430. /* mdelay(100); */
  431. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  432. DBG(0, "before suspend,power=0x%x\n", power);
  433. if (high_speed)
  434. power = 0x63;
  435. else
  436. power = 0x43;
  437. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  438. }
  439. void musb_h_remote_wakeup(void)
  440. {
  441. unsigned char power;
  442. msleep(25);
  443. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  444. power &= ~MUSB_POWER_RESUME;
  445. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  446. }
  447. bool musb_h_reset(void)
  448. {
  449. unsigned char power;
  450. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  451. power |= MUSB_POWER_RESET | MUSB_POWER_HSENAB;
  452. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  453. msleep(60);
  454. power &= ~MUSB_POWER_RESET;
  455. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  456. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  457. if (power & MUSB_POWER_HSMODE) {
  458. DBG(0, "the device is a hs device!\n");
  459. high_speed = true;
  460. return true;
  461. }
  462. DBG(0, "the device is a fs device!\n");
  463. high_speed = false;
  464. return false;
  465. }
  466. void musb_d_soft_connect(bool connect)
  467. {
  468. unsigned char power;
  469. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  470. if (connect)
  471. power |= MUSB_POWER_SOFTCONN;
  472. else
  473. power &= ~MUSB_POWER_SOFTCONN;
  474. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  475. }
  476. void musb_otg_set_session(bool set)
  477. {
  478. unsigned char devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  479. if (set)
  480. devctl |= MUSB_DEVCTL_SESSION;
  481. else
  482. devctl &= ~MUSB_DEVCTL_SESSION;
  483. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl);
  484. }
  485. void musb_h_enumerate(void)
  486. {
  487. struct usb_ctrlrequest setup_packet;
  488. struct usb_device_descriptor device_descriptor;
  489. struct usb_config_descriptor configuration_descriptor;
  490. struct usb_otg_descriptor *otg_descriptor;
  491. unsigned char descriptor[255];
  492. /* set address */
  493. musb_writew(mtk_musb->mregs, MUSB_TXFUNCADDR, 0);
  494. setup_packet.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  495. setup_packet.bRequest = USB_REQ_SET_ADDRESS;
  496. setup_packet.wIndex = 0;
  497. setup_packet.wValue = 1;
  498. setup_packet.wLength = 0;
  499. musb_h_setup(&setup_packet);
  500. musb_h_in_status();
  501. musb_writew(mtk_musb->mregs, MUSB_TXFUNCADDR, 1);
  502. DBG(0, "set address OK!\n");
  503. /* get device descriptor */
  504. setup_packet.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  505. setup_packet.bRequest = USB_REQ_GET_DESCRIPTOR;
  506. setup_packet.wIndex = 0;
  507. setup_packet.wValue = 0x0100;
  508. setup_packet.wLength = 0x40;
  509. musb_h_setup(&setup_packet);
  510. musb_h_in_data((char *)&device_descriptor, sizeof(struct usb_device_descriptor));
  511. musb_h_out_status();
  512. if (device_descriptor.idProduct == 0x1234) {
  513. DBG(0, "device pid not match!\n");
  514. g_otg_message.msg = OTG_MSG_DEV_NOT_SUPPORT;
  515. /* msleep(1000); */
  516. }
  517. DBG(0, "get device descriptor OK!device class=0x%x PID=0x%x VID=0x%x\n",
  518. device_descriptor.bDeviceClass, device_descriptor.idProduct,
  519. device_descriptor.idVendor);
  520. DBG(0, "get device descriptor OK!DescriptorType=0x%x DeviceSubClass=0x%x\n",
  521. device_descriptor.bDescriptorType, device_descriptor.bDeviceSubClass);
  522. /* get configuration descriptor */
  523. setup_packet.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  524. setup_packet.bRequest = USB_REQ_GET_DESCRIPTOR;
  525. setup_packet.wIndex = 0;
  526. setup_packet.wValue = 0x0200;
  527. setup_packet.wLength = 0x9;
  528. musb_h_setup(&setup_packet);
  529. musb_h_in_data((char *)&configuration_descriptor, sizeof(struct usb_config_descriptor));
  530. musb_h_out_status();
  531. DBG(0, "get configuration descriptor OK!\n");
  532. /* get all configuration descriptor */
  533. setup_packet.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  534. setup_packet.bRequest = USB_REQ_GET_DESCRIPTOR;
  535. setup_packet.wIndex = 0;
  536. setup_packet.wValue = 0x0200;
  537. setup_packet.wLength = configuration_descriptor.wTotalLength;
  538. musb_h_setup(&setup_packet);
  539. musb_h_in_data(descriptor, configuration_descriptor.wTotalLength);
  540. musb_h_out_status();
  541. DBG(0, "get all configuration descriptor OK!\n");
  542. /* get otg descriptor */
  543. otg_descriptor =
  544. (struct usb_otg_descriptor *)(descriptor + configuration_descriptor.wTotalLength - 3);
  545. DBG(0, "otg descriptor::bLegth=%d,bDescriptorTye=%d,bmAttr=%d\n", otg_descriptor->bLength,
  546. otg_descriptor->bDescriptorType, otg_descriptor->bmAttributes);
  547. if (otg_descriptor->bLength == 3 && otg_descriptor->bDescriptorType == 9) {
  548. DBG(0, "get an otg descriptor!\n");
  549. } else {
  550. DBG(0, "not an otg device, will pop Unsupported Device\n");
  551. g_otg_message.msg = OTG_MSG_DEV_NOT_SUPPORT;
  552. msleep(1000);
  553. }
  554. /* set hnp, need before set_configuration */
  555. set_hnp = true;
  556. setup_packet.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  557. setup_packet.bRequest = USB_REQ_SET_FEATURE;
  558. setup_packet.wIndex = 0;
  559. setup_packet.wValue = 0x3; /* b_hnp_enable */
  560. setup_packet.wLength = 0;
  561. musb_h_setup(&setup_packet);
  562. musb_h_in_status();
  563. DBG(0, "set hnp OK!\n");
  564. /* set configuration */
  565. setup_packet.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  566. setup_packet.bRequest = USB_REQ_SET_CONFIGURATION;
  567. setup_packet.wIndex = 0;
  568. setup_packet.wValue = configuration_descriptor.iConfiguration;
  569. setup_packet.wLength = 0;
  570. musb_h_setup(&setup_packet);
  571. musb_h_in_status();
  572. DBG(0, "set configuration OK!\n");
  573. }
  574. void musb_d_enumerated(void)
  575. {
  576. unsigned char devctl;
  577. unsigned short csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  578. DBG(0, "csr0=0x%x\n", csr0);
  579. if (csr0 & MUSB_CSR0_P_SETUPEND) {
  580. DBG(0, "SETUPEND\n");
  581. csr0 |= MUSB_CSR0_P_SVDSETUPEND;
  582. musb_writeb(mtk_musb->mregs, MUSB_OTG_CSR0, csr0);
  583. csr0 &= ~MUSB_CSR0_P_SVDSETUPEND;
  584. }
  585. if (csr0 & MUSB_CSR0_RXPKTRDY) {
  586. u8 count0;
  587. count0 = musb_readb(mtk_musb->mregs, MUSB_OTG_COUNT0);
  588. if (count0 == 8) {
  589. struct usb_ctrlrequest setup_packet;
  590. musb_d_setup(&setup_packet, count0); /* get the setup packet */
  591. if (setup_packet.bRequest == USB_REQ_SET_ADDRESS) {
  592. device_enumed = false;
  593. csr0 |= MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_DATAEND;
  594. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0); /* clear the RXPKTRDY */
  595. if (musb_polling_ep0_interrupt()) {
  596. DBG(0,
  597. "B-UUT:when set address, do not detect ep0 interrupt\n");
  598. return;
  599. }
  600. musb_writeb(mtk_musb->mregs, MUSB_FADDR, (u8) setup_packet.wValue);
  601. } else if (setup_packet.bRequest == USB_REQ_GET_DESCRIPTOR) {
  602. csr0 |= MUSB_CSR0_P_SVDRXPKTRDY;
  603. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0); /* clear the RXPKTRDY */
  604. musb_d_out_data(&setup_packet); /* device --> host */
  605. } else if (setup_packet.bRequest == USB_REQ_SET_CONFIGURATION) {
  606. csr0 |= MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_DATAEND;
  607. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0); /* clear the RXPKTRDY */
  608. if (musb_polling_ep0_interrupt())
  609. return;
  610. device_enumed = true;
  611. /* will set host_req for B-device */
  612. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  613. if (devctl & MUSB_DEVCTL_BDEVICE) {
  614. devctl |= MUSB_DEVCTL_HR;
  615. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl);
  616. }
  617. } else if (setup_packet.bRequest == USB_REQ_SET_FEATURE) {
  618. csr0 |= MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_DATAEND;
  619. musb_writew(mtk_musb->mregs, MUSB_OTG_CSR0, csr0); /* clear the RXPKTRDY */
  620. if (musb_polling_ep0_interrupt())
  621. return;
  622. }
  623. }
  624. }
  625. }
  626. void musb_otg_test_return(void)
  627. {
  628. }
  629. static int musb_host_test_mode(unsigned char cmd);
  630. void otg_cmd_a_uut(void)
  631. {
  632. unsigned long timeout;
  633. unsigned char devctl;
  634. bool timeout_flag = false;
  635. unsigned int ret;
  636. unsigned char power;
  637. unsigned short csr0;
  638. unsigned char intrusb;
  639. unsigned short intrtx;
  640. /* polling the session req from B-OPT and start a new session */
  641. device_enumed = false;
  642. TD_4_6:
  643. musb_otg_reset_usb();
  644. DBG(0, "A-UUT reset success\n");
  645. timeout = jiffies + 5 * HZ;
  646. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0);
  647. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  648. while (g_exec && (devctl & 0x18)) {
  649. DBG(0, "musb::not below session end!\n");
  650. msleep(100);
  651. if (time_after(jiffies, timeout)) {
  652. timeout_flag = true;
  653. return TEST_IS_STOP;
  654. }
  655. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  656. }
  657. if (timeout_flag) {
  658. timeout_flag = false;
  659. musb_otg_reset_usb();
  660. DBG(0, "timeout for below session end, after reset usb, devctl=0x%x\n",
  661. musb_readb(mtk_musb->mregs, MUSB_DEVCTL));
  662. }
  663. DBG(0, "polling session request,begin\n");
  664. ret = musb_polling_bus_interrupt(MUSB_INTR_SESSREQ);
  665. DBG(0, "polling session request,done,ret=0x%x\n", ret);
  666. if (TEST_IS_STOP == ret)
  667. return TEST_IS_STOP;
  668. musb_otg_set_session(true); /* session is set and VBUS will be out. */
  669. #if 1
  670. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  671. power &= ~MUSB_POWER_SOFTCONN;
  672. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  673. #endif
  674. /* polling the connect interrupt from B-OPT */
  675. DBG(0, "polling connect interrupt,begin\n");
  676. ret = musb_polling_bus_interrupt(MUSB_INTR_CONNECT);
  677. DBG(0, "polling connect interrupt,done,ret=0x%x\n", ret);
  678. if (TEST_IS_STOP == ret)
  679. return TEST_IS_STOP;
  680. if (DEV_NOT_CONNECT == ret) {
  681. DBG(0, "device is not connected in 15s\n");
  682. g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE;
  683. return TEST_IS_STOP;
  684. }
  685. DBG(0, "musb::connect interrupt is detected!\n");
  686. /* the test is fail because the reset starts less than100 ms from the B-OPT connect. the IF test needs */
  687. msleep(100);
  688. /* reset the bus,check whether it is a hs device */
  689. musb_h_reset(); /* should last for more than 50ms, TD.4.2 */
  690. musb_h_enumerate();
  691. /* suspend the bus */
  692. csr0 = musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0);
  693. DBG(0, "after enum B-OPT,csr0=0x%x\n", csr0);
  694. musb_h_suspend();
  695. /* polling the disconnect interrupt from B-OPT, and remote wakeup(TD.4.8) */
  696. DBG(0, "polling disconnect or remote wakeup,begin\n");
  697. ret = musb_polling_bus_interrupt(MUSB_INTR_DISCONNECT | MUSB_INTR_RESUME);
  698. DBG(0, "polling disconnect or remote wakeup,done,ret=0x%x\n", ret);
  699. if (TEST_IS_STOP == ret)
  700. return TEST_IS_STOP;
  701. if (MUSB_INTR_RESUME == ret) {
  702. /* for TD4.8 */
  703. musb_h_remote_wakeup();
  704. /* maybe need to access the B-OPT, get device descriptor */
  705. if (g_exec)
  706. wait_for_completion(&stop_event);
  707. return TEST_IS_STOP;
  708. }
  709. /* polling the reset interrupt from B-OPT */
  710. if (!(ret & MUSB_INTR_RESET)) {
  711. DBG(0, "polling reset for B-OPT,begin\n");
  712. ret = musb_polling_bus_interrupt(MUSB_INTR_RESET);
  713. DBG(0, "polling reset for B-OPT,done,ret=0x%x\n", ret);
  714. if (TEST_IS_STOP == ret)
  715. return TEST_IS_STOP;
  716. if (DEV_NOT_RESET == ret) {
  717. if (g_exec)
  718. wait_for_completion(&stop_event);
  719. return TEST_IS_STOP;
  720. }
  721. }
  722. DBG(0, "after receive reset,devctl=0x%x,csr0=0x%x\n",
  723. musb_readb(mtk_musb->mregs, MUSB_DEVCTL), musb_readw(mtk_musb->mregs, MUSB_OTG_CSR0));
  724. /* enumerate and polling the suspend interrupt form B-OPT */
  725. do {
  726. intrtx = musb_readw(mtk_musb->mregs, MUSB_INTRTX);
  727. mb();
  728. musb_writew(mtk_musb->mregs, MUSB_INTRTX, intrtx);
  729. intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB);
  730. mb();
  731. musb_writeb(mtk_musb->mregs, MUSB_INTRUSB, intrusb);
  732. if (intrtx || (intrusb & MUSB_INTR_SUSPEND)) {
  733. if (intrtx) {
  734. if (intrtx & 0x1)
  735. musb_d_enumerated();
  736. }
  737. if (intrusb) {
  738. /* maybe receive disconnect interrupt when the session is end */
  739. if (intrusb & MUSB_INTR_SUSPEND) {
  740. if (device_enumed) {
  741. /* return form the while loop */
  742. break;
  743. }
  744. /* TD.4.6 */
  745. musb_d_soft_connect(false);
  746. goto TD_4_6;
  747. }
  748. }
  749. } else
  750. wait_for_completion_timeout(&stop_event, 1);
  751. } while (g_exec); /* the enum will be repeated for 5 times */
  752. if (!g_exec)
  753. return TEST_IS_STOP; /* return form the switch-case */
  754. DBG(0, "polling connect form B-OPT,begin\n");
  755. ret = musb_polling_bus_interrupt(MUSB_INTR_CONNECT); /* B-OPT will connect again 100ms after A disconnect */
  756. DBG(0, "polling connect form B-OPT,done,ret=0x%x\n", ret);
  757. if (TEST_IS_STOP == ret)
  758. return TEST_IS_STOP;
  759. musb_h_reset(); /* should reset bus again, TD.4.7 */
  760. wait_for_completion(&stop_event);
  761. }
  762. void otg_cmd_b_uut(void)
  763. {
  764. unsigned long timeout;
  765. unsigned char devctl;
  766. bool timeout_flag = false;
  767. unsigned int ret;
  768. unsigned char power;
  769. unsigned char intrusb;
  770. unsigned short intrtx;
  771. musb_otg_reset_usb();
  772. /* The B-UUT issues an SRP to start a session with the A-OPT */
  773. musb_otg_set_session(true);
  774. /* 100ms after VBUS begins to decay the A-OPT powers VBUS */
  775. timeout = jiffies + 5 * HZ;
  776. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  777. while (((devctl & MUSB_DEVCTL_VBUS) >> MUSB_DEVCTL_VBUS_SHIFT) < 0x3) {
  778. if (time_after(jiffies, timeout)) {
  779. timeout_flag = true;
  780. break;
  781. }
  782. msleep(100);
  783. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  784. }
  785. if (timeout_flag) {
  786. DBG(0, "B-UUT set vbus timeout\n");
  787. g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE;
  788. timeout_flag = false;
  789. return TEST_IS_STOP;
  790. }
  791. /* After detecting the VBUS, B-UUT should connect to the A_OPT */
  792. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  793. power |= MUSB_POWER_HSENAB;
  794. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  795. /* TD5_5: */
  796. musb_d_soft_connect(true);
  797. device_enumed = false;
  798. /* polling the reset single form the A-OPT */
  799. DBG(0, "polling reset form A-OPT,begin\n");
  800. ret = musb_polling_bus_interrupt(MUSB_INTR_RESET);
  801. DBG(0, "polling reset form A-OPT,done,ret=0x%x\n", ret);
  802. if (TEST_IS_STOP == ret)
  803. return TEST_IS_STOP;
  804. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  805. if (power & MUSB_POWER_HSMODE)
  806. high_speed = true;
  807. else
  808. high_speed = false;
  809. /* The A-OPT enumerates the B-UUT */
  810. TD6_13:do {
  811. intrtx = musb_readw(mtk_musb->mregs, MUSB_INTRTX);
  812. mb();
  813. musb_writew(mtk_musb->mregs, MUSB_INTRTX, intrtx);
  814. intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB);
  815. mb();
  816. musb_writeb(mtk_musb->mregs, MUSB_INTRUSB, intrusb);
  817. if (intrtx || (intrusb & 0xf7)) {
  818. if (intrtx) {
  819. /* DBG(0,"B-enum,intrtx=0x%x\n",intrtx); */
  820. if (intrtx & 0x1)
  821. DBG(0, "ep0 interrupt\n");
  822. musb_d_enumerated();
  823. }
  824. if (intrusb) {
  825. if (intrusb & 0xf7)
  826. DBG(0, "B-enum,intrusb=0x%x,power=0x%x\n", intrusb,
  827. musb_readb(mtk_musb->mregs, MUSB_POWER));
  828. if ((device_enumed) && (intrusb & MUSB_INTR_SUSPEND)) {
  829. DBG(0,
  830. "suspend interrupt is received,power=0x%x,devctl=0x%x\n",
  831. musb_readb(mtk_musb->mregs, MUSB_POWER),
  832. musb_readb(mtk_musb->mregs, MUSB_DEVCTL));
  833. break;
  834. }
  835. }
  836. } else {
  837. DBG(0, "power=0x%x,devctl=0x%x,intrtx=0x%x,intrusb=0x%x\n",
  838. musb_readb(mtk_musb->mregs, MUSB_POWER), musb_readb(mtk_musb->mregs,
  839. MUSB_DEVCTL),
  840. musb_readw(mtk_musb->mregs, MUSB_INTRTX), musb_readb(mtk_musb->mregs,
  841. MUSB_INTRUSB));
  842. wait_for_completion_timeout(&stop_event, 1);
  843. }
  844. } while (g_exec);
  845. if (!g_exec)
  846. return TEST_IS_STOP;
  847. DBG(0, "hnp start\n");
  848. if (intrusb & MUSB_INTR_RESUME)
  849. goto TD6_13;
  850. if (!(intrusb & MUSB_INTR_CONNECT)) {
  851. /* polling the connect from A-OPT, the UUT acts as host */
  852. DBG(0, "polling connect or resume form A-OPT,begin\n");
  853. ret = musb_polling_bus_interrupt(MUSB_INTR_CONNECT | MUSB_INTR_RESUME);
  854. DBG(0, "polling connect or resume form A-OPT,done,ret=0x%x\n", ret);
  855. if (TEST_IS_STOP == ret)
  856. return TEST_IS_STOP;
  857. if (MUSB_INTR_RESUME == ret)
  858. goto TD6_13;
  859. if (DEV_HNP_TIMEOUT == ret) {
  860. DBG(0, "B-UUT HNP timeout\n");
  861. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  862. /* DBG(0,"hnp timeout,power=0x%x,devctl=0x%x\n",
  863. musb_readb(mtk_musb->mregs,MUSB_POWER),devctl); */
  864. devctl &= ~MUSB_DEVCTL_HR;
  865. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl);
  866. if (is_td_59)
  867. g_otg_message.msg = OTG_MSG_DEV_NOT_RESPONSE;
  868. return TEST_IS_STOP;
  869. }
  870. }
  871. /* reset the bus and check whether it is a hs device */
  872. musb_h_reset();
  873. musb_h_enumerate();
  874. /* suspend the bus */
  875. musb_h_suspend();
  876. /* polling the disconnect interrupt from A-OPT */
  877. DBG(0, "polling disconnect form A-OPT,begin\n");
  878. ret = musb_polling_bus_interrupt(MUSB_INTR_DISCONNECT);
  879. DBG(0, "polling disconnect form A-OPT,done,ret=0x%x\n", ret);
  880. /* DBG(0,"power=0x%x,devctl=0x%x,intrusb=0x%x\n",
  881. musb_readb(mtk_musb->mregs,MUSB_POWER),
  882. musb_readb(mtk_musb->mregs,MUSB_DEVCTL),musb_readb(mtk_musb->mregs,MUSB_INTRUSB)); */
  883. if (TEST_IS_STOP == ret)
  884. return TEST_IS_STOP;
  885. DBG(0, "A-OPT is disconnected, UUT will be back to device\n");
  886. if (!(ret & MUSB_INTR_RESET)) {
  887. musb_d_soft_connect(true);
  888. /* polling the reset single form the A-OPT */
  889. DBG(0, "polling reset form A-OPT,begin\n");
  890. ret = musb_polling_bus_interrupt(MUSB_INTR_RESET);
  891. /* musb_d_reset (); */
  892. DBG(0, "polling reset form A-OPT,done,ret=0x%x\n", ret);
  893. if (TEST_IS_STOP == ret)
  894. return TEST_IS_STOP;
  895. }
  896. device_enumed = false;
  897. if (g_exec)
  898. goto TD6_13; /* TD5_5 */
  899. wait_for_completion(&stop_event);
  900. }
  901. int musb_otg_exec_cmd(unsigned int cmd)
  902. {
  903. unsigned char devctl;
  904. unsigned char intrusb;
  905. unsigned char power;
  906. unsigned short csr0;
  907. unsigned int usb_l1intp;
  908. unsigned int usb_l1ints;
  909. if (!mtk_musb)
  910. DBG(0, "mtk_musb is NULL,error!\n");
  911. switch (cmd) {
  912. case HOST_CMD_ENV_INIT:
  913. musb_otg_env_init();
  914. return 0;
  915. case HOST_CMD_ENV_EXIT:
  916. musb_otg_env_exit();
  917. return 0;
  918. }
  919. /* init */
  920. musb_writeb(mtk_musb->mregs, MUSB_POWER, 0x21);
  921. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0);
  922. msleep(300);
  923. #ifdef DX_DBG
  924. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  925. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  926. intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB);
  927. DBG(0, "1:cmd=%d,devctl=0x%x,power=0x%x,intrusb=0x%x\n", cmd, devctl, power, intrusb);
  928. #endif
  929. musb_writew(mtk_musb->mregs, MUSB_INTRRX, 0xffff);
  930. musb_writew(mtk_musb->mregs, MUSB_INTRTX, 0xffff);
  931. musb_writeb(mtk_musb->mregs, MUSB_INTRUSB, 0xff);
  932. mdelay(10);
  933. #ifdef DX_DBG
  934. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  935. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  936. intrusb = musb_readb(mtk_musb->mregs, MUSB_INTRUSB);
  937. DBG(0, "2:cmd=%d,devctl=0x%x,power=0x%x,intrusb=0x%x\n", cmd, devctl, power, intrusb);
  938. #endif
  939. high_speed = false;
  940. g_exec = 1;
  941. DBG(0, "before exec:cmd=%d\n", cmd);
  942. switch (cmd) {
  943. /* electrical */
  944. case OTG_CMD_E_ENABLE_VBUS:
  945. DBG(0, "musb::enable VBUS!\n");
  946. musb_otg_set_session(true);
  947. musb_platform_set_vbus(mtk_musb, 1);
  948. while (g_exec)
  949. msleep(100);
  950. musb_otg_set_session(false);
  951. musb_platform_set_vbus(mtk_musb, 0);
  952. break;
  953. case OTG_CMD_E_ENABLE_SRP: /* need to clear session? */
  954. DBG(0, "musb::enable srp!\n");
  955. musb_otg_reset_usb();
  956. USBPHY_WRITE8(0x6c, 0x1);
  957. USBPHY_WRITE8(0x6d, 0x1);
  958. musb_writeb(mtk_musb->mregs, 0x7B, 1);
  959. musb_otg_set_session(true);
  960. while (g_exec)
  961. msleep(100);
  962. musb_otg_set_session(false);
  963. break;
  964. case OTG_CMD_E_START_DET_SRP:
  965. /* need as a A-device */
  966. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0);
  967. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  968. while (g_exec && (devctl & 0x18)) {
  969. DBG(0, "musb::not below session end!\n");
  970. msleep(100);
  971. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  972. }
  973. while (g_exec && (!(devctl & 0x10))) {
  974. DBG(0, "musb::not above session end!\n");
  975. msleep(100);
  976. devctl = musb_readb(mtk_musb->mregs, MUSB_DEVCTL);
  977. }
  978. devctl |= MUSB_DEVCTL_SESSION;
  979. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl);
  980. while (g_exec)
  981. msleep(100);
  982. musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, 0);
  983. break;
  984. case OTG_CMD_E_START_DET_VBUS:
  985. usb_l1intp = musb_readl(mtk_musb->mregs, USB_L1INTP);
  986. usb_l1intp &= ~(1 << 10);
  987. musb_writel(mtk_musb->mregs, USB_L1INTP, usb_l1intp);
  988. usb_l1ints = musb_readl(mtk_musb->mregs, USB_L1INTS);
  989. while ((usb_l1ints & (1 << 8)) == 0) {
  990. DBG(0, "musb::vbus is 0!\n");
  991. msleep(100);
  992. usb_l1ints = musb_readl(mtk_musb->mregs, USB_L1INTS);
  993. }
  994. DBG(0, "musb::vbus is detected!\n");
  995. power = musb_readb(mtk_musb->mregs, MUSB_POWER);
  996. power |= MUSB_POWER_SOFTCONN;
  997. musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
  998. while (g_exec)
  999. msleep(100);
  1000. musb_writeb(mtk_musb->mregs, MUSB_POWER, 0x21);
  1001. break;
  1002. case OTG_CMD_P_B_UUT_TD59:
  1003. is_td_59 = true;
  1004. if (is_td_59)
  1005. DBG(0, "TD5.9 will be tested!\n");
  1006. break;
  1007. /* protocal */
  1008. case OTG_CMD_P_A_UUT:
  1009. DBG(0, "A-UUT starts...\n");
  1010. otg_cmd_a_uut();
  1011. DBG(0, "the test as A-UUT is done\n");
  1012. break;
  1013. case OTG_CMD_P_B_UUT:
  1014. DBG(0, "B-UUT starts...\n");
  1015. otg_cmd_b_uut();
  1016. DBG(0, "the test as B_UUT is done\n");
  1017. break;
  1018. case HOST_CMD_TEST_SE0_NAK:
  1019. case HOST_CMD_TEST_J:
  1020. case HOST_CMD_TEST_K:
  1021. case HOST_CMD_TEST_PACKET:
  1022. case HOST_CMD_SUSPEND_RESUME:
  1023. case HOST_CMD_GET_DESCRIPTOR:
  1024. case HOST_CMD_SET_FEATURE:
  1025. musb_host_test_mode(cmd);
  1026. while (g_exec)
  1027. msleep(100);
  1028. break;
  1029. }
  1030. DBG(0, "musb_otg_exec_cmd--\n");
  1031. return 0;
  1032. }
  1033. void musb_otg_stop_cmd(void)
  1034. {
  1035. DBG(0, "musb_otg_stop_cmd++\n");
  1036. g_exec = 0;
  1037. is_td_59 = false;
  1038. complete(&stop_event);
  1039. }
  1040. unsigned int musb_otg_message(void)
  1041. {
  1042. /* for EM to pop the message */
  1043. unsigned int msg;
  1044. msg = g_otg_message.msg;
  1045. g_otg_message.msg = 0;
  1046. return msg;
  1047. }
  1048. void musb_otg_message_cb(void)
  1049. {
  1050. /* when the OK button is clicked on EM, this func is called. */
  1051. spin_lock(&g_otg_message.lock);
  1052. g_otg_message.msg = 0;
  1053. spin_unlock(&g_otg_message.lock);
  1054. }
  1055. static int musb_otg_test_open(struct inode *inode, struct file *file)
  1056. {
  1057. DBG(0, "musb_otg_test_open++\n");
  1058. return 0;
  1059. }
  1060. static int musb_otg_test_release(struct inode *inode, struct file *file)
  1061. {
  1062. return 0;
  1063. }
  1064. ssize_t musb_otg_test_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
  1065. {
  1066. int ret = 0;
  1067. unsigned int message = musb_otg_message();
  1068. if (message)
  1069. DBG(0, "musb_otg_test_read:message=0x%x\n", message);
  1070. if (put_user((unsigned int)message, (unsigned int *)buf))
  1071. ret = -EFAULT;
  1072. return ret;
  1073. }
  1074. ssize_t musb_otg_test_write(struct file *filp, const char __user *buf, size_t count,
  1075. loff_t *ppos)
  1076. {
  1077. int ret = 0;
  1078. unsigned char value;
  1079. if (get_user(value, (unsigned char *)buf))
  1080. ret = -EFAULT;
  1081. else {
  1082. if (value == OTG_STOP_CMD) {
  1083. DBG(0, "musb_otg_test_write::OTG_STOP_CMD\n");
  1084. musb_otg_stop_cmd();
  1085. } else if (value == OTG_INIT_MSG) {
  1086. DBG(0, "musb_otg_test_write::OTG_INIT_MSG\n");
  1087. musb_otg_message_cb();
  1088. } else {
  1089. DBG(0, "musb_otg_test_write::the value is invalid,0x%x\n", value);
  1090. ret = -EFAULT;
  1091. }
  1092. }
  1093. return ret;
  1094. }
  1095. static long musb_otg_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  1096. {
  1097. int ret = 0;
  1098. DBG(0, "musb_otg_test_ioctl:cmd=0x%x\n", cmd);
  1099. ret = musb_otg_exec_cmd(cmd);
  1100. return (long)ret;
  1101. }
  1102. static const struct file_operations musb_otg_test_fops = {
  1103. .owner = THIS_MODULE,
  1104. .open = musb_otg_test_open,
  1105. .release = musb_otg_test_release,
  1106. .read = musb_otg_test_read,
  1107. .write = musb_otg_test_write,
  1108. .unlocked_ioctl = musb_otg_test_ioctl,
  1109. };
  1110. static struct miscdevice musb_otg_test_dev = {
  1111. .minor = MISC_DYNAMIC_MINOR,
  1112. /* .minor = 254, */
  1113. .name = TEST_DRIVER_NAME,
  1114. .fops = &musb_otg_test_fops,
  1115. .mode = 0666,
  1116. };
  1117. static const u8 musb_host_test_packet[53] = {
  1118. /* implicit SYNC then DATA0 to start */
  1119. /* JKJKJKJK x9 */
  1120. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1121. /* JJKKJJKK x8 */
  1122. 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  1123. /* JJJJKKKK x8 */
  1124. 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
  1125. /* JJJJJJJKKKKKKK x8 */
  1126. 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  1127. /* JJJJJJJK x8 */
  1128. 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
  1129. /* JKKKKKKK x10, JK */
  1130. 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e
  1131. /* implicit CRC16 then EOP to end */
  1132. };
  1133. void musb_host_load_testpacket(struct musb *musb)
  1134. {
  1135. unsigned short csr0 = musb_readw(musb->mregs, 0x102);
  1136. DBG(0, "csr0=0x%x\n", csr0);
  1137. musb->ignore_disconnect = 1;
  1138. musb_otg_write_fifo(53, (u8 *) musb_host_test_packet);
  1139. }
  1140. void host_test_mode(struct musb *musb, unsigned int wIndex)
  1141. {
  1142. unsigned char temp;
  1143. unsigned char power;
  1144. struct usb_ctrlrequest setup_packet;
  1145. struct usb_device_descriptor device_descriptor;
  1146. setup_packet.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
  1147. setup_packet.bRequest = USB_REQ_GET_DESCRIPTOR;
  1148. setup_packet.wIndex = 0;
  1149. setup_packet.wValue = 0x0100;
  1150. setup_packet.wLength = 0x40;
  1151. musb_otg_set_session(true);
  1152. msleep(200);
  1153. DBG(0, "devctl = 0x%x\n", musb_readb(musb->mregs, MUSB_DEVCTL));
  1154. switch (wIndex) {
  1155. case HOST_CMD_TEST_SE0_NAK:
  1156. DBG(0, "TEST_SE0_NAK\n");
  1157. temp = MUSB_TEST_SE0_NAK;
  1158. musb_writeb(musb->mregs, MUSB_TESTMODE, temp);
  1159. break;
  1160. case HOST_CMD_TEST_J:
  1161. DBG(0, "TEST_J\n");
  1162. temp = MUSB_TEST_J;
  1163. musb_writeb(musb->mregs, MUSB_TESTMODE, temp);
  1164. break;
  1165. case HOST_CMD_TEST_K:
  1166. DBG(0, "TEST_K\n");
  1167. temp = MUSB_TEST_K;
  1168. musb_writeb(musb->mregs, MUSB_TESTMODE, temp);
  1169. break;
  1170. case HOST_CMD_TEST_PACKET:
  1171. DBG(0, "TEST_PACKET\n");
  1172. temp = MUSB_TEST_PACKET;
  1173. musb_host_load_testpacket(musb);
  1174. musb_writeb(musb->mregs, MUSB_TESTMODE, temp);
  1175. musb_writew(musb->mregs, 0x102, MUSB_CSR0_TXPKTRDY);
  1176. break;
  1177. case HOST_CMD_SUSPEND_RESUME: /* HS_HOST_PORT_SUSPEND_RESUME */
  1178. DBG(0, "HS_HOST_PORT_SUSPEND_RESUME\n");
  1179. msleep(5000); /* the host must continue sending SOFs for 15s */
  1180. DBG(0, "please begin to trigger suspend!\n");
  1181. msleep(10000);
  1182. power = musb_readb(musb->mregs, MUSB_POWER);
  1183. power |= MUSB_POWER_SUSPENDM | MUSB_POWER_ENSUSPEND;
  1184. musb_writeb(musb->mregs, MUSB_POWER, power);
  1185. msleep(5000);
  1186. DBG(0, "please begin to trigger resume!\n");
  1187. msleep(10000);
  1188. power &= ~MUSB_POWER_SUSPENDM;
  1189. power |= MUSB_POWER_RESUME;
  1190. musb_writeb(musb->mregs, MUSB_POWER, power);
  1191. mdelay(25);
  1192. power &= ~MUSB_POWER_RESUME;
  1193. musb_writeb(musb->mregs, MUSB_POWER, power);
  1194. /* SOF continue */
  1195. musb_h_setup(&setup_packet);
  1196. break;
  1197. case HOST_CMD_GET_DESCRIPTOR: /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
  1198. DBG(0, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR\n");
  1199. /* the host issues SOFs for 15s allowing the test engineer
  1200. to raise the scope trigger just above the SOF voltage level. */
  1201. msleep(15000);
  1202. musb_h_setup(&setup_packet);
  1203. break;
  1204. case HOST_CMD_SET_FEATURE: /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
  1205. DBG(0, "SINGLE_STEP_GET_DEVICE_DESCRIPTOR\n");
  1206. /* get device descriptor */
  1207. musb_h_setup(&setup_packet);
  1208. msleep(15000);
  1209. musb_h_in_data((char *)&device_descriptor, sizeof(struct usb_device_descriptor));
  1210. musb_h_out_status();
  1211. break;
  1212. default:
  1213. break;
  1214. }
  1215. /* while(1); */
  1216. }
  1217. static int musb_host_test_mode(unsigned char cmd)
  1218. {
  1219. musb_platform_set_vbus(mtk_musb, 1);
  1220. musb_otg_reset_usb();
  1221. host_test_mode(mtk_musb, cmd);
  1222. return 0;
  1223. }
  1224. static int __init musb_otg_test_init(void)
  1225. {
  1226. #ifdef CONFIG_OF
  1227. struct device_node *np;
  1228. np = of_find_compatible_node(NULL, NULL, "mediatek,PERICFG");
  1229. if (!np)
  1230. pr_debug("get PERICFG node fail");
  1231. pericfg_base = (unsigned long)of_iomap(np, 0);
  1232. #else
  1233. pericfg_base = PERICFG_BASE;
  1234. #endif
  1235. misc_register(&musb_otg_test_dev);
  1236. return 0;
  1237. }
  1238. static void __exit musb_otg_test_exit(void)
  1239. {
  1240. misc_deregister(&musb_otg_test_dev);
  1241. }
  1242. module_init(musb_otg_test_init);
  1243. module_exit(musb_otg_test_exit);