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