r667 - trunk/src/target/u-boot/patches
laforge at sita.openmoko.org
laforge at sita.openmoko.org
Sun Feb 4 22:23:24 CET 2007
Author: laforge
Date: 2007-02-04 22:23:23 +0100 (Sun, 04 Feb 2007)
New Revision: 667
Added:
trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch
Modified:
trunk/src/target/u-boot/patches/series
Log:
add initial version of s3c2410 udc driver for u-boot. This just implements the
USB control pipe so far. It enumerates, etc. - but doesn't give you actual tty access [yet]
Modified: trunk/src/target/u-boot/patches/series
===================================================================
--- trunk/src/target/u-boot/patches/series 2007-02-04 19:25:27 UTC (rev 666)
+++ trunk/src/target/u-boot/patches/series 2007-02-04 21:23:23 UTC (rev 667)
@@ -9,3 +9,7 @@
nand-read_write_oob.patch
env_nand_oob.patch
nand-dynamic_partitions.patch
+uboot-arm920_s3c2410_irq_demux.patch
+uboot-s3c2410-norelocate_irqvec_cpy.patch
+uboot-usbtty-acm.patch
+uboot-s3c2410_udc.patch
Added: trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch
===================================================================
--- trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch 2007-02-04 19:25:27 UTC (rev 666)
+++ trunk/src/target/u-boot/patches/uboot-s3c2410_udc.patch 2007-02-04 21:23:23 UTC (rev 667)
@@ -0,0 +1,1239 @@
+USB Device Controller Driver for Samsung S3C2410 SoC
+
+Index: u-boot.git/drivers/Makefile
+===================================================================
+--- u-boot.git.orig/drivers/Makefile 2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/drivers/Makefile 2007-02-04 20:01:43.000000000 +0100
+@@ -46,7 +46,7 @@
+ sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
+ status_led.o sym53c8xx.o ahci.o \
+ ti_pci1410a.o tigon3.o tsec.o \
+- usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
++ usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbdcore_s3c2410.o usbtty.o \
+ videomodes.o w83c553f.o \
+ ks8695eth.o \
+ pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o \
+Index: u-boot.git/drivers/usbdcore_s3c2410.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ u-boot.git/drivers/usbdcore_s3c2410.c 2007-02-04 22:04:04.000000000 +0100
+@@ -0,0 +1,759 @@
++/* S3C2410 USB Device Controller Driver for u-boot
++ *
++ * (C) Copyright 2007 by OpenMoko, Inc.
++ * Author: Harald Welte <laforge at openmoko.org>
++ *
++ * based on u-boot's udc_omap1510.c and linux' s3c2410_udc.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#include <common.h>
++
++#if defined(CONFIG_S3C2410) && defined(CONFIG_USB_DEVICE)
++
++#include <asm/io.h>
++#include <s3c2410.h>
++
++#include "usbdcore.h"
++#include "usbdcore_s3c2410.h"
++#include "usbdcore_ep0.h"
++
++
++/* Some kind of debugging output... */
++#if 1
++#define UDCDBG(str)
++#define UDCDBGA(fmt,args...)
++#else /* The bugs still exists... */
++#define UDCDBG(str) serial_printf("[%s] %s:%d: " str "\n", __FILE__,__FUNCTION__,__LINE__)
++#define UDCDBGA(fmt,args...) serial_printf("[%s] %s:%d: " fmt "\n", __FILE__,__FUNCTION__,__LINE__, ##args)
++#endif
++
++enum ep0_state {
++ EP0_IDLE,
++ EP0_IN_DATA_PHASE,
++ EP0_OUT_DATA_PHASE,
++ EP0_END_XFER,
++ EP0_STALL,
++};
++
++static struct urb *ep0_urb = NULL;
++
++static struct usb_device_instance *udc_device; /* Used in interrupt handler */
++static u16 udc_devstat = 0; /* UDC status (DEVSTAT) */
++static u32 udc_interrupts = 0;
++
++static void udc_stall_ep (unsigned int ep_addr);
++
++static struct usb_endpoint_instance *s3c2410_find_ep (int ep)
++{
++ int i;
++
++ for (i = 0; i < udc_device->bus->max_endpoints; i++) {
++ if (udc_device->bus->endpoint_array[i].endpoint_address == ep)
++ return &udc_device->bus->endpoint_array[i];
++ }
++ return NULL;
++}
++
++/* ************************************************************************** */
++/* IO
++ */
++
++static inline int fifo_count_out(void)
++{
++ int tmp;
++
++ tmp = inl(S3C2410_UDC_OUT_FIFO_CNT2_REG) << 8;
++ tmp |= inl(S3C2410_UDC_OUT_FIFO_CNT1_REG);
++
++ return tmp & 0xffff;
++}
++
++static const unsigned long ep_fifo_reg[S3C2410_UDC_NUM_ENDPOINTS] = {
++ S3C2410_UDC_EP0_FIFO_REG,
++ S3C2410_UDC_EP1_FIFO_REG,
++ S3C2410_UDC_EP2_FIFO_REG,
++ S3C2410_UDC_EP3_FIFO_REG,
++ S3C2410_UDC_EP4_FIFO_REG,
++};
++
++static int s3c2410_write_noniso_tx_fifo(struct usb_endpoint_instance *endpoint)
++{
++ struct urb *urb = endpoint->tx_urb;
++ unsigned int last, i;
++ unsigned int ep = endpoint->endpoint_address & 0x7f;
++ unsigned long fifo_reg = ep_fifo_reg[ep];
++
++#if 1
++ UDCDBGA("write_noniso_tx_fifo(ep=%d, fifo_reg=0x%x, len=%d, sent=%d, last=%d",
++ ep, fifo_reg, urb->actual_length, endpoint->sent, endpoint->last);
++#endif
++
++ if (!urb || ep >= S3C2410_UDC_NUM_ENDPOINTS) {
++ serial_printf("no urb or wrong endpoint\n");
++ return -1;
++ }
++
++ S3C2410_UDC_SETIX(ep);
++ if ((last = MIN(urb->actual_length - endpoint->sent,
++ endpoint->tx_packetSize))) {
++ u8 *cp = urb->buffer + endpoint->sent;
++
++ for (i = 0; i < last; i++)
++ outb(*(cp+i), fifo_reg);
++ }
++ endpoint->last = last;
++
++ if (endpoint->sent + last < urb->actual_length) {
++ //serial_putc('I');
++ //UDCDBG("INCOMPLETE");
++ return 0;
++ }
++
++ if (last == endpoint->tx_packetSize) {
++ /* we need to send one more packet (ZLP) */
++ //serial_putc('Z');
++ //UDCDBG("zero-pending");
++ return 0;
++ }
++
++ //serial_putc('C');
++ //UDCDBG("complete");
++ return 1;
++}
++
++
++static void s3c2410_deconfigure_device (void)
++{
++#if 0
++ int epnum;
++
++ UDCDBG ("clear Cfg_Lock");
++ outw (inw (UDC_SYSCON1) & ~UDC_Cfg_Lock, UDC_SYSCON1);
++ UDCREG (UDC_SYSCON1);
++
++ /* deconfigure all endpoints */
++ for (epnum = 1; epnum <= 15; epnum++) {
++ outw (0, UDC_EP_RX (epnum));
++ outw (0, UDC_EP_TX (epnum));
++ }
++#endif
++}
++
++static void s3c2410_configure_device (struct usb_device_instance *device)
++{
++ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++ S3C24X0_CLOCK_POWER * const cpower = S3C24X0_GetBase_CLOCK_POWER();
++
++ /* disable EP0-4 SUBD interrupts ? */
++ outl(0x00, S3C2410_UDC_USB_INT_EN_REG);
++
++ /* UPLL already configured by board-level init code */
++
++ /* configure USB pads to device mode */
++ gpio->MISCCR &= ~(S3C2410_MISCCR_USBHOST|S3C2410_MISCCR_USBSUSPND1);
++
++ /* don't disable USB clock */
++ cpower->CLKSLOW &= ~S3C2410_CLKSLOW_UCLK_OFF;
++
++ /* clear interrupt registers */
++ inl(S3C2410_UDC_EP_INT_REG);
++ inl(S3C2410_UDC_USB_INT_REG);
++ outl(0xff, S3C2410_UDC_EP_INT_REG);
++ outl(0xff, S3C2410_UDC_USB_INT_REG);
++
++ /* enable USB interrupts for RESET and SUSPEND/RESUME */
++ outl(S3C2410_UDC_USBINT_RESET|S3C2410_UDC_USBINT_SUSPEND,
++ S3C2410_UDC_USB_INT_EN_REG);
++}
++
++static void udc_set_address(unsigned char address)
++{
++ address |= 0x80; /* ADDR_UPDATE bit */
++ outl(address, S3C2410_UDC_FUNC_ADDR_REG);
++}
++
++extern struct usb_device_descriptor device_descriptor;
++
++static void s3c2410_udc_ep0(void)
++{
++ u_int8_t ep0csr;
++ struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
++
++ S3C2410_UDC_SETIX(0);
++ ep0csr = inl(S3C2410_UDC_IN_CSR1_REG);
++
++ UDCDBGA("-> Entering EP0 handler, EP0_CSR=0x%x, EP0_state=%u", ep0csr,
++ ep0->state);
++
++ /* clear stall status */
++ if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) {
++ UDCDBG("Clearing SENT_STALL");
++ clear_ep0_sst();
++ ep0->state = EP0_IDLE;
++ return;
++ }
++
++ /* clear setup end */
++ if (ep0csr & S3C2410_UDC_EP0_CSR_SE
++ /* && ep0->state != EP0_IDLE */) {
++ UDCDBG("Clearing SETUP_END");
++ clear_ep0_se();
++ ep0->state = EP0_IDLE;
++ return;
++ }
++
++ switch (ep0->state) {
++ case EP0_IDLE:
++ if (ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) {
++ int fifo_count;
++ unsigned char *datap = (unsigned char *) &ep0_urb->device_request;
++ /* host->device packet has been received */
++
++ /* pull it out of the fifo */
++ fifo_count = fifo_count_out();
++ if (fifo_count != 8) {
++ UDCDBGA("STRANGE FIFO COUNT: %u bytes", fifo_count);
++ set_ep0_ss();
++ return;
++ }
++
++ while (fifo_count--) {
++ *datap = (unsigned char)inl(S3C2410_UDC_EP0_FIFO_REG);
++ datap++;
++ }
++
++ if (ep0_recv_setup(ep0_urb)) {
++ /* Not a setup packet, stall next EP0 transaction */
++ UDCDBG("can't parse setup packet, still waiting for setup");
++ set_ep0_ss();
++ return;
++ }
++
++ /* There are two requests with which we need to deal manually here */
++ switch (ep0_urb->device_request.bRequest) {
++ case USB_REQ_SET_CONFIGURATION:
++ if (!ep0_urb->device_request.wValue)
++ usbd_device_event_irq (udc_device, DEVICE_DE_CONFIGURED, 0);
++ else
++ usbd_device_event_irq (udc_device, DEVICE_CONFIGURED, 0);
++ break;
++ case USB_REQ_SET_ADDRESS:
++ udc_set_address(udc_device->address);
++ break;
++ }
++
++ /* check whether we need to write/read */
++ if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK)
++ == USB_REQ_HOST2DEVICE) {
++ UDCDBG("control write on EP0");
++ /* FIXME: implement this. We now only do setup_out with
++ * empty data phase */
++ //set_ep0_ss();
++ //ep0->state = EP0_OUT_DATA_PHASE;
++ set_ep0_de_out();
++ } else {
++ /* device -> host */
++ UDCDBG("control read on EP0");
++ clear_ep0_opr();
++
++ ep0->tx_urb = ep0_urb;
++ ep0->sent = ep0->last = 0;
++
++ if (s3c2410_write_noniso_tx_fifo(ep0)) {
++ ep0->state = EP0_IDLE;
++ //if (!inl(S3C2410_UDC_USB_INT_REG) & S3C2410_UDC_USBINT_RESET)
++ set_ep0_de_in();
++ } else {
++ ep0->state = EP0_IN_DATA_PHASE;
++ set_ep0_ipr();
++#if 1
++ do {
++ ep0csr = inl(S3C2410_UDC_IN_CSR1_REG);
++ if ((ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY))
++ continue;
++ //serial_printf("csr0=0x%x\n", ep0csr);
++
++ ep0->sent += ep0->last;
++ if (s3c2410_write_noniso_tx_fifo(ep0)) {
++ ep0->state = EP0_IDLE;
++ set_ep0_de_in();
++ break;
++ } else
++ set_ep0_ipr();
++ } while (1);
++#endif
++ }
++ }
++ }
++ break;
++ case EP0_IN_DATA_PHASE:
++
++ if (!(ep0csr & S3C2410_UDC_EP0_CSR_IPKRDY)) {
++ ep0->sent += ep0->last;
++
++ if (s3c2410_write_noniso_tx_fifo(ep0)) {
++ ep0->state = EP0_IDLE;
++ set_ep0_de_in();
++ } else {
++ ep0->state = EP0_IN_DATA_PHASE;
++ set_ep0_ipr();
++ }
++ }
++ break;
++ case EP0_OUT_DATA_PHASE:
++ /* FIXME: Not supported */
++ break;
++ case EP0_END_XFER:
++ ep0->state = EP0_IDLE;
++ break;
++ case EP0_STALL:
++ //set_ep0_ss;
++ ep0->state = EP0_IDLE;
++ break;
++ }
++}
++
++
++static void s3c2410_udc_epn(int ep)
++{
++ struct usb_endpoint_instance *endpoint;
++ struct urb *urb;
++ u32 ep_csr1;
++
++ /* FIXME: implement data endpoint handling */
++ UDCDBGA("for ep=%u", ep);
++
++ if (ep >= S3C2410_UDC_NUM_ENDPOINTS)
++ return;
++
++ endpoint = &udc_device->bus->endpoint_array[ep];
++
++ S3C2410_UDC_SETIX(ep);
++ ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG);
++
++ if (endpoint->endpoint_address & USB_DIR_IN) {
++ /* IN transfer (device to host) */
++ urb = endpoint->tx_urb;
++ if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) {
++ /* Stall handshake */
++ outl(0x00, S3C2410_UDC_IN_CSR1_REG);
++ return;
++ }
++ if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && urb) {
++ /* push pending data into FIFO */
++ if ((endpoint->last == endpoint->tx_packetSize) &&
++ (urb->actual_length - endpoint->sent - endpoint->last == 0)) {
++ endpoint->sent += endpoint->last;
++ /* Write 0 bytes of data (ZLP) */
++ outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++ } else {
++ /* write actual data to fifo */
++ s3c2410_write_noniso_tx_fifo(endpoint);
++ outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG);
++
++ usbd_tx_complete(endpoint);
++ }
++ }
++ } else {
++ /* OUT transfer (host to device) */
++ urb = endpoint->rcv_urb;
++ if (ep_csr1 & S3C2410_UDC_OCSR1_SENTSTL) {
++ /* Stall handshake */
++ outl(0x00, S3C2410_UDC_IN_CSR1_REG);
++ return;
++ }
++ if ((ep_csr1 & S3C2410_UDC_OCSR1_PKTRDY) && urb) {
++ /* Read pending data from fifo */
++ u32 fifo_count = fifo_count_out();
++ int is_last = 0;
++ u32 i, urb_avail = urb->buffer_length - urb->actual_length;
++ u8 *cp;
++
++ if (fifo_count < endpoint->rcv_packetSize)
++ is_last = 1;
++
++ if (fifo_count < urb_avail)
++ urb_avail = fifo_count;
++
++ for (i = 0; i < urb_avail; i++)
++ *cp++ = inb(ep_fifo_reg[ep]);
++
++ if (is_last) {
++ outl(ep_csr1 & ~S3C2410_UDC_OCSR1_PKTRDY,
++ S3C2410_UDC_OUT_CSR1_REG);
++ }
++ usbd_rcv_complete(endpoint, urb_avail, 0);
++ }
++ }
++
++ urb = endpoint->rcv_urb;
++}
++
++/*
++-------------------------------------------------------------------------------
++*/
++
++/* Handle general USB interrupts and dispatch according to type.
++ * This function implements TRM Figure 14-13.
++ */
++int udc_irq(void)
++{
++ struct usb_endpoint_instance *ep0 = udc_device->bus->endpoint_array;
++ u_int32_t save_idx = inl(S3C2410_UDC_INDEX_REG);
++
++ /* read interrupt sources */
++ u_int32_t usb_status = inl(S3C2410_UDC_USB_INT_REG);
++ u_int32_t usbd_status = inl(S3C2410_UDC_EP_INT_REG);
++
++ UDCDBGA("< IRQ usbs=0x%02x, usbds=0x%02x start >", usb_status,
++ usbd_status);
++
++ /* clear interrupts */
++ outl(usb_status, S3C2410_UDC_USB_INT_REG);
++ //outl(usbd_status, S3C2410_UDC_EP_INT_REG);
++
++ if (usb_status & S3C2410_UDC_USBINT_RESET) {
++ //serial_putc('R');
++ UDCDBGA("RESET pwr=0x%x", inl(S3C2410_UDC_PWR_REG));
++ udc_setup_ep(udc_device, 0, ep0);
++ outl(S3C2410_UDC_EP0_CSR_SSE|S3C2410_UDC_EP0_CSR_SOPKTRDY, S3C2410_UDC_EP0_CSR_REG);
++ ep0->state = EP0_IDLE;
++ usbd_device_event_irq (udc_device, DEVICE_RESET, 0);
++ }
++
++ if (usb_status & S3C2410_UDC_USBINT_RESUME) {
++ UDCDBG("RESUME");
++ usbd_device_event_irq(udc_device, DEVICE_BUS_ACTIVITY, 0);
++ }
++
++ if (usb_status & S3C2410_UDC_USBINT_SUSPEND) {
++ UDCDBG("SUSPEND");
++ usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0);
++ }
++
++ /* Endpoint Interrupts */
++ if (usbd_status) {
++ int i;
++
++ if (usbd_status & S3C2410_UDC_INT_EP0) {
++ s3c2410_udc_ep0();
++ outl(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG);
++ }
++
++ for (i = 1; i < 5; i++) {
++ u_int32_t tmp = 1 << i;
++
++ if (usbd_status & tmp) {
++ /* FIXME: Handle EP X */
++ s3c2410_udc_epn(i);
++ outl(tmp, S3C2410_UDC_EP_INT_REG);
++ }
++ }
++ }
++ S3C2410_UDC_SETIX(save_idx);
++ udc_interrupts++;
++
++ return usb_status | usbd_status;
++}
++
++/*
++-------------------------------------------------------------------------------
++*/
++
++
++/*
++ * Start of public functions.
++ */
++
++/* Called to start packet transmission. */
++void udc_endpoint_write (struct usb_endpoint_instance *endpoint)
++{
++ unsigned short epnum =
++ endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
++
++ UDCDBGA ("Starting transmit on ep %x", epnum);
++
++ if (endpoint->tx_urb) {
++#if 0
++ /* select the endpoint FIFO */
++ outw (UDC_EP_Sel | UDC_EP_Dir | epnum, UDC_EP_NUM);
++ /* write data to FIFO */
++ omap1510_write_noniso_tx_fifo (endpoint);
++ /* enable tx FIFO to start transmission */
++ outw (UDC_Set_FIFO_En, UDC_CTRL);
++ /* deselect the endpoint FIFO */
++ outw (UDC_EP_Dir | epnum, UDC_EP_NUM);
++#endif
++ }
++}
++
++/* Start to initialize h/w stuff */
++int udc_init (void)
++{
++ S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
++ S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
++
++ udc_device = NULL;
++
++ UDCDBG ("starting");
++
++ /* Set and check clock control.
++ * We might ought to be using the clock control API to do
++ * this instead of fiddling with the clock registers directly
++ * here.
++ */
++ clk_power->CLKCON |= (1 << 7);
++ irq->INTMSK &= ~BIT_USBD;
++
++ /* Print banner with device revision */
++ printf ("USB: S3C2410 USB Deviced\n");
++
++ /*
++ * At this point, device is ready for configuration...
++ */
++
++ //UDCDBG("disable USB interrupts");
++ UDCDBG("enable USB interrupts");
++ outl(0xff, S3C2410_UDC_EP_INT_EN_REG);
++ outl(0x04, S3C2410_UDC_USB_INT_EN_REG);
++
++ return 0;
++}
++
++/* Stall endpoint */
++static void udc_stall_ep(unsigned int ep_num)
++{
++ UDCDBGA ("stall ep %d", ep_num);
++
++ S3C2410_UDC_SETIX(ep_num);
++
++ switch (ep_num) {
++ case 0:
++ outw(S3C2410_UDC_EP0_CSR_SENDSTL, S3C2410_UDC_EP0_CSR_REG);
++ break;
++ /* FIXME */
++ default:
++#if 0
++ if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
++ outw(ep_num)
++ if (inw (UDC_EP_RX (ep_num)) & UDC_EPn_RX_Valid) {
++ /* we have a valid rx endpoint, so halt it */
++ outw (UDC_EP_Sel | ep_num, UDC_EP_NUM);
++ outw (UDC_Set_Halt, UDC_CTRL);
++ outw (ep_num, UDC_EP_NUM);
++ }
++ } else {
++ if (inw (UDC_EP_TX (ep_num)) & UDC_EPn_TX_Valid) {
++ /* we have a valid tx endpoint, so halt it */
++ outw (UDC_EP_Sel | UDC_EP_Dir | ep_num, UDC_EP_NUM);
++ outw (UDC_Set_Halt, UDC_CTRL);
++ outw (ep_num, UDC_EP_NUM);
++ }
++ }
++#endif
++ break;
++ }
++}
++
++/*
++ * udc_setup_ep - setup endpoint
++ *
++ * Associate a physical endpoint with endpoint_instance
++ */
++int udc_setup_ep (struct usb_device_instance *device,
++ unsigned int ep, struct usb_endpoint_instance *endpoint)
++{
++ int ep_addr = endpoint->endpoint_address;
++ int packet_size;
++ int attributes;
++
++ u_int32_t maxp;
++
++ if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
++ /* IN endpoint */
++ packet_size = endpoint->tx_packetSize;
++ attributes = endpoint->tx_attributes;
++ } else {
++ /* OUT endpoint */
++ packet_size = endpoint->rcv_packetSize;
++ attributes = endpoint->rcv_attributes;
++ }
++
++ if (packet_size <= 8)
++ maxp = S3C2410_UDC_MAXP_8;
++ else if (packet_size <= 16)
++ maxp = S3C2410_UDC_MAXP_16;
++ else if (packet_size <= 32)
++ maxp = S3C2410_UDC_MAXP_32;
++ else
++ maxp = S3C2410_UDC_MAXP_64;
++
++ UDCDBGA("setting up endpoint %u addr %x packet_size %u maxp %u", ep,
++ endpoint->endpoint_address, packet_size, maxp);
++
++ /* Set maximum packet size */
++ S3C2410_UDC_SETIX(ep);
++ writel(maxp, S3C2410_UDC_MAXP_REG);
++
++ return 0;
++}
++
++/* ************************************************************************** */
++
++/**
++ * udc_connected - is the USB cable connected
++ *
++ * Return non-zero if cable is connected.
++ */
++#if 0
++int udc_connected (void)
++{
++ return ((inw (UDC_DEVSTAT) & UDC_ATT) == UDC_ATT);
++}
++#endif
++
++/* Turn on the USB connection by enabling the pullup resistor */
++void udc_connect (void)
++{
++ UDCDBG ("connect, enable Pullup");
++#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2)
++ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++ // s3c2410_gpio_setpin(GTA01_GPIO_USB_PULLUP, 1);
++ gpio->GPBDAT |= (1 << 9);
++#endif
++}
++
++/* Turn off the USB connection by disabling the pullup resistor */
++void udc_disconnect (void)
++{
++ UDCDBG ("disconnect, disable Pullup");
++#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2)
++ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
++
++ //s3c2410_gpio_setpin(GTA01_GPIO_USB_PULLUP, 0);
++ gpio->GPBDAT &= ~(1 << 9);
++#endif
++}
++
++/* Switch on the UDC */
++void udc_enable (struct usb_device_instance *device)
++{
++ UDCDBGA ("enable device %p, status %d", device, device->status);
++
++ /* initialize driver state variables */
++ udc_devstat = 0;
++
++ /* Save the device structure pointer */
++ udc_device = device;
++
++ /* Setup ep0 urb */
++ if (!ep0_urb) {
++ ep0_urb =
++ usbd_alloc_urb (udc_device,
++ udc_device->bus->endpoint_array);
++ } else {
++ serial_printf ("udc_enable: ep0_urb already allocated %p\n",
++ ep0_urb);
++ }
++
++#ifdef FIXME
++ /* The VBUS_MODE bit selects whether VBUS detection is done via
++ * software (1) or hardware (0). When software detection is
++ * selected, VBUS_CTRL selects whether USB is not connected (0)
++ * or connected (1).
++ */
++ outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_CTRL | UDC_VBUS_MODE,
++ FUNC_MUX_CTRL_0);
++ UDCREGL (FUNC_MUX_CTRL_0);
++#endif
++
++ s3c2410_configure_device(device);
++}
++
++/* Switch off the UDC */
++void udc_disable (void)
++{
++ UDCDBG ("disable UDC");
++
++ s3c2410_deconfigure_device();
++
++#ifdef FIXME
++ /* The VBUS_MODE bit selects whether VBUS detection is done via
++ * software (1) or hardware (0). When software detection is
++ * selected, VBUS_CTRL selects whether USB is not connected (0)
++ * or connected (1).
++ */
++ outl (inl (FUNC_MUX_CTRL_0) | UDC_VBUS_MODE, FUNC_MUX_CTRL_0);
++ outl (inl (FUNC_MUX_CTRL_0) & ~UDC_VBUS_CTRL, FUNC_MUX_CTRL_0);
++ UDCREGL (FUNC_MUX_CTRL_0);
++#endif
++
++ /* Free ep0 URB */
++ if (ep0_urb) {
++ /*usbd_dealloc_urb(ep0_urb); */
++ ep0_urb = NULL;
++ }
++
++ /* Reset device pointer.
++ * We ought to do this here to balance the initialization of udc_device
++ * in udc_enable, but some of our other exported functions get called
++ * by the bus interface driver after udc_disable, so we have to hang on
++ * to the device pointer to avoid a null pointer dereference. */
++ /* udc_device = NULL; */
++}
++
++/**
++ * udc_startup - allow udc code to do any additional startup
++ */
++void udc_startup_events (struct usb_device_instance *device)
++{
++ /* The DEVICE_INIT event puts the USB device in the state STATE_INIT. */
++ usbd_device_event_irq (device, DEVICE_INIT, 0);
++
++ /* The DEVICE_CREATE event puts the USB device in the state
++ * STATE_ATTACHED.
++ */
++ usbd_device_event_irq (device, DEVICE_CREATE, 0);
++
++ /* Some USB controller driver implementations signal
++ * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
++ * DEVICE_HUB_CONFIGURED causes a transition to the state STATE_POWERED,
++ * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
++ * The OMAP USB client controller has the capability to detect when the
++ * USB cable is connected to a powered USB bus via the ATT bit in the
++ * DEVSTAT register, so we will defer the DEVICE_HUB_CONFIGURED and
++ * DEVICE_RESET events until later.
++ */
++
++ /* The GTA01 can detect usb device attachment, but we just assume being
++ * attached for now (go to STATE_POWERED) */
++ usbd_device_event_irq (device, DEVICE_HUB_CONFIGURED, 0);
++
++ udc_enable (device);
++}
++
++void udc_set_nak(int epid)
++{
++
++}
++
++void udc_unset_nak(int epid)
++{
++}
++#endif
+Index: u-boot.git/drivers/usbdcore_s3c2410.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ u-boot.git/drivers/usbdcore_s3c2410.h 2007-02-04 20:01:43.000000000 +0100
+@@ -0,0 +1,273 @@
++/* linux/include/asm/arch-s3c2410/regs-udc.h
++ *
++ * Copyright (C) 2004 Herbert Poetzl <herbert at 13thfloor.at>
++ *
++ * This include file is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * Changelog:
++ * 01-08-2004 Initial creation
++ * 12-09-2004 Cleanup for submission
++ * 24-10-2004 Fixed S3C2410_UDC_MAXP_REG definition
++ * 10-03-2005 Changed S3C2410_VA to S3C24XX_VA
++ * 10-01-2007 Modify for u-boot
++ */
++
++#ifndef __ASM_ARCH_REGS_UDC_H
++#define __ASM_ARCH_REGS_UDC_H
++
++#define S3C2410_UDC_REG_BASE_PHYS 0x52000000
++#define S3C2410_UDC_NUM_ENDPOINTS 5
++
++#define S3C2410_USBDREG(x) (x + S3C2410_UDC_REG_BASE_PHYS)
++
++#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140)
++#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144)
++#define S3C2410_UDC_EP_INT_REG S3C2410_USBDREG(0x0148)
++
++#define S3C2410_UDC_USB_INT_REG S3C2410_USBDREG(0x0158)
++#define S3C2410_UDC_EP_INT_EN_REG S3C2410_USBDREG(0x015c)
++
++#define S3C2410_UDC_USB_INT_EN_REG S3C2410_USBDREG(0x016c)
++
++#define S3C2410_UDC_FRAME_NUM1_REG S3C2410_USBDREG(0x0170)
++#define S3C2410_UDC_FRAME_NUM2_REG S3C2410_USBDREG(0x0174)
++
++#define S3C2410_UDC_EP0_FIFO_REG S3C2410_USBDREG(0x01c0)
++#define S3C2410_UDC_EP1_FIFO_REG S3C2410_USBDREG(0x01c4)
++#define S3C2410_UDC_EP2_FIFO_REG S3C2410_USBDREG(0x01c8)
++#define S3C2410_UDC_EP3_FIFO_REG S3C2410_USBDREG(0x01cc)
++#define S3C2410_UDC_EP4_FIFO_REG S3C2410_USBDREG(0x01d0)
++
++#define S3C2410_UDC_EP1_DMA_CON S3C2410_USBDREG(0x0200)
++#define S3C2410_UDC_EP1_DMA_UNIT S3C2410_USBDREG(0x0204)
++#define S3C2410_UDC_EP1_DMA_FIFO S3C2410_USBDREG(0x0208)
++#define S3C2410_UDC_EP1_DMA_TTC_L S3C2410_USBDREG(0x020c)
++#define S3C2410_UDC_EP1_DMA_TTC_M S3C2410_USBDREG(0x0210)
++#define S3C2410_UDC_EP1_DMA_TTC_H S3C2410_USBDREG(0x0214)
++
++#define S3C2410_UDC_EP2_DMA_CON S3C2410_USBDREG(0x0218)
++#define S3C2410_UDC_EP2_DMA_UNIT S3C2410_USBDREG(0x021c)
++#define S3C2410_UDC_EP2_DMA_FIFO S3C2410_USBDREG(0x0220)
++#define S3C2410_UDC_EP2_DMA_TTC_L S3C2410_USBDREG(0x0224)
++#define S3C2410_UDC_EP2_DMA_TTC_M S3C2410_USBDREG(0x0228)
++#define S3C2410_UDC_EP2_DMA_TTC_H S3C2410_USBDREG(0x022c)
++
++#define S3C2410_UDC_EP3_DMA_CON S3C2410_USBDREG(0x0240)
++#define S3C2410_UDC_EP3_DMA_UNIT S3C2410_USBDREG(0x0244)
++#define S3C2410_UDC_EP3_DMA_FIFO S3C2410_USBDREG(0x0248)
++#define S3C2410_UDC_EP3_DMA_TTC_L S3C2410_USBDREG(0x024c)
++#define S3C2410_UDC_EP3_DMA_TTC_M S3C2410_USBDREG(0x0250)
++#define S3C2410_UDC_EP3_DMA_TTC_H S3C2410_USBDREG(0x0254)
++
++#define S3C2410_UDC_EP4_DMA_CON S3C2410_USBDREG(0x0258)
++#define S3C2410_UDC_EP4_DMA_UNIT S3C2410_USBDREG(0x025c)
++#define S3C2410_UDC_EP4_DMA_FIFO S3C2410_USBDREG(0x0260)
++#define S3C2410_UDC_EP4_DMA_TTC_L S3C2410_USBDREG(0x0264)
++#define S3C2410_UDC_EP4_DMA_TTC_M S3C2410_USBDREG(0x0268)
++#define S3C2410_UDC_EP4_DMA_TTC_H S3C2410_USBDREG(0x026c)
++
++#define S3C2410_UDC_INDEX_REG S3C2410_USBDREG(0x0178)
++
++/* indexed registers */
++
++#define S3C2410_UDC_MAXP_REG S3C2410_USBDREG(0x0180)
++
++#define S3C2410_UDC_EP0_CSR_REG S3C2410_USBDREG(0x0184)
++
++#define S3C2410_UDC_IN_CSR1_REG S3C2410_USBDREG(0x0184)
++#define S3C2410_UDC_IN_CSR2_REG S3C2410_USBDREG(0x0188)
++
++#define S3C2410_UDC_OUT_CSR1_REG S3C2410_USBDREG(0x0190)
++#define S3C2410_UDC_OUT_CSR2_REG S3C2410_USBDREG(0x0194)
++#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198)
++#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c)
++
++
++
++#define S3C2410_UDC_PWR_ISOUP (1<<7) // R/W
++#define S3C2410_UDC_PWR_RESET (1<<3) // R
++#define S3C2410_UDC_PWR_RESUME (1<<2) // R/W
++#define S3C2410_UDC_PWR_SUSPEND (1<<1) // R
++#define S3C2410_UDC_PWR_ENSUSPEND (1<<0) // R/W
++
++#define S3C2410_UDC_PWR_DEFAULT 0x00
++
++#define S3C2410_UDC_INT_EP4 (1<<4) // R/W (clear only)
++#define S3C2410_UDC_INT_EP3 (1<<3) // R/W (clear only)
++#define S3C2410_UDC_INT_EP2 (1<<2) // R/W (clear only)
++#define S3C2410_UDC_INT_EP1 (1<<1) // R/W (clear only)
++#define S3C2410_UDC_INT_EP0 (1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_USBINT_RESET (1<<2) // R/W (clear only)
++#define S3C2410_UDC_USBINT_RESUME (1<<1) // R/W (clear only)
++#define S3C2410_UDC_USBINT_SUSPEND (1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_INTE_EP4 (1<<4) // R/W
++#define S3C2410_UDC_INTE_EP3 (1<<3) // R/W
++#define S3C2410_UDC_INTE_EP2 (1<<2) // R/W
++#define S3C2410_UDC_INTE_EP1 (1<<1) // R/W
++#define S3C2410_UDC_INTE_EP0 (1<<0) // R/W
++
++#define S3C2410_UDC_USBINTE_RESET (1<<2) // R/W
++#define S3C2410_UDC_USBINTE_SUSPEND (1<<0) // R/W
++
++
++#define S3C2410_UDC_INDEX_EP0 (0x00)
++#define S3C2410_UDC_INDEX_EP1 (0x01) // ??
++#define S3C2410_UDC_INDEX_EP2 (0x02) // ??
++#define S3C2410_UDC_INDEX_EP3 (0x03) // ??
++#define S3C2410_UDC_INDEX_EP4 (0x04) // ??
++
++#define S3C2410_UDC_ICSR1_CLRDT (1<<6) // R/W
++#define S3C2410_UDC_ICSR1_SENTSTL (1<<5) // R/W (clear only)
++#define S3C2410_UDC_ICSR1_SENDSTL (1<<4) // R/W
++#define S3C2410_UDC_ICSR1_FFLUSH (1<<3) // W (set only)
++#define S3C2410_UDC_ICSR1_UNDRUN (1<<2) // R/W (clear only)
++#define S3C2410_UDC_ICSR1_PKTRDY (1<<0) // R/W (set only)
++
++#define S3C2410_UDC_ICSR2_AUTOSET (1<<7) // R/W
++#define S3C2410_UDC_ICSR2_ISO (1<<6) // R/W
++#define S3C2410_UDC_ICSR2_MODEIN (1<<5) // R/W
++#define S3C2410_UDC_ICSR2_DMAIEN (1<<4) // R/W
++
++#define S3C2410_UDC_OCSR1_CLRDT (1<<7) // R/W
++#define S3C2410_UDC_OCSR1_SENTSTL (1<<6) // R/W (clear only)
++#define S3C2410_UDC_OCSR1_SENDSTL (1<<5) // R/W
++#define S3C2410_UDC_OCSR1_FFLUSH (1<<4) // R/W
++#define S3C2410_UDC_OCSR1_DERROR (1<<3) // R
++#define S3C2410_UDC_OCSR1_OVRRUN (1<<2) // R/W (clear only)
++#define S3C2410_UDC_OCSR1_PKTRDY (1<<0) // R/W (clear only)
++
++#define S3C2410_UDC_OCSR2_AUTOCLR (1<<7) // R/W
++#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W
++#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W
++
++#define S3C2410_UDC_SETIX(X) writel(X, S3C2410_UDC_INDEX_REG)
++
++#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0)
++#define S3C2410_UDC_EP0_CSR_IPKRDY (1<<1)
++#define S3C2410_UDC_EP0_CSR_SENTSTL (1<<2)
++#define S3C2410_UDC_EP0_CSR_DE (1<<3)
++#define S3C2410_UDC_EP0_CSR_SE (1<<4)
++#define S3C2410_UDC_EP0_CSR_SENDSTL (1<<5)
++#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1<<6)
++#define S3C2410_UDC_EP0_CSR_SSE (1<<7)
++
++#define S3C2410_UDC_MAXP_8 (1<<0)
++#define S3C2410_UDC_MAXP_16 (1<<1)
++#define S3C2410_UDC_MAXP_32 (1<<2)
++#define S3C2410_UDC_MAXP_64 (1<<3)
++
++/****************** MACROS ******************/
++#define BIT_MASK 0xFF
++
++#if 1
++#define maskl(v,m,a) \
++ writel((readl(a) & ~(m))|((v)&(m)), (a))
++#else
++#define maskl(v,m,a) do { \
++ unsigned long foo = readl(a); \
++ unsigned long bar = (foo & ~(m)) | ((v)&(m)); \
++ serial_printf("0x%08x:0x%x->0x%x\n", (a), foo, bar); \
++ writel(bar, (a)); \
++} while(0)
++#endif
++
++#define clear_ep0_sst() do { \
++ S3C2410_UDC_SETIX(0); \
++ writel(0x00, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define clear_ep0_se() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl(S3C2410_UDC_EP0_CSR_SSE, \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define clear_ep0_opr() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl(S3C2410_UDC_EP0_CSR_SOPKTRDY, \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define set_ep0_ipr() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl(S3C2410_UDC_EP0_CSR_IPKRDY, \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define set_ep0_de() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl(S3C2410_UDC_EP0_CSR_DE, \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define set_ep0_ss() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl(S3C2410_UDC_EP0_CSR_SENDSTL, \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define set_ep0_de_out() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY \
++ | S3C2410_UDC_EP0_CSR_DE), \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define set_ep0_sse_out() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl((S3C2410_UDC_EP0_CSR_SOPKTRDY \
++ | S3C2410_UDC_EP0_CSR_SSE), \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++#define set_ep0_de_in() do { \
++ S3C2410_UDC_SETIX(0); \
++ maskl((S3C2410_UDC_EP0_CSR_IPKRDY \
++ | S3C2410_UDC_EP0_CSR_DE), \
++ BIT_MASK, S3C2410_UDC_EP0_CSR_REG); \
++} while(0)
++
++
++#if 0
++
++#define clear_stall_ep1_out(base) do { \
++ S3C2410_UDC_SETIX(base,EP1); \
++ orl(0,base+S3C2410_UDC_OUT_CSR1_REG); \
++} while(0)
++
++
++#define clear_stall_ep2_out(base) do { \
++ S3C2410_UDC_SETIX(base,EP2); \
++ orl(0, base+S3C2410_UDC_OUT_CSR1_REG); \
++} while(0)
++
++
++#define clear_stall_ep3_out(base) do { \
++ S3C2410_UDC_SETIX(base,EP3); \
++ orl(0,base+S3C2410_UDC_OUT_CSR1_REG); \
++} while(0)
++
++
++#define clear_stall_ep4_out(base) do { \
++ S3C2410_UDC_SETIX(base,EP4); \
++ orl(0, base+S3C2410_UDC_OUT_CSR1_REG); \
++} while(0)
++
++#endif
++
++/* S3C2410 Endpoint parameters */
++#define EP0_MAX_PACKET_SIZE 8
++#define UDC_OUT_ENDPOINT 2
++#define UDC_OUT_PACKET_SIZE 64
++#define UDC_IN_ENDPOINT 1
++#define UDC_IN_PACKET_SIZE 64
++#define UDC_INT_ENDPOINT 5
++#define UDC_INT_PACKET_SIZE 16
++#define UDC_BULK_PACKET_SIZE 16
++
++#endif
+Index: u-boot.git/include/s3c2410.h
+===================================================================
+--- u-boot.git.orig/include/s3c2410.h 2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/include/s3c2410.h 2007-02-04 20:01:43.000000000 +0100
+@@ -233,4 +233,40 @@
+ rINTPND;\
+ }
+ /* Wait until rINTPND is changed for the case that the ISR is very short. */
++
++#define S3C2410_MISCCR_USBDEV (0<<3)
++#define S3C2410_MISCCR_USBHOST (1<<3)
++
++#define S3C2410_MISCCR_CLK0_MPLL (0<<4)
++#define S3C2410_MISCCR_CLK0_UPLL (1<<4)
++#define S3C2410_MISCCR_CLK0_FCLK (2<<4)
++#define S3C2410_MISCCR_CLK0_HCLK (3<<4)
++#define S3C2410_MISCCR_CLK0_PCLK (4<<4)
++#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4)
++#define S3C2410_MISCCR_CLK0_MASK (7<<4)
++
++#define S3C2410_MISCCR_CLK1_MPLL (0<<8)
++#define S3C2410_MISCCR_CLK1_UPLL (1<<8)
++#define S3C2410_MISCCR_CLK1_FCLK (2<<8)
++#define S3C2410_MISCCR_CLK1_HCLK (3<<8)
++#define S3C2410_MISCCR_CLK1_PCLK (4<<8)
++#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8)
++#define S3C2410_MISCCR_CLK1_MASK (7<<8)
++
++#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
++#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
++
++#define S3C2410_MISCCR_nRSTCON (1<<16)
++
++#define S3C2410_MISCCR_nEN_SCLK0 (1<<17)
++#define S3C2410_MISCCR_nEN_SCLK1 (1<<18)
++#define S3C2410_MISCCR_nEN_SCLKE (1<<19)
++#define S3C2410_MISCCR_SDSLEEP (7<<17)
++
++#define S3C2410_CLKSLOW_UCLK_OFF (1<<7)
++#define S3C2410_CLKSLOW_MPLL_OFF (1<<5)
++#define S3C2410_CLKSLOW_SLOW (1<<4)
++#define S3C2410_CLKSLOW_SLOWVAL(x) (x)
++#define S3C2410_CLKSLOW_GET_SLOWVAL(x) ((x) & 7)
++
+ #endif /*__S3C2410_H__*/
+Index: u-boot.git/drivers/usbdcore_ep0.c
+===================================================================
+--- u-boot.git.orig/drivers/usbdcore_ep0.c 2007-02-04 20:01:39.000000000 +0100
++++ u-boot.git/drivers/usbdcore_ep0.c 2007-02-04 20:41:17.000000000 +0100
+@@ -43,10 +43,10 @@
+
+ #include <common.h>
+
+-#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE)
++#if defined(CONFIG_USB_DEVICE)
+ #include "usbdcore.h"
+
+-#if 0
++#if 1
+ #define dbg_ep0(lvl,fmt,args...) serial_printf("[%s] %s:%d: "fmt"\n",__FILE__,__FUNCTION__,__LINE__,##args)
+ #else
+ #define dbg_ep0(lvl,fmt,args...)
+@@ -190,6 +190,9 @@
+ return -1L;
+ }
+
++ /* re-initialize the ep0 buffer pointer */
++ urb->buffer = (u8 *) urb->buffer_data;
++
+ /* setup tx urb */
+ urb->actual_length = 0;
+ cp = urb->buffer;
+@@ -206,6 +209,9 @@
+ usbd_device_device_descriptor (device, port))) {
+ return -1;
+ }
++ urb->buffer = device_descriptor;
++ urb->actual_length = MIN(sizeof(*device_descriptor), max);
++#if 0
+ /* copy descriptor for this device */
+ copy_config (urb, device_descriptor,
+ sizeof (struct usb_device_descriptor),
+@@ -217,6 +223,7 @@
+ device_descriptor->bMaxPacketSize0 =
+ urb->device->bus->maxpacketsize;
+
++#endif
+ }
+ /*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */
+ break;
+@@ -250,9 +257,14 @@
+ index);
+ return -1;
+ }
++ urb->buffer = configuration_descriptor;
++ urb->actual_length =
++ MIN(le16_to_cpu(configuration_descriptor->wTotalLength), max);
++#if 0
+ copy_config (urb, configuration_descriptor,
+ le16_to_cpu(configuration_descriptor->wTotalLength),
+ max);
++#endif
+ }
+ break;
+
+@@ -543,7 +555,8 @@
+ /*dbg_ep0(2, "address: %d %d %d", */
+ /* request->wValue, le16_to_cpu(request->wValue), device->address); */
+
+- serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
++ //serial_printf ("DEVICE_ADDRESS_ASSIGNED.. event?\n");
++ //udc_set_address(device->address);
+ return 0;
+
+ case USB_REQ_SET_DESCRIPTOR: /* XXX should we support this? */
+Index: u-boot.git/include/configs/gta01.h
+===================================================================
+--- u-boot.git.orig/include/configs/gta01.h 2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/include/configs/gta01.h 2007-02-04 20:01:43.000000000 +0100
+@@ -173,6 +173,16 @@
+ #define CONFIG_USB_OHCI 1
+ #endif
+
++#define CONFIG_USB_DEVICE 1
++#define CONFIG_USB_TTY 1
++#if 0
++#define CONFIG_USBD_MANUFACTURER "OpenMoko, Inc."
++#define CONFIG_USBD_PRODUCT_NAME "Neo1973 Bootloader"
++#define CONFIG_USBD_VENDORID 0x2342
++#define CONFIG_USBD_PRODUCTID 0x0815
++#endif
++
++
+ /*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+Index: u-boot.git/common/main.c
+===================================================================
+--- u-boot.git.orig/common/main.c 2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/common/main.c 2007-02-04 20:01:43.000000000 +0100
+@@ -962,6 +962,10 @@
+ show_activity(0);
+ }
+ #endif
++#ifdef CONFIG_USB_DEVICE__
++ while (udc_irq_poll())
++ ;
++#endif
+ c = getc();
+
+ /*
+Index: u-boot.git/cpu/arm920t/s3c24x0/interrupts.c
+===================================================================
+--- u-boot.git.orig/cpu/arm920t/s3c24x0/interrupts.c 2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/cpu/arm920t/s3c24x0/interrupts.c 2007-02-04 20:01:43.000000000 +0100
+@@ -222,6 +222,13 @@
+ S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
+ u_int32_t intpnd = irq->INTPND;
+
++#ifdef CONFIG_USB_DEVICE
++ if (intpnd & BIT_USBD) {
++ udc_irq();
++ irq->SRCPND = BIT_USBD;
++ irq->INTPND = BIT_USBD;
++ }
++#endif /* USB_DEVICE */
+ }
+ #endif /* USE_IRQ */
+
+Index: u-boot.git/drivers/usbtty.h
+===================================================================
+--- u-boot.git.orig/drivers/usbtty.h 2007-02-04 20:00:53.000000000 +0100
++++ u-boot.git/drivers/usbtty.h 2007-02-04 20:01:43.000000000 +0100
+@@ -29,6 +29,8 @@
+ #include "usbdcore_mpc8xx.h"
+ #elif defined(CONFIG_OMAP1510)
+ #include "usbdcore_omap1510.h"
++#elif defined(CONFIG_S3C2410)
++#include "usbdcore_s3c2410.h"
+ #endif
+
+ #include <config.h>
More information about the commitlog
mailing list