hal_udc.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777
  1. /* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
  2. * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
  3. * the the People's Republic of China and other countries.
  4. * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
  5. * DISCLAIMER
  6. * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
  7. * IF YOU NEED TO INTEGRATE THIRD PART'S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
  8. * IN ALLWINNER'SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
  9. * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
  10. * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
  11. * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
  12. * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PART'S TECHNOLOGY.
  13. * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
  14. * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
  15. * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
  16. * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
  17. * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18. * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
  22. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  23. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  25. * OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <stdio.h>
  28. #include <stdint.h>
  29. //#include <arch/mach/platform.h>
  30. //#include <arch/mach/irqs.h>
  31. #include <interrupt.h>
  32. //#include <io.h>
  33. #include <sunxi_hal_common.h>
  34. #include <usb/ch9.h>
  35. #include <hal_osal.h>
  36. #include <hal_clk.h>
  37. #include <hal_reset.h>
  38. #include <hal_cfg.h>
  39. #include "udc.h"
  40. #include "udc_platform.h"
  41. #include "../include/platform_usb.h"
  42. #define KEY_UDC_IRQ_FLAG "usbd_irq_flag"
  43. #define KEY_UDC_DRIVER_LEVEL "usbd_driver_level"
  44. #ifndef ARRAY_SIZE
  45. #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
  46. #endif
  47. /* UDC base address */
  48. static volatile UDC_REGISTER_T *musb = (UDC_REGISTER_T *)SUNXI_USB_OTG_PBASE;
  49. static volatile USBPHY_REGISTER_T *musb_phy = (USBPHY_REGISTER_T *)(SUNXI_USB_OTG_PBASE + USB_PHY_BASE_OFFSET);
  50. sunxi_udc_io_t sunxi_udc;
  51. /* UDC private data */
  52. udc_priv_t g_udc;
  53. /* NOTICE: 4K or 8K fifo size */
  54. #define SW_UDC_EPNUMS 4
  55. static udc_fifo_t g_ep_fifo[] = {
  56. {0, 0, 512, 0}, /* ep0 */
  57. {1 | USB_DIR_IN, 512, 512, 0}, /* bulk-in */
  58. {1 | USB_DIR_OUT, 1024, 512, 0}, /* bulk-out */
  59. {2 | USB_DIR_IN, 1536, 512, 0}, /* bulk-in */
  60. {2 | USB_DIR_OUT, 2048, 512, 0}, /* bulk-out */
  61. {3, 2560, 1024, 0}, /* iso */
  62. {4, 3584, 512, 0}, /* int */
  63. };
  64. /**
  65. * ep_fifo_in[i] = {n} i: the physic ep index, n: ep_fifo's index for the ep
  66. *
  67. * eg: ep_fifo_in[2] = {3} ===> ep2_in is in ep_fifo[3]
  68. *
  69. * ep3_iso_name and ep4_int_name cannot be tx or rx simultaneously.
  70. *
  71. */
  72. static const uint32_t g_ep_fifo_in[] = {0, 1, 3, 5, 6, 7};
  73. static const uint32_t g_ep_fifo_out[] = {0, 2, 4, 5, 6, 8};
  74. #define SW_UDC_ENDPOINTS ARRAY_SIZE(g_ep_fifo)
  75. /* identify ep0 control request */
  76. static uint8_t g_crq_bRequest;
  77. static uint8_t g_crq_wIndex;
  78. static hal_spinlock_t udc_lock;
  79. static void usbc_wakeup_clear_change_detect(void)
  80. {
  81. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_VBUS_CHANGE_DETECT);
  82. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_ID_CHANGE_DETECT);
  83. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_DPDM_CHANGE_DETECT);
  84. }
  85. static void usbc_enable_dpdm_pullup(bool enable)
  86. {
  87. if (enable) {
  88. USB_DRV_SetBits32(&musb_phy->iscr, USB_ISCR_DPDM_PULLUP_EN);
  89. } else {
  90. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_DPDM_PULLUP_EN);
  91. }
  92. usbc_wakeup_clear_change_detect();
  93. log_udc_dbg("dp dm pull up %s\r\n", enable ? "enabled" : "disabled");
  94. }
  95. static void usbc_enable_id_pullup(bool enable)
  96. {
  97. if (enable) {
  98. USB_DRV_SetBits32(&musb_phy->iscr, USB_ISCR_ID_PULLUP_EN);
  99. } else {
  100. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_ID_PULLUP_EN);
  101. }
  102. usbc_wakeup_clear_change_detect();
  103. log_udc_dbg("id pull up %s\r\n", enable ? "enabled" : "disabled");
  104. }
  105. static void usbc_force_id(uint32_t id_type)
  106. {
  107. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_FORCE_ID_MASK);
  108. USB_DRV_SetBits32(&musb_phy->iscr, id_type);
  109. usbc_wakeup_clear_change_detect();
  110. log_udc_dbg("force id type: 0x%x\r\n", id_type);
  111. }
  112. static void usbc_force_vbus_valid(uint32_t vbus_type)
  113. {
  114. USB_DRV_ClearBits32(&musb_phy->iscr, USB_ISCR_FORCE_VBUS_MASK);
  115. USB_DRV_SetBits32(&musb_phy->iscr, vbus_type);
  116. usbc_wakeup_clear_change_detect();
  117. log_udc_dbg("force vbus valid type: 0x%x\r\n", vbus_type);
  118. }
  119. static void usbc_select_bus(udc_io_type_t io_type, udc_ep_type_t ep_type, uint32_t ep_index)
  120. {
  121. uint32_t reg_val;
  122. reg_val = USB_DRV_Reg8(&musb->vend0);
  123. if (io_type == UDC_IO_TYPE_DMA) {
  124. if (ep_type == UDC_EP_TYPE_TX) {
  125. reg_val |= ((ep_index - 0x01) << 1)
  126. << USB_VEND0_DRQ_SEL; /* drq_sel */
  127. reg_val |= 0x1 << USB_VEND0_BUS_SEL; /* io_dma */
  128. }
  129. } else {
  130. reg_val &= 0x00; /* clear drq_sel, select pio */
  131. }
  132. /*
  133. * in SUN8IW5 SUN8IW6 and later ic, FIFO_BUS_SEL bit(bit24 of reg0x40
  134. * for host/device) is fixed to 1, the hw guarantee that it's ok for
  135. * cpu/inner_dma/outer_dma transfer.
  136. */
  137. reg_val |= 0x1 << USB_VEND0_BUS_SEL;
  138. USB_DRV_WriteReg8(&musb->vend0, reg_val);
  139. }
  140. static void usbc_phy_set_ctl(bool set)
  141. {
  142. /* NOTICE: 40nm platform is different */
  143. if (set) {
  144. USB_DRV_SetBits32(&musb_phy->phyctrl28nm, USB_PHYCTL28NM_VBUSVLDEXT);
  145. USB_DRV_ClearBits32(&musb_phy->phyctrl28nm, USB_PHYCTL28NM_SIDDQ);
  146. } else {
  147. USB_DRV_SetBits32(&musb_phy->phyctrl28nm, USB_PHYCTL28NM_SIDDQ);
  148. }
  149. log_udc_dbg("phy %s ctl\r\n", set ? "set" : "clear");
  150. }
  151. static void usbc_phy_otg_sel(bool otg_sel)
  152. {
  153. if (otg_sel) {
  154. USB_DRV_SetBits32(&musb_phy->physel, USB_PHYSEL_OTG_SEL);
  155. } else {
  156. USB_DRV_ClearBits32(&musb_phy->physel, USB_PHYSEL_OTG_SEL);
  157. }
  158. }
  159. static uint32_t usbc_get_active_ep(void)
  160. {
  161. return USB_DRV_Reg8(&musb->index);
  162. }
  163. static void usbc_select_active_ep(uint8_t ep_index)
  164. {
  165. USB_DRV_WriteReg8(&musb->index, ep_index);
  166. }
  167. static void usbc_udc_disable(void)
  168. {
  169. log_udc_dbg("udc disable\r\n");
  170. /* disable all interrupts */
  171. USB_DRV_WriteReg8(&musb->intrusbe, 0);
  172. USB_DRV_WriteReg8(&musb->intrtxe, 0);
  173. USB_DRV_WriteReg8(&musb->intrrxe, 0);
  174. /* clear the interrupt registers */
  175. USB_DRV_WriteReg(&musb->intrtx, 0xffff);
  176. USB_DRV_WriteReg(&musb->intrrx, 0xffff);
  177. USB_DRV_WriteReg8(&musb->intrusb, 0xff);
  178. /* clear soft connect */
  179. USB_DRV_ClearBits8(&musb->power, USB_POWER_SOFTCONN);
  180. }
  181. static void usbc_udc_enable(void)
  182. {
  183. log_udc_dbg("udc enable\r\n");
  184. /* config usb transfer type, default: bulk transfer */
  185. USB_DRV_ClearBits8(&musb->power, USB_POWER_ISOUPDATE);
  186. /* config usb gadget speed, default: high speed */
  187. USB_DRV_SetBits8(&musb->power, USB_POWER_HSENAB);
  188. /* enable usb bus interrupt */
  189. USB_DRV_SetBits8(&musb->intrusbe, USB_INTRUSB_SUSPEND
  190. | USB_INTRUSB_RESUME
  191. | USB_INTRUSB_RESET);
  192. /* enable ep0 interrupt */
  193. USB_DRV_SetBits(&musb->intrtxe, USB_INTRE_EPEN << 0);
  194. /* set soft connect */
  195. USB_DRV_SetBits8(&musb->power, USB_POWER_SOFTCONN);
  196. //krhino_spin_lock_init(&g_udc.lock);
  197. }
  198. /* mask the useless irq, save disconect, reset, resume, suspend */
  199. static uint32_t usbc_filtrate_irq(uint32_t usb_irq)
  200. {
  201. uint32_t irq = usb_irq;
  202. irq &= ~(USB_INTRUSBE_VBUSERROR
  203. | USB_INTRUSBE_SESSREQ
  204. | USB_INTRUSBE_CONN
  205. | USB_INTRUSBE_SOF);
  206. USB_DRV_ClearBits8(&musb->intrusb, USB_INTRUSBE_VBUSERROR
  207. | USB_INTRUSBE_SESSREQ
  208. | USB_INTRUSBE_CONN
  209. | USB_INTRUSBE_SOF);
  210. return irq;
  211. }
  212. static void *usbc_select_fifo(uint32_t ep_index)
  213. {
  214. uint32_t offset;
  215. offset = 0x0 + (ep_index << 2);
  216. return (void *)((char *)&musb->fifo0 + offset);
  217. }
  218. static uint32_t usbc_read_packet(void *fifo, uint32_t cnt, void *buf)
  219. {
  220. uint32_t len, i32, i8;
  221. uint8_t *buf8;
  222. uint32_t *buf32;
  223. /* adjust data */
  224. buf32 = buf;
  225. len = cnt;
  226. i32 = len >> 2;
  227. i8 = len & 0x03;
  228. /* deal with 4 byte part */
  229. while (i32--) {
  230. *buf32++ = USB_DRV_Reg32(fifo);
  231. }
  232. /* deal with not 4 byte part */
  233. buf8 = (uint8_t *)buf32;
  234. while (i8--) {
  235. *buf8++ = USB_DRV_Reg8(fifo);
  236. }
  237. return len;
  238. }
  239. static void usbc_write_packet(void *fifo, uint32_t cnt, void *buf)
  240. {
  241. uint32_t len, i32, i8;
  242. uint8_t *buf8;
  243. uint32_t *buf32;
  244. /* adjust data */
  245. buf32 = buf;
  246. len = cnt;
  247. i32 = len >> 2;
  248. i8 = len & 0x03;
  249. /* deal with 4 byte part */
  250. while (i32--) {
  251. USB_DRV_WriteReg32(fifo, *buf32++);
  252. }
  253. /* deal with not 4 byte part */
  254. buf8 = (uint8_t *)buf32;
  255. while (i8--) {
  256. USB_DRV_WriteReg8(fifo, *buf8++);
  257. }
  258. }
  259. static void usbc_ep_config_default(uint8_t is_in)
  260. {
  261. /* NOTICE: must already select active ep */
  262. if (is_in) {
  263. /* clear tx csr */
  264. USB_DRV_WriteReg(&musb->txcsr, 0x00);
  265. /* clear tx ep max packet */
  266. USB_DRV_WriteReg(&musb->txmap, 0x00);
  267. /* flush fifo */
  268. USB_DRV_WriteReg(&musb->txcsr, USB_TXCSR_CLRDATATOG
  269. | USB_TXCSR_FLUSHFIFO);
  270. } else {
  271. /* clear rx csr */
  272. USB_DRV_WriteReg(&musb->rxcsr, 0x00);
  273. /* clear rx ep max packet */
  274. USB_DRV_WriteReg(&musb->rxmap, 0x00);
  275. /* flush fifo */
  276. USB_DRV_WriteReg(&musb->rxcsr, USB_RXCSR_CLRDATATOG
  277. | USB_RXCSR_FLUSHFIFO);
  278. }
  279. }
  280. static void usbc_ep_config(uint32_t ts_type, uint16_t maxpacket,
  281. uint8_t is_double_fifo, uint8_t is_in)
  282. {
  283. uint32_t reg_val;
  284. uint32_t temp;
  285. /* NOTICE: must already select active ep */
  286. if (is_in) {
  287. /* config tx csr */
  288. reg_val = USB_TXCSR_MODE | USB_TXCSR_CLRDATATOG | USB_TXCSR_FLUSHFIFO;
  289. USB_DRV_WriteReg(&musb->txcsr, reg_val);
  290. if (is_double_fifo) /* config twice */
  291. USB_DRV_WriteReg(&musb->txcsr, reg_val);
  292. /* config tx ep max packet */
  293. reg_val = USB_DRV_Reg(&musb->txmap);
  294. temp = maxpacket & USB_TXMAXP_MAXPAYLOAD_MASK;
  295. reg_val |= temp;
  296. USB_DRV_WriteReg(&musb->txmap, reg_val);
  297. /* config tx ep transfer type */
  298. switch (ts_type) {
  299. case USB_ENDPOINT_XFER_ISOC:
  300. USB_DRV_SetBits(&musb->txcsr, USB_TXCSR_ISO);
  301. break;
  302. case USB_ENDPOINT_XFER_INT:
  303. case USB_ENDPOINT_XFER_BULK:
  304. USB_DRV_ClearBits(&musb->txcsr, USB_TXCSR_ISO);
  305. break;
  306. default:
  307. USB_DRV_ClearBits(&musb->txcsr, USB_TXCSR_ISO);
  308. break;
  309. }
  310. } else {
  311. /* config rx csr */
  312. reg_val = USB_RXCSR_CLRDATATOG | USB_RXCSR_FLUSHFIFO;
  313. USB_DRV_WriteReg(&musb->rxcsr, reg_val);
  314. if (is_double_fifo) /* config twice */
  315. USB_DRV_WriteReg(&musb->rxcsr, reg_val);
  316. /* config rx ep max packet */
  317. reg_val = USB_DRV_Reg(&musb->rxmap);
  318. temp = maxpacket & USB_RXMAXP_MAXPAYLOAD_MASK;
  319. reg_val |= temp;
  320. USB_DRV_WriteReg(&musb->rxmap, reg_val);
  321. /* config rx ep transfer type */
  322. switch (ts_type) {
  323. case USB_ENDPOINT_XFER_ISOC:
  324. USB_DRV_SetBits(&musb->rxcsr, USB_RXCSR_ISO);
  325. break;
  326. case USB_ENDPOINT_XFER_INT:
  327. USB_DRV_SetBits(&musb->rxcsr, USB_RXCSR_DISNYET);
  328. break;
  329. case USB_ENDPOINT_XFER_BULK:
  330. USB_DRV_ClearBits(&musb->rxcsr, USB_RXCSR_ISO);
  331. break;
  332. default:
  333. USB_DRV_ClearBits(&musb->rxcsr, USB_RXCSR_ISO);
  334. break;
  335. }
  336. }
  337. }
  338. static void usbc_ep_fifo_config(uint32_t fifo_addr, uint32_t fifo_size,
  339. uint8_t is_double_fifo, uint8_t is_in)
  340. {
  341. uint32_t temp;
  342. uint32_t size; /* fifo_size = 2^(size + 3) */
  343. uint32_t addr; /* fifo_addr = addr * 8 */
  344. /* NOTICE: must already select active ep */
  345. /* 512 align */
  346. size = 0;
  347. temp = fifo_size + 511;
  348. temp &= ~511;
  349. temp >>= 3;
  350. temp >>= 1;
  351. while (temp) {
  352. size++;
  353. temp >>= 1;
  354. }
  355. /* caculate addr */
  356. addr = fifo_addr >> 3;
  357. if (is_in) {
  358. /* config fifo addr */
  359. USB_DRV_WriteReg(&musb->txfifoadd, addr);
  360. /* config fifo size */
  361. USB_DRV_WriteReg8(&musb->txfifosz, (size & USB_FIFOSZ_SIZE_MASK));
  362. if (is_double_fifo)
  363. USB_DRV_SetBits8(&musb->txfifosz, USB_FIFOSZ_DPB);
  364. } else {
  365. /* config fifo addr */
  366. USB_DRV_WriteReg(&musb->rxfifoadd, addr);
  367. /* config fifo size */
  368. USB_DRV_WriteReg8(&musb->rxfifosz, (size & USB_FIFOSZ_SIZE_MASK));
  369. if (is_double_fifo)
  370. USB_DRV_SetBits8(&musb->rxfifosz, USB_FIFOSZ_DPB);
  371. }
  372. }
  373. static void usbc_ep_intr_enable(uint8_t ep_idx, uint8_t is_in)
  374. {
  375. /* NOTICE: must already select active ep */
  376. if (is_in) {
  377. USB_DRV_SetBits(&musb->intrtxe, USB_INTRE_EPEN << ep_idx);
  378. } else {
  379. USB_DRV_SetBits(&musb->intrrxe, USB_INTRE_EPEN << ep_idx);
  380. }
  381. }
  382. static udc_errno_t crq_get_status(struct usb_ctrlrequest *crq)
  383. {
  384. uint16_t status = 0;
  385. uint8_t buf[8];
  386. uint8_t ep_idx = crq->wIndex & 0x7f;
  387. uint8_t is_in = crq->wIndex & USB_DIR_IN;
  388. void *fifo;
  389. switch (crq->bRequestType & USB_RECIP_MASK) {
  390. case USB_RECIP_INTERFACE:
  391. buf[0] = 0x00;
  392. buf[1] = 0x00;
  393. break;
  394. case USB_RECIP_DEVICE:
  395. buf[0] = 0x01;
  396. buf[1] = 0x00;
  397. break;
  398. case USB_RECIP_ENDPOINT:
  399. if (crq->wLength > 2)
  400. return UDC_ERRNO_CMD_INVALID;
  401. if (ep_idx == 0) {
  402. status = USB_DRV_Reg(&musb->txcsr) & USB_CSR0_SENDSTALL;
  403. } else {
  404. if (is_in)
  405. status = USB_DRV_Reg(&musb->txcsr) & USB_TXCSR_SENDSTALL;
  406. else
  407. status = USB_DRV_Reg(&musb->rxcsr) & USB_RXCSR_SENDSTALL;
  408. }
  409. status = status ? 1 : 0;
  410. if (status) {
  411. buf[0] = 0x01;
  412. buf[1] = 0x00;
  413. } else {
  414. buf[0] = 0x00;
  415. buf[1] = 0x00;
  416. }
  417. break;
  418. default:
  419. return UDC_ERRNO_CMD_INVALID;
  420. }
  421. /* need udelay(5)? */
  422. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY);
  423. fifo = usbc_select_fifo(0);
  424. usbc_write_packet(fifo, crq->wLength, buf);
  425. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_TXPKTRDY
  426. | USB_CSR0_DATAEND);
  427. return UDC_ERRNO_SUCCESS;
  428. }
  429. static int32_t pio_read_fifo(udc_ep_t *ep, bool need_callback)
  430. {
  431. bool is_last;
  432. void *fifo;
  433. void *buf;
  434. uint32_t idx;
  435. uint32_t fifo_count;
  436. uint32_t bufferspace;
  437. uint32_t avail;
  438. uint32_t count;
  439. if (!ep->pdata) {
  440. log_udc_dbg("ep data buf is NULL\r\n");
  441. return -3;
  442. }
  443. idx = ep->ep_addr & 0x7f;
  444. /* select fifo*/
  445. fifo = usbc_select_fifo(idx);
  446. buf = ep->pdata + ep->data_actual;
  447. bufferspace = ep->data_len - ep->data_actual;
  448. if (bufferspace <= 0) {
  449. log_udc_err("receive buffer full\r\n");
  450. /* callback to user ?*/
  451. return -3;
  452. }
  453. fifo_count = USB_DRV_Reg(&musb->rxcount);
  454. if (fifo_count > ep->maxpacket)
  455. avail = ep->maxpacket;
  456. else
  457. avail = fifo_count;
  458. count = min(bufferspace, avail);
  459. ep->data_actual += count;
  460. usbc_read_packet(fifo, count, buf);
  461. /* checking this with ep0 is not accurate as we already
  462. * read a control request */
  463. if (idx != 0 && (fifo_count < ep->maxpacket || ep->data_len == ep->data_actual))
  464. is_last = 1;
  465. else
  466. is_last = (ep->data_len <= ep->data_actual) ? 1 : 0;
  467. if (idx) { /* ep1~4*/
  468. USB_DRV_ClearBits(&musb->rxcsr, USB_RXCSR_RXPKTRDY
  469. | USB_RXCSR_OVERRUN
  470. | USB_RXCSR_DATAERROR);
  471. if (is_last) {
  472. /* callback to user */
  473. if (need_callback && g_udc.callback)
  474. g_udc.callback(ep->ep_addr, UDC_EVENT_RX_DATA,
  475. ep->pdata, ep->data_actual);
  476. ep->pdata = NULL;
  477. ep->data_actual = 0;
  478. }
  479. } else { /* ep0 */
  480. if (is_last) {
  481. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY
  482. | USB_CSR0_DATAEND);
  483. /* callback to user */
  484. if (need_callback && g_udc.callback)
  485. g_udc.callback(ep->ep_addr, UDC_EVENT_RX_DATA,
  486. ep->pdata, ep->data_actual);
  487. ep->pdata = NULL;
  488. ep->data_actual = 0;
  489. g_udc.ep0state = UDC_EP0_IDLE;
  490. } else {
  491. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY);
  492. }
  493. }
  494. return count;
  495. }
  496. static uint32_t pio_read_fifo_crq(struct usb_ctrlrequest *crq)
  497. {
  498. uint32_t fifo_count;
  499. uint32_t i;
  500. void *pout = crq;
  501. void *fifo;
  502. fifo = usbc_select_fifo(0);
  503. fifo_count = USB_DRV_Reg(&musb->rxcount);
  504. log_udc_dbg("ep0 fifo count is %d\r\n", fifo_count);
  505. if (fifo_count != 8) {
  506. i = 0;
  507. while (i < 16 && (fifo_count != 8)) {
  508. fifo_count = USB_DRV_Reg(&musb->rxcount);
  509. i++;
  510. }
  511. if (i >= 16) {
  512. log_udc_err("ep0 get fifo len failed\r\n");
  513. }
  514. }
  515. return usbc_read_packet(fifo, fifo_count, pout);
  516. }
  517. static int32_t pio_write_fifo(udc_ep_t *ep)
  518. {
  519. bool is_last;
  520. void *fifo;
  521. void *buf;
  522. uint32_t idx;
  523. uint32_t count;
  524. if (!ep->pdata) {
  525. log_udc_dbg("ep data buf is NULL\r\n");
  526. return UDC_ERRNO_BUF_NULL;
  527. }
  528. idx = ep->ep_addr & 0x7f;
  529. fifo = usbc_select_fifo(idx);
  530. count = min(ep->data_len - ep->data_actual, ep->maxpacket);
  531. buf = ep->pdata + ep->data_actual;
  532. ep->data_actual += count;
  533. usbc_write_packet(fifo, count, buf);
  534. /* check if the last packet
  535. * last packet is often short (sometimes a zlp) */
  536. if (count != ep->maxpacket || ep->data_len == ep->data_actual)
  537. is_last = 1;
  538. else
  539. is_last = 0;
  540. if (idx) { /* ep1~4 */
  541. USB_DRV_ClearBits(&musb->txcsr, USB_TXCSR_UNDERRUN)
  542. USB_DRV_SetBits(&musb->txcsr, USB_TXCSR_TXPKTRDY);
  543. if (is_last) {
  544. ep->pdata = NULL;
  545. ep->data_actual = 0;
  546. }
  547. } else { /* ep0 */
  548. if (is_last) {
  549. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_TXPKTRDY
  550. | USB_CSR0_DATAEND);
  551. ep->pdata = NULL;
  552. ep->data_actual = 0;
  553. g_udc.ep0state = UDC_EP0_IDLE;
  554. } else {
  555. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_TXPKTRDY);
  556. }
  557. }
  558. return count;
  559. }
  560. static void udc_set_halt_ex(uint8_t ep_addr, int value);
  561. static void udc_handle_ep0_idle(void)
  562. {
  563. uint32_t len;
  564. uint32_t string_idx;
  565. uint32_t config_idx;
  566. struct usb_ctrlrequest *crq = &g_udc.crq;
  567. udc_ep_t *ep0 = &g_udc.ep0;
  568. int is_in = 0;
  569. /* start control request */
  570. if (!(USB_DRV_Reg(&musb->txcsr) & USB_CSR0_RXPKTRDY)) {
  571. log_udc_dbg("ep0 setup data is not ready\r\n");
  572. return;
  573. }
  574. len = pio_read_fifo_crq(crq);
  575. if (len != sizeof(*crq)) {
  576. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY);
  577. USB_DRV_SetBits(&musb->txcsr, USB_CSR0_SENDSTALL);
  578. goto stall;
  579. }
  580. log_udc_dbg("ep0: bRequest = 0x%x, bRequestType = 0x%x, wValue = 0x%x, "
  581. "wIndex = 0x%x, wLength = 0x%x\r\n",
  582. crq->bRequest, crq->bRequestType, crq->wValue,
  583. crq->wIndex, crq->wLength);
  584. g_udc.req_std = ((crq->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD);
  585. if (g_udc.req_std) { /* standard request */
  586. switch (crq->bRequest) {
  587. case USB_REQ_GET_DESCRIPTOR:
  588. if (crq->bRequestType != USB_DIR_IN) {
  589. goto stall;
  590. }
  591. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY);
  592. switch (crq->wValue >> 8) {
  593. case USB_DT_DEVICE:
  594. log_udc_dbg("get device descriptor\r\n");
  595. /* fill device descriptor */
  596. ep0->pdata = g_udc.device_desc;
  597. ep0->data_len = min(crq->wLength, (uint16_t)sizeof(*g_udc.device_desc));
  598. ep0->data_actual = 0;
  599. g_udc.ep0state = UDC_EP0_IN_DATA_PHASE;
  600. break;
  601. case USB_DT_CONFIG:
  602. log_udc_dbg("get configuration descriptor\r\n");
  603. ep0->pdata = g_udc.config_desc;
  604. ep0->data_len = min(crq->wLength, g_udc.config_desc_len);
  605. ep0->data_actual = 0;
  606. g_udc.ep0state = UDC_EP0_IN_DATA_PHASE;
  607. break;
  608. case USB_DT_STRING:
  609. log_udc_dbg("get string descriptor\r\n");
  610. string_idx = crq->wValue & 0xff;
  611. if (string_idx > g_udc.string_desc_num) {
  612. log_udc_err("get string descriptor index overflow\r\n");
  613. goto stall;
  614. }
  615. ep0->pdata = g_udc.string_desc[string_idx];
  616. ep0->data_len = min(crq->wLength, g_udc.string_desc[string_idx]->bLength);
  617. ep0->data_actual = 0;
  618. g_udc.ep0state = UDC_EP0_IN_DATA_PHASE;
  619. break;
  620. default:
  621. /* not support */
  622. log_udc_err("Get descriptor request not supported\r\n");
  623. goto stall;
  624. }
  625. break;
  626. case USB_REQ_SET_CONFIGURATION:
  627. log_udc_dbg("set configuration\r\n");
  628. /* rx receive over, data end, tx packet ready */
  629. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY
  630. | USB_CSR0_DATAEND);
  631. config_idx = crq->wValue & 0xff;
  632. if (config_idx > g_udc.device_desc->bNumConfigurations) {
  633. log_udc_err("set configuration index overflow\r\n");
  634. goto stall;
  635. }
  636. /* callback to user to reset configuration, interfaces and endpoints */
  637. if (g_udc.callback)
  638. g_udc.callback(0, UDC_EVENT_RX_STANDARD_REQUEST, crq, sizeof(*crq));
  639. break;
  640. case USB_REQ_GET_CONFIGURATION:
  641. log_udc_info("get configuration\r\n");
  642. /* TODO */
  643. break;
  644. case USB_REQ_SET_INTERFACE:
  645. log_udc_dbg("set interface\r\n");
  646. /* rx receive over, data end, tx packet ready */
  647. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY
  648. | USB_CSR0_DATAEND);
  649. /* TODO: callback to user to set altsetting */
  650. break;
  651. case USB_REQ_GET_INTERFACE:
  652. log_udc_info("get interface\r\n");
  653. /* TODO */
  654. break;
  655. case USB_REQ_SET_ADDRESS:
  656. log_udc_dbg("set address\r\n");
  657. if (crq->bRequestType == USB_RECIP_DEVICE) {
  658. g_udc.address = crq->wValue & 0x7f;
  659. /* rx receive over, data end, tx packet ready */
  660. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY
  661. | USB_CSR0_DATAEND);
  662. g_udc.ep0state = UDC_EP0_END_XFER;
  663. g_crq_bRequest = USB_REQ_SET_ADDRESS;
  664. return;
  665. }
  666. break;
  667. case USB_REQ_GET_STATUS:
  668. log_udc_dbg("get status\r\n");
  669. if (crq_get_status(crq) != UDC_ERRNO_SUCCESS)
  670. goto stall;
  671. break;
  672. case USB_REQ_CLEAR_FEATURE:
  673. log_udc_dbg("clear feature\r\n");
  674. /* --<1>--data direction must be host to device */
  675. if (crq->bRequestType & (1 << 7)) {
  676. log_udc_err("USB_REQ_CLEAR_FEATURE:\n");
  677. log_udc_err("data is not host to device\n");
  678. break;
  679. }
  680. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY
  681. | USB_CSR0_DATAEND);
  682. /* --<3>--data stage */
  683. if (crq->bRequestType == USB_RECIP_DEVICE) {
  684. /* wValue 0-1 */
  685. if (crq->wValue) {
  686. /*dev->devstatus &= ~(1 << USB_DEVICE_REMOTE_WAKEUP);*/
  687. } else {
  688. int k = 0;
  689. for (k = 0; k < SW_UDC_ENDPOINTS; k++) {
  690. is_in = crq->wIndex & USB_DIR_IN;
  691. udc_set_halt_ex(g_ep_fifo[k].ep_addr, 0);
  692. }
  693. }
  694. } else if (crq->bRequestType == USB_RECIP_INTERFACE) {
  695. /* do nothing */
  696. } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
  697. /* --<3>--release the forbidden of ep */
  698. /* wValue 0-1 */
  699. if (crq->wValue) {
  700. /*dev->devstatus &= ~(1 << USB_DEVICE_REMOTE_WAKEUP);*/
  701. } else {
  702. int k = 0;
  703. is_in = crq->wIndex & USB_DIR_IN;
  704. for (k = 0; k < SW_UDC_ENDPOINTS; k++) {
  705. if (g_ep_fifo[k].ep_addr == (crq->wIndex & 0xff))
  706. udc_set_halt_ex(g_ep_fifo[k].ep_addr, 0);
  707. }
  708. }
  709. } else {
  710. log_udc_dbg("PANIC : nonsupport set feature request. (%d)\r\n",
  711. crq->bRequestType);
  712. goto stall;
  713. }
  714. g_udc.ep0state = UDC_EP0_IDLE;
  715. break;
  716. case USB_REQ_SET_FEATURE:
  717. log_udc_info("set feature\r\n");
  718. /* TODO */
  719. break;
  720. default:
  721. /* not support */
  722. log_udc_err("Standard request not supported\r\n");
  723. goto stall;
  724. }
  725. /* callback to user to handle after then */
  726. if (g_udc.callback)
  727. g_udc.callback(0, UDC_EVENT_RX_STANDARD_REQUEST, crq, sizeof(*crq));
  728. } else { /* class request */
  729. /* callback to user to handle specific class requests */
  730. if (g_udc.callback)
  731. g_udc.callback(0, UDC_EVENT_RX_CLASS_REQUEST, crq, sizeof(*crq));
  732. }
  733. /* finish data stage in just one interrupt */
  734. switch (g_udc.ep0state) {
  735. case UDC_EP0_IN_DATA_PHASE:
  736. if (!(USB_DRV_Reg(&musb->txcsr) & USB_CSR0_TXPKTRDY))
  737. pio_write_fifo(&g_udc.ep0);
  738. g_udc.ep0state = UDC_EP0_IDLE;
  739. break;
  740. case UDC_EP0_OUT_DATA_PHASE:
  741. if (USB_DRV_Reg(&musb->txcsr) & USB_CSR0_RXPKTRDY)
  742. pio_read_fifo(&g_udc.ep0, true);
  743. g_udc.ep0state = UDC_EP0_IDLE;
  744. break;
  745. default:
  746. break;
  747. }
  748. return;
  749. stall:
  750. log_udc_dbg("ep0 send stall...\r\n");
  751. USB_DRV_WriteReg(&musb->txcsr, USB_CSR0_SERVICEDRXPKTRDY);
  752. USB_DRV_SetBits(&musb->txcsr, USB_CSR0_SENDSTALL);
  753. }
  754. static void udc_handle_ep0(void)
  755. {
  756. log_udc_dbg("Handling ep0, ep0state is %d\r\n", g_udc.ep0state);
  757. /* select ep0 */
  758. usbc_select_active_ep(0);
  759. /* clear stall status */
  760. if (USB_DRV_Reg(&musb->txcsr) & USB_CSR0_SENTSTALL) {
  761. log_udc_err("EP0 Stall\r\n");
  762. /* clear ep0 stall */
  763. USB_DRV_ClearBits(&musb->txcsr, USB_CSR0_SENDSTALL);
  764. USB_DRV_ClearBits(&musb->txcsr, USB_CSR0_SENTSTALL);
  765. g_udc.ep0state = UDC_EP0_IDLE;
  766. return;
  767. }
  768. /* clear setup end */
  769. if (USB_DRV_Reg(&musb->txcsr) & USB_CSR0_SETUPEND) {
  770. log_udc_dbg("EP0 Setup End\r\n");
  771. /* clear ep0 setup end */
  772. USB_DRV_SetBits(&musb->txcsr, USB_CSR0_SERVICEDSETUPEND);
  773. g_udc.ep0state = UDC_EP0_IDLE;
  774. }
  775. switch (g_udc.ep0state) {
  776. case UDC_EP0_IDLE:
  777. udc_handle_ep0_idle();
  778. break;
  779. case UDC_EP0_IN_DATA_PHASE: /* GET_DESCRIPTER etc... */
  780. log_udc_dbg("ep0 in data phase...\r\n");
  781. if (!(USB_DRV_Reg(&musb->txcsr) & USB_CSR0_TXPKTRDY))
  782. pio_write_fifo(&g_udc.ep0);
  783. break;
  784. case UDC_EP0_OUT_DATA_PHASE: /* SET_DESCRIPTER etc... */
  785. log_udc_dbg("ep0 out data phase...\r\n");
  786. if (USB_DRV_Reg(&musb->txcsr) & USB_CSR0_RXPKTRDY)
  787. pio_read_fifo(&g_udc.ep0, true);
  788. break;
  789. case UDC_EP0_END_XFER:
  790. log_udc_dbg("ep0 end xfer, g_crq_bRequest = 0x%x\r\n", g_crq_bRequest);
  791. switch (g_crq_bRequest) {
  792. case USB_REQ_SET_ADDRESS:
  793. /* clear ep0 setup end */
  794. USB_DRV_SetBits(&musb->txcsr, USB_CSR0_SERVICEDSETUPEND);
  795. /* set address */
  796. USB_DRV_WriteReg8(&musb->faddr, g_udc.address);
  797. log_udc_dbg("Set address: %d\r\n", g_udc.address);
  798. break;
  799. case USB_REQ_SET_FEATURE:
  800. /* TODO: enter test mode */
  801. break;
  802. default:
  803. break;
  804. }
  805. g_crq_bRequest = 0;
  806. g_udc.ep0state = UDC_EP0_IDLE;
  807. break;
  808. case UDC_EP0_STALL:
  809. log_udc_dbg("ep0 stall...\r\n");
  810. g_udc.ep0state = UDC_EP0_IDLE;
  811. break;
  812. }
  813. }
  814. static void udc_handle_ep(uint32_t fifo_idx)
  815. {
  816. udc_fifo_t fifo_config;
  817. uint8_t ep_idx;
  818. uint8_t old_ep_idx;
  819. uint8_t is_in;
  820. fifo_config = g_ep_fifo[fifo_idx];
  821. ep_idx = fifo_config.ep_addr & 0x7f;
  822. is_in = fifo_config.ep_addr & USB_DIR_IN;
  823. /* select ep */
  824. old_ep_idx = usbc_get_active_ep();
  825. usbc_select_active_ep(ep_idx);
  826. log_udc_dbg("Handling %s ep%d...\n", is_in ? "tx" : "rx", ep_idx);
  827. if (is_in) {
  828. if (USB_DRV_Reg(&musb->txcsr) & USB_TXCSR_SENTSTALL) {
  829. log_udc_err("tx ep%d is stall\n", ep_idx);
  830. USB_DRV_ClearBits(&musb->txcsr, USB_TXCSR_SENTSTALL
  831. | USB_TXCSR_SENDSTALL);
  832. /* clear data toggle */
  833. USB_DRV_SetBits(&musb->txcsr, USB_TXCSR_CLRDATATOG);
  834. goto end;
  835. }
  836. if (!(USB_DRV_Reg(&musb->txcsr) & USB_TXCSR_TXPKTRDY)) {
  837. if (!g_udc.epin[ep_idx - 1].pdata) {
  838. /* callback to user to fill tx buf */
  839. if (g_udc.callback)
  840. g_udc.callback(g_udc.epin[ep_idx - 1].ep_addr,
  841. UDC_EVENT_TX_COMPLETE, NULL, 0);
  842. } else {
  843. pio_write_fifo(&g_udc.epin[ep_idx - 1]);
  844. }
  845. }
  846. } else {
  847. if (USB_DRV_Reg(&musb->rxcsr) & USB_RXCSR_SENTSTALL) {
  848. log_udc_err("rx ep%d is stall\n", ep_idx);
  849. USB_DRV_ClearBits(&musb->rxcsr, USB_RXCSR_SENTSTALL
  850. | USB_RXCSR_SENDSTALL);
  851. /* clear data toggle */
  852. USB_DRV_SetBits(&musb->rxcsr, USB_RXCSR_CLRDATATOG);
  853. goto end;
  854. }
  855. if (USB_DRV_Reg(&musb->rxcsr) & USB_RXCSR_RXPKTRDY)
  856. pio_read_fifo(&g_udc.epout[ep_idx - 1], true);
  857. }
  858. end:
  859. /* restore ep */
  860. usbc_select_active_ep(old_ep_idx);
  861. }
  862. static irqreturn_t udc_irq_handler(int dummy, void *dev_id)
  863. {
  864. uint32_t usb_irq, tx_irq, rx_irq;
  865. uint32_t old_ep_idx;
  866. uint32_t i;
  867. uint32_t flags;
  868. // krhino_spin_lock_irq_save(&g_udc.lock, flags);
  869. flags = hal_spin_lock_irqsave(&udc_lock);
  870. /* save index */
  871. old_ep_idx = USB_DRV_Reg8(&musb->index);
  872. /* read status registers */
  873. usb_irq = USB_DRV_Reg8(&musb->intrusb);
  874. tx_irq = USB_DRV_Reg(&musb->intrtx);
  875. rx_irq = USB_DRV_Reg(&musb->intrrx);
  876. usb_irq = usbc_filtrate_irq(usb_irq);
  877. log_udc_dbg("usb_irq: %02x, tx_irq: %02x, rx_irq: %02x\n",
  878. usb_irq, tx_irq, rx_irq);
  879. /* RESET */
  880. if (usb_irq & USB_INTRUSB_RESET) {
  881. log_udc_dbg("irq: Reset\r\n");
  882. /* clear irq pending */
  883. USB_DRV_WriteReg8(&musb->intrusb, USB_INTRUSB_RESET);
  884. /* select ep0 */
  885. usbc_select_active_ep(0);
  886. /* set default address: 0x0 */
  887. USB_DRV_WriteReg8(&musb->faddr, 0x00);
  888. g_udc.address = 0;
  889. g_udc.ep0state = UDC_EP0_IDLE;
  890. g_udc.speed = UDC_SPEED_UNKNOWN;
  891. goto end;
  892. }
  893. /* RESUME */
  894. if (usb_irq & USB_INTRUSB_RESUME) {
  895. log_udc_dbg("irq: Resume\r\n");
  896. /* clear irq pending */
  897. USB_DRV_WriteReg8(&musb->intrusb, USB_INTRUSB_RESUME);
  898. if (g_udc.speed != UDC_SPEED_UNKNOWN) {
  899. /* TODO: Resume work */
  900. }
  901. }
  902. /* SUSPEND */
  903. if (usb_irq & USB_INTRUSB_SUSPEND) {
  904. log_udc_dbg("irq: Suspend\r\n");
  905. /* clear irq pending */
  906. USB_DRV_WriteReg8(&musb->intrusb, USB_INTRUSB_SUSPEND);
  907. if (g_udc.speed != UDC_SPEED_UNKNOWN) {
  908. /* TODO: Suspend work */
  909. }
  910. g_udc.ep0state = UDC_EP0_IDLE;
  911. }
  912. /* EP0 control transfer */
  913. if (tx_irq & USB_INTRTX_EP0) {
  914. log_udc_dbg("irq: ep0\r\n");
  915. /* clear irq pending by setting it to a 1 */
  916. USB_DRV_WriteReg(&musb->intrtx, USB_INTRTX_EP0);
  917. if (g_udc.speed == UDC_SPEED_UNKNOWN) {
  918. if (USB_DRV_Reg8(&musb->power) & USB_POWER_HSMODE) {
  919. log_udc_dbg("usb enter High-speed mode\r\n");
  920. g_udc.speed = UDC_SPEED_HIGH;
  921. } else {
  922. log_udc_dbg("usb enter Full-speed mode\r\n");
  923. g_udc.speed = UDC_SPEED_FULL;
  924. }
  925. }
  926. udc_handle_ep0();
  927. }
  928. /* firstly to get data */
  929. /* rx endpoint data transfers */
  930. for (i = 1; i <= SW_UDC_EPNUMS; i++) {
  931. uint32_t tmp = 1 << i;
  932. if (rx_irq & tmp) {
  933. log_udc_dbg("rx irq: ep%d\n", i);
  934. /* clear irq pending by setting it to a 1 */
  935. USB_DRV_WriteReg(&musb->intrrx, 0x1 << i);
  936. udc_handle_ep(g_ep_fifo_out[i]);
  937. }
  938. }
  939. /* tx endpoint data transfers */
  940. for (i = 1; i <= SW_UDC_EPNUMS; i++) {
  941. uint32_t tmp = 1 << i;
  942. if (tx_irq & tmp) {
  943. log_udc_dbg("tx irq: ep%d\n", i);
  944. /* clear irq pending by setting it to a 1 */
  945. USB_DRV_WriteReg(&musb->intrtx, 0x1 << i);
  946. udc_handle_ep(g_ep_fifo_in[i]);
  947. }
  948. }
  949. end:
  950. /* restore ep */
  951. usbc_select_active_ep(old_ep_idx);
  952. // krhino_spin_unlock_irq_restore(&g_udc.lock, flags);
  953. hal_spin_unlock_irqrestore(&udc_lock, flags);
  954. return IRQ_HANDLED;
  955. }
  956. void hal_udc_device_desc_init(struct usb_device_descriptor *device_desc)
  957. {
  958. g_udc.device_desc = device_desc;
  959. }
  960. void hal_udc_config_desc_init(void *config_desc, uint32_t len)
  961. {
  962. g_udc.config_desc = config_desc;
  963. g_udc.config_desc_len = len;
  964. }
  965. void hal_udc_string_desc_init(const void *string_desc)
  966. {
  967. g_udc.string_desc[g_udc.string_desc_num]
  968. = (struct usb_string_descriptor *)string_desc;
  969. g_udc.string_desc_num++;
  970. }
  971. static void ep_info_init(void)
  972. {
  973. uint32_t i;
  974. /* ep0 init */
  975. g_udc.ep0.ep_addr = 0;
  976. g_udc.ep0.maxpacket = UDC_MAX_PACKET_SIZE_EP0;
  977. /* epin init */
  978. for (i = 0; i < UDC_MAX_NUM_EP_TX; i++) {
  979. g_udc.epin[i].ep_addr = i + 1;
  980. g_udc.epin[i].maxpacket = UDC_MAX_PACKET_SIZE_EP_BULK;
  981. }
  982. /* epout init */
  983. for (i = 0; i < UDC_MAX_NUM_EP_RX; i++) {
  984. g_udc.epout[i].ep_addr = i + 1;
  985. g_udc.epout[i].maxpacket = UDC_MAX_PACKET_SIZE_EP_BULK;
  986. }
  987. }
  988. static void udc_set_halt_ex(uint8_t ep_addr, int value)
  989. {
  990. uint8_t ep_idx;
  991. uint8_t is_in;
  992. uint8_t old_ep_idx;
  993. ep_idx = ep_addr & 0x7f;
  994. is_in = ep_addr & USB_DIR_IN;
  995. /* select ep */
  996. old_ep_idx = usbc_get_active_ep();
  997. usbc_select_active_ep(ep_idx);
  998. if (ep_idx == 0) {
  999. USB_DRV_ClearBits(&musb->txcsr, USB_CSR0_SENDSTALL);
  1000. USB_DRV_ClearBits(&musb->txcsr, USB_CSR0_SENTSTALL);
  1001. } else {
  1002. if (is_in) {
  1003. if (value) {
  1004. USB_DRV_SetBits(&musb->txcsr, USB_TXCSR_SENDSTALL);
  1005. } else {
  1006. USB_DRV_ClearBits(&musb->txcsr, USB_TXCSR_SENTSTALL);
  1007. USB_DRV_ClearBits(&musb->txcsr, USB_TXCSR_SENDSTALL);
  1008. USB_DRV_SetBits(&musb->txcsr, USB_TXCSR_CLRDATATOG);
  1009. }
  1010. } else {
  1011. if (value) {
  1012. USB_DRV_SetBits(&musb->rxcsr, USB_RXCSR_SENDSTALL);
  1013. } else {
  1014. USB_DRV_ClearBits(&musb->rxcsr, USB_RXCSR_SENDSTALL);
  1015. USB_DRV_ClearBits(&musb->rxcsr, USB_RXCSR_SENTSTALL);
  1016. USB_DRV_SetBits(&musb->rxcsr, USB_RXCSR_CLRDATATOG);
  1017. }
  1018. }
  1019. }
  1020. usbc_select_active_ep(old_ep_idx);
  1021. return;
  1022. }
  1023. void hal_udc_ep_enable(uint8_t ep_addr, uint16_t maxpacket, uint32_t ts_type)
  1024. {
  1025. uint8_t fifo_idx;
  1026. uint8_t ep_idx;
  1027. uint8_t is_in;
  1028. udc_fifo_t fifo_config;
  1029. uint8_t old_ep_idx;
  1030. uint32_t reg_val;
  1031. uint32_t flags;
  1032. ep_idx = ep_addr & 0x7f;
  1033. is_in = ep_addr & USB_DIR_IN;
  1034. /* maybe use in irq, can't spinlock */
  1035. /*krhino_spin_lock_irq_save(&g_udc.lock, flags);*/
  1036. /* select ep */
  1037. old_ep_idx = usbc_get_active_ep();
  1038. usbc_select_active_ep(ep_idx);
  1039. if (is_in)
  1040. fifo_idx = g_ep_fifo_in[ep_idx];
  1041. else
  1042. fifo_idx = g_ep_fifo_out[ep_idx];
  1043. fifo_config = g_ep_fifo[fifo_idx];
  1044. log_udc_dbg("ep_addr: 0x%x, maxpacket: %d, ts_type: %d\n",
  1045. ep_addr, maxpacket, ts_type);
  1046. log_udc_dbg("fifo_idx: %d, fifo.ep_addr: 0x%x, fifo.addr: %d, fifo.size: %d, fifo.dbf: %d\n",
  1047. fifo_idx, fifo_config.ep_addr, fifo_config.fifo_addr,
  1048. fifo_config.fifo_size, fifo_config.double_fifo);
  1049. /* TODO: check validity */
  1050. usbc_ep_config_default(is_in);
  1051. /* set max packet, type, direction, address;
  1052. * reset fifo counters, enable irq */
  1053. usbc_ep_config(ts_type, maxpacket, fifo_config.double_fifo, is_in);
  1054. usbc_ep_fifo_config(fifo_config.fifo_addr, fifo_config.fifo_size,
  1055. fifo_config.double_fifo, is_in);
  1056. if (ts_type == USB_ENDPOINT_XFER_ISOC)
  1057. USB_DRV_SetBits8(&musb->power, USB_POWER_ISOUPDATE);
  1058. /* enable ep interrupt */
  1059. usbc_ep_intr_enable(ep_idx, is_in);
  1060. /* restore ep */
  1061. usbc_select_active_ep(old_ep_idx);
  1062. /*krhino_spin_unlock_irq_restore(&g_udc.lock, flags);*/
  1063. }
  1064. void hal_udc_ep_disable(uint8_t ep_addr)
  1065. {
  1066. /* TODO */
  1067. }
  1068. int32_t hal_udc_ep_read(uint8_t ep_addr, void *buf, uint32_t len)
  1069. {
  1070. uint8_t ep_idx;
  1071. uint8_t is_in;
  1072. udc_ep_t *ep;
  1073. uint8_t old_ep_idx;
  1074. int32_t ret = UDC_ERRNO_RX_NOT_READY;
  1075. uint32_t flags;
  1076. ep_idx = ep_addr & 0x7f;
  1077. is_in = ep_addr & USB_DIR_IN;
  1078. // krhino_spin_lock_irq_save(&g_udc.lock, flags);
  1079. flags = hal_spin_lock_irqsave(&udc_lock);
  1080. /* select ep */
  1081. old_ep_idx = usbc_get_active_ep();
  1082. usbc_select_active_ep(ep_idx);
  1083. if (ep_idx == 0) {
  1084. ep = &g_udc.ep0;
  1085. } else if (!is_in) {
  1086. ep = &g_udc.epout[ep_idx - 1];
  1087. } else {
  1088. ret = UDC_ERRNO_EP_INVALID;
  1089. goto end;
  1090. }
  1091. ep->pdata = buf;
  1092. ep->data_len = len;
  1093. if (USB_DRV_Reg(&musb->rxcsr) & USB_RXCSR_RXPKTRDY)
  1094. ret = pio_read_fifo(ep, false);
  1095. end:
  1096. /* restore ep */
  1097. usbc_select_active_ep(old_ep_idx);
  1098. // krhino_spin_unlock_irq_restore(&g_udc.lock, flags);
  1099. hal_spin_unlock_irqrestore(&udc_lock, flags);
  1100. return ret;
  1101. }
  1102. int32_t hal_udc_ep_write(uint8_t ep_addr, void *buf, uint32_t len)
  1103. {
  1104. uint8_t ep_idx;
  1105. uint8_t is_in;
  1106. udc_ep_t *ep;
  1107. uint8_t old_ep_idx;
  1108. int32_t ret = UDC_ERRNO_TX_BUSY;
  1109. uint32_t flags;
  1110. ep_idx = ep_addr & 0x7f;
  1111. is_in = ep_addr & USB_DIR_IN;
  1112. // krhino_spin_lock_irq_save(&g_udc.lock, flags);
  1113. flags = hal_spin_lock_irqsave(&udc_lock);
  1114. /* select ep */
  1115. old_ep_idx = usbc_get_active_ep();
  1116. usbc_select_active_ep(ep_idx);
  1117. if (ep_idx == 0) {
  1118. ep = &g_udc.ep0;
  1119. } else if (is_in) {
  1120. ep = &g_udc.epin[ep_idx - 1];
  1121. } else {
  1122. ret = UDC_ERRNO_EP_INVALID;
  1123. goto end;
  1124. }
  1125. ep->pdata = buf;
  1126. ep->data_len = len;
  1127. while((USB_DRV_Reg(&musb->txcsr) & USB_TXCSR_TXPKTRDY));
  1128. ret = pio_write_fifo(ep);
  1129. end:
  1130. /* restore ep */
  1131. usbc_select_active_ep(old_ep_idx);
  1132. // krhino_spin_unlock_irq_restore(&g_udc.lock, flags);
  1133. hal_spin_unlock_irqrestore(&udc_lock, flags);
  1134. return ret;
  1135. }
  1136. void USBC_EnterMode_Test_J(void)
  1137. {
  1138. USB_DRV_SetBits8(&musb->testmode, USB_TESTMODE_TESTSE0NAK);
  1139. }
  1140. void USBC_EnterMode_Test_K(void)
  1141. {
  1142. USB_DRV_SetBits8(&musb->testmode, USB_TESTMODE_TESTJ);
  1143. }
  1144. void USBC_EnterMode_Test_SE0_NAK(void)
  1145. {
  1146. USB_DRV_SetBits8(&musb->testmode, USB_TESTMODE_TESTK);
  1147. }
  1148. void USBC_EnterMode_TestPacket(void)
  1149. {
  1150. USB_DRV_SetBits8(&musb->testmode, USB_TESTMODE_TESTPACKET);
  1151. }
  1152. void USBC_EnterMode_Idle(void)
  1153. {
  1154. USB_DRV_ClearBits8(&musb->testmode, USB_TESTMODE_TESTSE0NAK);
  1155. USB_DRV_ClearBits8(&musb->testmode, USB_TESTMODE_TESTJ);
  1156. USB_DRV_ClearBits8(&musb->testmode, USB_TESTMODE_TESTK);
  1157. USB_DRV_ClearBits8(&musb->testmode, USB_TESTMODE_TESTPACKET);
  1158. }
  1159. static const unsigned char TestPkt[54] = {
  1160. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA,
  1161. 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xEE, 0xEE, 0xEE,
  1162. 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
  1163. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xBF, 0xDF,
  1164. 0xEF, 0xF7, 0xFB, 0xFD, 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7,
  1165. 0xFB, 0xFD, 0x7E, 0x00
  1166. };
  1167. ssize_t ed_test(const char *buf, size_t count)
  1168. {
  1169. if (!strncmp(buf, "test_j_state", 12)) {
  1170. USBC_EnterMode_Test_J();
  1171. hal_log_info("test_mode:%s\n", "test_j_state");
  1172. } else if (!strncmp(buf, "test_k_state", 12)) {
  1173. USBC_EnterMode_Test_K();
  1174. hal_log_info("test_mode:%s\n", "test_k_state");
  1175. } else if (!strncmp(buf, "test_se0_nak", 12)) {
  1176. USBC_EnterMode_Test_SE0_NAK();
  1177. hal_log_info("test_mode:%s\n", "test_se0_nak");
  1178. } else if (!strncmp(buf, "test_pack", 9)) {
  1179. void *fifo;
  1180. hal_log_info("test_mode___:%s\n", "test_pack");
  1181. USB_DRV_SetBits32(&musb->power, (0x1 << 0));
  1182. hal_sleep(1);
  1183. fifo = usbc_select_fifo(0);
  1184. usbc_write_packet(fifo, 54, (u32 *)TestPkt);
  1185. USB_DRV_SetBits(&musb->txcsr, (0x1 << 1));
  1186. USBC_EnterMode_TestPacket();
  1187. } else if (!strncmp(buf, "disable_test_mode", 17)) {
  1188. hal_log_info("start disable_test_mode\n");
  1189. USBC_EnterMode_Idle();
  1190. } else {
  1191. hal_log_err("ERR: test_mode Argment is invalid\n");
  1192. }
  1193. return count;
  1194. }
  1195. static int usbd_new_phyx_tp_write(int addr, int data, int len)
  1196. {
  1197. int temp = 0;
  1198. int j = 0;
  1199. int dtmp = 0;
  1200. /*device: 0x410(phy_ctl)*/
  1201. dtmp = data;
  1202. for (j = 0; j < len; j++)
  1203. {
  1204. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1205. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1206. temp |= (0x1 << 1);
  1207. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1208. DRV_WriteReg8((long)&musb_phy->phyctrl28nm + 1, addr + j);
  1209. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1210. temp &= ~(0x1 << 0);
  1211. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1212. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1213. temp &= ~(0x1 << 7);
  1214. temp |= (dtmp & 0x1) << 7;
  1215. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1216. temp |= (0x1 << 0);
  1217. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1218. temp &= ~(0x1 << 0);
  1219. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1220. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1221. temp &= ~(0x1 << 1);
  1222. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1223. dtmp >>= 1;
  1224. }
  1225. return 0;
  1226. }
  1227. static int usbd_new_phyx_tp_read(int addr, int len)
  1228. {
  1229. int temp = 0;
  1230. int i = 0;
  1231. int j = 0;
  1232. int ret = 0;
  1233. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1234. temp |= (0x1 << 1);
  1235. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1236. for (j = len; j > 0; j--)
  1237. {
  1238. DRV_WriteReg8((long)&musb_phy->phyctrl28nm + 1, (addr + j - 1));
  1239. for (i = 0; i < 0x4; i++);
  1240. temp = DRV_Reg8(&musb_phy->physta);
  1241. ret <<= 1;
  1242. ret |= (temp & 0x1);
  1243. }
  1244. temp = DRV_Reg8(&musb_phy->phyctrl28nm);
  1245. temp &= ~(0x1 << 1);
  1246. DRV_WriteReg8(&musb_phy->phyctrl28nm, temp);
  1247. return ret;
  1248. }
  1249. static ssize_t hal_udc_phy_init(void)
  1250. {
  1251. int value = 0;
  1252. usbd_new_phyx_tp_write(0x30, 0xef, 0x0D);
  1253. // printf("tx_tune: addr:%x,len:%x, value:%x\n", 0x60, 0x0E, usbd_new_phyx_tp_read(0x60, 0x0E));
  1254. value = usbd_new_phyx_tp_read(0x60, 0x0E);
  1255. // printf("driverlevel:%x\n", driverlevel);
  1256. value = (value & (~0x0f)) | sunxi_udc.drive_level;
  1257. usbd_new_phyx_tp_write(0x60, value, 0x0E);
  1258. // printf("tx_tune: addr:%x,len:%x, value:%x\n", 0x60, 0x0E, usbd_new_phyx_tp_read(0x60, 0x0E));
  1259. usbd_new_phyx_tp_write(0x44, 0xf, 0x04);
  1260. return 0;
  1261. }
  1262. ssize_t hal_udc_driverlevel_adjust(int driverlevel)
  1263. {
  1264. int value = 0;
  1265. printf("tx_tune: addr:%x,len:%x, value:%x\n", 0x60, 0x0E, usbd_new_phyx_tp_read(0x60, 0x0E));
  1266. value = usbd_new_phyx_tp_read(0x60, 0x0E);
  1267. printf("driverlevel:%x\n", driverlevel);
  1268. value = (value & (~0x0f)) | driverlevel;
  1269. usbd_new_phyx_tp_write(0x60, value, 0x0E);
  1270. printf("tx_tune: addr:%x,len:%x, value:%x\n", 0x60, 0x0E, usbd_new_phyx_tp_read(0x60, 0x0E));
  1271. return 0;
  1272. }
  1273. void hal_udc_ep_set_buf(uint8_t ep_addr, void *buf, uint32_t len)
  1274. {
  1275. uint8_t ep_idx;
  1276. uint8_t is_in;
  1277. uint32_t flags;
  1278. ep_idx = ep_addr & 0x7f;
  1279. is_in = ep_addr & USB_DIR_IN;
  1280. // krhino_spin_lock_irq_save(&g_udc.lock, flags);
  1281. flags = hal_spin_lock_irqsave(&udc_lock);
  1282. if (is_in) {
  1283. g_udc.epin[ep_idx - 1].pdata = buf;
  1284. g_udc.epin[ep_idx - 1].data_len = len;
  1285. } else {
  1286. g_udc.epout[ep_idx - 1].pdata = buf;
  1287. g_udc.epout[ep_idx - 1].data_len = len;
  1288. }
  1289. // krhino_spin_unlock_irq_restore(&g_udc.lock, flags);
  1290. hal_spin_unlock_irqrestore(&udc_lock, flags);
  1291. }
  1292. void hal_udc_register_callback(udc_callback_t user_callback)
  1293. {
  1294. g_udc.callback = user_callback;
  1295. }
  1296. int32_t hal_udc_enter_test_mode(uint32_t test_mode)
  1297. {
  1298. /* TODO */
  1299. return 0;
  1300. }
  1301. int32_t udc_init(void)
  1302. {
  1303. /* NOTICE: clock and regulator must be ready first */
  1304. ep_info_init();
  1305. /* udc bsp init */
  1306. usbc_enable_dpdm_pullup(true);
  1307. usbc_enable_id_pullup(true);
  1308. usbc_force_id(USB_ISCR_FORCE_ID_HIGH);
  1309. usbc_force_vbus_valid(USB_ISCR_FORCE_VBUS_HIGH);
  1310. usbc_select_bus(UDC_IO_TYPE_PIO, UDC_EP_TYPE_EP0, 0);
  1311. usbc_phy_set_ctl(true);
  1312. usbc_phy_otg_sel(true);
  1313. hal_udc_phy_init();
  1314. /* disable udc before request irq */
  1315. usbc_udc_disable();
  1316. /* request irq */
  1317. if (request_irq(sunxi_udc.irq_no, udc_irq_handler, sunxi_udc.irq_flag, "usb_udc", NULL) < 0) {
  1318. log_udc_err("request irq error\n");
  1319. return -1;
  1320. }
  1321. enable_irq(sunxi_udc.irq_no);
  1322. /* udc enable */
  1323. usbc_udc_enable();
  1324. return 0;
  1325. }
  1326. int32_t udc_deinit(void)
  1327. {
  1328. struct platform_usb_config *otg_table = platform_get_otg_table();
  1329. /*free irq*/
  1330. free_irq(otg_table->irq, NULL);
  1331. /* udc bsp deinit */
  1332. usbc_enable_dpdm_pullup(false);
  1333. usbc_enable_id_pullup(false);
  1334. usbc_force_id(USB_ISCR_FORCE_ID_DISABLED);
  1335. usbc_force_vbus_valid(USB_ISCR_FORCE_VBUS_DISABLED);
  1336. return 0;
  1337. }
  1338. static int32_t open_udc_clk(sunxi_udc_io_t sunxi_udc)
  1339. {
  1340. hal_reset_type_t reset_type = HAL_SUNXI_RESET;
  1341. hal_clk_type_t clk_type = HAL_SUNXI_CCU;
  1342. hal_clk_status_t ret;
  1343. sunxi_udc.reset_phy = hal_reset_control_get(reset_type, sunxi_udc.reset_phy_clk);
  1344. ret = hal_reset_control_deassert(sunxi_udc.reset_phy);
  1345. if (ret)
  1346. {
  1347. hal_log_err("reset phy err!\n");
  1348. return -1;
  1349. }
  1350. sunxi_udc.reset_otg = hal_reset_control_get(reset_type, sunxi_udc.reset_otg_clk);
  1351. ret = hal_reset_control_deassert(sunxi_udc.reset_otg);
  1352. if (ret)
  1353. {
  1354. hal_log_err("reset otg err!\n");
  1355. return -1;
  1356. }
  1357. sunxi_udc.phy_clk = hal_clock_get(clk_type, sunxi_udc.phy_clk_id);
  1358. ret = hal_clock_enable(sunxi_udc.phy_clk);
  1359. if (ret)
  1360. {
  1361. hal_log_err("couldn't enable usb_phy_clk!\n");
  1362. return -1;
  1363. }
  1364. sunxi_udc.otg_clk = hal_clock_get(clk_type, sunxi_udc.otg_clk_id);
  1365. ret = hal_clock_enable(sunxi_udc.otg_clk);
  1366. if (ret)
  1367. {
  1368. hal_log_err("couldn't enable otg_clk!\n");
  1369. return -1;
  1370. }
  1371. return 0;
  1372. }
  1373. static int32_t close_udc_clk(sunxi_udc_io_t sunxi_udc)
  1374. {
  1375. // int ret;
  1376. hal_reset_type_t reset_type = HAL_SUNXI_RESET;
  1377. hal_clk_type_t clk_type = HAL_SUNXI_CCU;
  1378. hal_clk_status_t ret;
  1379. sunxi_udc.phy_clk = hal_clock_get(clk_type, sunxi_udc.phy_clk_id);
  1380. ret = hal_clock_disable(sunxi_udc.phy_clk);
  1381. if (ret)
  1382. {
  1383. hal_log_err("couldn't disable usb_phy_clk!\n");
  1384. return -1;
  1385. }
  1386. sunxi_udc.otg_clk = hal_clock_get(clk_type, sunxi_udc.otg_clk_id);
  1387. ret = hal_clock_disable(sunxi_udc.otg_clk);
  1388. if (ret)
  1389. {
  1390. hal_log_err("couldn't disable otg_clk!\n");
  1391. return -1;
  1392. }
  1393. sunxi_udc.reset_otg = hal_reset_control_get(reset_type, sunxi_udc.reset_otg_clk);
  1394. ret = hal_reset_control_assert(sunxi_udc.reset_otg);
  1395. if (ret)
  1396. {
  1397. hal_log_err("reset otg err!\n");
  1398. return -1;
  1399. }
  1400. sunxi_udc.reset_phy = hal_reset_control_get(reset_type, sunxi_udc.reset_phy_clk);
  1401. ret = hal_reset_control_assert(sunxi_udc.reset_phy);
  1402. if (ret)
  1403. {
  1404. hal_log_err("reset phy err!\n");
  1405. return -1;
  1406. }
  1407. return 0;
  1408. }
  1409. void sunxi_udc_get_config_param(void)
  1410. {
  1411. #ifndef CONFIG_KERNEL_FREERTOS
  1412. int ret = -1;
  1413. char udc_name[10] = {0};
  1414. sprintf(udc_name, "usbc0");
  1415. ret = Hal_Cfg_GetKeyValue(udc_name, KEY_UDC_IRQ_FLAG, (int32_t *)&sunxi_udc.irq_flag, 1);
  1416. if (ret) {
  1417. hal_log_err("%s %s fetch error!", udc_name, KEY_UDC_IRQ_FLAG);
  1418. sunxi_udc.irq_flag = 0x0;
  1419. }
  1420. ret = Hal_Cfg_GetKeyValue(udc_name, KEY_UDC_DRIVER_LEVEL, (int32_t *)&sunxi_udc.drive_level, 1);
  1421. if (ret) {
  1422. hal_log_err("%s %s fetch error!", udc_name, KEY_UDC_DRIVER_LEVEL);
  1423. sunxi_udc.drive_level = 0x8;
  1424. }
  1425. if (sunxi_udc.drive_level > 0xf)
  1426. {
  1427. sunxi_udc.drive_level = 0x8;
  1428. }
  1429. #else
  1430. sunxi_udc.irq_flag = 0;
  1431. sunxi_udc.drive_level = 0x8;
  1432. #endif
  1433. }
  1434. int32_t hal_udc_init(void)
  1435. {
  1436. uint32_t ret;
  1437. struct platform_usb_config *otg_config = platform_get_otg_table();
  1438. sunxi_udc.otg_clk_id = otg_config->usb_clk;
  1439. sunxi_udc.reset_otg_clk = otg_config->usb_rst;
  1440. sunxi_udc.phy_clk_id = otg_config->phy_clk;
  1441. sunxi_udc.reset_phy_clk = otg_config->phy_rst;
  1442. sunxi_udc.irq_no = otg_config->irq;
  1443. /* request gpio */
  1444. //hal_pinmux_set_function();
  1445. ret = open_udc_clk(sunxi_udc);
  1446. if (ret) {
  1447. log_udc_err("open udc clk failed\n");
  1448. return -1;
  1449. }
  1450. sunxi_udc_get_config_param();
  1451. udc_init();
  1452. return 0;
  1453. }
  1454. int32_t hal_udc_deinit(void)
  1455. {
  1456. udc_deinit();
  1457. close_udc_clk(sunxi_udc);
  1458. return 0;
  1459. }