summaryrefslogtreecommitdiff
path: root/firmware/drivers/usb/arcotg_dcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/usb/arcotg_dcd.c')
-rw-r--r--firmware/drivers/usb/arcotg_dcd.c320
1 files changed, 161 insertions, 159 deletions
diff --git a/firmware/drivers/usb/arcotg_dcd.c b/firmware/drivers/usb/arcotg_dcd.c
index b545026a61..59ca93a072 100644
--- a/firmware/drivers/usb/arcotg_dcd.c
+++ b/firmware/drivers/usb/arcotg_dcd.c
@@ -118,14 +118,15 @@ timer_expired(struct timer * timer)
118/* gets called by usb_stack_init() to register 118/* gets called by usb_stack_init() to register
119 * this arcotg device conrtollder driver in the 119 * this arcotg device conrtollder driver in the
120 * stack. */ 120 * stack. */
121void usb_dcd_init(void) { 121void usb_dcd_init(void)
122{
122 usb_controller_register(&arcotg_dcd); 123 usb_controller_register(&arcotg_dcd);
123} 124}
124 125
125/*-------------------------------------------------------------------------*/ 126/*-------------------------------------------------------------------------*/
126 127
127void usb_arcotg_dcd_init(void) { 128void usb_arcotg_dcd_init(void)
128 129{
129 struct timer t; 130 struct timer t;
130 int i, ep_num = 0; 131 int i, ep_num = 0;
131 132
@@ -180,35 +181,36 @@ void usb_arcotg_dcd_init(void) {
180 /* put controller in device mode */ 181 /* put controller in device mode */
181 UDC_USBMODE |= USB_MODE_CTRL_MODE_DEVICE; 182 UDC_USBMODE |= USB_MODE_CTRL_MODE_DEVICE;
182 183
183 /* init queue heads */ 184 /* init queue heads */
184 qh_init(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL, USB_MAX_CTRL_PAYLOAD, 0, 0); 185 qh_init(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL, USB_MAX_CTRL_PAYLOAD, 0, 0);
185 qh_init(0, USB_SEND, USB_ENDPOINT_XFER_CONTROL, USB_MAX_CTRL_PAYLOAD, 0, 0); 186 qh_init(0, USB_SEND, USB_ENDPOINT_XFER_CONTROL, USB_MAX_CTRL_PAYLOAD, 0, 0);
186 187
187 UDC_ENDPOINTLISTADDR = (unsigned int)dev_qh; 188 UDC_ENDPOINTLISTADDR = (unsigned int)dev_qh;
188} 189}
189 190
190void usb_arcotg_dcd_shutdown(void) { 191void usb_arcotg_dcd_shutdown(void)
192{
191 193
192} 194}
193 195
194void usb_arcotg_dcd_start(void) { 196void usb_arcotg_dcd_start(void)
195 197{
196 logf("start"); 198 logf("start");
197 199
198 if (arcotg_dcd.device_driver != NULL) { 200 if (arcotg_dcd.device_driver != NULL) {
199 logf("YEEEEEEESSSSSSS"); 201 logf("YEEEEEEESSSSSSS");
200 } else { 202 } else {
201 logf("NOOOOOO"); 203 logf("NOOOOOO");
202 } 204 }
203 205
204 /* clear stopped bit */ 206 /* clear stopped bit */
205 dcd_controller.stopped = false; 207 dcd_controller.stopped = false;
206 208
207 UDC_USBCMD |= USB_CMD_RUN; 209 UDC_USBCMD |= USB_CMD_RUN;
208} 210}
209 211
210void usb_arcotg_dcd_stop(void) { 212void usb_arcotg_dcd_stop(void)
211 213{
212 logf("stop"); 214 logf("stop");
213 215
214 /* set stopped bit */ 216 /* set stopped bit */
@@ -217,8 +219,8 @@ void usb_arcotg_dcd_stop(void) {
217 UDC_USBCMD &= ~USB_CMD_RUN; 219 UDC_USBCMD &= ~USB_CMD_RUN;
218} 220}
219 221
220void usb_arcotg_dcd_irq(void) { 222void usb_arcotg_dcd_irq(void)
221 223{
222 if (dcd_controller.stopped == true) { 224 if (dcd_controller.stopped == true) {
223 return; 225 return;
224 } 226 }
@@ -241,10 +243,10 @@ void usb_arcotg_dcd_irq(void) {
241 } 243 }
242 244
243 if (UDC_ENDPTCOMPLETE) { 245 if (UDC_ENDPTCOMPLETE) {
244 UDC_ENDPTCOMPLETE = UDC_ENDPTCOMPLETE; 246 UDC_ENDPTCOMPLETE = UDC_ENDPTCOMPLETE;
245 } 247 }
246 } 248 }
247 249
248 if (UDC_USBSTS & USB_STS_PORT_CHANGE) { 250 if (UDC_USBSTS & USB_STS_PORT_CHANGE) {
249 port_change_int(); 251 port_change_int();
250 } 252 }
@@ -269,12 +271,12 @@ void usb_arcotg_dcd_irq(void) {
269/*-------------------------------------------------------------------------*/ 271/*-------------------------------------------------------------------------*/
270/* interrupt handlers */ 272/* interrupt handlers */
271 273
272static void setup_received_int(struct usb_ctrlrequest* request) { 274static void setup_received_int(struct usb_ctrlrequest* request)
273 275{
274 int error = 0; 276 int error = 0;
275 uint8_t address = 0; 277 uint8_t address = 0;
276 int handled = 0; /* set to zero if we do not handle the message, */ 278 int handled = 0; /* set to zero if we do not handle the message, */
277 /* and should pass it to the driver */ 279 /* and should pass it to the driver */
278 280
279 logf("setup_int"); 281 logf("setup_int");
280 into_usb_ctrlrequest(request); 282 into_usb_ctrlrequest(request);
@@ -324,16 +326,16 @@ static void setup_received_int(struct usb_ctrlrequest* request) {
324 } 326 }
325 327
326 if (handled == 0) { 328 if (handled == 0) {
327 handled = 1; /* dont pass it to driver */ 329 handled = 1; /* dont pass it to driver */
328 } 330 }
329 } 331 }
330#if 0 332#if 0
331 if (rc == 0) { 333 if (rc == 0) {
332 /* send status only if _arcotg_ep_set_halt success */ 334 /* send status only if _arcotg_ep_set_halt success */
333 if (ep0_prime_status(udc, EP_DIR_IN)) 335 if (ep0_prime_status(udc, EP_DIR_IN))
334 Ep0Stall(udc); 336 Ep0Stall(udc);
335 } 337 }
336#endif 338#endif
337 break; 339 break;
338 } 340 }
339 341
@@ -358,8 +360,8 @@ static void setup_received_int(struct usb_ctrlrequest* request) {
358 } 360 }
359} 361}
360 362
361static void port_change_int(void) { 363static void port_change_int(void)
362 364{
363 //logf("port_change_int"); 365 //logf("port_change_int");
364 uint32_t tmp; 366 uint32_t tmp;
365 enum usb_device_speed speed = USB_SPEED_UNKNOWN; 367 enum usb_device_speed speed = USB_SPEED_UNKNOWN;
@@ -386,7 +388,7 @@ static void port_change_int(void) {
386 388
387 /* update speed */ 389 /* update speed */
388 arcotg_dcd.speed = speed; 390 arcotg_dcd.speed = speed;
389 391
390 /* update USB state */ 392 /* update USB state */
391 if (!dcd_controller.resume_state) { 393 if (!dcd_controller.resume_state) {
392 dcd_controller.usb_state = USB_STATE_DEFAULT; 394 dcd_controller.usb_state = USB_STATE_DEFAULT;
@@ -398,8 +400,8 @@ static void port_change_int(void) {
398 } 400 }
399} 401}
400 402
401static void suspend_int(void) { 403static void suspend_int(void)
402 404{
403 //logf("suspend_int"); 405 //logf("suspend_int");
404 dcd_controller.resume_state = dcd_controller.usb_state; 406 dcd_controller.resume_state = dcd_controller.usb_state;
405 dcd_controller.usb_state = USB_STATE_SUSPENDED; 407 dcd_controller.usb_state = USB_STATE_SUSPENDED;
@@ -410,8 +412,8 @@ static void suspend_int(void) {
410 } 412 }
411} 413}
412 414
413static void resume_int(void) { 415static void resume_int(void)
414 416{
415 //logf("resume_int"); 417 //logf("resume_int");
416 dcd_controller.usb_state = dcd_controller.resume_state; 418 dcd_controller.usb_state = dcd_controller.resume_state;
417 dcd_controller.resume_state = USB_STATE_NOTATTACHED; 419 dcd_controller.resume_state = USB_STATE_NOTATTACHED;
@@ -422,8 +424,8 @@ static void resume_int(void) {
422 } 424 }
423} 425}
424 426
425static void reset_int(void) { 427static void reset_int(void)
426 428{
427 //logf("reset_int"); 429 //logf("reset_int");
428 struct timer t; 430 struct timer t;
429 431
@@ -459,12 +461,12 @@ static void reset_int(void) {
459/*-------------------------------------------------------------------------*/ 461/*-------------------------------------------------------------------------*/
460/* usb controller ops */ 462/* usb controller ops */
461 463
462int usb_arcotg_dcd_enable(struct usb_ep* ep) { 464int usb_arcotg_dcd_enable(struct usb_ep* ep)
463 465{
464 unsigned short max = 0; 466 unsigned short max = 0;
465 unsigned char mult = 0, zlt = 0; 467 unsigned char mult = 0, zlt = 0;
466 int retval = 0; 468 int retval = 0;
467 char *val = NULL; /* for debug */ 469 char *val = NULL; /* for debug */
468 470
469 /* catch bogus parameter */ 471 /* catch bogus parameter */
470 if (!ep) { 472 if (!ep) {
@@ -496,105 +498,105 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep) {
496 498
497#if 0 499#if 0
498 switch (ep->desc->bmAttributes & 0x03) { 500 switch (ep->desc->bmAttributes & 0x03) {
499 case USB_ENDPOINT_XFER_BULK: 501 case USB_ENDPOINT_XFER_BULK:
500 if (strstr(ep->ep.name, "-iso") || strstr(ep->ep.name, "-int")) { 502 if (strstr(ep->ep.name, "-iso") || strstr(ep->ep.name, "-int")) {
501 goto en_done; 503 goto en_done;
502 } 504 }
503 mult = 0; 505 mult = 0;
504 zlt = 1; 506 zlt = 1;
505 507
506 switch (arcotg_dcd.speed) { 508 switch (arcotg_dcd.speed) {
507 case USB_SPEED_HIGH: 509 case USB_SPEED_HIGH:
508 if ((max == 128) || (max == 256) || (max == 512)) { 510 if ((max == 128) || (max == 256) || (max == 512)) {
509 break; 511 break;
510 } 512 }
511 default: 513 default:
512 switch (max) { 514 switch (max) {
513 case 4: 515 case 4:
514 case 8: 516 case 8:
515 case 16: 517 case 16:
516 case 32: 518 case 32:
517 case 64: 519 case 64:
518 break; 520 break;
519 default: 521 default:
520 + case USB_SPEED_LOW: 522 + case USB_SPEED_LOW:
521 + goto en_done; 523 + goto en_done;
522 + } 524 + }
523 + } 525 + }
524 + break; 526 + break;
525 + case USB_ENDPOINT_XFER_INT: 527 + case USB_ENDPOINT_XFER_INT:
526 + if (strstr(ep->ep.name, "-iso")) /* bulk is ok */ 528 + if (strstr(ep->ep.name, "-iso")) /* bulk is ok */
527 + goto en_done; 529 + goto en_done;
528 + mult = 0; 530 + mult = 0;
529 + zlt = 1; 531 + zlt = 1;
530 + switch (udc->gadget.speed) { 532 + switch (udc->gadget.speed) {
531 + case USB_SPEED_HIGH: 533 + case USB_SPEED_HIGH:
532 + if (max <= 1024) 534 + if (max <= 1024)
533 + break; 535 + break;
534 + case USB_SPEED_FULL: 536 + case USB_SPEED_FULL:
535 + if (max <= 64) 537 + if (max <= 64)
536 + break; 538 + break;
537 + default: 539 + default:
538 + if (max <= 8) 540 + if (max <= 8)
539 + break; 541 + break;
540 + goto en_done; 542 + goto en_done;
541 + } 543 + }
542 + break; 544 + break;
543 + case USB_ENDPOINT_XFER_ISOC: 545 + case USB_ENDPOINT_XFER_ISOC:
544 + if (strstr(ep->ep.name, "-bulk") || strstr(ep->ep.name, "-int")) 546 + if (strstr(ep->ep.name, "-bulk") || strstr(ep->ep.name, "-int"))
545 + goto en_done; 547 + goto en_done;
546 + mult = (unsigned char) 548 + mult = (unsigned char)
547 + (1 + ((le16_to_cpu(desc->wMaxPacketSize) >> 11) & 0x03)); 549 + (1 + ((le16_to_cpu(desc->wMaxPacketSize) >> 11) & 0x03));
548 + zlt = 0; 550 + zlt = 0;
549 + switch (udc->gadget.speed) { 551 + switch (udc->gadget.speed) {
550 + case USB_SPEED_HIGH: 552 + case USB_SPEED_HIGH:
551 + if (max <= 1024) 553 + if (max <= 1024)
552 + break; 554 + break;
553 + case USB_SPEED_FULL: 555 + case USB_SPEED_FULL:
554 + if (max <= 1023) 556 + if (max <= 1023)
555 + break; 557 + break;
556 + default: 558 + default:
557 + goto en_done; 559 + goto en_done;
558 + } 560 + }
559 + break; 561 + break;
560 + case USB_ENDPOINT_XFER_CONTROL: 562 + case USB_ENDPOINT_XFER_CONTROL:
561 + if (strstr(ep->ep.name, "-iso") || strstr(ep->ep.name, "-int")) 563 + if (strstr(ep->ep.name, "-iso") || strstr(ep->ep.name, "-int"))
562 + goto en_done; 564 + goto en_done;
563 + mult = 0; 565 + mult = 0;
564 + zlt = 1; 566 + zlt = 1;
565 + switch (udc->gadget.speed) { 567 + switch (udc->gadget.speed) {
566 + case USB_SPEED_HIGH: 568 + case USB_SPEED_HIGH:
567 + case USB_SPEED_FULL: 569 + case USB_SPEED_FULL:
568 + switch (max) { 570 + switch (max) {
569 + case 1: 571 + case 1:
570 + case 2: 572 + case 2:
571 + case 4: 573 + case 4:
572 + case 8: 574 + case 8:
573 + case 16: 575 + case 16:
574 + case 32: 576 + case 32:
575 + case 64: 577 + case 64:
576 + break; 578 + break;
577 + default: 579 + default:
578 + goto en_done; 580 + goto en_done;
579 + } 581 + }
580 + case USB_SPEED_LOW: 582 + case USB_SPEED_LOW:
581 + switch (max) { 583 + switch (max) {
582 + case 1: 584 + case 1:
583 + case 2: 585 + case 2:
584 + case 4: 586 + case 4:
585 + case 8: 587 + case 8:
586 + break; 588 + break;
587 + default: 589 + default:
588 + goto en_done; 590 + goto en_done;
589 + } 591 + }
590 + default: 592 + default:
591 + goto en_done; 593 + goto en_done;
592 + } 594 + }
593 + break; 595 + break;
594 + 596 +
595 + default: 597 + default:
596 + goto en_done; 598 + goto en_done;
597 + } 599 + }
598#endif 600#endif
599 601
600 /* here initialize variable of ep */ 602 /* here initialize variable of ep */
@@ -643,8 +645,8 @@ int usb_arcotg_dcd_enable(struct usb_ep* ep) {
643 return retval; 645 return retval;
644} 646}
645 647
646int usb_arcotg_dcd_set_halt(struct usb_ep* ep, bool halt) { 648int usb_arcotg_dcd_set_halt(struct usb_ep* ep, bool halt)
647 649{
648 int status = -EOPNOTSUPP; /* operation not supported */ 650 int status = -EOPNOTSUPP; /* operation not supported */
649 unsigned char dir = 0; 651 unsigned char dir = 0;
650 unsigned int tmp_epctrl = 0; 652 unsigned int tmp_epctrl = 0;
@@ -688,8 +690,8 @@ out:
688 return status; 690 return status;
689} 691}
690 692
691int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* res) { 693int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* res)
692 694{
693 char* ptr; 695 char* ptr;
694 int todo, error, size, done = 0; 696 int todo, error, size, done = 0;
695 int index = 1; /* use as default ep0 tx qh and td */ 697 int index = 1; /* use as default ep0 tx qh and td */
@@ -750,8 +752,8 @@ int usb_arcotg_dcd_send(struct usb_ep* ep, struct usb_response* res) {
750 return done; 752 return done;
751} 753}
752 754
753int usb_arcotg_dcd_receive(struct usb_ep* ep, struct usb_response* res) { 755int usb_arcotg_dcd_receive(struct usb_ep* ep, struct usb_response* res)
754 756{
755 char* ptr; 757 char* ptr;
756 int todo, error, size, done = 0; 758 int todo, error, size, done = 0;
757 int index = 0; /* use as default ep0 rx qh and td */ 759 int index = 0; /* use as default ep0 rx qh and td */
@@ -812,9 +814,9 @@ int usb_arcotg_dcd_receive(struct usb_ep* ep, struct usb_response* res) {
812/* lifecylce */ 814/* lifecylce */
813 815
814static void qh_init(unsigned char ep_num, unsigned char dir, unsigned char ep_type, 816static void qh_init(unsigned char ep_num, unsigned char dir, unsigned char ep_type,
815 unsigned int max_pkt_len, unsigned int zlt, unsigned char mult) { 817 unsigned int max_pkt_len, unsigned int zlt, unsigned char mult)
816 818{
817 struct dqh *qh = &dev_qh[2 * ep_num + dir]; 819 struct dqh *qh = &dev_qh[2 * ep_num + dir];
818 uint32_t tmp = 0; 820 uint32_t tmp = 0;
819 memset(qh, 0, sizeof(struct dqh)); 821 memset(qh, 0, sizeof(struct dqh));
820 822
@@ -856,8 +858,8 @@ static void qh_init(unsigned char ep_num, unsigned char dir, unsigned char ep_ty
856 logf("qh: init %d", (2 * ep_num + dir)); 858 logf("qh: init %d", (2 * ep_num + dir));
857} 859}
858 860
859static void td_init(struct dtd* td, void* buffer, uint32_t todo) { 861static void td_init(struct dtd* td, void* buffer, uint32_t todo)
860 862{
861 /* see 32.14.5.2 Building a Transfer Descriptor */ 863 /* see 32.14.5.2 Building a Transfer Descriptor */
862 864
863 /* init first 7 dwords with 0 */ 865 /* init first 7 dwords with 0 */
@@ -878,8 +880,8 @@ static void td_init(struct dtd* td, void* buffer, uint32_t todo) {
878 td->buf_ptr0 = (uint32_t)buffer; 880 td->buf_ptr0 = (uint32_t)buffer;
879} 881}
880 882
881static void ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type) { 883static void ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type)
882 884{
883 unsigned int tmp_epctrl = 0; 885 unsigned int tmp_epctrl = 0;
884 struct timer t; 886 struct timer t;
885 887
@@ -901,23 +903,23 @@ static void ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_t
901 } 903 }
902 904
903 UDC_ENDPTCTRL(ep_num) = tmp_epctrl; 905 UDC_ENDPTCTRL(ep_num) = tmp_epctrl;
904 906
905 /* wait for the write reg to finish */ 907 /* wait for the write reg to finish */
906 908
907 timer_set(&t, SETUP_TIMER); 909 timer_set(&t, SETUP_TIMER);
908 while (!(UDC_ENDPTCTRL(ep_num) & (tmp_epctrl & (EPCTRL_TX_ENABLE | EPCTRL_RX_ENABLE)))) { 910 while (!(UDC_ENDPTCTRL(ep_num) & (tmp_epctrl & (EPCTRL_TX_ENABLE | EPCTRL_RX_ENABLE)))) {
909 if (timer_expired(&t)) { 911 if (timer_expired(&t)) {
910 logf("TIMEOUT: enable ep"); 912 logf("TIMEOUT: enable ep");
911 return; 913 return;
912 } 914 }
913 } 915 }
914} 916}
915 917
916/*-------------------------------------------------------------------------*/ 918/*-------------------------------------------------------------------------*/
917/* helpers for sending/receiving */ 919/* helpers for sending/receiving */
918 920
919static int td_enqueue(struct dtd* td, struct dqh* qh, unsigned int mask) { 921static int td_enqueue(struct dtd* td, struct dqh* qh, unsigned int mask)
920 922{
921 struct timer t; 923 struct timer t;
922 924
923 qh->dtd_ovrl.next_dtd = (unsigned int)td; 925 qh->dtd_ovrl.next_dtd = (unsigned int)td;
@@ -940,8 +942,8 @@ static int td_enqueue(struct dtd* td, struct dqh* qh, unsigned int mask) {
940 return 0; 942 return 0;
941} 943}
942 944
943static int td_wait(struct dtd* td, unsigned int mask) { 945static int td_wait(struct dtd* td, unsigned int mask)
944 946{
945 struct timer t; 947 struct timer t;
946 timer_set(&t, TRANSFER_TIMER); 948 timer_set(&t, TRANSFER_TIMER);
947 949
@@ -960,8 +962,8 @@ static int td_wait(struct dtd* td, unsigned int mask) {
960 } 962 }
961} 963}
962 964
963static int usb_ack(struct usb_ctrlrequest * s, int error) { 965static int usb_ack(struct usb_ctrlrequest * s, int error)
964 966{
965 if (error) { 967 if (error) {
966 logf("STALLing ep0"); 968 logf("STALLing ep0");
967 UDC_ENDPTCTRL0 |= 1 << 16; /* stall */ 969 UDC_ENDPTCTRL0 |= 1 << 16; /* stall */