MINI2440: Removed unneeded dependency
[u-boot-openmoko/mini2440.git] / drivers / usb / usbdcore_s3c2410.c
blob13cd3d6794ec11d96bc8513e387395353d11a6b4
1 /* S3C2410 USB Device Controller Driver for u-boot
3 * (C) Copyright 2007 by OpenMoko, Inc.
4 * Author: Harald Welte <laforge@openmoko.org>
6 * based on Linux' s3c2410_udc.c, which is
7 * Copyright (C) 2004-2006 Herbert Pƶtzl - Arnaud Patard
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include <config.h>
27 #if (defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || \
28 defined(CONFIG_S3C2442) || defined(CONFIG_S3C2443)) && defined(CONFIG_USB_DEVICE)
30 #include <common.h>
32 /* we can't use the regular debug macros since the console might be
33 * set to usbtty, which would cause deadlocks! */
34 #ifdef DEBUG
35 #undef debug
36 #undef debugX
37 #define debug(fmt,args...) serial_printf (fmt ,##args)
38 #define debugX(level,fmt,args...) if (DEBUG>=level) serial_printf(fmt,##args)
39 #endif
41 DECLARE_GLOBAL_DATA_PTR;
43 #include <asm/io.h>
44 #include <s3c2410.h>
46 #include "usbdcore.h"
47 #include "usbdcore_s3c2410.h"
48 #include "usbdcore_ep0.h"
49 #include <usb_cdc_acm.h>
51 static void debug_urb_buffer(char *prefix, struct usb_endpoint_instance *ep)
53 #ifdef DEBUG
54 int num;
55 static char buf[128];
57 if (!ep->tx_urb) {
58 serial_printf("no tx_urb\n");
59 return;
62 num = MIN(ep->tx_urb->actual_length - ep->sent, ep->tx_packetSize);
64 memset(buf, 0, sizeof(buf));
65 strncpy(buf, ep->tx_urb->buffer + ep->sent, num);
67 serial_printf("%s(%d:%s)\n", prefix, num, buf);
68 #endif
72 enum ep0_state {
73 EP0_IDLE,
74 EP0_IN_DATA_PHASE,
75 EP0_OUT_DATA_PHASE,
76 EP0_END_XFER,
77 EP0_STALL,
80 static struct urb *ep0_urb = NULL;
82 static struct usb_device_instance *udc_device; /* Used in interrupt handler */
84 static inline int fifo_count_out(void)
86 int tmp;
88 tmp = inl(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
89 tmp |= inl(S3C2410_UDC_OUT_FIFO_CNT1_REG);
91 return tmp & 0xffff;
94 static const unsigned long ep_fifo_reg[S3C2410_UDC_NUM_ENDPOINTS] = {
95 S3C2410_UDC_EP0_FIFO_REG,
96 S3C2410_UDC_EP1_FIFO_REG,
97 S3C2410_UDC_EP2_FIFO_REG,
98 S3C2410_UDC_EP3_FIFO_REG,
99 S3C2410_UDC_EP4_FIFO_REG,
102 static int s3c2410_write_noniso_tx_fifo(struct usb_endpoint_instance *endpoint)
104 struct urb *urb = endpoint->tx_urb;
105 unsigned int last, i;
106 unsigned int ep = endpoint->endpoint_address & 0x7f;
107 unsigned long fifo_reg = ep_fifo_reg[ep];
109 /* WARNING: don't ever put serial debug printf's in non-error codepaths
110 * here, it is called from the time critical EP0 codepath ! */
112 if (!urb || ep >= S3C2410_UDC_NUM_ENDPOINTS) {
113 serial_printf("no urb or wrong endpoint\n");
114 return -1;
117 S3C2410_UDC_SETIX(ep);
118 if ((last = MIN(urb->actual_length - endpoint->sent,
119 endpoint->tx_packetSize))) {
120 u8 *cp = urb->buffer + endpoint->sent;
122 for (i = 0; i < last; i++)
123 outb(*(cp+i), fifo_reg);
125 endpoint->last = last;
127 if (endpoint->sent + last < urb->actual_length) {
128 /* not all data has been transmitted so far */
129 return 0;
132 if (last == endpoint->tx_packetSize) {
133 /* we need to send one more packet (ZLP) */
134 return 0;
137 return 1;
141 static void s3c2410_deconfigure_device (void)
143 outl(0, S3C2410_UDC_EP1_DMA_CON);
144 outl(0, S3C2410_UDC_EP2_DMA_CON);
145 outl(0, S3C2410_UDC_EP3_DMA_CON);
146 outl(0, S3C2410_UDC_EP4_DMA_CON);
149 static void s3c2410_configure_device (struct usb_device_instance *device)
151 S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
152 S3C24X0_CLOCK_POWER * const cpower = S3C24X0_GetBase_CLOCK_POWER();
154 /* disable EP0-4 SUBD interrupts ? */
155 outl(0x00, S3C2410_UDC_USB_INT_EN_REG);
157 /* UPLL already configured by board-level init code */
159 /* configure USB pads to device mode */
160 gpio->MISCCR &= ~(S3C2410_MISCCR_USBHOST|S3C2410_MISCCR_USBSUSPND1);
162 /* don't disable USB clock */
163 cpower->CLKSLOW &= ~S3C2410_CLKSLOW_UCLK_OFF;
165 /* clear interrupt registers */
166 inl(S3C2410_UDC_EP_INT_REG);
167 inl(S3C2410_UDC_USB_INT_REG);
168 outl(0xff, S3C2410_UDC_EP_INT_REG);
169 outl(0xff, S3C2410_UDC_USB_INT_REG);
171 /* enable USB interrupts for RESET and SUSPEND/RESUME */
172 outl(S3C2410_UDC_USBINT_RESET|S3C2410_UDC_USBINT_SUSPEND,
173 S3C2410_UDC_USB_INT_EN_REG);
176 static void udc_set_address(unsigned char address)
178 address |= 0x80; /* ADDR_UPDATE bit */
179 outl(address, S3C2410_UDC_FUNC_ADDR_REG);
182 extern struct usb_device_descriptor device_descriptor;
184 static void s3c2410_udc_ep0(void)
186 u_int8_t ep0csr;
187 struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
189 S3C2410_UDC_SETIX(0);
190 ep0csr = inl(S3C2410_UDC_IN_CSR1_REG);
192 /* clear stall status */
193 if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
194 /* serial_printf("Clearing SENT_STALL\n"); */
195 clear_ep0_sst();
196 if (ep0csr & S3C2410_UDC_EP0_CSR_SOPKTRDY)
197 clear_ep0_opr();
198 ep0->state = EP0_IDLE;
199 return;
202 /* clear setup end */
203 if (ep0csr & S3C2410_UDC_EP0_CSR_SE
204 /* && ep0->state != EP0_IDLE */) {
205 /* serial_printf("Clearing SETUP_END\n"); */
206 clear_ep0_se();
207 #if 1
208 if (ep0csr & S3C2410_UDC_EP0_CSR_SOPKTRDY) {
209 /* Flush FIFO */
210 while (inl(S3C2410_UDC_OUT_FIFO_CNT1_REG))
211 inl(S3C2410_UDC_EP0_FIFO_REG);
212 clear_ep0_opr();
214 #endif
215 ep0->state = EP0_IDLE;
216 return;
219 /* Don't ever put [serial] debugging in non-error codepaths here, it
220 * will violate the tight timing constraints of this USB Device
221 * controller (and lead to bus enumeration failures) */
223 switch (ep0->state) {
224 int i, fifo_count;
225 unsigned char *datap;
226 case EP0_IDLE:
227 if (!(ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY))
228 break;
230 datap = (unsigned char *) &ep0_urb->device_request;
231 /* host->device packet has been received */
233 /* pull it out of the fifo */
234 fifo_count = fifo_count_out();
235 for (i = 0; i < fifo_count; i++) {
236 *datap = (unsigned char)inl(S3C2410_UDC_EP0_FIFO_REG);
237 datap++;
239 if (fifo_count != 8) {
240 debug("STRANGE FIFO COUNT: %u bytes\n", fifo_count);
241 set_ep0_ss();
242 return;
245 if (ep0_urb->device_request.wLength == 0) {
246 if (ep0_recv_setup(ep0_urb)) {
247 /* Not a setup packet, stall next EP0 transaction */
248 debug("can't parse setup packet1\n");
249 set_ep0_ss();
250 set_ep0_de_out();
251 ep0->state = EP0_IDLE;
252 return;
254 /* There are some requests with which we need to deal
255 * manually here */
256 switch (ep0_urb->device_request.bRequest) {
257 case USB_REQ_SET_CONFIGURATION:
258 if (!ep0_urb->device_request.wValue)
259 usbd_device_event_irq(udc_device,
260 DEVICE_DE_CONFIGURED, 0);
261 else
262 usbd_device_event_irq(udc_device,
263 DEVICE_CONFIGURED, 0);
264 break;
265 case USB_REQ_SET_ADDRESS:
266 udc_set_address(udc_device->address);
267 usbd_device_event_irq(udc_device,
268 DEVICE_ADDRESS_ASSIGNED, 0);
269 break;
270 default:
271 break;
273 set_ep0_de_out();
274 ep0->state = EP0_IDLE;
275 } else {
276 if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
277 == USB_REQ_HOST2DEVICE) {
278 clear_ep0_opr();
279 ep0->state = EP0_OUT_DATA_PHASE;
280 ep0_urb->buffer = ep0_urb->buffer_data;
281 ep0_urb->buffer_length = sizeof(ep0_urb->buffer_data);
282 ep0_urb->actual_length = 0;
283 } else {
284 ep0->state = EP0_IN_DATA_PHASE;
286 if (ep0_recv_setup(ep0_urb)) {
287 /* Not a setup packet, stall next EP0 transaction */
288 debug("can't parse setup packet2\n");
289 set_ep0_ss();
290 //set_ep0_de_out();
291 ep0->state = EP0_IDLE;
292 return;
294 clear_ep0_opr();
295 ep0->tx_urb = ep0_urb;
296 ep0->sent = ep0->last = 0;
298 if (s3c2410_write_noniso_tx_fifo(ep0)) {
299 ep0->state = EP0_IDLE;
300 set_ep0_de_in();
301 } else
302 set_ep0_ipr();
305 break;
306 case EP0_IN_DATA_PHASE:
307 if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY)) {
308 ep0->sent += ep0->last;
310 if (s3c2410_write_noniso_tx_fifo(ep0)) {
311 ep0->state = EP0_IDLE;
312 set_ep0_de_in();
313 } else
314 set_ep0_ipr();
316 break;
317 case EP0_OUT_DATA_PHASE:
318 if (ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) {
319 u32 urb_avail = ep0_urb->buffer_length - ep0_urb->actual_length;
320 u_int8_t *cp = ep0_urb->buffer + ep0_urb->actual_length;
321 int i, fifo_count;
323 fifo_count = fifo_count_out();
324 if (fifo_count < urb_avail)
325 urb_avail = fifo_count;
327 for (i = 0; i < urb_avail; i++)
328 *cp++ = inl(S3C2410_UDC_EP0_FIFO_REG);
330 ep0_urb->actual_length += urb_avail;
332 if (fifo_count < ep0->rcv_packetSize ||
333 ep0_urb->actual_length >= ep0_urb->device_request.wLength) {
334 ep0->state = EP0_IDLE;
335 if (ep0_recv_setup(ep0_urb)) {
336 /* Not a setup packet, stall next EP0 transaction */
337 debug("can't parse setup packet3\n");
338 set_ep0_ss();
339 //set_ep0_de_out();
340 return;
342 set_ep0_de_out();
343 } else
344 clear_ep0_opr();
346 break;
347 case EP0_END_XFER:
348 ep0->state = EP0_IDLE;
349 break;
350 case EP0_STALL:
351 //set_ep0_ss;
352 ep0->state = EP0_IDLE;
353 break;
358 static void s3c2410_udc_epn(int ep)
360 struct usb_endpoint_instance *endpoint;
361 struct urb *urb;
362 u32 ep_csr1;
364 if (ep >= S3C2410_UDC_NUM_ENDPOINTS)
365 return;
367 endpoint = &udc_device->bus->endpoint_array[ep];
369 S3C2410_UDC_SETIX(ep);
371 if (endpoint->endpoint_address & USB_DIR_IN) {
372 /* IN transfer (device to host) */
373 ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG);
374 debug("for ep=%u, CSR1=0x%x ", ep, ep_csr1);
376 urb = endpoint->tx_urb;
377 if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
378 /* Stall handshake */
379 debug("stall\n");
380 outl(0x00, S3C2410_UDC_IN_CSR1_REG);
381 return;
383 if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && urb &&
384 urb->actual_length) {
386 debug("completing previously send data ");
387 usbd_tx_complete(endpoint);
389 /* push pending data into FIFO */
390 if ((endpoint->last == endpoint->tx_packetSize) &&
391 (urb->actual_length - endpoint->sent - endpoint->last == 0)) {
392 endpoint->sent += endpoint->last;
393 /* Write 0 bytes of data (ZLP) */
394 debug("ZLP ");
395 outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
396 } else {
397 /* write actual data to fifo */
398 debug_urb_buffer("TX_DATA", endpoint);
399 s3c2410_write_noniso_tx_fifo(endpoint);
400 outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
403 debug("\n");
404 } else {
405 /* OUT transfer (host to device) */
406 ep_csr1 = inl(S3C2410_UDC_OUT_CSR1_REG);
407 debug("for ep=%u, CSR1=0x%x ", ep, ep_csr1);
409 urb = endpoint->rcv_urb;
410 if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
411 /* Stall handshake */
412 outl(0x00, S3C2410_UDC_IN_CSR1_REG);
413 return;
415 if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && urb) {
416 /* Read pending data from fifo */
417 u32 fifo_count = fifo_count_out();
418 int is_last = 0;
419 u32 i, urb_avail = urb->buffer_length - urb->actual_length;
420 u8 *cp = urb->buffer + urb->actual_length;
422 if (fifo_count < endpoint->rcv_packetSize)
423 is_last = 1;
425 debug("fifo_count=%u is_last=%, urb_avail=%u)\n",
426 fifo_count, is_last, urb_avail);
428 if (fifo_count < urb_avail)
429 urb_avail = fifo_count;
431 for (i = 0; i < urb_avail; i++)
432 *cp++ = inb(ep_fifo_reg[ep]);
434 if (is_last)
435 outl(ep_csr1 & ~S3C2410_UDC_OCSR1_PKTRDY,
436 S3C2410_UDC_OUT_CSR1_REG);
438 usbd_rcv_complete(endpoint, urb_avail, 0);
442 urb = endpoint->rcv_urb;
446 -------------------------------------------------------------------------------
449 /* this is just an empty wrapper for usbtty who assumes polling operation */
450 void udc_irq(void)
454 /* Handle general USB interrupts and dispatch according to type.
455 * This function implements TRM Figure 14-13.
457 void s3c2410_udc_irq(void)
459 struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
460 u_int32_t save_idx = inl(S3C2410_UDC_INDEX_REG);
462 /* read interrupt sources */
463 u_int32_t usb_status = inl(S3C2410_UDC_USB_INT_REG);
464 u_int32_t usbd_status = inl(S3C2410_UDC_EP_INT_REG);
466 //debug("< IRQ usbs=0x%02x, usbds=0x%02x start >", usb_status, usbd_status);
468 /* clear interrupts */
469 outl(usb_status, S3C2410_UDC_USB_INT_REG);
471 if (usb_status & S3C2410_UDC_USBINT_RESET) {
472 //serial_putc('R');
473 debug("RESET pwr=0x%x\n", inl(S3C2410_UDC_PWR_REG));
474 udc_setup_ep(udc_device, 0, ep0);
475 outl(S3C2410_UDC_EP0_CSR_SSE|S3C2410_UDC_EP0_CSR_SOPKTRDY, S3C2410_UDC_EP0_CSR_REG);
476 ep0->state = EP0_IDLE;
477 usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
480 if (usb_status & S3C2410_UDC_USBINT_RESUME) {
481 debug("RESUME\n");
482 usbd_device_event_irq(udc_device, DEVICE_BUS_ACTIVITY, 0);
485 if (usb_status & S3C2410_UDC_USBINT_SUSPEND) {
486 debug("SUSPEND\n");
487 usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
490 /* Endpoint Interrupts */
491 if (usbd_status) {
492 int i;
494 if (usbd_status & S3C2410_UDC_INT_EP0) {
495 outl(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
496 s3c2410_udc_ep0();
499 for (i = 1; i < 5; i++) {
500 u_int32_t tmp = 1 << i;
502 if (usbd_status & tmp) {
503 /* FIXME: Handle EP X */
504 outl(tmp, S3C2410_UDC_EP_INT_REG);
505 s3c2410_udc_epn(i);
509 S3C2410_UDC_SETIX(save_idx);
513 -------------------------------------------------------------------------------
518 * Start of public functions.
521 /* Called to start packet transmission. */
522 void udc_endpoint_write (struct usb_endpoint_instance *endpoint)
524 unsigned short epnum =
525 endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
527 debug("Entering for ep %x ", epnum);
529 if (endpoint->tx_urb) {
530 u32 ep_csr1;
531 debug_urb_buffer("We have an URB, transmitting", endpoint);
533 s3c2410_write_noniso_tx_fifo(endpoint);
535 S3C2410_UDC_SETIX(epnum);
537 ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG);
538 outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
539 } else
540 debug("\n");
543 /* Start to initialize h/w stuff */
544 int udc_init (void)
546 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
547 S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
549 udc_device = NULL;
551 /* Set and check clock control.
552 * We might ought to be using the clock control API to do
553 * this instead of fiddling with the clock registers directly
554 * here.
556 clk_power->CLKCON |= (1 << 7);
558 /* Print banner with device revision */
559 printf("USB: S3C2410 USB Deviced\n");
562 * At this point, device is ready for configuration...
564 outl(0x00, S3C2410_UDC_EP_INT_EN_REG);
565 outl(0x00, S3C2410_UDC_USB_INT_EN_REG);
567 irq->INTMSK &= ~BIT_USBD;
569 return 0;
573 * udc_setup_ep - setup endpoint
575 * Associate a physical endpoint with endpoint_instance
577 int udc_setup_ep (struct usb_device_instance *device,
578 unsigned int ep, struct usb_endpoint_instance *endpoint)
580 int ep_addr = endpoint->endpoint_address;
581 int packet_size;
582 int attributes;
583 u_int32_t maxp;
585 S3C2410_UDC_SETIX(ep);
587 if (ep) {
588 if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
589 /* IN endpoint */
590 outl(S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT,
591 S3C2410_UDC_IN_CSR1_REG);
592 outl(S3C2410_UDC_ICSR2_MODEIN, S3C2410_UDC_IN_CSR2_REG);
593 packet_size = endpoint->tx_packetSize;
594 attributes = endpoint->tx_attributes;
595 } else {
596 /* OUT endpoint */
597 outl(S3C2410_UDC_ICSR1_CLRDT, S3C2410_UDC_IN_CSR1_REG);
598 outl(0, S3C2410_UDC_IN_CSR2_REG);
599 outl(S3C2410_UDC_OCSR1_FFLUSH|S3C2410_UDC_OCSR1_CLRDT,
600 S3C2410_UDC_OUT_CSR1_REG);
601 outl(0, S3C2410_UDC_OUT_CSR2_REG);
602 packet_size = endpoint->rcv_packetSize;
603 attributes = endpoint->rcv_attributes;
605 } else
606 packet_size = endpoint->tx_packetSize;
608 switch (packet_size) {
609 case 8:
610 maxp = S3C2410_UDC_MAXP_8;
611 break;
612 case 16:
613 maxp = S3C2410_UDC_MAXP_16;
614 break;
615 case 32:
616 maxp = S3C2410_UDC_MAXP_32;
617 break;
618 case 64:
619 maxp = S3C2410_UDC_MAXP_64;
620 break;
621 default:
622 debug("invalid packet size %u\n", packet_size);
623 return -1;
626 debug("setting up endpoint %u addr %x packet_size %u maxp %u\n", ep,
627 endpoint->endpoint_address, packet_size, maxp);
629 /* Set maximum packet size */
630 writel(maxp, S3C2410_UDC_MAXP_REG);
632 return 0;
635 /* ************************************************************************** */
638 * udc_connected - is the USB cable connected
640 * Return non-zero if cable is connected.
642 #if 0
643 int udc_connected (void)
645 return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);
647 #endif
649 /* Turn on the USB connection by enabling the pullup resistor */
650 void udc_connect (void)
652 debug("connect, enable Pullup\n");
653 S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
655 udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0);
656 udelay(10000);
657 udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 1);
659 irq->INTMSK &= ~BIT_USBD;
662 /* Turn off the USB connection by disabling the pullup resistor */
663 void udc_disconnect (void)
665 debug("disconnect, disable Pullup\n");
666 S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
668 udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0);
670 /* Disable interrupt (we don't want to get interrupts while the kernel
671 * is relocating itself */
672 irq->INTMSK |= BIT_USBD;
675 /* Switch on the UDC */
676 void udc_enable (struct usb_device_instance *device)
678 debug("enable device %p, status %d\n", device, device->status);
680 /* Save the device structure pointer */
681 udc_device = device;
683 /* Setup ep0 urb */
684 if (!ep0_urb)
685 ep0_urb = usbd_alloc_urb(udc_device,
686 udc_device->bus->endpoint_array);
687 else
688 serial_printf("udc_enable: ep0_urb already allocated %p\n",
689 ep0_urb);
691 s3c2410_configure_device(device);
694 /* Switch off the UDC */
695 void udc_disable (void)
697 debug("disable UDC\n");
699 s3c2410_deconfigure_device();
701 /* Free ep0 URB */
702 if (ep0_urb) {
703 /*usbd_dealloc_urb(ep0_urb); */
704 ep0_urb = NULL;
707 /* Reset device pointer.
708 * We ought to do this here to balance the initialization of udc_device
709 * in udc_enable, but some of our other exported functions get called
710 * by the bus interface driver after udc_disable, so we have to hang on
711 * to the device pointer to avoid a null pointer dereference. */
712 /* udc_device = NULL; */
716 * udc_startup - allow udc code to do any additional startup
718 void udc_startup_events (struct usb_device_instance *device)
720 /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
721 usbd_device_event_irq (device, DEVICE_INIT, 0);
723 /* The DEVICE_CREATE event puts the USB device in the state
724 * STATE_ATTACHED.
726 usbd_device_event_irq (device, DEVICE_CREATE, 0);
728 /* Some USB controller driver implementations signal
729 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
730 * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
731 * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
732 * The OMAP USB client controller has the capability to detect when the
733 * USB cable is connected to a powered USB bus via the ATT bit in the
734 * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
735 * DEVICE_RESET events until later.
738 /* The GTA01 can detect usb device attachment, but we just assume being
739 * attached for now (go to STATE_POWERED) */
740 usbd_device_event_irq (device, DEVICE_HUB_CONFIGURED, 0);
742 udc_enable (device);
745 void udc_set_nak(int epid)
747 /* FIXME: implement this */
750 void udc_unset_nak(int epid)
752 /* FIXME: implement this */
755 #endif /* CONFIG_S3C2410 && CONFIG_USB_DEVICE */