summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bios_emulator/Makefile1
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/dm9000x.c2
-rw-r--r--drivers/net/e1000.c1
-rw-r--r--drivers/net/fec_mxc.c1
-rw-r--r--drivers/net/lan91c96.c452
-rw-r--r--drivers/net/lan91c96.h110
-rw-r--r--drivers/serial/usbtty.h2
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/musb/Makefile2
-rw-r--r--drivers/usb/musb/musb_core.c8
-rw-r--r--drivers/usb/musb/musb_core.h40
-rw-r--r--drivers/usb/musb/musb_debug.h205
-rw-r--r--drivers/usb/musb/musb_hcd.c2
-rw-r--r--drivers/usb/musb/musb_udc.c963
-rw-r--r--drivers/usb/musb/omap3.c134
-rw-r--r--drivers/usb/musb/omap3.h48
-rw-r--r--drivers/usb/phy/Makefile44
-rw-r--r--drivers/usb/phy/twl4030.c189
-rw-r--r--drivers/video/cfb_console.c2
20 files changed, 1874 insertions, 336 deletions
diff --git a/drivers/bios_emulator/Makefile b/drivers/bios_emulator/Makefile
index dd9c102ba..feba4da75 100644
--- a/drivers/bios_emulator/Makefile
+++ b/drivers/bios_emulator/Makefile
@@ -23,6 +23,7 @@ EXTRA_CFLAGS += -I. -I./include -I$(TOPDIR)/include \
CFLAGS += $(EXTRA_CFLAGS)
HOSTCFLAGS += $(EXTRA_CFLAGS)
+CPPFLAGS += $(EXTRA_CFLAGS)
all: $(LIB)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index fc9887b51..904727e1b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -44,7 +44,7 @@ COBJS-$(CONFIG_GRETH) += greth.o
COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o
COBJS-$(CONFIG_KIRKWOOD_EGIGA) += kirkwood_egiga.o
COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
-COBJS-$(CONFIG_DRIVER_LAN91C96) += lan91c96.o
+COBJS-$(CONFIG_LAN91C96) += lan91c96.o
COBJS-$(CONFIG_MACB) += macb.o
COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index 73dd33572..a7fef5603 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -75,7 +75,7 @@ TODO: external MII is not functional, only internal at the moment.
#define DM9000_DMP_PACKET(func,packet,length) \
do { \
int i; \
- printf(func ": length: %d\n", length); \
+ printf("%s: length: %d\n", func, length); \
for (i = 0; i < length; i++) { \
if (i % 8 == 0) \
printf("\n%s: %02x: ", func, i); \
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 7f9f783c4..2825342ff 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -79,6 +79,7 @@ static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546GB_COPPER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF},
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index ad073077c..19116f253 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -450,6 +450,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
*/
if (fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE) < 0) {
free(fec->base_ptr);
+ fec->base_ptr = NULL;
return -ENOMEM;
}
fec_tbd_init(fec);
diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c
index 65565bcb0..90e400249 100644
--- a/drivers/net/lan91c96.c
+++ b/drivers/net/lan91c96.c
@@ -60,6 +60,7 @@
#include <common.h>
#include <command.h>
+#include <malloc.h>
#include "lan91c96.h"
#include <net.h>
@@ -108,11 +109,7 @@
*
*------------------------------------------------------------------------
*/
-#define CARDNAME "LAN91C96"
-
-#define SMC_BASE_ADDRESS CONFIG_LAN91C96_BASE
-
-#define SMC_DEV_NAME "LAN91C96"
+#define DRIVER_NAME "LAN91C96"
#define SMC_ALLOC_MAX_TRY 5
#define SMC_TX_TIMEOUT 30
@@ -124,64 +121,12 @@
#undef USE_32_BIT
#endif
-/*-----------------------------------------------------------------
- *
- * The driver can be entered at any of the following entry points.
- *
- *-----------------------------------------------------------------
- */
-
-extern int eth_init (bd_t * bd);
-extern void eth_halt (void);
-extern int eth_rx (void);
-extern int eth_send (volatile void *packet, int length);
-#if 0
-static int smc_hw_init (void);
-#endif
-
-/*
- * This is called by register_netdev(). It is responsible for
- * checking the portlist for the SMC9000 series chipset. If it finds
- * one, then it will initialize the device, find the hardware information,
- * and sets up the appropriate device parameters.
- * NOTE: Interrupts are *OFF* when this procedure is called.
- *
- * NB:This shouldn't be static since it is referred to externally.
- */
-int smc_init (void);
-
-/*
- * This is called by unregister_netdev(). It is responsible for
- * cleaning up before the driver is finally unregistered and discarded.
- */
-void smc_destructor (void);
-
-/*
- * The kernel calls this function when someone wants to use the device,
- * typically 'ifconfig ethX up'.
- */
-static int smc_open (bd_t *bd);
-
-
-/*
- * This is called by the kernel in response to 'ifconfig ethX down'. It
- * is responsible for cleaning up everything that the open routine
- * does, and maybe putting the card into a powerdown state.
- */
-static int smc_close (void);
-
-/*
- * This is a separate procedure to handle the receipt of a packet, to
- * leave the interrupt code looking slightly cleaner
- */
-static int smc_rcv (void);
-
/* See if a MAC address is defined in the current environment. If so use it. If not
. print a warning and set the environment and other globals with the default.
. If an EEPROM is present it really should be consulted.
*/
-int smc_get_ethaddr(bd_t *bd);
-int get_rom_mac(unsigned char *v_rom_mac);
+static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev);
+static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac);
/* ------------------------------------------------------------
* Internal routines
@@ -195,7 +140,7 @@ static unsigned char smc_mac_addr[] = { 0xc0, 0x00, 0x00, 0x1b, 0x62, 0x9c };
* the default mac address.
*/
-void smc_set_mac_addr (const unsigned char *addr)
+static void smc_set_mac_addr(const unsigned char *addr)
{
int i;
@@ -204,45 +149,21 @@ void smc_set_mac_addr (const unsigned char *addr)
}
}
-/*
- * smc_get_macaddr is no longer used. If you want to override the default
- * mac address, call smc_get_mac_addr as a part of the board initialisation.
- */
-
-#if 0
-void smc_get_macaddr (byte * addr)
-{
- /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
- unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
- int i;
-
-
- for (i = 0; i < 6; i++) {
- addr[0] = *(dnp1110_mac + 0);
- addr[1] = *(dnp1110_mac + 1);
- addr[2] = *(dnp1110_mac + 2);
- addr[3] = *(dnp1110_mac + 3);
- addr[4] = *(dnp1110_mac + 4);
- addr[5] = *(dnp1110_mac + 5);
- }
-}
-#endif /* 0 */
-
/***********************************************
* Show available memory *
***********************************************/
-void dump_memory_info (void)
+void dump_memory_info(struct eth_device *dev)
{
word mem_info;
word old_bank;
- old_bank = SMC_inw (LAN91C96_BANK_SELECT) & 0xF;
+ old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT) & 0xF;
- SMC_SELECT_BANK (0);
- mem_info = SMC_inw (LAN91C96_MIR);
+ SMC_SELECT_BANK(dev, 0);
+ mem_info = SMC_inw(dev, LAN91C96_MIR);
PRINTK2 ("Memory: %4d available\n", (mem_info >> 8) * 2048);
- SMC_SELECT_BANK (old_bank);
+ SMC_SELECT_BANK(dev, old_bank);
}
/*
@@ -252,28 +173,15 @@ void dump_memory_info (void)
static void print_packet (byte *, int);
#endif
-/* #define tx_done(dev) 1 */
-
-
-/* this does a soft reset on the device */
-static void smc_reset (void);
-
-/* Enable Interrupts, Receive, and Transmit */
-static void smc_enable (void);
-
-/* this puts the device in an inactive state */
-static void smc_shutdown (void);
-
-
-static int poll4int (byte mask, int timeout)
+static int poll4int (struct eth_device *dev, byte mask, int timeout)
{
int tmo = get_timer (0) + timeout * CONFIG_SYS_HZ;
int is_timeout = 0;
- word old_bank = SMC_inw (LAN91C96_BANK_SELECT);
+ word old_bank = SMC_inw(dev, LAN91C96_BANK_SELECT);
PRINTK2 ("Polling...\n");
- SMC_SELECT_BANK (2);
- while ((SMC_inw (LAN91C96_INT_STATS) & mask) == 0) {
+ SMC_SELECT_BANK(dev, 2);
+ while ((SMC_inw(dev, LAN91C96_INT_STATS) & mask) == 0) {
if (get_timer (0) >= tmo) {
is_timeout = 1;
break;
@@ -281,7 +189,7 @@ static int poll4int (byte mask, int timeout)
}
/* restore old bank selection */
- SMC_SELECT_BANK (old_bank);
+ SMC_SELECT_BANK(dev, old_bank);
if (is_timeout)
return 1;
@@ -290,7 +198,7 @@ static int poll4int (byte mask, int timeout)
}
/*
- * Function: smc_reset( void )
+ * Function: smc_reset
* Purpose:
* This sets the SMC91111 chip to its normal state, hopefully from whatever
* mess that any other DOS driver has put it in.
@@ -306,28 +214,28 @@ static int poll4int (byte mask, int timeout)
* 5. clear all interrupts
*
*/
-static void smc_reset (void)
+static void smc_reset(struct eth_device *dev)
{
- PRINTK2 ("%s:smc_reset\n", SMC_DEV_NAME);
+ PRINTK2("%s:smc_reset\n", dev->name);
/* This resets the registers mostly to defaults, but doesn't
affect EEPROM. That seems unnecessary */
- SMC_SELECT_BANK (0);
- SMC_outw (LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
+ SMC_SELECT_BANK(dev, 0);
+ SMC_outw(dev, LAN91C96_RCR_SOFT_RST, LAN91C96_RCR);
udelay (10);
/* Disable transmit and receive functionality */
- SMC_outw (0, LAN91C96_RCR);
- SMC_outw (0, LAN91C96_TCR);
+ SMC_outw(dev, 0, LAN91C96_RCR);
+ SMC_outw(dev, 0, LAN91C96_TCR);
/* set the control register */
- SMC_SELECT_BANK (1);
- SMC_outw (SMC_inw (LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
+ SMC_SELECT_BANK(dev, 1);
+ SMC_outw(dev, SMC_inw(dev, LAN91C96_CONTROL) | LAN91C96_CTR_BIT_8,
LAN91C96_CONTROL);
/* Disable all interrupts */
- SMC_outb (0, LAN91C96_INT_MASK);
+ SMC_outb(dev, 0, LAN91C96_INT_MASK);
}
/*
@@ -338,24 +246,24 @@ static void smc_reset (void)
* 2. Enable the transmitter
* 3. Enable the receiver
*/
-static void smc_enable ()
+static void smc_enable(struct eth_device *dev)
{
- PRINTK2 ("%s:smc_enable\n", SMC_DEV_NAME);
- SMC_SELECT_BANK (0);
+ PRINTK2("%s:smc_enable\n", dev->name);
+ SMC_SELECT_BANK(dev, 0);
/* Initialize the Memory Configuration Register. See page
49 of the LAN91C96 data sheet for details. */
- SMC_outw (LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
+ SMC_outw(dev, LAN91C96_MCR_TRANSMIT_PAGES, LAN91C96_MCR);
/* Initialize the Transmit Control Register */
- SMC_outw (LAN91C96_TCR_TXENA, LAN91C96_TCR);
+ SMC_outw(dev, LAN91C96_TCR_TXENA, LAN91C96_TCR);
/* Initialize the Receive Control Register
* FIXME:
* The promiscuous bit set because I could not receive ARP reply
* packets from the server when I send a ARP request. It only works
* when I set the promiscuous bit
*/
- SMC_outw (LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
+ SMC_outw(dev, LAN91C96_RCR_RXEN | LAN91C96_RCR_PRMS, LAN91C96_RCR);
}
/*
@@ -372,18 +280,18 @@ static void smc_enable ()
* the manual says that it will wake up in response to any I/O requests
* in the register space. Empirical results do not show this working.
*/
-static void smc_shutdown ()
+static void smc_shutdown(struct eth_device *dev)
{
- PRINTK2 (CARDNAME ":smc_shutdown\n");
+ PRINTK2("%s:smc_shutdown\n", dev->name);
/* no more interrupts for me */
- SMC_SELECT_BANK (2);
- SMC_outb (0, LAN91C96_INT_MASK);
+ SMC_SELECT_BANK(dev, 2);
+ SMC_outb(dev, 0, LAN91C96_INT_MASK);
/* and tell the card to stay away from that nasty outside world */
- SMC_SELECT_BANK (0);
- SMC_outb (0, LAN91C96_RCR);
- SMC_outb (0, LAN91C96_TCR);
+ SMC_SELECT_BANK(dev, 0);
+ SMC_outb(dev, 0, LAN91C96_RCR);
+ SMC_outb(dev, 0, LAN91C96_TCR);
}
@@ -405,7 +313,8 @@ static void smc_shutdown ()
* Enable the transmit interrupt, so I know if it failed
* Free the kernel data if I actually sent it.
*/
-static int smc_send_packet (volatile void *packet, int packet_length)
+static int smc_send_packet(struct eth_device *dev, volatile void *packet,
+ int packet_length)
{
byte packet_no;
unsigned long ioaddr;
@@ -417,7 +326,7 @@ static int smc_send_packet (volatile void *packet, int packet_length)
byte status;
- PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME);
+ PRINTK3("%s:smc_hardware_send_packet\n", dev->name);
length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;
@@ -437,30 +346,31 @@ static int smc_send_packet (volatile void *packet, int packet_length)
numPages >>= 8; /* Divide by 256 */
if (numPages > 7) {
- printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
+ printf("%s: Far too big packet error. \n", dev->name);
return 0;
}
/* now, try to allocate the memory */
- SMC_SELECT_BANK (2);
- SMC_outw (LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
+ SMC_SELECT_BANK(dev, 2);
+ SMC_outw(dev, LAN91C96_MMUCR_ALLOC_TX | numPages, LAN91C96_MMU);
again:
try++;
time_out = MEMORY_WAIT_TIME;
do {
- status = SMC_inb (LAN91C96_INT_STATS);
+ status = SMC_inb(dev, LAN91C96_INT_STATS);
if (status & LAN91C96_IST_ALLOC_INT) {
- SMC_outb (LAN91C96_IST_ALLOC_INT, LAN91C96_INT_STATS);
+ SMC_outb(dev, LAN91C96_IST_ALLOC_INT,
+ LAN91C96_INT_STATS);
break;
}
} while (--time_out);
if (!time_out) {
PRINTK2 ("%s: memory allocation, try %d failed ...\n",
- SMC_DEV_NAME, try);
+ dev->name, try);
if (try < SMC_ALLOC_MAX_TRY)
goto again;
else
@@ -468,30 +378,30 @@ static int smc_send_packet (volatile void *packet, int packet_length)
}
PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
- SMC_DEV_NAME, try);
+ dev->name, try);
/* I can send the packet now.. */
- ioaddr = SMC_BASE_ADDRESS;
+ ioaddr = dev->iobase;
buf = (byte *) packet;
/* If I get here, I _know_ there is a packet slot waiting for me */
- packet_no = SMC_inb (LAN91C96_ARR);
+ packet_no = SMC_inb(dev, LAN91C96_ARR);
if (packet_no & LAN91C96_ARR_FAILED) {
/* or isn't there? BAD CHIP! */
- printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
+ printf("%s: Memory allocation failed. \n", dev->name);
return 0;
}
/* we have a packet address, so tell the card to use it */
- SMC_outb (packet_no, LAN91C96_PNR);
+ SMC_outb(dev, packet_no, LAN91C96_PNR);
/* point to the beginning of the packet */
- SMC_outw (LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
+ SMC_outw(dev, LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
- PRINTK3 ("%s: Trying to xmit packet of length %x\n",
- SMC_DEV_NAME, length);
+ PRINTK3("%s: Trying to xmit packet of length %x\n",
+ dev->name, length);
#if SMC_DEBUG > 2
printf ("Transmitting Packet\n");
@@ -501,11 +411,11 @@ static int smc_send_packet (volatile void *packet, int packet_length)
/* send the packet length ( +6 for status, length and ctl byte )
and the status word ( set to zeros ) */
#ifdef USE_32_BIT
- SMC_outl ((length + 6) << 16, LAN91C96_DATA_HIGH);
+ SMC_outl(dev, (length + 6) << 16, LAN91C96_DATA_HIGH);
#else
- SMC_outw (0, LAN91C96_DATA_HIGH);
+ SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
/* send the packet length ( +6 for status words, length, and ctl */
- SMC_outw ((length + 6), LAN91C96_DATA_HIGH);
+ SMC_outw(dev, (length + 6), LAN91C96_DATA_HIGH);
#endif /* USE_32_BIT */
/* send the actual data
@@ -516,54 +426,52 @@ static int smc_send_packet (volatile void *packet, int packet_length)
* almost as much time as is saved?
*/
#ifdef USE_32_BIT
- SMC_outsl (LAN91C96_DATA_HIGH, buf, length >> 2);
+ SMC_outsl(dev, LAN91C96_DATA_HIGH, buf, length >> 2);
if (length & 0x2)
- SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
+ SMC_outw(dev, *((word *) (buf + (length & 0xFFFFFFFC))),
LAN91C96_DATA_HIGH);
#else
- SMC_outsw (LAN91C96_DATA_HIGH, buf, (length) >> 1);
+ SMC_outsw(dev, LAN91C96_DATA_HIGH, buf, (length) >> 1);
#endif /* USE_32_BIT */
/* Send the last byte, if there is one. */
if ((length & 1) == 0) {
- SMC_outw (0, LAN91C96_DATA_HIGH);
+ SMC_outw(dev, 0, LAN91C96_DATA_HIGH);
} else {
- SMC_outw (buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
+ SMC_outw(dev, buf[length - 1] | 0x2000, LAN91C96_DATA_HIGH);
}
/* and let the chipset deal with it */
- SMC_outw (LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
+ SMC_outw(dev, LAN91C96_MMUCR_ENQUEUE, LAN91C96_MMU);
/* poll for TX INT */
- if (poll4int (LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
+ if (poll4int (dev, LAN91C96_MSK_TX_INT, SMC_TX_TIMEOUT)) {
/* sending failed */
- PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
+ PRINTK2("%s: TX timeout, sending failed...\n", dev->name);
/* release packet */
- SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+ SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
/* wait for MMU getting ready (low) */
- while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
+ while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
udelay (10);
- }
- PRINTK2 ("MMU ready\n");
+ PRINTK2("MMU ready\n");
return 0;
} else {
/* ack. int */
- SMC_outw (LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
+ SMC_outw(dev, LAN91C96_IST_TX_INT, LAN91C96_INT_STATS);
- PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME, length);
+ PRINTK2("%s: Sent packet of length %d \n", dev->name, length);
/* release packet */
- SMC_outw (LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
+ SMC_outw(dev, LAN91C96_MMUCR_RELEASE_TX, LAN91C96_MMU);
/* wait for MMU getting ready (low) */
- while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY) {
+ while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
udelay (10);
- }
PRINTK2 ("MMU ready\n");
}
@@ -571,20 +479,6 @@ static int smc_send_packet (volatile void *packet, int packet_length)
return length;
}
-/*-------------------------------------------------------------------------
- * smc_destructor( struct net_device * dev )
- * Input parameters:
- * dev, pointer to the device structure
- *
- * Output:
- * None.
- *--------------------------------------------------------------------------
- */
-void smc_destructor ()
-{
- PRINTK2 (CARDNAME ":smc_destructor\n");
-}
-
/*
* Open and Initialize the board
@@ -592,20 +486,20 @@ void smc_destructor ()
* Set up everything, reset the card, etc ..
*
*/
-static int smc_open (bd_t *bd)
+static int smc_open(bd_t *bd, struct eth_device *dev)
{
int i, err; /* used to set hw ethernet address */
- PRINTK2 ("%s:smc_open\n", SMC_DEV_NAME);
+ PRINTK2("%s:smc_open\n", dev->name);
/* reset the hardware */
- smc_reset ();
- smc_enable ();
-
- SMC_SELECT_BANK (1);
+ smc_reset(dev);
+ smc_enable(dev);
- err = smc_get_ethaddr (bd); /* set smc_mac_addr, and sync it with u-boot globals */
+ SMC_SELECT_BANK(dev, 1);
+ /* set smc_mac_addr, and sync it with u-boot globals */
+ err = smc_get_ethaddr(bd, dev);
if (err < 0)
return -1;
#ifdef USE_32_BIT
@@ -614,11 +508,11 @@ static int smc_open (bd_t *bd)
address = smc_mac_addr[i + 1] << 8;
address |= smc_mac_addr[i];
- SMC_outw (address, LAN91C96_IA0 + i);
+ SMC_outw(dev, address, LAN91C96_IA0 + i);
}
#else
for (i = 0; i < 6; i++)
- SMC_outb (smc_mac_addr[i], LAN91C96_IA0 + i);
+ SMC_outb(dev, smc_mac_addr[i], LAN91C96_IA0 + i);
#endif
return 0;
}
@@ -635,7 +529,7 @@ static int smc_open (bd_t *bd)
* o otherwise, read in the packet
*-------------------------------------------------------------
*/
-static int smc_rcv ()
+static int smc_rcv(struct eth_device *dev)
{
int packet_number;
word status;
@@ -647,26 +541,26 @@ static int smc_rcv ()
#endif
- SMC_SELECT_BANK (2);
- packet_number = SMC_inw (LAN91C96_FIFO);
+ SMC_SELECT_BANK(dev, 2);
+ packet_number = SMC_inw(dev, LAN91C96_FIFO);
if (packet_number & LAN91C96_FIFO_RXEMPTY) {
return 0;
}
- PRINTK3 ("%s:smc_rcv\n", SMC_DEV_NAME);
+ PRINTK3("%s:smc_rcv\n", dev->name);
/* start reading from the start of the packet */
- SMC_outw (LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
+ SMC_outw(dev, LAN91C96_PTR_READ | LAN91C96_PTR_RCV |
LAN91C96_PTR_AUTO_INCR, LAN91C96_POINTER);
/* First two words are status and packet_length */
#ifdef USE_32_BIT
- stat_len = SMC_inl (LAN91C96_DATA_HIGH);
+ stat_len = SMC_inl(dev, LAN91C96_DATA_HIGH);
status = stat_len & 0xffff;
packet_length = stat_len >> 16;
#else
- status = SMC_inw (LAN91C96_DATA_HIGH);
- packet_length = SMC_inw (LAN91C96_DATA_HIGH);
+ status = SMC_inw(dev, LAN91C96_DATA_HIGH);
+ packet_length = SMC_inw(dev, LAN91C96_DATA_HIGH);
#endif
packet_length &= 0x07ff; /* mask off top bits */
@@ -690,13 +584,14 @@ static int smc_rcv ()
to send the DWORDs or the bytes first, or some
mixture. A mixture might improve already slow PIO
performance */
- SMC_insl (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 2);
+ SMC_insl(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
+ packet_length >> 2);
/* read the left over bytes */
if (packet_length & 3) {
int i;
byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3));
- dword leftover = SMC_inl (LAN91C96_DATA_HIGH);
+ dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH);
for (i = 0; i < (packet_length & 3); i++)
*tail++ = (byte) (leftover >> (8 * i)) & 0xff;
@@ -704,13 +599,14 @@ static int smc_rcv ()
#else
PRINTK3 (" Reading %d words and %d byte(s) \n",
(packet_length >> 1), packet_length & 1);
- SMC_insw (LAN91C96_DATA_HIGH, NetRxPackets[0], packet_length >> 1);
+ SMC_insw(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
+ packet_length >> 1);
#endif /* USE_32_BIT */
#if SMC_DEBUG > 2
printf ("Receiving Packet\n");
- print_packet (NetRxPackets[0], packet_length);
+ print_packet((byte *)NetRxPackets[0], packet_length);
#endif
} else {
/* error ... */
@@ -718,13 +614,13 @@ static int smc_rcv ()
is_error = 1;
}
- while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+ while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
udelay (1); /* Wait until not busy */
/* error or good, tell the card to get rid of this packet */
- SMC_outw (LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
+ SMC_outw(dev, LAN91C96_MMUCR_RELEASE_RX, LAN91C96_MMU);
- while (SMC_inw (LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
+ while (SMC_inw(dev, LAN91C96_MMU) & LAN91C96_MMUCR_NO_BUSY)
udelay (1); /* Wait until not busy */
if (!is_error) {
@@ -745,18 +641,18 @@ static int smc_rcv ()
* an 'ifconfig ethX down'
*
-----------------------------------------------------*/
-static int smc_close ()
+static int smc_close(struct eth_device *dev)
{
- PRINTK2 ("%s:smc_close\n", SMC_DEV_NAME);
+ PRINTK2("%s:smc_close\n", dev->name);
/* clear everything */
- smc_shutdown ();
+ smc_shutdown(dev);
return 0;
}
#if SMC_DEBUG > 2
-static void print_packet (byte * buf, int length)
+static void print_packet(byte *buf, int length)
{
#if 0
int i;
@@ -792,86 +688,40 @@ static void print_packet (byte * buf, int length)
}
#endif /* SMC_DEBUG > 2 */
-int eth_init (bd_t * bd)
-{
- return (smc_open(bd));
-}
-
-void eth_halt ()
+static int lan91c96_init(struct eth_device *dev, bd_t *bd)
{
- smc_close ();
+ return smc_open(bd, dev);
}
-int eth_rx ()
+static void lan91c96_halt(struct eth_device *dev)
{
- return smc_rcv ();
+ smc_close(dev);
}
-int eth_send (volatile void *packet, int length)
+static int lan91c96_recv(struct eth_device *dev)
{
- return smc_send_packet (packet, length);
+ return smc_rcv(dev);
}
-
-#if 0
-/*-------------------------------------------------------------------------
- * smc_hw_init()
- *
- * Function:
- * Reset and enable the device, check if the I/O space location
- * is correct
- *
- * Input parameters:
- * None
- *
- * Output:
- * 0 --> success
- * 1 --> error
- *--------------------------------------------------------------------------
- */
-static int smc_hw_init ()
+static int lan91c96_send(struct eth_device *dev, volatile void *packet,
+ int length)
{
- unsigned short status_test;
-
- /* The attribute register of the LAN91C96 is located at address
- 0x0e000000 on the lubbock platform */
- volatile unsigned *attaddr = (unsigned *) (0x0e000000);
-
- /* first reset, then enable the device. Sequence is critical */
- attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_SRESET;
- udelay (100);
- attaddr[LAN91C96_ECOR] &= ~LAN91C96_ECOR_SRESET;
- attaddr[LAN91C96_ECOR] |= LAN91C96_ECOR_ENABLE;
-
- /* force 16-bit mode */
- attaddr[LAN91C96_ECSR] &= ~LAN91C96_ECSR_IOIS8;
- udelay (100);
-
- /* check if the I/O address is correct, the upper byte of the
- bank select register should read 0x33 */
-
- status_test = SMC_inw (LAN91C96_BANK_SELECT);
- if ((status_test & 0xFF00) != 0x3300) {
- printf ("Failed to initialize ethernetchip\n");
- return 1;
- }
- return 0;
+ return smc_send_packet(dev, packet, length);
}
-#endif /* 0 */
-/* smc_get_ethaddr (bd_t * bd)
+/* smc_get_ethaddr
*
* This checks both the environment and the ROM for an ethernet address. If
* found, the environment takes precedence.
*/
-int smc_get_ethaddr (bd_t * bd)
+static int smc_get_ethaddr(bd_t *bd, struct eth_device *dev)
{
uchar v_mac[6];
if (!eth_getenv_enetaddr("ethaddr", v_mac)) {
/* get ROM mac value if any */
- if (!get_rom_mac(v_mac)) {
+ if (!get_rom_mac(dev, v_mac)) {
printf("\n*** ERROR: ethaddr is NOT set !!\n");
return -1;
}
@@ -888,7 +738,7 @@ int smc_get_ethaddr (bd_t * bd)
* Note, this has omly been tested for the OMAP730 P2.
*/
-int get_rom_mac (unsigned char *v_rom_mac)
+static int get_rom_mac(struct eth_device *dev, unsigned char *v_rom_mac)
{
#ifdef HARDCODE_MAC /* used for testing or to supress run time warnings */
char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
@@ -897,11 +747,75 @@ int get_rom_mac (unsigned char *v_rom_mac)
return (1);
#else
int i;
- SMC_SELECT_BANK (1);
+ SMC_SELECT_BANK(dev, 1);
for (i=0; i<6; i++)
{
- v_rom_mac[i] = SMC_inb (LAN91C96_IA0 + i);
+ v_rom_mac[i] = SMC_inb(dev, LAN91C96_IA0 + i);
}
return (1);
#endif
}
+
+/* Structure to detect the device IDs */
+struct id_type {
+ u8 id;
+ char *name;
+};
+static struct id_type supported_chips[] = {
+ {0, ""}, /* Dummy entry to prevent id check failure */
+ {9, "LAN91C110"},
+ {8, "LAN91C100FD"},
+ {7, "LAN91C100"},
+ {5, "LAN91C95"},
+ {4, "LAN91C94/LAN91C96"},
+ {3, "LAN91C90/LAN91C92"},
+};
+/* lan91c96_detect_chip
+ * See:
+ * http://www.embeddedsys.com/subpages/resources/images/documents/LAN91C96_datasheet.pdf
+ * page 71 - that is the closest we get to detect this device
+ */
+static int lan91c96_detect_chip(struct eth_device *dev)
+{
+ u8 chip_id;
+ int r;
+ SMC_SELECT_BANK(dev, 3);
+ chip_id = SMC_inw(dev, 0xA) & LAN91C96_REV_REVID;
+ SMC_SELECT_BANK(dev, 0);
+ for (r = 0; r < sizeof(supported_chips) / sizeof(struct id_type); r++)
+ if (chip_id == supported_chips[r].id)
+ return r;
+ return 0;
+}
+
+int lan91c96_initialize(u8 dev_num, int base_addr)
+{
+ struct eth_device *dev;
+ int r = 0;
+
+ dev = malloc(sizeof(*dev));
+ if (!dev) {
+ free(dev);
+ return 0;
+ }
+ memset(dev, 0, sizeof(*dev));
+
+ dev->iobase = base_addr;
+
+ /* Try to detect chip. Will fail if not present. */
+ r = lan91c96_detect_chip(dev);
+ if (!r) {
+ free(dev);
+ return 0;
+ }
+ get_rom_mac(dev, dev->enetaddr);
+
+ dev->init = lan91c96_init;
+ dev->halt = lan91c96_halt;
+ dev->send = lan91c96_send;
+ dev->recv = lan91c96_recv;
+ sprintf(dev->name, "%s-%hu", supported_chips[r].name, dev_num);
+
+ eth_register(dev);
+ return 0;
+}
diff --git a/drivers/net/lan91c96.h b/drivers/net/lan91c96.h
index 5beddda04..6fbb0e3cb 100644
--- a/drivers/net/lan91c96.h
+++ b/drivers/net/lan91c96.h
@@ -46,14 +46,6 @@
#include <asm/io.h>
#include <config.h>
-/*
- * This function may be called by the board specific initialisation code
- * in order to override the default mac address.
- */
-
-void smc_set_mac_addr(const unsigned char *addr);
-
-
/* I want some simple types */
typedef unsigned char byte;
@@ -86,66 +78,71 @@ typedef unsigned long int dword;
#define SMC_IO_SHIFT 0
#endif
-#define SMCREG(r) (SMC_BASE_ADDRESS+((r)<<SMC_IO_SHIFT))
+#define SMCREG(edev, r) ((edev)->iobase+((r)<<SMC_IO_SHIFT))
-#define SMC_inl(r) (*((volatile dword *)SMCREG(r)))
-#define SMC_inw(r) (*((volatile word *)SMCREG(r)))
-#define SMC_inb(p) ({ \
+#define SMC_inl(edev, r) (*((volatile dword *)SMCREG(edev, r)))
+#define SMC_inw(edev, r) (*((volatile word *)SMCREG(edev, r)))
+#define SMC_inb(edev, p) ({ \
unsigned int __p = p; \
- unsigned int __v = SMC_inw(__p & ~1); \
+ unsigned int __v = SMC_inw(edev, __p & ~1); \
if (__p & 1) __v >>= 8; \
else __v &= 0xff; \
__v; })
-#define SMC_outl(d,r) (*((volatile dword *)SMCREG(r)) = d)
-#define SMC_outw(d,r) (*((volatile word *)SMCREG(r)) = d)
-#define SMC_outb(d,r) ({ word __d = (byte)(d); \
- word __w = SMC_inw((r)&~1); \
+#define SMC_outl(edev, d, r) (*((volatile dword *)SMCREG(edev, r)) = d)
+#define SMC_outw(edev, d, r) (*((volatile word *)SMCREG(edev, r)) = d)
+#define SMC_outb(edev, d, r) ({ word __d = (byte)(d); \
+ word __w = SMC_inw(edev, (r)&~1); \
__w &= ((r)&1) ? 0x00FF : 0xFF00; \
__w |= ((r)&1) ? __d<<8 : __d; \
- SMC_outw(__w,(r)&~1); \
+ SMC_outw(edev, __w, (r)&~1); \
})
-#define SMC_outsl(r,b,l) ({ int __i; \
+#define SMC_outsl(edev, r, b, l) ({ int __i; \
dword *__b2; \
__b2 = (dword *) b; \
for (__i = 0; __i < l; __i++) { \
- SMC_outl( *(__b2 + __i), r ); \
+ SMC_outl(edev, *(__b2 + __i),\
+ r); \
} \
})
-#define SMC_outsw(r,b,l) ({ int __i; \
+#define SMC_outsw(edev, r, b, l) ({ int __i; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
- SMC_outw( *(__b2 + __i), r ); \
+ SMC_outw(edev, *(__b2 + __i),\
+ r); \
} \
})
-#define SMC_insl(r,b,l) ({ int __i ; \
+#define SMC_insl(edev, r, b, l) ({ int __i ; \
dword *__b2; \
__b2 = (dword *) b; \
for (__i = 0; __i < l; __i++) { \
- *(__b2 + __i) = SMC_inl(r); \
- SMC_inl(0); \
+ *(__b2 + __i) = SMC_inl(edev,\
+ r); \
+ SMC_inl(edev, 0); \
}; \
})
-#define SMC_insw(r,b,l) ({ int __i ; \
+#define SMC_insw(edev, r, b, l) ({ int __i ; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
- *(__b2 + __i) = SMC_inw(r); \
- SMC_inw(0); \
+ *(__b2 + __i) = SMC_inw(edev,\
+ r); \
+ SMC_inw(edev, 0); \
}; \
})
-#define SMC_insb(r,b,l) ({ int __i ; \
+#define SMC_insb(edev, r, b, l) ({ int __i ; \
byte *__b2; \
__b2 = (byte *) b; \
for (__i = 0; __i < l; __i++) { \
- *(__b2 + __i) = SMC_inb(r); \
- SMC_inb(0); \
+ *(__b2 + __i) = SMC_inb(edev,\
+ r); \
+ SMC_inb(edev, 0); \
}; \
})
@@ -155,40 +152,35 @@ typedef unsigned long int dword;
* We have only 16 Bit PCMCIA access on Socket 0
*/
-#define SMC_inw(r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))))
-#define SMC_inb(r) (((r)&1) ? SMC_inw((r)&~1)>>8 : SMC_inw(r)&0xFF)
+#define SMC_inw(edev, r) (*((volatile word *)((edev)->iobase+(r))))
+#define SMC_inb(edev, r) (((r)&1) ? SMC_inw(edev, (r)&~1)>>8 :\
+ SMC_inw(edev, r)&0xFF)
-#define SMC_outw(d,r) (*((volatile word *)(SMC_BASE_ADDRESS+(r))) = d)
-#define SMC_outb(d,r) ({ word __d = (byte)(d); \
- word __w = SMC_inw((r)&~1); \
+#define SMC_outw(edev, d, r) (*((volatile word *)((edev)->iobase+(r))) = d)
+#define SMC_outb(edev, d, r) ({ word __d = (byte)(d); \
+ word __w = SMC_inw(edev, (r)&~1); \
__w &= ((r)&1) ? 0x00FF : 0xFF00; \
__w |= ((r)&1) ? __d<<8 : __d; \
- SMC_outw(__w,(r)&~1); \
+ SMC_outw(edev, __w, (r)&~1); \
})
-#if 0
-#define SMC_outsw(r,b,l) outsw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_outsw(r,b,l) ({ int __i; \
+#define SMC_outsw(edev, r, b, l) ({ int __i; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
- SMC_outw( *(__b2 + __i), r); \
+ SMC_outw(edev, *(__b2 + __i),\
+ r); \
} \
})
-#endif
-#if 0
-#define SMC_insw(r,b,l) insw(SMC_BASE_ADDRESS+(r), (b), (l))
-#else
-#define SMC_insw(r,b,l) ({ int __i ; \
+#define SMC_insw(edev, r, b, l) ({ int __i ; \
word *__b2; \
__b2 = (word *) b; \
for (__i = 0; __i < l; __i++) { \
- *(__b2 + __i) = SMC_inw(r); \
- SMC_inw(0); \
+ *(__b2 + __i) = SMC_inw(edev,\
+ r); \
+ SMC_inw(edev, 0); \
}; \
})
-#endif
#endif
@@ -608,25 +600,25 @@ typedef unsigned long int dword;
/* select a register bank, 0 to 3 */
-#define SMC_SELECT_BANK(x) { SMC_outw( x, LAN91C96_BANK_SELECT ); }
+#define SMC_SELECT_BANK(edev, x) { SMC_outw(edev, x, LAN91C96_BANK_SELECT); }
/* this enables an interrupt in the interrupt mask register */
-#define SMC_ENABLE_INT(x) {\
+#define SMC_ENABLE_INT(edev, x) {\
unsigned char mask;\
- SMC_SELECT_BANK(2);\
- mask = SMC_inb( LAN91C96_INT_MASK );\
+ SMC_SELECT_BANK(edev, 2);\
+ mask = SMC_inb(edev, LAN91C96_INT_MASK);\
mask |= (x);\
- SMC_outb( mask, LAN91C96_INT_MASK ); \
+ SMC_outb(edev, mask, LAN91C96_INT_MASK); \
}
/* this disables an interrupt from the interrupt mask register */
-#define SMC_DISABLE_INT(x) {\
+#define SMC_DISABLE_INT(edev, x) {\
unsigned char mask;\
- SMC_SELECT_BANK(2);\
- mask = SMC_inb( LAN91C96_INT_MASK );\
+ SMC_SELECT_BANK(edev, 2);\
+ mask = SMC_inb(edev, LAN91C96_INT_MASK);\
mask &= ~(x);\
- SMC_outb( mask, LAN91C96_INT_MASK ); \
+ SMC_outb(edev, mask, LAN91C96_INT_MASK); \
}
/*----------------------------------------------------------------------
diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h
index f746d6317..6b6c4a162 100644
--- a/drivers/serial/usbtty.h
+++ b/drivers/serial/usbtty.h
@@ -29,6 +29,8 @@
#include <usb/mpc8xx_udc.h>
#elif defined(CONFIG_OMAP1510)
#include <usb/omap1510_udc.h>
+#elif defined(CONFIG_MUSB_UDC)
+#include <usb/musb_udc.h>
#elif defined(CONFIG_PXA27X)
#include <usb/pxa27x_udc.h>
#endif
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 324c308f4..ba85991e8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -96,7 +96,7 @@ static struct descriptor {
* UE_DIR_IN | EHCI_INTR_ENDPT
*/
3, /* bmAttributes: UE_INTERRUPT */
- 8, 0, /* wMaxPacketSize */
+ 8, /* wMaxPacketSize */
255 /* bInterval */
},
};
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 09e0a5f32..f2ccd9fe0 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libusb_musb.a
COBJS-$(CONFIG_MUSB_HCD) += musb_hcd.o musb_core.o
+COBJS-$(CONFIG_MUSB_UDC) += musb_udc.o musb_core.o
COBJS-$(CONFIG_USB_DAVINCI) += davinci.o
+COBJS-$(CONFIG_USB_OMAP3) += omap3.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index ec57fc811..22f3dba0c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -32,7 +32,9 @@ struct musb_regs *musbr;
*/
void musb_start(void)
{
+#if defined(CONFIG_MUSB_HCD)
u8 devctl;
+#endif
/* disable all interrupts */
writew(0, &musbr->intrtxe);
@@ -74,9 +76,10 @@ void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt)
/* Configure fifo size and fifo base address */
writeb(idx, &musbr->txfifosz);
writew(fifoaddr >> 3, &musbr->txfifoadd);
+
+ csr = readw(&musbr->txcsr);
#if defined(CONFIG_MUSB_HCD)
/* clear the data toggle bit */
- csr = readw(&musbr->txcsr);
writew(csr | MUSB_TXCSR_CLRDATATOG, &musbr->txcsr);
#endif
/* Flush fifo if required */
@@ -87,9 +90,10 @@ void musb_configure_ep(struct musb_epinfo *epinfo, u8 cnt)
/* Configure fifo size and fifo base address */
writeb(idx, &musbr->rxfifosz);
writew(fifoaddr >> 3, &musbr->rxfifoadd);
+
+ csr = readw(&musbr->rxcsr);
#if defined(CONFIG_MUSB_HCD)
/* clear the data toggle bit */
- csr = readw(&musbr->rxcsr);
writew(csr | MUSB_RXCSR_CLRDATATOG, &musbr->rxcsr);
#endif
/* Flush fifo if required */
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index f9da3f0b2..15c7f49a3 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -40,6 +40,36 @@
#define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */
+/* EP0 */
+struct musb_ep0_regs {
+ u16 reserved4;
+ u16 csr0;
+ u16 reserved5;
+ u16 reserved6;
+ u16 count0;
+ u8 host_type0;
+ u8 host_naklimit0;
+ u8 reserved7;
+ u8 reserved8;
+ u8 reserved9;
+ u8 configdata;
+};
+
+/* EP 1-15 */
+struct musb_epN_regs {
+ u16 txmaxp;
+ u16 txcsr;
+ u16 rxmaxp;
+ u16 rxcsr;
+ u16 rxcount;
+ u8 txtype;
+ u8 txinterval;
+ u8 rxtype;
+ u8 rxinterval;
+ u8 reserved0;
+ u8 fifosize;
+};
+
/* Mentor USB core register overlay structure */
struct musb_regs {
/* common registers */
@@ -97,6 +127,16 @@ struct musb_regs {
u8 rxhubaddr;
u8 rxhubport;
} tar[16];
+ /*
+ * end point registers
+ * ep0 elements are valid when array index is 0
+ * otherwise epN is valid
+ */
+ union musb_ep_regs {
+ struct musb_ep0_regs ep0;
+ struct musb_epN_regs epN;
+ } ep[16];
+
} __attribute__((aligned(32)));
/*
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h
new file mode 100644
index 000000000..62380ffc6
--- /dev/null
+++ b/drivers/usb/musb/musb_debug.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * 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
+ */
+
+/* Define MUSB_DEBUG before including this file to get debug macros */
+#ifdef MUSB_DEBUG
+
+#define MUSB_FLAGS_PRINT(v, x, y) \
+ if (((v) & MUSB_##x##_##y)) \
+ serial_printf("\t\t"#y"\n")
+
+static inline void musb_print_pwr(u8 b)
+{
+ serial_printf("\tpower 0x%2.2x\n", b);
+ MUSB_FLAGS_PRINT(b, POWER, ISOUPDATE);
+ MUSB_FLAGS_PRINT(b, POWER, SOFTCONN);
+ MUSB_FLAGS_PRINT(b, POWER, HSENAB);
+ MUSB_FLAGS_PRINT(b, POWER, HSMODE);
+ MUSB_FLAGS_PRINT(b, POWER, RESET);
+ MUSB_FLAGS_PRINT(b, POWER, RESUME);
+ MUSB_FLAGS_PRINT(b, POWER, SUSPENDM);
+ MUSB_FLAGS_PRINT(b, POWER, ENSUSPEND);
+}
+
+static inline void musb_print_csr0(u16 w)
+{
+ serial_printf("\tcsr0 0x%4.4x\n", w);
+ MUSB_FLAGS_PRINT(w, CSR0, FLUSHFIFO);
+ MUSB_FLAGS_PRINT(w, CSR0_P, SVDSETUPEND);
+ MUSB_FLAGS_PRINT(w, CSR0_P, SVDRXPKTRDY);
+ MUSB_FLAGS_PRINT(w, CSR0_P, SENDSTALL);
+ MUSB_FLAGS_PRINT(w, CSR0_P, SETUPEND);
+ MUSB_FLAGS_PRINT(w, CSR0_P, DATAEND);
+ MUSB_FLAGS_PRINT(w, CSR0_P, SENTSTALL);
+ MUSB_FLAGS_PRINT(w, CSR0, TXPKTRDY);
+ MUSB_FLAGS_PRINT(w, CSR0, RXPKTRDY);
+}
+
+static inline void musb_print_intrusb(u8 b)
+{
+ serial_printf("\tintrusb 0x%2.2x\n", b);
+ MUSB_FLAGS_PRINT(b, INTR, VBUSERROR);
+ MUSB_FLAGS_PRINT(b, INTR, SESSREQ);
+ MUSB_FLAGS_PRINT(b, INTR, DISCONNECT);
+ MUSB_FLAGS_PRINT(b, INTR, CONNECT);
+ MUSB_FLAGS_PRINT(b, INTR, SOF);
+ MUSB_FLAGS_PRINT(b, INTR, RESUME);
+ MUSB_FLAGS_PRINT(b, INTR, SUSPEND);
+
+ if (b & MUSB_INTR_BABBLE)
+ serial_printf("\t\tMUSB_INTR_RESET or MUSB_INTR_BABBLE\n");
+
+}
+
+static inline void musb_print_intrtx(u16 w)
+{
+ serial_printf("\tintrtx 0x%4.4x\n", w);
+}
+
+static inline void musb_print_intrrx(u16 w)
+{
+ serial_printf("\tintrx 0x%4.4x\n", w);
+}
+
+static inline void musb_print_devctl(u8 b)
+{
+ serial_printf("\tdevctl 0x%2.2x\n", b);
+ if (b & MUSB_DEVCTL_BDEVICE)
+ serial_printf("\t\tB device\n");
+ else
+ serial_printf("\t\tA device\n");
+ if (b & MUSB_DEVCTL_FSDEV)
+ serial_printf("\t\tFast Device -(host mode)\n");
+ if (b & MUSB_DEVCTL_LSDEV)
+ serial_printf("\t\tSlow Device -(host mode)\n");
+ if (b & MUSB_DEVCTL_HM)
+ serial_printf("\t\tHost mode\n");
+ else
+ serial_printf("\t\tPeripherial mode\n");
+ if (b & MUSB_DEVCTL_HR)
+ serial_printf("\t\tHost request started(B device)\n");
+ else
+ serial_printf("\t\tHost request finished(B device)\n");
+ if (b & MUSB_DEVCTL_BDEVICE) {
+ if (b & MUSB_DEVCTL_SESSION)
+ serial_printf("\t\tStart of session(B device)\n");
+ else
+ serial_printf("\t\tEnd of session(B device)\n");
+ } else {
+ if (b & MUSB_DEVCTL_SESSION)
+ serial_printf("\t\tStart of session(A device)\n");
+ else
+ serial_printf("\t\tEnd of session(A device)\n");
+ }
+}
+
+static inline void musb_print_config(u8 b)
+{
+ serial_printf("\tconfig 0x%2.2x\n", b);
+ if (b & MUSB_CONFIGDATA_MPRXE)
+ serial_printf("\t\tAuto combine rx bulk packets\n");
+ if (b & MUSB_CONFIGDATA_MPTXE)
+ serial_printf("\t\tAuto split tx bulk packets\n");
+ if (b & MUSB_CONFIGDATA_BIGENDIAN)
+ serial_printf("\t\tBig Endian ordering\n");
+ else
+ serial_printf("\t\tLittle Endian ordering\n");
+ if (b & MUSB_CONFIGDATA_HBRXE)
+ serial_printf("\t\tHigh speed rx iso endpoint\n");
+ if (b & MUSB_CONFIGDATA_HBTXE)
+ serial_printf("\t\tHigh speed tx iso endpoint\n");
+ if (b & MUSB_CONFIGDATA_DYNFIFO)
+ serial_printf("\t\tDynamic fifo sizing\n");
+ if (b & MUSB_CONFIGDATA_SOFTCONE)
+ serial_printf("\t\tSoft Connect\n");
+ if (b & MUSB_CONFIGDATA_UTMIDW)
+ serial_printf("\t\t16 bit data width\n");
+ else
+ serial_printf("\t\t8 bit data width\n");
+}
+
+static inline void musb_print_rxmaxp(u16 w)
+{
+ serial_printf("\trxmaxp 0x%4.4x\n", w);
+}
+
+static inline void musb_print_rxcsr(u16 w)
+{
+ serial_printf("\trxcsr 0x%4.4x\n", w);
+ MUSB_FLAGS_PRINT(w, RXCSR, AUTOCLEAR);
+ MUSB_FLAGS_PRINT(w, RXCSR, DMAENAB);
+ MUSB_FLAGS_PRINT(w, RXCSR, DISNYET);
+ MUSB_FLAGS_PRINT(w, RXCSR, PID_ERR);
+ MUSB_FLAGS_PRINT(w, RXCSR, DMAMODE);
+ MUSB_FLAGS_PRINT(w, RXCSR, CLRDATATOG);
+ MUSB_FLAGS_PRINT(w, RXCSR, FLUSHFIFO);
+ MUSB_FLAGS_PRINT(w, RXCSR, DATAERROR);
+ MUSB_FLAGS_PRINT(w, RXCSR, FIFOFULL);
+ MUSB_FLAGS_PRINT(w, RXCSR, RXPKTRDY);
+ MUSB_FLAGS_PRINT(w, RXCSR_P, SENTSTALL);
+ MUSB_FLAGS_PRINT(w, RXCSR_P, SENDSTALL);
+ MUSB_FLAGS_PRINT(w, RXCSR_P, OVERRUN);
+
+ if (w & MUSB_RXCSR_P_ISO)
+ serial_printf("\t\tiso mode\n");
+ else
+ serial_printf("\t\tbulk mode\n");
+
+}
+
+static inline void musb_print_txmaxp(u16 w)
+{
+ serial_printf("\ttxmaxp 0x%4.4x\n", w);
+}
+
+static inline void musb_print_txcsr(u16 w)
+{
+ serial_printf("\ttxcsr 0x%4.4x\n", w);
+ MUSB_FLAGS_PRINT(w, TXCSR, TXPKTRDY);
+ MUSB_FLAGS_PRINT(w, TXCSR, FIFONOTEMPTY);
+ MUSB_FLAGS_PRINT(w, TXCSR, FLUSHFIFO);
+ MUSB_FLAGS_PRINT(w, TXCSR, CLRDATATOG);
+ MUSB_FLAGS_PRINT(w, TXCSR_P, UNDERRUN);
+ MUSB_FLAGS_PRINT(w, TXCSR_P, SENTSTALL);
+ MUSB_FLAGS_PRINT(w, TXCSR_P, SENDSTALL);
+
+ if (w & MUSB_TXCSR_MODE)
+ serial_printf("\t\tTX mode\n");
+ else
+ serial_printf("\t\tRX mode\n");
+}
+
+#else
+
+/* stubs */
+
+#define musb_print_pwr(b)
+#define musb_print_csr0(w)
+#define musb_print_intrusb(b)
+#define musb_print_intrtx(w)
+#define musb_print_intrrx(w)
+#define musb_print_devctl(b)
+#define musb_print_config(b)
+#define musb_print_rxmaxp(w)
+#define musb_print_rxcsr(w)
+#define musb_print_txmaxp(w)
+#define musb_print_txcsr(w)
+
+#endif /* MUSB_DEBUG */
diff --git a/drivers/usb/musb/musb_hcd.c b/drivers/usb/musb/musb_hcd.c
index 4ca94cb31..555d2dc1b 100644
--- a/drivers/usb/musb/musb_hcd.c
+++ b/drivers/usb/musb/musb_hcd.c
@@ -803,7 +803,7 @@ void usb_event_poll()
{
struct stdio_dev *dev;
struct usb_device *usb_kbd_dev;
- struct usb_interface_descriptor *iface;
+ struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
int pipe;
int maxp;
diff --git a/drivers/usb/musb/musb_udc.c b/drivers/usb/musb/musb_udc.c
new file mode 100644
index 000000000..fc43cf4f0
--- /dev/null
+++ b/drivers/usb/musb/musb_udc.c
@@ -0,0 +1,963 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This file is a rewrite of the usb device part of
+ * repository git.omapzoom.org/repo/u-boot.git, branch master,
+ * file cpu/omap3/fastboot.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * -------------------------------------------------------------------------
+ *
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * -------------------------------------------------------------------------
+ *
+ * The details of connecting the device to the uboot usb device subsystem
+ * came from the old omap3 repository www.sakoman.net/u-boot-omap3.git,
+ * branch omap3-dev-usb, file drivers/usb/usbdcore_musb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * -------------------------------------------------------------------------
+ *
+ * (C) Copyright 2008 Texas Instruments Incorporated.
+ *
+ * Based on
+ * u-boot OMAP1510 USB drivers (drivers/usbdcore_omap1510.c)
+ * twl4030 init based on linux (drivers/i2c/chips/twl4030_usb.c)
+ *
+ * Author: Diego Dompe (diego.dompe@ridgerun.com)
+ * Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * -------------------------------------------------------------------------
+ *
+ * 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>
+#include <usb/musb_udc.h>
+#include "../gadget/ep0.h"
+#include "musb_core.h"
+#if defined(CONFIG_USB_OMAP3)
+#include "omap3.h"
+#elif defined(CONFIG_USB_DAVINCI)
+#include "davinci.h"
+#endif
+
+/* Define MUSB_DEBUG for debugging */
+/* #define MUSB_DEBUG */
+#include "musb_debug.h"
+
+#define MAX_ENDPOINT 15
+
+#define GET_ENDPOINT(dev,ep) \
+(((struct usb_device_instance *)(dev))->bus->endpoint_array + ep)
+
+#define SET_EP0_STATE(s) \
+do { \
+ if ((0 <= (s)) && (SET_ADDRESS >= (s))) { \
+ if ((s) != ep0_state) { \
+ if ((debug_setup) && (debug_level > 1)) \
+ serial_printf("INFO : Changing state " \
+ "from %s to %s in %s at " \
+ "line %d\n", \
+ ep0_state_strings[ep0_state],\
+ ep0_state_strings[s], \
+ __PRETTY_FUNCTION__, \
+ __LINE__); \
+ ep0_state = s; \
+ } \
+ } else { \
+ if (debug_level > 0) \
+ serial_printf("Error at %s %d with setting " \
+ "state %d is invalid\n", \
+ __PRETTY_FUNCTION__, __LINE__, s); \
+ } \
+} while (0)
+
+/* static implies these initialized to 0 or NULL */
+static int debug_setup;
+static int debug_level;
+static struct musb_epinfo epinfo[MAX_ENDPOINT * 2];
+static enum ep0_state_enum {
+ IDLE = 0,
+ TX,
+ RX,
+ SET_ADDRESS
+} ep0_state = IDLE;
+static char *ep0_state_strings[4] = {
+ "IDLE",
+ "TX",
+ "RX",
+ "SET_ADDRESS",
+};
+
+static struct urb *ep0_urb;
+struct usb_endpoint_instance *ep0_endpoint;
+static struct usb_device_instance *udc_device;
+static int enabled;
+
+#ifdef MUSB_DEBUG
+static void musb_db_regs(void)
+{
+ u8 b;
+ u16 w;
+
+ b = readb(&musbr->faddr);
+ serial_printf("\tfaddr 0x%2.2x\n", b);
+
+ b = readb(&musbr->power);
+ musb_print_pwr(b);
+
+ w = readw(&musbr->ep[0].ep0.csr0);
+ musb_print_csr0(w);
+
+ b = readb(&musbr->devctl);
+ musb_print_devctl(b);
+
+ b = readb(&musbr->ep[0].ep0.configdata);
+ musb_print_config(b);
+
+ w = readw(&musbr->frame);
+ serial_printf("\tframe 0x%4.4x\n", w);
+
+ b = readb(&musbr->index);
+ serial_printf("\tindex 0x%2.2x\n", b);
+
+ w = readw(&musbr->ep[1].epN.rxmaxp);
+ musb_print_rxmaxp(w);
+
+ w = readw(&musbr->ep[1].epN.rxcsr);
+ musb_print_rxcsr(w);
+
+ w = readw(&musbr->ep[1].epN.txmaxp);
+ musb_print_txmaxp(w);
+
+ w = readw(&musbr->ep[1].epN.txcsr);
+ musb_print_txcsr(w);
+}
+#else
+#define musb_db_regs()
+#endif /* DEBUG_MUSB */
+
+static void musb_peri_softconnect(void)
+{
+ u8 power, devctl;
+ u8 intrusb;
+ u16 intrrx, intrtx;
+
+ /* Power off MUSB */
+ power = readb(&musbr->power);
+ power &= ~MUSB_POWER_SOFTCONN;
+ writeb(power, &musbr->power);
+
+ /* Read intr to clear */
+ intrusb = readb(&musbr->intrusb);
+ intrrx = readw(&musbr->intrrx);
+ intrtx = readw(&musbr->intrtx);
+
+ udelay(1000 * 1000); /* 1 sec */
+
+ /* Power on MUSB */
+ power = readb(&musbr->power);
+ power |= MUSB_POWER_SOFTCONN;
+ /*
+ * The usb device interface is usb 1.1
+ * Disable 2.0 high speed by clearring the hsenable bit.
+ */
+ power &= ~MUSB_POWER_HSENAB;
+ writeb(power, &musbr->power);
+
+ /* Check if device is in b-peripheral mode */
+ devctl = readb(&musbr->devctl);
+ if (!(devctl & MUSB_DEVCTL_BDEVICE) ||
+ (devctl & MUSB_DEVCTL_HM)) {
+ serial_printf("ERROR : Unsupport USB mode\n");
+ serial_printf("Check that mini-B USB cable is attached "
+ "to the device\n");
+ }
+
+ if (debug_setup && (debug_level > 1))
+ musb_db_regs();
+}
+
+static void musb_peri_reset(void)
+{
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("INFO : %s reset\n", __PRETTY_FUNCTION__);
+
+ if (ep0_endpoint)
+ ep0_endpoint->endpoint_address = 0xff;
+
+ /* Sync sw and hw addresses */
+ writeb(udc_device->address, &musbr->faddr);
+
+ SET_EP0_STATE(IDLE);
+}
+
+static void musb_peri_resume(void)
+{
+ /* noop */
+}
+
+static void musb_peri_ep0_stall(void)
+{
+ u16 csr0;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ csr0 |= MUSB_CSR0_P_SENDSTALL;
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("INFO : %s stall\n", __PRETTY_FUNCTION__);
+}
+
+static void musb_peri_ep0_ack_req(void)
+{
+ u16 csr0;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ csr0 |= MUSB_CSR0_P_SVDRXPKTRDY;
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_ep0_tx_ready(void)
+{
+ u16 csr0;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ csr0 |= MUSB_CSR0_TXPKTRDY;
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_ep0_tx_ready_and_last(void)
+{
+ u16 csr0;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ csr0 |= (MUSB_CSR0_TXPKTRDY | MUSB_CSR0_P_DATAEND);
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_peri_ep0_last(void)
+{
+ u16 csr0;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ csr0 |= MUSB_CSR0_P_DATAEND;
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+}
+
+static void musb_peri_ep0_set_address(void)
+{
+ u8 faddr;
+ writeb(udc_device->address, &musbr->faddr);
+
+ /* Verify */
+ faddr = readb(&musbr->faddr);
+ if (udc_device->address == faddr) {
+ SET_EP0_STATE(IDLE);
+ usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0);
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("INFO : %s Address set to %d\n",
+ __PRETTY_FUNCTION__, udc_device->address);
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s Address missmatch "
+ "sw %d vs hw %d\n",
+ __PRETTY_FUNCTION__,
+ udc_device->address, faddr);
+ }
+}
+
+static void musb_peri_rx_ack(unsigned int ep)
+{
+ u16 peri_rxcsr;
+
+ peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);
+ peri_rxcsr &= ~MUSB_RXCSR_RXPKTRDY;
+ writew(peri_rxcsr, &musbr->ep[ep].epN.rxcsr);
+}
+
+static void musb_peri_tx_ready(unsigned int ep)
+{
+ u16 peri_txcsr;
+
+ peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
+ peri_txcsr |= MUSB_TXCSR_TXPKTRDY;
+ writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
+}
+
+static void musb_peri_ep0_zero_data_request(int err)
+{
+ musb_peri_ep0_ack_req();
+
+ if (err) {
+ musb_peri_ep0_stall();
+ SET_EP0_STATE(IDLE);
+ } else {
+
+ musb_peri_ep0_last();
+
+ /* USBD state */
+ switch (ep0_urb->device_request.bRequest) {
+ case USB_REQ_SET_ADDRESS:
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("INFO : %s received set "
+ "address\n", __PRETTY_FUNCTION__);
+ break;
+
+ case USB_REQ_SET_CONFIGURATION:
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("INFO : %s Configured\n",
+ __PRETTY_FUNCTION__);
+ usbd_device_event_irq(udc_device, DEVICE_CONFIGURED, 0);
+ break;
+ }
+
+ /* EP0 state */
+ if (USB_REQ_SET_ADDRESS == ep0_urb->device_request.bRequest) {
+ SET_EP0_STATE(SET_ADDRESS);
+ } else {
+ SET_EP0_STATE(IDLE);
+ }
+ }
+}
+
+static void musb_peri_ep0_rx_data_request(void)
+{
+ /*
+ * This is the completion of the data OUT / RX
+ *
+ * Host is sending data to ep0 that is not
+ * part of setup. This comes from the cdc_recv_setup
+ * op that is device specific.
+ *
+ */
+ musb_peri_ep0_ack_req();
+
+ ep0_endpoint->rcv_urb = ep0_urb;
+ ep0_urb->actual_length = 0;
+ SET_EP0_STATE(RX);
+}
+
+static void musb_peri_ep0_tx_data_request(int err)
+{
+ if (err) {
+ musb_peri_ep0_stall();
+ SET_EP0_STATE(IDLE);
+ } else {
+ musb_peri_ep0_ack_req();
+
+ ep0_endpoint->tx_urb = ep0_urb;
+ ep0_endpoint->sent = 0;
+ SET_EP0_STATE(TX);
+ }
+}
+
+static void musb_peri_ep0_idle(void)
+{
+ u16 count0;
+ int err;
+ u16 csr0;
+
+ /*
+ * Verify addresses
+ * A lot of confusion can be caused if the address
+ * in software, udc layer, does not agree with the
+ * hardware. Since the setting of the hardware address
+ * must be set after the set address request, the
+ * usb state machine is out of sync for a few frame.
+ * It is a good idea to run this check when changes
+ * are made to the state machine.
+ */
+ if ((debug_level > 0) &&
+ (ep0_state != SET_ADDRESS)) {
+ u8 faddr;
+
+ faddr = readb(&musbr->faddr);
+ if (udc_device->address != faddr) {
+ serial_printf("ERROR : %s addresses do not"
+ "match sw %d vs hw %d\n",
+ __PRETTY_FUNCTION__,
+ udc_device->address, faddr);
+ udelay(1000 * 1000);
+ hang();
+ }
+ }
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+ if (!(MUSB_CSR0_RXPKTRDY & csr0))
+ goto end;
+
+ count0 = readw(&musbr->ep[0].ep0.count0);
+ if (count0 == 0)
+ goto end;
+
+ if (count0 != 8) {
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("WARN : %s SETUP incorrect size %d\n",
+ __PRETTY_FUNCTION__, count0);
+ musb_peri_ep0_stall();
+ goto end;
+ }
+
+ read_fifo(0, count0, &ep0_urb->device_request);
+
+ if (debug_level > 2)
+ print_usb_device_request(&ep0_urb->device_request);
+
+ if (ep0_urb->device_request.wLength == 0) {
+ err = ep0_recv_setup(ep0_urb);
+
+ /* Zero data request */
+ musb_peri_ep0_zero_data_request(err);
+ } else {
+ /* Is data coming or going ? */
+ u8 reqType = ep0_urb->device_request.bmRequestType;
+
+ if (USB_REQ_DEVICE2HOST == (reqType & USB_REQ_DIRECTION_MASK)) {
+ err = ep0_recv_setup(ep0_urb);
+ /* Device to host */
+ musb_peri_ep0_tx_data_request(err);
+ } else {
+ /*
+ * Host to device
+ *
+ * The RX routine will call ep0_recv_setup
+ * when the data packet has arrived.
+ */
+ musb_peri_ep0_rx_data_request();
+ }
+ }
+
+end:
+ return;
+}
+
+static void musb_peri_ep0_rx(void)
+{
+ /*
+ * This is the completion of the data OUT / RX
+ *
+ * Host is sending data to ep0 that is not
+ * part of setup. This comes from the cdc_recv_setup
+ * op that is device specific.
+ *
+ * Pass the data back to driver ep0_recv_setup which
+ * should give the cdc_recv_setup the chance to handle
+ * the rx
+ */
+ u16 csr0;
+ u16 count0;
+
+ if (debug_level > 3) {
+ if (0 != ep0_urb->actual_length) {
+ serial_printf("%s finished ? %d of %d\n",
+ __PRETTY_FUNCTION__,
+ ep0_urb->actual_length,
+ ep0_urb->device_request.wLength);
+ }
+ }
+
+ if (ep0_urb->device_request.wLength == ep0_urb->actual_length) {
+ musb_peri_ep0_last();
+ SET_EP0_STATE(IDLE);
+ ep0_recv_setup(ep0_urb);
+ return;
+ }
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ if (!(MUSB_CSR0_RXPKTRDY & csr0))
+ return;
+
+ count0 = readw(&musbr->ep[0].ep0.count0);
+
+ if (count0) {
+ struct usb_endpoint_instance *endpoint;
+ u32 length;
+ u8 *data;
+
+ endpoint = ep0_endpoint;
+ if (endpoint && endpoint->rcv_urb) {
+ struct urb *urb = endpoint->rcv_urb;
+ unsigned int remaining_space = urb->buffer_length -
+ urb->actual_length;
+
+ if (remaining_space) {
+ int urb_bad = 0; /* urb is good */
+
+ if (count0 > remaining_space)
+ length = remaining_space;
+ else
+ length = count0;
+
+ data = (u8 *) urb->buffer_data;
+ data += urb->actual_length;
+
+ /* The common musb fifo reader */
+ read_fifo(0, length, data);
+
+ musb_peri_ep0_ack_req();
+
+ /*
+ * urb's actual_length is updated in
+ * usbd_rcv_complete
+ */
+ usbd_rcv_complete(endpoint, length, urb_bad);
+
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s no space in "
+ "rcv buffer\n",
+ __PRETTY_FUNCTION__);
+ }
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s problem with "
+ "endpoint\n",
+ __PRETTY_FUNCTION__);
+ }
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s with nothing to do\n",
+ __PRETTY_FUNCTION__);
+ }
+}
+
+static void musb_peri_ep0_tx(void)
+{
+ u16 csr0;
+ int transfer_size = 0;
+ unsigned int p, pm;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+ /* Check for pending tx */
+ if (csr0 & MUSB_CSR0_TXPKTRDY)
+ goto end;
+
+ /* Check if this is the last packet sent */
+ if (ep0_endpoint->sent >= ep0_urb->actual_length) {
+ SET_EP0_STATE(IDLE);
+ goto end;
+ }
+
+ transfer_size = ep0_urb->actual_length - ep0_endpoint->sent;
+ /* Is the transfer size negative ? */
+ if (transfer_size <= 0) {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s problem with the"
+ " transfer size %d\n",
+ __PRETTY_FUNCTION__,
+ transfer_size);
+ SET_EP0_STATE(IDLE);
+ goto end;
+ }
+
+ /* Truncate large transfers to the fifo size */
+ if (transfer_size > ep0_endpoint->tx_packetSize)
+ transfer_size = ep0_endpoint->tx_packetSize;
+
+ write_fifo(0, transfer_size, &ep0_urb->buffer[ep0_endpoint->sent]);
+ ep0_endpoint->sent += transfer_size;
+
+ /* Done or more to send ? */
+ if (ep0_endpoint->sent >= ep0_urb->actual_length)
+ musb_ep0_tx_ready_and_last();
+ else
+ musb_ep0_tx_ready();
+
+ /* Wait a bit */
+ pm = 10;
+ for (p = 0; p < pm; p++) {
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+ if (!(csr0 & MUSB_CSR0_TXPKTRDY))
+ break;
+
+ /* Double the delay. */
+ udelay(1 << pm);
+ }
+
+ if ((ep0_endpoint->sent >= ep0_urb->actual_length) && (p < pm))
+ SET_EP0_STATE(IDLE);
+
+end:
+ return;
+}
+
+static void musb_peri_ep0(void)
+{
+ u16 csr0;
+
+ if (SET_ADDRESS == ep0_state)
+ return;
+
+ csr0 = readw(&musbr->ep[0].ep0.csr0);
+
+ /* Error conditions */
+ if (MUSB_CSR0_P_SENTSTALL & csr0) {
+ csr0 &= ~MUSB_CSR0_P_SENTSTALL;
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+ SET_EP0_STATE(IDLE);
+ }
+ if (MUSB_CSR0_P_SETUPEND & csr0) {
+ csr0 |= MUSB_CSR0_P_SVDSETUPEND;
+ writew(csr0, &musbr->ep[0].ep0.csr0);
+ SET_EP0_STATE(IDLE);
+ if ((debug_setup) && (debug_level > 1))
+ serial_printf("WARN: %s SETUPEND\n",
+ __PRETTY_FUNCTION__);
+ }
+
+ /* Normal states */
+ if (IDLE == ep0_state)
+ musb_peri_ep0_idle();
+
+ if (TX == ep0_state)
+ musb_peri_ep0_tx();
+
+ if (RX == ep0_state)
+ musb_peri_ep0_rx();
+}
+
+static void musb_peri_rx_ep(unsigned int ep)
+{
+ u16 peri_rxcount = readw(&musbr->ep[ep].epN.rxcount);
+
+ if (peri_rxcount) {
+ struct usb_endpoint_instance *endpoint;
+ u32 length;
+ u8 *data;
+
+ endpoint = GET_ENDPOINT(udc_device, ep);
+ if (endpoint && endpoint->rcv_urb) {
+ struct urb *urb = endpoint->rcv_urb;
+ unsigned int remaining_space = urb->buffer_length -
+ urb->actual_length;
+
+ if (remaining_space) {
+ int urb_bad = 0; /* urb is good */
+
+ if (peri_rxcount > remaining_space)
+ length = remaining_space;
+ else
+ length = peri_rxcount;
+
+ data = (u8 *) urb->buffer_data;
+ data += urb->actual_length;
+
+ /* The common musb fifo reader */
+ read_fifo(ep, length, data);
+
+ musb_peri_rx_ack(ep);
+
+ /*
+ * urb's actual_length is updated in
+ * usbd_rcv_complete
+ */
+ usbd_rcv_complete(endpoint, length, urb_bad);
+
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s %d no space "
+ "in rcv buffer\n",
+ __PRETTY_FUNCTION__, ep);
+ }
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s %d problem with "
+ "endpoint\n",
+ __PRETTY_FUNCTION__, ep);
+ }
+
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s %d with nothing to do\n",
+ __PRETTY_FUNCTION__, ep);
+ }
+}
+
+static void musb_peri_rx(u16 intr)
+{
+ unsigned int ep;
+
+ /* Check for EP0 */
+ if (0x01 & intr)
+ musb_peri_ep0();
+
+ for (ep = 1; ep < 16; ep++) {
+ if ((1 << ep) & intr)
+ musb_peri_rx_ep(ep);
+ }
+}
+
+static void musb_peri_tx(u16 intr)
+{
+ /* Check for EP0 */
+ if (0x01 & intr)
+ musb_peri_ep0_tx();
+
+ /*
+ * Use this in the future when handling epN tx
+ *
+ * u8 ep;
+ *
+ * for (ep = 1; ep < 16; ep++) {
+ * if ((1 << ep) & intr) {
+ * / * handle tx for this endpoint * /
+ * }
+ * }
+ */
+}
+
+void udc_irq(void)
+{
+ /* This is a high freq called function */
+ if (enabled) {
+ u8 intrusb;
+
+ intrusb = readb(&musbr->intrusb);
+
+ /*
+ * See drivers/usb/gadget/mpc8xx_udc.c for
+ * state diagram going from detached through
+ * configuration.
+ */
+ if (MUSB_INTR_RESUME & intrusb) {
+ usbd_device_event_irq(udc_device,
+ DEVICE_BUS_ACTIVITY, 0);
+ musb_peri_resume();
+ }
+
+ musb_peri_ep0();
+
+ if (MUSB_INTR_RESET & intrusb) {
+ usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+ musb_peri_reset();
+ }
+
+ if (MUSB_INTR_DISCONNECT & intrusb) {
+ /* cable unplugged from hub/host */
+ usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+ musb_peri_reset();
+ usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0);
+ }
+
+ if (MUSB_INTR_SOF & intrusb) {
+ usbd_device_event_irq(udc_device,
+ DEVICE_BUS_ACTIVITY, 0);
+ musb_peri_resume();
+ }
+
+ if (MUSB_INTR_SUSPEND & intrusb) {
+ usbd_device_event_irq(udc_device,
+ DEVICE_BUS_INACTIVE, 0);
+ }
+
+ if (ep0_state != SET_ADDRESS) {
+ u16 intrrx, intrtx;
+
+ intrrx = readw(&musbr->intrrx);
+ intrtx = readw(&musbr->intrtx);
+
+ if (intrrx)
+ musb_peri_rx(intrrx);
+
+ if (intrtx)
+ musb_peri_tx(intrtx);
+ } else {
+ if (MUSB_INTR_SOF & intrusb) {
+ u8 faddr;
+ faddr = readb(&musbr->faddr);
+ /*
+ * Setting of the address can fail.
+ * Normally it succeeds the second time.
+ */
+ if (udc_device->address != faddr)
+ musb_peri_ep0_set_address();
+ }
+ }
+ }
+}
+
+void udc_set_nak(int ep_num)
+{
+ /* noop */
+}
+
+void udc_unset_nak(int ep_num)
+{
+ /* noop */
+}
+
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
+{
+ int ret = 0;
+
+ /* Transmit only if the hardware is available */
+ if (endpoint->tx_urb && endpoint->state == 0) {
+ unsigned int ep = endpoint->endpoint_address &
+ USB_ENDPOINT_NUMBER_MASK;
+
+ u16 peri_txcsr = readw(&musbr->ep[ep].epN.txcsr);
+
+ /* Error conditions */
+ if (peri_txcsr & MUSB_TXCSR_P_UNDERRUN) {
+ peri_txcsr &= ~MUSB_TXCSR_P_UNDERRUN;
+ writew(peri_txcsr, &musbr->ep[ep].epN.txcsr);
+ }
+
+ if (debug_level > 1)
+ musb_print_txcsr(peri_txcsr);
+
+ /* Check if a packet is waiting to be sent */
+ if (!(peri_txcsr & MUSB_TXCSR_TXPKTRDY)) {
+ u32 length;
+ u8 *data;
+ struct urb *urb = endpoint->tx_urb;
+ unsigned int remaining_packet = urb->actual_length -
+ endpoint->sent;
+
+ if (endpoint->tx_packetSize < remaining_packet)
+ length = endpoint->tx_packetSize;
+ else
+ length = remaining_packet;
+
+ data = (u8 *) urb->buffer;
+ data += endpoint->sent;
+
+ /* common musb fifo function */
+ write_fifo(ep, length, data);
+
+ musb_peri_tx_ready(ep);
+
+ endpoint->last = length;
+ /* usbd_tx_complete will take care of updating 'sent' */
+ usbd_tx_complete(endpoint);
+ }
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s Problem with urb %p "
+ "or ep state %d\n",
+ __PRETTY_FUNCTION__,
+ endpoint->tx_urb, endpoint->state);
+ }
+
+ return ret;
+}
+
+void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
+ struct usb_endpoint_instance *endpoint)
+{
+ if (0 == id) {
+ /* EP0 */
+ ep0_endpoint = endpoint;
+ ep0_endpoint->endpoint_address = 0xff;
+ ep0_urb = usbd_alloc_urb(device, endpoint);
+ } else if (MAX_ENDPOINT >= id) {
+ int ep_addr;
+
+ /* Check the direction */
+ ep_addr = endpoint->endpoint_address;
+ if (USB_DIR_IN == (ep_addr & USB_ENDPOINT_DIR_MASK)) {
+ /* IN */
+ epinfo[(id * 2) + 1].epsize = endpoint->tx_packetSize;
+ } else {
+ /* OUT */
+ epinfo[id * 2].epsize = endpoint->rcv_packetSize;
+ }
+
+ musb_configure_ep(&epinfo[0],
+ sizeof(epinfo) / sizeof(struct musb_epinfo));
+ } else {
+ if (debug_level > 0)
+ serial_printf("ERROR : %s endpoint request %d "
+ "exceeds maximum %d\n",
+ __PRETTY_FUNCTION__, id, MAX_ENDPOINT);
+ }
+}
+
+void udc_connect(void)
+{
+ /* noop */
+}
+
+void udc_disconnect(void)
+{
+ /* noop */
+}
+
+void udc_enable(struct usb_device_instance *device)
+{
+ /* Save the device structure pointer */
+ udc_device = device;
+
+ enabled = 1;
+}
+
+void udc_disable(void)
+{
+ enabled = 0;
+}
+
+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);
+
+ /* Resets the address to 0 */
+ usbd_device_event_irq(device, DEVICE_RESET, 0);
+
+ udc_enable(device);
+}
+
+int udc_init(void)
+{
+ int ret;
+ int ep_loop;
+
+ ret = musb_platform_init();
+ if (ret < 0)
+ goto end;
+
+ /* Configure all the endpoint FIFO's and start usb controller */
+ musbr = musb_cfg.regs;
+
+ /* Initialize the endpoints */
+ for (ep_loop = 0; ep_loop < MAX_ENDPOINT * 2; ep_loop++) {
+ epinfo[ep_loop].epnum = (ep_loop / 2) + 1;
+ epinfo[ep_loop].epdir = ep_loop % 2; /* OUT, IN */
+ epinfo[ep_loop].epsize = 0;
+ }
+
+ musb_peri_softconnect();
+
+ ret = 0;
+end:
+
+ return ret;
+}
diff --git a/drivers/usb/musb/omap3.c b/drivers/usb/musb/omap3.c
new file mode 100644
index 000000000..ea98c3cac
--- /dev/null
+++ b/drivers/usb/musb/omap3.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This is file is based on
+ * repository git.gitorious.org/u-boot-omap3/mainline.git,
+ * branch omap3-dev-usb, file drivers/usb/host/omap3530_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2009 Texas Instruments
+ *
+ * ------------------------------------------------------------------------
+ *
+ * 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 <twl4030.h>
+#include "omap3.h"
+
+static int platform_needs_initialization = 1;
+
+struct musb_config musb_cfg = {
+ (struct musb_regs *)MENTOR_USB0_BASE,
+ OMAP3_USB_TIMEOUT,
+ 0
+};
+
+/*
+ * OMAP3 USB OTG registers.
+ */
+struct omap3_otg_regs {
+ u32 revision;
+ u32 sysconfig;
+ u32 sysstatus;
+ u32 interfsel;
+ u32 simenable;
+ u32 forcestdby;
+};
+
+static struct omap3_otg_regs *otg;
+
+#define OMAP3_OTG_SYSCONFIG_SMART_STANDBY_MODE 0x2000
+#define OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE 0x1000
+#define OMAP3_OTG_SYSCONFIG_SMART_IDLE_MODE 0x0010
+#define OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE 0x0008
+#define OMAP3_OTG_SYSCONFIG_ENABLEWAKEUP 0x0004
+#define OMAP3_OTG_SYSCONFIG_SOFTRESET 0x0002
+#define OMAP3_OTG_SYSCONFIG_AUTOIDLE 0x0001
+
+#define OMAP3_OTG_SYSSTATUS_RESETDONE 0x0001
+
+#define OMAP3_OTG_INTERFSEL_OMAP 0x0001
+
+#define OMAP3_OTG_FORCESTDBY_STANDBY 0x0001
+
+
+#ifdef DEBUG_MUSB_OMAP3
+static void musb_db_otg_regs(void)
+{
+ u32 l;
+ l = readl(&otg->revision);
+ serial_printf("OTG_REVISION 0x%x\n", l);
+ l = readl(&otg->sysconfig);
+ serial_printf("OTG_SYSCONFIG 0x%x\n", l);
+ l = readl(&otg->sysstatus);
+ serial_printf("OTG_SYSSTATUS 0x%x\n", l);
+ l = readl(&otg->interfsel);
+ serial_printf("OTG_INTERFSEL 0x%x\n", l);
+ l = readl(&otg->forcestdby);
+ serial_printf("OTG_FORCESTDBY 0x%x\n", l);
+}
+#endif
+
+int musb_platform_init(void)
+{
+ int ret = -1;
+
+ if (platform_needs_initialization) {
+ u32 stdby;
+
+ /*
+ * OMAP3EVM uses ISP1504 phy and so
+ * twl4030 related init is not required.
+ */
+#ifdef CONFIG_TWL4030_USB
+ if (twl4030_usb_ulpi_init()) {
+ serial_printf("ERROR: %s Could not initialize PHY\n",
+ __PRETTY_FUNCTION__);
+ goto end;
+ }
+#endif
+ otg = (struct omap3_otg_regs *)OMAP3_OTG_BASE;
+
+ /* Set OTG to always be on */
+ writel(OMAP3_OTG_SYSCONFIG_NO_STANDBY_MODE |
+ OMAP3_OTG_SYSCONFIG_NO_IDLE_MODE, &otg->sysconfig);
+
+ /* Set the interface */
+ writel(OMAP3_OTG_INTERFSEL_OMAP, &otg->interfsel);
+
+ /* Clear force standby */
+ stdby = readl(&otg->forcestdby);
+ stdby &= ~OMAP3_OTG_FORCESTDBY_STANDBY;
+ writel(stdby, &otg->forcestdby);
+
+ platform_needs_initialization = 0;
+ }
+
+ ret = platform_needs_initialization;
+end:
+ return ret;
+
+}
+
+void musb_platform_deinit(void)
+{
+ /* noop */
+}
diff --git a/drivers/usb/musb/omap3.h b/drivers/usb/musb/omap3.h
new file mode 100644
index 000000000..20fc9d294
--- /dev/null
+++ b/drivers/usb/musb/omap3.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This file is based on the file drivers/usb/musb/davinci.h
+ *
+ * This is the unique part of its copyright:
+ *
+ * --------------------------------------------------------------------
+ *
+ * Copyright (c) 2008 Texas Instruments
+ * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
+ *
+ * --------------------------------------------------------------------
+ *
+ * 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
+ */
+#ifndef _MUSB_OMAP3_H_
+#define _MUSB_OMAP3_H_
+
+#include "musb_core.h"
+
+/* Base address of MUSB registers */
+#define MENTOR_USB0_BASE (OMAP34XX_CORE_L4_IO_BASE + 0xAB000)
+
+/* Base address of OTG registers */
+#define OMAP3_OTG_BASE (MENTOR_USB0_BASE + 0x400)
+
+/* Timeout for USB module */
+#define OMAP3_USB_TIMEOUT 0x3FFFFFF
+
+int musb_platform_init(void);
+
+#endif /* _MUSB_OMAP3_H */
+
diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile
new file mode 100644
index 000000000..200b907d9
--- /dev/null
+++ b/drivers/usb/phy/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2009 Wind River Systems, Inc.
+# Tom Rix <Tom.Rix@windriver.com>
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB := $(obj)libusb_phy.a
+
+COBJS-$(CONFIG_TWL4030_USB) += twl4030.o
+COBJS-y := twl4030.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/usb/phy/twl4030.c b/drivers/usb/phy/twl4030.c
new file mode 100644
index 000000000..54d2e615c
--- /dev/null
+++ b/drivers/usb/phy/twl4030.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * This is file is based on
+ * repository git.gitorious.org/u-boot-omap3/mainline.git,
+ * branch omap3-dev-usb, file drivers/usb/gadget/twl4030_usb.c
+ *
+ * This is the unique part of its copyright :
+ *
+ * ------------------------------------------------------------------------
+ *
+ * * (C) Copyright 2009 Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * Based on: twl4030_usb.c in linux 2.6 (drivers/i2c/chips/twl4030_usb.c)
+ * Copyright (C) 2004-2007 Texas Instruments
+ * Copyright (C) 2008 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * Author: Atin Malaviya (atin.malaviya@gmail.com)
+ *
+ * ------------------------------------------------------------------------
+ *
+ * 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 <twl4030.h>
+
+/* Defines for bits in registers */
+#define OPMODE_MASK (3 << 3)
+#define XCVRSELECT_MASK (3 << 0)
+#define CARKITMODE (1 << 2)
+#define OTG_ENAB (1 << 5)
+#define PHYPWD (1 << 0)
+#define CLOCKGATING_EN (1 << 2)
+#define CLK32K_EN (1 << 1)
+#define REQ_PHY_DPLL_CLK (1 << 0)
+#define PHY_DPLL_CLK (1 << 0)
+
+static int twl4030_usb_write(u8 address, u8 data)
+{
+ int ret;
+
+ ret = twl4030_i2c_write_u8(TWL4030_CHIP_USB, data, address);
+ if (ret != 0)
+ printf("TWL4030:USB:Write[0x%x] Error %d\n", address, ret);
+
+ return ret;
+}
+
+static int twl4030_usb_read(u8 address)
+{
+ u8 data;
+ int ret;
+
+ ret = twl4030_i2c_read_u8(TWL4030_CHIP_USB, &data, address);
+ if (ret == 0)
+ ret = data;
+ else
+ printf("TWL4030:USB:Read[0x%x] Error %d\n", address, ret);
+
+ return ret;
+}
+
+static void twl4030_usb_ldo_init(void)
+{
+ /* Enable writing to power configuration registers */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0xC0,
+ TWL4030_PM_MASTER_PROTECT_KEY);
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x0C,
+ TWL4030_PM_MASTER_PROTECT_KEY);
+
+ /* put VUSB3V1 LDO in active state */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+ TWL4030_PM_RECEIVER_VUSB_DEDICATED2);
+
+ /* input to VUSB3V1 LDO is from VBAT, not VBUS */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x14,
+ TWL4030_PM_RECEIVER_VUSB_DEDICATED1);
+
+ /* turn on 3.1V regulator */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+ TWL4030_PM_RECEIVER_VUSB3V1_DEV_GRP);
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+ TWL4030_PM_RECEIVER_VUSB3V1_TYPE);
+
+ /* turn on 1.5V regulator */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+ TWL4030_PM_RECEIVER_VUSB1V5_DEV_GRP);
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+ TWL4030_PM_RECEIVER_VUSB1V5_TYPE);
+
+ /* turn on 1.8V regulator */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
+ TWL4030_PM_RECEIVER_VUSB1V8_DEV_GRP);
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x00,
+ TWL4030_PM_RECEIVER_VUSB1V8_TYPE);
+
+ /* disable access to power configuration registers */
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, 0x00,
+ TWL4030_PM_MASTER_PROTECT_KEY);
+}
+
+static void twl4030_phy_power(void)
+{
+ u8 pwr, clk;
+
+ /* Power the PHY */
+ pwr = twl4030_usb_read(TWL4030_USB_PHY_PWR_CTRL);
+ pwr &= ~PHYPWD;
+ twl4030_usb_write(TWL4030_USB_PHY_PWR_CTRL, pwr);
+ /* Enable clocks */
+ clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+ clk |= CLOCKGATING_EN | CLK32K_EN;
+ twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+}
+
+/*
+ * Initiaze the ULPI interface
+ * ULPI : Universal Transceiver Macrocell Low Pin Interface
+ * An interface between the USB link controller like musb and the
+ * the PHY or transceiver that drives the actual bus.
+ */
+int twl4030_usb_ulpi_init(void)
+{
+ long timeout = 1000 * 1000; /* 1 sec */;
+ u8 clk, sts, pwr;
+
+ /* twl4030 ldo init */
+ twl4030_usb_ldo_init();
+
+ /* Enable the twl4030 phy */
+ twl4030_phy_power();
+
+ /* Enable DPLL to access PHY registers over I2C */
+ clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+ clk |= REQ_PHY_DPLL_CLK;
+ twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+
+ /* Check if the PHY DPLL is locked */
+ sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+ while (!(sts & PHY_DPLL_CLK) && 0 < timeout) {
+ udelay(10);
+ sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+ timeout -= 10;
+ }
+
+ /* Final check */
+ sts = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL_STS);
+ if (!(sts & PHY_DPLL_CLK)) {
+ printf("Error:TWL4030:USB Timeout setting PHY DPLL clock\n");
+ return -1;
+ }
+
+ /*
+ * There are two circuit blocks attached to the PHY,
+ * Carkit and USB OTG. Disable Carkit and enable USB OTG
+ */
+ twl4030_usb_write(TWL4030_USB_IFC_CTRL_CLR, CARKITMODE);
+ pwr = twl4030_usb_read(TWL4030_USB_POWER_CTRL);
+ pwr |= OTG_ENAB;
+ twl4030_usb_write(TWL4030_USB_POWER_CTRL_SET, pwr);
+
+ /* Clear the opmode bits to ensure normal encode */
+ twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, OPMODE_MASK);
+
+ /* Clear the xcvrselect bits to enable the high speed transeiver */
+ twl4030_usb_write(TWL4030_USB_FUNC_CTRL_CLR, XCVRSELECT_MASK);
+
+ /* Let ULPI control the DPLL clock */
+ clk = twl4030_usb_read(TWL4030_USB_PHY_CLK_CTRL);
+ clk &= ~REQ_PHY_DPLL_CLK;
+ twl4030_usb_write(TWL4030_USB_PHY_CLK_CTRL, clk);
+
+ return 0;
+}
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 16d6689f2..c07a26e3c 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -403,8 +403,6 @@ static const int video_font_draw_table32[16][4] = {
{ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
-int gunzip(void *, int, unsigned char *, unsigned long *);
-
/******************************************************************************/
static void video_drawchars (int xx, int yy, unsigned char *s, int count)