diff options
Diffstat (limited to 'packages/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch')
-rw-r--r-- | packages/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch | 1263 |
1 files changed, 0 insertions, 1263 deletions
diff --git a/packages/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch b/packages/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch deleted file mode 100644 index 8dadbbb7de..0000000000 --- a/packages/u-boot/u-boot-mkimage-openmoko-native/uboot-s3c2410_udc.patch +++ /dev/null @@ -1,1263 +0,0 @@ -USB Device Controller Driver for Samsung S3C2410 SoC - -Index: u-boot/drivers/Makefile -=================================================================== ---- u-boot.orig/drivers/Makefile -+++ u-boot/drivers/Makefile -@@ -47,7 +47,7 @@ - status_led.o sym53c8xx.o systemace.o ahci.o \ - ti_pci1410a.o tigon3.o tsec.o \ - tsi108_eth.o tsi108_i2c.o tsi108_pci.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 \ - pcf50606.o \ -Index: u-boot/drivers/usbdcore_s3c2410.c -=================================================================== ---- /dev/null -+++ u-boot/drivers/usbdcore_s3c2410.c -@@ -0,0 +1,730 @@ -+/* S3C2410 USB Device Controller Driver for u-boot -+ * -+ * (C) Copyright 2007 by Openmoko, Inc. -+ * Author: Harald Welte <laforge@openmoko.org> -+ * -+ * based on Linux' s3c2410_udc.c, which is -+ * Copyright (C) 2004-2006 Herbert Pƶtzl - Arnaud Patard -+ * -+ * 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 <config.h> -+ -+#if defined(CONFIG_S3C2410) && defined(CONFIG_USB_DEVICE) -+ -+#include <common.h> -+ -+/* we can't use the regular debug macros since the console might be -+ * set to usbtty, which would cause deadlocks! */ -+#ifdef DEBUG -+#undef debug -+#undef debugX -+#define debug(fmt,args...) serial_printf (fmt ,##args) -+#define debugX(level,fmt,args...) if (DEBUG>=level) serial_printf(fmt,##args) -+#endif -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+#include <asm/io.h> -+#include <s3c2410.h> -+ -+#include "usbdcore.h" -+#include "usbdcore_s3c2410.h" -+#include "usbdcore_ep0.h" -+#include <usb_cdc_acm.h> -+ -+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 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]; -+ -+ /* WARNING: don't ever put serial debug printf's in non-error codepaths -+ * here, it is called from the time critical EP0 codepath ! */ -+ -+ 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) { -+ /* not all data has been transmitted so far */ -+ return 0; -+ } -+ -+ if (last == endpoint->tx_packetSize) { -+ /* we need to send one more packet (ZLP) */ -+ return 0; -+ } -+ -+ return 1; -+} -+ -+ -+static void s3c2410_deconfigure_device (void) -+{ -+ /* FIXME: Implement this */ -+} -+ -+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); -+ -+ /* clear stall status */ -+ if (ep0csr & S3C2410_UDC_EP0_CSR_SENTSTL) { -+ serial_printf("Clearing SENT_STALL\n"); -+ clear_ep0_sst(); -+ if (ep0csr & S3C2410_UDC_EP0_CSR_SOPKTRDY) -+ clear_ep0_opr(); -+ ep0->state = EP0_IDLE; -+ return; -+ } -+ -+ /* clear setup end */ -+ if (ep0csr & S3C2410_UDC_EP0_CSR_SE -+ /* && ep0->state != EP0_IDLE */) { -+ serial_printf("Clearing SETUP_END\n"); -+ clear_ep0_se(); -+#if 1 -+ if (ep0csr & S3C2410_UDC_EP0_CSR_SOPKTRDY) { -+ /* Flush FIFO */ -+ while (inl(S3C2410_UDC_OUT_FIFO_CNT1_REG)) -+ inl(S3C2410_UDC_EP0_FIFO_REG); -+ clear_ep0_opr(); -+ } -+#endif -+ ep0->state = EP0_IDLE; -+ return; -+ } -+ -+ /* Don't ever put [serial] debugging in non-error codepaths here, it -+ * will violate the tight timing constraints of this USB Device -+ * controller (and lead to bus enumeration failures) */ -+ -+ switch (ep0->state) { -+ int i, fifo_count; -+ unsigned char *datap; -+ case EP0_IDLE: -+ if (!(ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY)) -+ break; -+ -+ datap = (unsigned char *) &ep0_urb->device_request; -+ /* host->device packet has been received */ -+ -+ /* pull it out of the fifo */ -+ fifo_count = fifo_count_out(); -+ for (i = 0; i < fifo_count; i++) { -+ *datap = (unsigned char)inl(S3C2410_UDC_EP0_FIFO_REG); -+ datap++; -+ } -+ if (fifo_count != 8) { -+ debug("STRANGE FIFO COUNT: %u bytes\n", fifo_count); -+ set_ep0_ss(); -+ return; -+ } -+ -+ if (ep0_urb->device_request.wLength == 0) { -+ if (ep0_recv_setup(ep0_urb)) { -+ /* Not a setup packet, stall next EP0 transaction */ -+ debug("can't parse setup packet1\n"); -+ set_ep0_ss(); -+ set_ep0_de_out(); -+ ep0->state = EP0_IDLE; -+ return; -+ } -+ /* There are some 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); -+ usbd_device_event_irq(udc_device, -+ DEVICE_ADDRESS_ASSIGNED, 0); -+ break; -+ default: -+ break; -+ } -+ set_ep0_de_out(); -+ ep0->state = EP0_IDLE; -+ } else { -+ if ((ep0_urb->device_request.bmRequestType & USB_REQ_DIRECTION_MASK) -+ == USB_REQ_HOST2DEVICE) { -+ clear_ep0_opr(); -+ ep0->state = EP0_OUT_DATA_PHASE; -+ ep0_urb->buffer = ep0_urb->buffer_data; -+ ep0_urb->buffer_length = sizeof(ep0_urb->buffer_data); -+ ep0_urb->actual_length = 0; -+ } else { -+ ep0->state = EP0_IN_DATA_PHASE; -+ -+ if (ep0_recv_setup(ep0_urb)) { -+ /* Not a setup packet, stall next EP0 transaction */ -+ debug("can't parse setup packet2\n"); -+ set_ep0_ss(); -+ //set_ep0_de_out(); -+ ep0->state = EP0_IDLE; -+ return; -+ } -+ clear_ep0_opr(); -+ ep0->tx_urb = ep0_urb; -+ ep0->sent = ep0->last = 0; -+ -+ if (s3c2410_write_noniso_tx_fifo(ep0)) { -+ ep0->state = EP0_IDLE; -+ set_ep0_de_in(); -+ } else -+ set_ep0_ipr(); -+ } -+ } -+ 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 -+ set_ep0_ipr(); -+ } -+ break; -+ case EP0_OUT_DATA_PHASE: -+ if (ep0csr & S3C2410_UDC_EP0_CSR_OPKRDY) { -+ u32 urb_avail = ep0_urb->buffer_length - ep0_urb->actual_length; -+ u_int8_t *cp = ep0_urb->buffer + ep0_urb->actual_length; -+ int i, fifo_count; -+ -+ fifo_count = fifo_count_out(); -+ if (fifo_count < urb_avail) -+ urb_avail = fifo_count; -+ -+ for (i = 0; i < urb_avail; i++) -+ *cp++ = inl(S3C2410_UDC_EP0_FIFO_REG); -+ -+ ep0_urb->actual_length += urb_avail; -+ -+ if (fifo_count < ep0->rcv_packetSize || -+ ep0_urb->actual_length >= ep0_urb->device_request.wLength) { -+ ep0->state = EP0_IDLE; -+ if (ep0_recv_setup(ep0_urb)) { -+ /* Not a setup packet, stall next EP0 transaction */ -+ debug("can't parse setup packet3\n"); -+ set_ep0_ss(); -+ //set_ep0_de_out(); -+ return; -+ } -+ set_ep0_de_out(); -+ } else -+ clear_ep0_opr(); -+ } -+ 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; -+ -+ if (ep >= S3C2410_UDC_NUM_ENDPOINTS) -+ return; -+ -+ endpoint = &udc_device->bus->endpoint_array[ep]; -+ -+ S3C2410_UDC_SETIX(ep); -+ -+ if (endpoint->endpoint_address & USB_DIR_IN) { -+ /* IN transfer (device to host) */ -+ ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG); -+ debug("for ep=%u, CSR1=0x%x ", ep, ep_csr1); -+ -+ urb = endpoint->tx_urb; -+ if (ep_csr1 & S3C2410_UDC_ICSR1_SENTSTL) { -+ /* Stall handshake */ -+ debug("stall\n"); -+ outl(0x00, S3C2410_UDC_IN_CSR1_REG); -+ return; -+ } -+ if (!(ep_csr1 & S3C2410_UDC_ICSR1_PKTRDY) && urb && -+ urb->actual_length) { -+ -+ debug("completing previously send data "); -+ usbd_tx_complete(endpoint); -+ -+ /* 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) */ -+ debug("ZLP "); -+ outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG); -+ } else { -+ /* write actual data to fifo */ -+ debug("TX_DATA "); -+ s3c2410_write_noniso_tx_fifo(endpoint); -+ outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG); -+ } -+ } -+ debug("\n"); -+ } else { -+ /* OUT transfer (host to device) */ -+ ep_csr1 = inl(S3C2410_UDC_OUT_CSR1_REG); -+ debug("for ep=%u, CSR1=0x%x ", ep, ep_csr1); -+ -+ 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 = urb->buffer + urb->actual_length; -+ -+ if (fifo_count < endpoint->rcv_packetSize) -+ is_last = 1; -+ -+ debug("fifo_count=%u is_last=%, urb_avail=%u)\n", -+ fifo_count, is_last, urb_avail); -+ -+ 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; -+} -+ -+/* -+------------------------------------------------------------------------------- -+*/ -+ -+/* this is just an empty wrapper for usbtty who assumes polling operation */ -+void udc_irq(void) -+{ -+} -+ -+/* Handle general USB interrupts and dispatch according to type. -+ * This function implements TRM Figure 14-13. -+ */ -+void s3c2410_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); -+ -+ //debug("< IRQ usbs=0x%02x, usbds=0x%02x start >", usb_status, usbd_status); -+ -+ /* clear interrupts */ -+ outl(usb_status, S3C2410_UDC_USB_INT_REG); -+ -+ if (usb_status & S3C2410_UDC_USBINT_RESET) { -+ //serial_putc('R'); -+ debug("RESET pwr=0x%x\n", 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) { -+ debug("RESUME\n"); -+ usbd_device_event_irq(udc_device, DEVICE_BUS_ACTIVITY, 0); -+ } -+ -+ if (usb_status & S3C2410_UDC_USBINT_SUSPEND) { -+ debug("SUSPEND\n"); -+ usbd_device_event_irq(udc_device, DEVICE_BUS_INACTIVE, 0); -+ } -+ -+ /* Endpoint Interrupts */ -+ if (usbd_status) { -+ int i; -+ -+ if (usbd_status & S3C2410_UDC_INT_EP0) { -+ outl(S3C2410_UDC_INT_EP0, S3C2410_UDC_EP_INT_REG); -+ s3c2410_udc_ep0(); -+ } -+ -+ for (i = 1; i < 5; i++) { -+ u_int32_t tmp = 1 << i; -+ -+ if (usbd_status & tmp) { -+ /* FIXME: Handle EP X */ -+ outl(tmp, S3C2410_UDC_EP_INT_REG); -+ s3c2410_udc_epn(i); -+ } -+ } -+ } -+ S3C2410_UDC_SETIX(save_idx); -+} -+ -+/* -+------------------------------------------------------------------------------- -+*/ -+ -+ -+/* -+ * 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; -+ -+ debug("Entering for ep %x ", epnum); -+ -+ if (endpoint->tx_urb) { -+ u32 ep_csr1; -+ debug("We have an URB, transmitting\n"); -+ -+ s3c2410_write_noniso_tx_fifo(endpoint); -+ -+ S3C2410_UDC_SETIX(epnum); -+ -+ ep_csr1 = inl(S3C2410_UDC_IN_CSR1_REG); -+ outl(ep_csr1|S3C2410_UDC_ICSR1_PKTRDY, S3C2410_UDC_IN_CSR1_REG); -+ } else -+ debug("\n"); -+} -+ -+/* 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; -+ -+ /* 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); -+ -+ /* Print banner with device revision */ -+ printf("USB: S3C2410 USB Deviced\n"); -+ -+ /* -+ * At this point, device is ready for configuration... -+ */ -+ outl(0x00, S3C2410_UDC_EP_INT_EN_REG); -+ outl(0x00, S3C2410_UDC_USB_INT_EN_REG); -+ -+ irq->INTMSK &= ~BIT_USBD; -+ -+ return 0; -+} -+ -+/* -+ * 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; -+ -+ S3C2410_UDC_SETIX(ep); -+ -+ if (ep) { -+ if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { -+ /* IN endpoint */ -+ outl(S3C2410_UDC_ICSR1_FFLUSH|S3C2410_UDC_ICSR1_CLRDT, -+ S3C2410_UDC_IN_CSR1_REG); -+ outl(S3C2410_UDC_ICSR2_MODEIN, S3C2410_UDC_IN_CSR2_REG); -+ packet_size = endpoint->tx_packetSize; -+ attributes = endpoint->tx_attributes; -+ } else { -+ /* OUT endpoint */ -+ outl(S3C2410_UDC_ICSR1_CLRDT, S3C2410_UDC_IN_CSR1_REG); -+ outl(0, S3C2410_UDC_IN_CSR2_REG); -+ outl(S3C2410_UDC_OCSR1_FFLUSH|S3C2410_UDC_OCSR1_CLRDT, -+ S3C2410_UDC_OUT_CSR1_REG); -+ outl(0, S3C2410_UDC_OUT_CSR2_REG); -+ packet_size = endpoint->rcv_packetSize; -+ attributes = endpoint->rcv_attributes; -+ } -+ } else -+ packet_size = endpoint->tx_packetSize; -+ -+ switch (packet_size) { -+ case 8: -+ maxp = S3C2410_UDC_MAXP_8; -+ break; -+ case 16: -+ maxp = S3C2410_UDC_MAXP_16; -+ break; -+ case 32: -+ maxp = S3C2410_UDC_MAXP_32; -+ break; -+ case 64: -+ maxp = S3C2410_UDC_MAXP_64; -+ break; -+ default: -+ debug("invalid packet size %u\n", packet_size); -+ return -1; -+ } -+ -+ debug("setting up endpoint %u addr %x packet_size %u maxp %u\n", ep, -+ endpoint->endpoint_address, packet_size, maxp); -+ -+ /* Set maximum packet size */ -+ 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) -+{ -+ debug("connect, enable Pullup\n"); -+ S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT(); -+ -+ udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0); -+ udelay(10000); -+ udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 1); -+ -+ irq->INTMSK &= ~BIT_USBD; -+} -+ -+/* Turn off the USB connection by disabling the pullup resistor */ -+void udc_disconnect (void) -+{ -+ debug("disconnect, disable Pullup\n"); -+ S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT(); -+ -+ udc_ctrl(UDC_CTRL_PULLUP_ENABLE, 0); -+ -+ /* Disable interrupt (we don't want to get interrupts while the kernel -+ * is relocating itself */ -+ irq->INTMSK |= BIT_USBD; -+} -+ -+/* Switch on the UDC */ -+void udc_enable (struct usb_device_instance *device) -+{ -+ debug("enable device %p, status %d\n", device, device->status); -+ -+ /* 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); -+ -+ s3c2410_configure_device(device); -+} -+ -+/* Switch off the UDC */ -+void udc_disable (void) -+{ -+ debug("disable UDC\n"); -+ -+ s3c2410_deconfigure_device(); -+ -+ /* 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) -+{ -+ /* FIXME: implement this */ -+} -+ -+void udc_unset_nak(int epid) -+{ -+ /* FIXME: implement this */ -+} -+ -+#endif /* CONFIG_S3C2410 && CONFIG_USB_DEVICE */ -Index: u-boot/drivers/usbdcore_s3c2410.h -=================================================================== ---- /dev/null -+++ u-boot/drivers/usbdcore_s3c2410.h -@@ -0,0 +1,273 @@ -+/* linux/include/asm/arch-s3c2410/regs-udc.h -+ * -+ * Copyright (C) 2004 Herbert Poetzl <herbert@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 16 -+#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/drivers/usbdcore_ep0.c -=================================================================== ---- u-boot.orig/drivers/usbdcore_ep0.c -+++ u-boot/drivers/usbdcore_ep0.c -@@ -43,7 +43,7 @@ - - #include <common.h> - --#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE) -+#if defined(CONFIG_USB_DEVICE) - #include "usbdcore.h" - - #if 0 -@@ -187,9 +187,13 @@ - if (!urb || !urb->buffer || !urb->buffer_length - || (urb->buffer_length < 255)) { - dbg_ep0 (2, "invalid urb %p", urb); -+ serial_printf("invalid urb %p", urb); - 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,17 +210,8 @@ - usbd_device_device_descriptor (device, port))) { - return -1; - } -- /* copy descriptor for this device */ -- copy_config (urb, device_descriptor, -- sizeof (struct usb_device_descriptor), -- max); -- -- /* correct the correct control endpoint 0 max packet size into the descriptor */ -- device_descriptor = -- (struct usb_device_descriptor *) urb->buffer; -- device_descriptor->bMaxPacketSize0 = -- urb->device->bus->maxpacketsize; -- -+ urb->buffer = device_descriptor; -+ urb->actual_length = MIN(sizeof(*device_descriptor), max); - } - /*dbg_ep0(3, "copied device configuration, actual_length: %x", urb->actual_length); */ - break; -@@ -250,11 +245,9 @@ - index); - return -1; - } -- copy_config (urb, configuration_descriptor, -- sizeof (struct -- usb_configuration_descriptor), -- max); -- -+ urb->buffer = configuration_descriptor; -+ urb->actual_length = -+ MIN(le16_to_cpu(configuration_descriptor->wTotalLength), max); - } - break; - -@@ -376,6 +369,7 @@ - dbg_ep0 (0, "entering ep0_recv_setup()"); - if (!urb || !urb->device) { - dbg_ep0 (3, "invalid URB %p", urb); -+ serial_printf("invalid URB %p", urb); - return -1; - } - -@@ -400,6 +394,7 @@ - return device->cdc_recv_setup(request, urb); - dbg_ep0 (1, "non standard request: %x", - request->bmRequestType & USB_REQ_TYPE_MASK); -+ serial_printf("non standard request: %x", request->bmRequestType & USB_REQ_TYPE_MASK); - return -1; /* Stall here */ - } - -@@ -448,6 +443,8 @@ - dbg_ep0 (1, "request %s not allowed in UNKNOWN state: %s", - USBD_DEVICE_REQUESTS (request->bRequest), - usbd_device_states[device->device_state]); -+ serial_printf("request %s not allowed in UNKNOWN state: %s", USBD_DEVICE_REQUESTS (request->bRequest), usbd_device_states[device->device_state]); -+ break; - return -1; - } - -@@ -545,7 +542,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/include/configs/neo1973_gta01.h -=================================================================== ---- u-boot.orig/include/configs/neo1973_gta01.h -+++ u-boot/include/configs/neo1973_gta01.h -@@ -173,6 +173,16 @@ - #define CONFIG_USB_OHCI 1 - #endif - -+#define CONFIG_USB_DEVICE 1 -+#define CONFIG_USB_TTY 1 -+#define CFG_CONSOLE_IS_IN_ENV 1 -+#define CONFIG_USBD_VENDORID 0x1457 /* Linux/NetChip */ -+#define CONFIG_USBD_PRODUCTID_GSERIAL 0x5120 /* gserial */ -+#define CONFIG_USBD_PRODUCTID_CDCACM 0x5119 /* CDC ACM */ -+#define CONFIG_USBD_MANUFACTURER "Openmoko, Inc" -+#define CONFIG_USBD_PRODUCT_NAME "Neo1973 Bootloader " U_BOOT_VERSION -+#define CONFIG_EXTRA_ENV_SETTINGS "usbtty=cdc_acm\0" -+ - /*----------------------------------------------------------------------- - * Physical Memory Map - */ -Index: u-boot/cpu/arm920t/s3c24x0/interrupts.c -=================================================================== ---- u-boot.orig/cpu/arm920t/s3c24x0/interrupts.c -+++ u-boot/cpu/arm920t/s3c24x0/interrupts.c -@@ -222,6 +222,13 @@ - S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT(); - u_int32_t intpnd = irq->INTPND; - -+#ifdef CONFIG_USB_DEVICE -+ if (intpnd & BIT_USBD) { -+ s3c2410_udc_irq(); -+ irq->SRCPND = BIT_USBD; -+ irq->INTPND = BIT_USBD; -+ } -+#endif /* USB_DEVICE */ - } - #endif /* USE_IRQ */ - -Index: u-boot/drivers/usbtty.h -=================================================================== ---- u-boot.orig/drivers/usbtty.h -+++ u-boot/drivers/usbtty.h -@@ -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> -Index: u-boot/board/neo1973/common/cmd_neo1973.c -=================================================================== ---- u-boot.orig/board/neo1973/common/cmd_neo1973.c -+++ u-boot/board/neo1973/common/cmd_neo1973.c -@@ -72,6 +72,18 @@ - neo1973_vibrator(1); - else - neo1973_vibrator(0); -+ } else if (!strcmp(argv[1], "udc")) { -+ if (argc < 3) -+ goto out_help; -+ if (!strcmp(argv[2], "udc")) { -+ if (argc < 4) -+ goto out_help; -+ if (!strcmp(argv[3], "on")) -+ udc_connect(); -+ else -+ udc_disconnect(); -+ } else -+ goto out_help; - } else { - out_help: - printf("Usage:\n%s\n", cmdtp->usage); -@@ -95,5 +107,6 @@ - "neo1973 charger off - disable charging\n" - "neo1973 backlight (on|off) - switch backlight on or off\n" - "neo1973 vibrator (on|off) - switch vibrator on or off\n" -+ "neo1973 udc pullup (on|off) - switch pull-up on or off\n" - ); - #endif /* CFG_CMD_BDI */ -Index: u-boot/board/neo1973/gta01/Makefile -=================================================================== ---- u-boot.orig/board/neo1973/gta01/Makefile -+++ u-boot/board/neo1973/gta01/Makefile -@@ -25,7 +25,7 @@ - - LIB = lib$(BOARD).a - --OBJS := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o -+OBJS := gta01.o pcf50606.o ../common/cmd_neo1973.o ../common/jbt6k74.o ../common/udc.o - SOBJS := ../common/lowlevel_init.o - - $(LIB): $(OBJS) $(SOBJS) -Index: u-boot/board/neo1973/common/udc.c -=================================================================== ---- /dev/null -+++ u-boot/board/neo1973/common/udc.c -@@ -0,0 +1,23 @@ -+ -+#include <common.h> -+#include <usbdcore.h> -+#include <s3c2410.h> -+ -+void udc_ctrl(enum usbd_event event, int param) -+{ -+ S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO(); -+ -+ switch (event) { -+ case UDC_CTRL_PULLUP_ENABLE: -+#if defined(CONFIG_ARCH_GTA01_v4) || defined(CONFIG_ARCH_GTA01B_v2) || \ -+ defined(CONFIG_ARCH_GTA01B_v3) || defined(CONFIG_ARCH_GTA01B_v4) -+ if (param) -+ gpio->GPBDAT |= (1 << 9); -+ else -+ gpio->GPBDAT &= ~(1 << 9); -+#endif -+ break; -+ default: -+ break; -+ } -+} -Index: u-boot/include/usbdcore.h -=================================================================== ---- u-boot.orig/include/usbdcore.h -+++ u-boot/include/usbdcore.h -@@ -671,4 +671,10 @@ - void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad); - void usbd_tx_complete (struct usb_endpoint_instance *endpoint); - -+enum usbd_event { -+ UDC_CTRL_PULLUP_ENABLE, -+}; -+ -+void udc_ctrl(enum usbd_event event, int param); -+#endif - #endif |