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
27 #if defined(CONFIG_S3C2410) && defined(CONFIG_USB_DEVICE)
31 /* we can't use the regular debug macros since the console might be
32 * set to usbtty, which would cause deadlocks! */
36 #define debug(fmt,args...) serial_printf (fmt ,##args)
37 #define debugX(level,fmt,args...) if (DEBUG>=level) serial_printf(fmt,##args)
40 DECLARE_GLOBAL_DATA_PTR
;
46 #include "usbdcore_s3c2410.h"
47 #include "usbdcore_ep0.h"
48 #include <usb_cdc_acm.h>
50 static void debug_urb_buffer(char *prefix
, struct usb_endpoint_instance
*ep
)
57 serial_printf("no tx_urb\n");
61 num
= MIN(ep
->tx_urb
->actual_length
- ep
->sent
, ep
->tx_packetSize
);
63 memset(buf
, 0, sizeof(buf
));
64 strncpy(buf
, ep
->tx_urb
->buffer
+ ep
->sent
, num
);
66 serial_printf("%s(%d:%s)\n", prefix
, num
, buf
);
79 static struct urb
*ep0_urb
= NULL
;
81 static struct usb_device_instance
*udc_device
; /* Used in interrupt handler */
83 static inline int fifo_count_out(void)
87 tmp
= inl(S3C2410_UDC_OUT_FIFO_CNT2_REG
) << 8;
88 tmp
|= inl(S3C2410_UDC_OUT_FIFO_CNT1_REG
);
93 static const unsigned long ep_fifo_reg
[S3C2410_UDC_NUM_ENDPOINTS
] = {
94 S3C2410_UDC_EP0_FIFO_REG
,
95 S3C2410_UDC_EP1_FIFO_REG
,
96 S3C2410_UDC_EP2_FIFO_REG
,
97 S3C2410_UDC_EP3_FIFO_REG
,
98 S3C2410_UDC_EP4_FIFO_REG
,
101 static int s3c2410_write_noniso_tx_fifo(struct usb_endpoint_instance
*endpoint
)
103 struct urb
*urb
= endpoint
->tx_urb
;
104 unsigned int last
, i
;
105 unsigned int ep
= endpoint
->endpoint_address
& 0x7f;
106 unsigned long fifo_reg
= ep_fifo_reg
[ep
];
108 /* WARNING: don't ever put serial debug printf's in non-error codepaths
109 * here, it is called from the time critical EP0 codepath ! */
111 if (!urb
|| ep
>= S3C2410_UDC_NUM_ENDPOINTS
) {
112 serial_printf("no urb or wrong endpoint\n");
116 S3C2410_UDC_SETIX(ep
);
117 if ((last
= MIN(urb
->actual_length
- endpoint
->sent
,
118 endpoint
->tx_packetSize
))) {
119 u8
*cp
= urb
->buffer
+ endpoint
->sent
;
121 for (i
= 0; i
< last
; i
++)
122 outb(*(cp
+i
), fifo_reg
);
124 endpoint
->last
= last
;
126 if (endpoint
->sent
+ last
< urb
->actual_length
) {
127 /* not all data has been transmitted so far */
131 if (last
== endpoint
->tx_packetSize
) {
132 /* we need to send one more packet (ZLP) */
140 static void s3c2410_deconfigure_device (void)
142 /* FIXME: Implement this */
145 static void s3c2410_configure_device (struct usb_device_instance
*device
)
147 S3C24X0_GPIO
* const gpio
= S3C24X0_GetBase_GPIO();
148 S3C24X0_CLOCK_POWER
* const cpower
= S3C24X0_GetBase_CLOCK_POWER();
150 /* disable EP0-4 SUBD interrupts ? */
151 outl(0x00, S3C2410_UDC_USB_INT_EN_REG
);
153 /* UPLL already configured by board-level init code */
155 /* configure USB pads to device mode */
156 gpio
->MISCCR
&= ~(S3C2410_MISCCR_USBHOST
|S3C2410_MISCCR_USBSUSPND1
);
158 /* don't disable USB clock */
159 cpower
->CLKSLOW
&= ~S3C2410_CLKSLOW_UCLK_OFF
;
161 /* clear interrupt registers */
162 inl(S3C2410_UDC_EP_INT_REG
);
163 inl(S3C2410_UDC_USB_INT_REG
);
164 outl(0xff, S3C2410_UDC_EP_INT_REG
);
165 outl(0xff, S3C2410_UDC_USB_INT_REG
);
167 /* enable USB interrupts for RESET and SUSPEND/RESUME */
168 outl(S3C2410_UDC_USBINT_RESET
|S3C2410_UDC_USBINT_SUSPEND
,
169 S3C2410_UDC_USB_INT_EN_REG
);
172 static void udc_set_address(unsigned char address
)
174 address
|= 0x80; /* ADDR_UPDATE bit */
175 outl(address
, S3C2410_UDC_FUNC_ADDR_REG
);
178 extern struct usb_device_descriptor device_descriptor
;
180 static void s3c2410_udc_ep0(void)
183 struct usb_endpoint_instance
*ep0
= udc_device
->bus
->endpoint_array
;
185 S3C2410_UDC_SETIX(0);
186 ep0csr
= inl(S3C2410_UDC_IN_CSR1_REG
);
188 /* clear stall status */
189 if (ep0csr
& S3C2410_UDC_EP0_CSR_SENTSTL
) {
190 serial_printf("Clearing SENT_STALL\n");
192 if (ep0csr
& S3C2410_UDC_EP0_CSR_SOPKTRDY
)
194 ep0
->state
= EP0_IDLE
;
198 /* clear setup end */
199 if (ep0csr
& S3C2410_UDC_EP0_CSR_SE
200 /* && ep0->state != EP0_IDLE */) {
201 serial_printf("Clearing SETUP_END\n");
204 if (ep0csr
& S3C2410_UDC_EP0_CSR_SOPKTRDY
) {
206 while (inl(S3C2410_UDC_OUT_FIFO_CNT1_REG
))
207 inl(S3C2410_UDC_EP0_FIFO_REG
);
211 ep0
->state
= EP0_IDLE
;
215 /* Don't ever put [serial] debugging in non-error codepaths here, it
216 * will violate the tight timing constraints of this USB Device
217 * controller (and lead to bus enumeration failures) */
219 switch (ep0
->state
) {
221 unsigned char *datap
;
223 if (!(ep0csr
& S3C2410_UDC_EP0_CSR_OPKRDY
))
226 datap
= (unsigned char *) &ep0_urb
->device_request
;
227 /* host->device packet has been received */
229 /* pull it out of the fifo */
230 fifo_count
= fifo_count_out();
231 for (i
= 0; i
< fifo_count
; i
++) {
232 *datap
= (unsigned char)inl(S3C2410_UDC_EP0_FIFO_REG
);
235 if (fifo_count
!= 8) {
236 debug("STRANGE FIFO COUNT: %u bytes\n", fifo_count
);
241 if (ep0_urb
->device_request
.wLength
== 0) {
242 if (ep0_recv_setup(ep0_urb
)) {
243 /* Not a setup packet, stall next EP0 transaction */
244 debug("can't parse setup packet1\n");
247 ep0
->state
= EP0_IDLE
;
250 /* There are some requests with which we need to deal
252 switch (ep0_urb
->device_request
.bRequest
) {
253 case USB_REQ_SET_CONFIGURATION
:
254 if (!ep0_urb
->device_request
.wValue
)
255 usbd_device_event_irq(udc_device
,
256 DEVICE_DE_CONFIGURED
, 0);
258 usbd_device_event_irq(udc_device
,
259 DEVICE_CONFIGURED
, 0);
261 case USB_REQ_SET_ADDRESS
:
262 udc_set_address(udc_device
->address
);
263 usbd_device_event_irq(udc_device
,
264 DEVICE_ADDRESS_ASSIGNED
, 0);
270 ep0
->state
= EP0_IDLE
;
272 if ((ep0_urb
->device_request
.bmRequestType
& USB_REQ_DIRECTION_MASK
)
273 == USB_REQ_HOST2DEVICE
) {
275 ep0
->state
= EP0_OUT_DATA_PHASE
;
276 ep0_urb
->buffer
= ep0_urb
->buffer_data
;
277 ep0_urb
->buffer_length
= sizeof(ep0_urb
->buffer_data
);
278 ep0_urb
->actual_length
= 0;
280 ep0
->state
= EP0_IN_DATA_PHASE
;
282 if (ep0_recv_setup(ep0_urb
)) {
283 /* Not a setup packet, stall next EP0 transaction */
284 debug("can't parse setup packet2\n");
287 ep0
->state
= EP0_IDLE
;
291 ep0
->tx_urb
= ep0_urb
;
292 ep0
->sent
= ep0
->last
= 0;
294 if (s3c2410_write_noniso_tx_fifo(ep0
)) {
295 ep0
->state
= EP0_IDLE
;
302 case EP0_IN_DATA_PHASE
:
303 if (!(ep0csr
& S3C2410_UDC_EP0_CSR_IPKRDY
)) {
304 ep0
->sent
+= ep0
->last
;
306 if (s3c2410_write_noniso_tx_fifo(ep0
)) {
307 ep0
->state
= EP0_IDLE
;
313 case EP0_OUT_DATA_PHASE
:
314 if (ep0csr
& S3C2410_UDC_EP0_CSR_OPKRDY
) {
315 u32 urb_avail
= ep0_urb
->buffer_length
- ep0_urb
->actual_length
;
316 u_int8_t
*cp
= ep0_urb
->buffer
+ ep0_urb
->actual_length
;
319 fifo_count
= fifo_count_out();
320 if (fifo_count
< urb_avail
)
321 urb_avail
= fifo_count
;
323 for (i
= 0; i
< urb_avail
; i
++)
324 *cp
++ = inl(S3C2410_UDC_EP0_FIFO_REG
);
326 ep0_urb
->actual_length
+= urb_avail
;
328 if (fifo_count
< ep0
->rcv_packetSize
||
329 ep0_urb
->actual_length
>= ep0_urb
->device_request
.wLength
) {
330 ep0
->state
= EP0_IDLE
;
331 if (ep0_recv_setup(ep0_urb
)) {
332 /* Not a setup packet, stall next EP0 transaction */
333 debug("can't parse setup packet3\n");
344 ep0
->state
= EP0_IDLE
;
348 ep0
->state
= EP0_IDLE
;
354 static void s3c2410_udc_epn(int ep
)
356 struct usb_endpoint_instance
*endpoint
;
360 if (ep
>= S3C2410_UDC_NUM_ENDPOINTS
)
363 endpoint
= &udc_device
->bus
->endpoint_array
[ep
];
365 S3C2410_UDC_SETIX(ep
);
367 if (endpoint
->endpoint_address
& USB_DIR_IN
) {
368 /* IN transfer (device to host) */
369 ep_csr1
= inl(S3C2410_UDC_IN_CSR1_REG
);
370 debug("for ep=%u, CSR1=0x%x ", ep
, ep_csr1
);
372 urb
= endpoint
->tx_urb
;
373 if (ep_csr1
& S3C2410_UDC_ICSR1_SENTSTL
) {
374 /* Stall handshake */
376 outl(0x00, S3C2410_UDC_IN_CSR1_REG
);
379 if (!(ep_csr1
& S3C2410_UDC_ICSR1_PKTRDY
) && urb
&&
380 urb
->actual_length
) {
382 debug("completing previously send data ");
383 usbd_tx_complete(endpoint
);
385 /* push pending data into FIFO */
386 if ((endpoint
->last
== endpoint
->tx_packetSize
) &&
387 (urb
->actual_length
- endpoint
->sent
- endpoint
->last
== 0)) {
388 endpoint
->sent
+= endpoint
->last
;
389 /* Write 0 bytes of data (ZLP) */
391 outl(ep_csr1
|S3C2410_UDC_ICSR1_PKTRDY
, S3C2410_UDC_IN_CSR1_REG
);
393 /* write actual data to fifo */
394 debug_urb_buffer("TX_DATA", endpoint
);
395 s3c2410_write_noniso_tx_fifo(endpoint
);
396 outl(ep_csr1
|S3C2410_UDC_ICSR1_PKTRDY
, S3C2410_UDC_IN_CSR1_REG
);
401 /* OUT transfer (host to device) */
402 ep_csr1
= inl(S3C2410_UDC_OUT_CSR1_REG
);
403 debug("for ep=%u, CSR1=0x%x ", ep
, ep_csr1
);
405 urb
= endpoint
->rcv_urb
;
406 if (ep_csr1
& S3C2410_UDC_OCSR1_SENTSTL
) {
407 /* Stall handshake */
408 outl(0x00, S3C2410_UDC_IN_CSR1_REG
);
411 if ((ep_csr1
& S3C2410_UDC_OCSR1_PKTRDY
) && urb
) {
412 /* Read pending data from fifo */
413 u32 fifo_count
= fifo_count_out();
415 u32 i
, urb_avail
= urb
->buffer_length
- urb
->actual_length
;
416 u8
*cp
= urb
->buffer
+ urb
->actual_length
;
418 if (fifo_count
< endpoint
->rcv_packetSize
)
421 debug("fifo_count=%u is_last=%, urb_avail=%u)\n",
422 fifo_count
, is_last
, urb_avail
);
424 if (fifo_count
< urb_avail
)
425 urb_avail
= fifo_count
;
427 for (i
= 0; i
< urb_avail
; i
++)
428 *cp
++ = inb(ep_fifo_reg
[ep
]);
431 outl(ep_csr1
& ~S3C2410_UDC_OCSR1_PKTRDY
,
432 S3C2410_UDC_OUT_CSR1_REG
);
434 usbd_rcv_complete(endpoint
, urb_avail
, 0);
438 urb
= endpoint
->rcv_urb
;
442 -------------------------------------------------------------------------------
445 /* this is just an empty wrapper for usbtty who assumes polling operation */
450 /* Handle general USB interrupts and dispatch according to type.
451 * This function implements TRM Figure 14-13.
453 void s3c2410_udc_irq(void)
455 struct usb_endpoint_instance
*ep0
= udc_device
->bus
->endpoint_array
;
456 u_int32_t save_idx
= inl(S3C2410_UDC_INDEX_REG
);
458 /* read interrupt sources */
459 u_int32_t usb_status
= inl(S3C2410_UDC_USB_INT_REG
);
460 u_int32_t usbd_status
= inl(S3C2410_UDC_EP_INT_REG
);
462 //debug("< IRQ usbs=0x%02x, usbds=0x%02x start >", usb_status, usbd_status);
464 /* clear interrupts */
465 outl(usb_status
, S3C2410_UDC_USB_INT_REG
);
467 if (usb_status
& S3C2410_UDC_USBINT_RESET
) {
469 debug("RESET pwr=0x%x\n", inl(S3C2410_UDC_PWR_REG
));
470 udc_setup_ep(udc_device
, 0, ep0
);
471 outl(S3C2410_UDC_EP0_CSR_SSE
|S3C2410_UDC_EP0_CSR_SOPKTRDY
, S3C2410_UDC_EP0_CSR_REG
);
472 ep0
->state
= EP0_IDLE
;
473 usbd_device_event_irq (udc_device
, DEVICE_RESET
, 0);
476 if (usb_status
& S3C2410_UDC_USBINT_RESUME
) {
478 usbd_device_event_irq(udc_device
, DEVICE_BUS_ACTIVITY
, 0);
481 if (usb_status
& S3C2410_UDC_USBINT_SUSPEND
) {
483 usbd_device_event_irq(udc_device
, DEVICE_BUS_INACTIVE
, 0);
486 /* Endpoint Interrupts */
490 if (usbd_status
& S3C2410_UDC_INT_EP0
) {
491 outl(S3C2410_UDC_INT_EP0
, S3C2410_UDC_EP_INT_REG
);
495 for (i
= 1; i
< 5; i
++) {
496 u_int32_t tmp
= 1 << i
;
498 if (usbd_status
& tmp
) {
499 /* FIXME: Handle EP X */
500 outl(tmp
, S3C2410_UDC_EP_INT_REG
);
505 S3C2410_UDC_SETIX(save_idx
);
509 -------------------------------------------------------------------------------
514 * Start of public functions.
517 /* Called to start packet transmission. */
518 void udc_endpoint_write (struct usb_endpoint_instance
*endpoint
)
520 unsigned short epnum
=
521 endpoint
->endpoint_address
& USB_ENDPOINT_NUMBER_MASK
;
523 debug("Entering for ep %x ", epnum
);
525 if (endpoint
->tx_urb
) {
527 debug_urb_buffer("We have an URB, transmitting", endpoint
);
529 s3c2410_write_noniso_tx_fifo(endpoint
);
531 S3C2410_UDC_SETIX(epnum
);
533 ep_csr1
= inl(S3C2410_UDC_IN_CSR1_REG
);
534 outl(ep_csr1
|S3C2410_UDC_ICSR1_PKTRDY
, S3C2410_UDC_IN_CSR1_REG
);
539 /* Start to initialize h/w stuff */
542 S3C24X0_CLOCK_POWER
* const clk_power
= S3C24X0_GetBase_CLOCK_POWER();
543 S3C24X0_INTERRUPT
* irq
= S3C24X0_GetBase_INTERRUPT();
547 /* Set and check clock control.
548 * We might ought to be using the clock control API to do
549 * this instead of fiddling with the clock registers directly
552 clk_power
->CLKCON
|= (1 << 7);
554 /* Print banner with device revision */
555 printf("USB: S3C2410 USB Deviced\n");
558 * At this point, device is ready for configuration...
560 outl(0x00, S3C2410_UDC_EP_INT_EN_REG
);
561 outl(0x00, S3C2410_UDC_USB_INT_EN_REG
);
563 irq
->INTMSK
&= ~BIT_USBD
;
569 * udc_setup_ep - setup endpoint
571 * Associate a physical endpoint with endpoint_instance
573 int udc_setup_ep (struct usb_device_instance
*device
,
574 unsigned int ep
, struct usb_endpoint_instance
*endpoint
)
576 int ep_addr
= endpoint
->endpoint_address
;
581 S3C2410_UDC_SETIX(ep
);
584 if ((ep_addr
& USB_ENDPOINT_DIR_MASK
) == USB_DIR_IN
) {
586 outl(S3C2410_UDC_ICSR1_FFLUSH
|S3C2410_UDC_ICSR1_CLRDT
,
587 S3C2410_UDC_IN_CSR1_REG
);
588 outl(S3C2410_UDC_ICSR2_MODEIN
, S3C2410_UDC_IN_CSR2_REG
);
589 packet_size
= endpoint
->tx_packetSize
;
590 attributes
= endpoint
->tx_attributes
;
593 outl(S3C2410_UDC_ICSR1_CLRDT
, S3C2410_UDC_IN_CSR1_REG
);
594 outl(0, S3C2410_UDC_IN_CSR2_REG
);
595 outl(S3C2410_UDC_OCSR1_FFLUSH
|S3C2410_UDC_OCSR1_CLRDT
,
596 S3C2410_UDC_OUT_CSR1_REG
);
597 outl(0, S3C2410_UDC_OUT_CSR2_REG
);
598 packet_size
= endpoint
->rcv_packetSize
;
599 attributes
= endpoint
->rcv_attributes
;
602 packet_size
= endpoint
->tx_packetSize
;
604 switch (packet_size
) {
606 maxp
= S3C2410_UDC_MAXP_8
;
609 maxp
= S3C2410_UDC_MAXP_16
;
612 maxp
= S3C2410_UDC_MAXP_32
;
615 maxp
= S3C2410_UDC_MAXP_64
;
618 debug("invalid packet size %u\n", packet_size
);
622 debug("setting up endpoint %u addr %x packet_size %u maxp %u\n", ep
,
623 endpoint
->endpoint_address
, packet_size
, maxp
);
625 /* Set maximum packet size */
626 writel(maxp
, S3C2410_UDC_MAXP_REG
);
631 /* ************************************************************************** */
634 * udc_connected - is the USB cable connected
636 * Return non-zero if cable is connected.
639 int udc_connected (void)
641 return ((inw (UDC_DEVSTAT
) & UDC_ATT
) == UDC_ATT
);
645 /* Turn on the USB connection by enabling the pullup resistor */
646 void udc_connect (void)
648 debug("connect, enable Pullup\n");
649 S3C24X0_INTERRUPT
* irq
= S3C24X0_GetBase_INTERRUPT();
651 udc_ctrl(UDC_CTRL_PULLUP_ENABLE
, 0);
653 udc_ctrl(UDC_CTRL_PULLUP_ENABLE
, 1);
655 irq
->INTMSK
&= ~BIT_USBD
;
658 /* Turn off the USB connection by disabling the pullup resistor */
659 void udc_disconnect (void)
661 debug("disconnect, disable Pullup\n");
662 S3C24X0_INTERRUPT
* irq
= S3C24X0_GetBase_INTERRUPT();
664 udc_ctrl(UDC_CTRL_PULLUP_ENABLE
, 0);
666 /* Disable interrupt (we don't want to get interrupts while the kernel
667 * is relocating itself */
668 irq
->INTMSK
|= BIT_USBD
;
671 /* Switch on the UDC */
672 void udc_enable (struct usb_device_instance
*device
)
674 debug("enable device %p, status %d\n", device
, device
->status
);
676 /* Save the device structure pointer */
681 ep0_urb
= usbd_alloc_urb(udc_device
,
682 udc_device
->bus
->endpoint_array
);
684 serial_printf("udc_enable: ep0_urb already allocated %p\n",
687 s3c2410_configure_device(device
);
690 /* Switch off the UDC */
691 void udc_disable (void)
693 debug("disable UDC\n");
695 s3c2410_deconfigure_device();
699 /*usbd_dealloc_urb(ep0_urb); */
703 /* Reset device pointer.
704 * We ought to do this here to balance the initialization of udc_device
705 * in udc_enable, but some of our other exported functions get called
706 * by the bus interface driver after udc_disable, so we have to hang on
707 * to the device pointer to avoid a null pointer dereference. */
708 /* udc_device = NULL; */
712 * udc_startup - allow udc code to do any additional startup
714 void udc_startup_events (struct usb_device_instance
*device
)
716 /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
717 usbd_device_event_irq (device
, DEVICE_INIT
, 0);
719 /* The DEVICE_CREATE event puts the USB device in the state
722 usbd_device_event_irq (device
, DEVICE_CREATE
, 0);
724 /* Some USB controller driver implementations signal
725 * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
726 * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
727 * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
728 * The OMAP USB client controller has the capability to detect when the
729 * USB cable is connected to a powered USB bus via the ATT bit in the
730 * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
731 * DEVICE_RESET events until later.
734 /* The GTA01 can detect usb device attachment, but we just assume being
735 * attached for now (go to STATE_POWERED) */
736 usbd_device_event_irq (device
, DEVICE_HUB_CONFIGURED
, 0);
741 void udc_set_nak(int epid
)
743 /* FIXME: implement this */
746 void udc_unset_nak(int epid
)
748 /* FIXME: implement this */
751 #endif /* CONFIG_S3C2410 && CONFIG_USB_DEVICE */