diff options
Diffstat (limited to 'drivers/usb/gadget/musb_udc.c')
-rwxr-xr-x | drivers/usb/gadget/musb_udc.c | 813 |
1 files changed, 813 insertions, 0 deletions
diff --git a/drivers/usb/gadget/musb_udc.c b/drivers/usb/gadget/musb_udc.c new file mode 100755 index 000000000..a46a6e948 --- /dev/null +++ b/drivers/usb/gadget/musb_udc.c @@ -0,0 +1,813 @@ +/* + * (C) Copyright 2009 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 <asm/io.h> +// #include <asm/arch/clocks.h> +// #include <asm/arch/clocks_omap3.h> +// #include <asm/arch/sys_proto.h> +#include <usbdevice.h> +#include <usb/musb_udc.h> +#include "ep0.h" + +/* Private definitions */ +enum ep0_status { IDLE, DATA_STAGE, DATA_COMPLETE }; + +/* Private variables */ +static struct usb_device_instance *udc_device; +static enum ep0_status ep0status = IDLE; +static unsigned char do_set_address = 0; +static struct urb *ep0_urb = NULL; + +/* Helper functions */ + +/* sr32 from cpu/arm_cortexa8/omap3/syslib.c */ +/***************************************************************** + * sr32 - clear & set a value in a bit range for a 32 bit address + *****************************************************************/ +static void sr32(void *addr, u32 start_bit, u32 num_bits, u32 value) +{ + u32 tmp, msk = 0; + msk = 1 << num_bits; + --msk; + tmp = readl((u32)addr) & ~(msk << start_bit); + tmp |= value << start_bit; + writel(tmp, (u32)addr); +} + +static void insl(u32 reg, u32 *data, u32 size) +{ + u32 t; + + for (t = 0; t < size; t++, data++) + *data = inl(reg); +} + +static void outsl(u32 reg, u32 *data, u32 size) +{ + u32 t; + + for (t = 0; t < size; t++, data++) + outl(*data, reg); +} + +static void outsb(u32 reg, u8 *data, u32 size) +{ + u32 t; + + for (t = 0; t < size; t++, data++) + outb(*data, reg); +} + +static void musb_fifo_read(int epnumber, u8 *data, u32 size) +{ + if ((u32)data & 0x3) { /* Not aligned data */ + insb((UDC_FIFO0 + (epnumber << 2)), data, size); + } else { /* 32 bits aligned data */ + int i; + + insl(UDC_FIFO0 + (epnumber << 2), (u32 *)data, size >> 2); + data += size & ~0x3; + i = size & 0x3; + while (i--) { + *data = inb(UDC_FIFO0 + (epnumber << 2)); + data++; + } + } +} + +static void musb_fifo_write(int epnumber, u8 *data, u32 size) +{ + if ((u32)data & 0x3) { /* Not aligned data */ + outsb(UDC_FIFO0 + (epnumber << 2), data, size); + } else { /* 32 bits aligned data */ + int i; + + outsl(UDC_FIFO0 + (epnumber << 2), (u32 *)data, size >> 2); + data += size & ~0x3; + i = size & 0x3; + while (i--) { + outb(*data, UDC_FIFO0 + (epnumber << 2)); + data++; + } + } +} + +static void musb_fifos_configure(struct usb_device_instance *device) +{ + int ep; + struct usb_bus_instance *bus; + struct usb_endpoint_instance *endpoint; + unsigned short ep_ptr, ep_size, ep_doublebuffer; + int ep_addr, packet_size, buffer_size, attributes; + + bus = device->bus; + + ep_ptr = 0; + + for (ep = 0; ep < bus->max_endpoints; ep++) { + endpoint = bus->endpoint_array + ep; + ep_addr = endpoint->endpoint_address; + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { + /* IN endpoint */ + packet_size = endpoint->tx_packetSize; + attributes = endpoint->tx_attributes; + } else { + /* OUT endpoint */ + packet_size = endpoint->rcv_packetSize; + attributes = endpoint->rcv_attributes; + } + + switch (packet_size) { + case 0: + ep_size = 0; + break; + case 8: + ep_size = 0; + break; + case 16: + ep_size = 1; + break; + case 32: + ep_size = 2; + break; + case 64: + ep_size = 3; + break; + case 128: + ep_size = 4; + break; + case 256: + ep_size = 5; + break; + case 512: + ep_size = 6; + break; + default: + serial_printf("ep 0x%02x has bad packet size %d", + ep_addr, packet_size); + packet_size = 0; + ep_size = 0; + break; + } + + switch (attributes & USB_ENDPOINT_XFERTYPE_MASK) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + case USB_ENDPOINT_XFER_INT: + default: + /* A non-isochronous endpoint may optionally be + * double-buffered. For now we disable + * double-buffering. + */ + ep_doublebuffer = 0; + if (packet_size > 64) + packet_size = 0; + if (!ep || !ep_doublebuffer) + buffer_size = packet_size; + else + buffer_size = packet_size * 2; + break; + case USB_ENDPOINT_XFER_ISOC: + /* Isochronous endpoints are always double- + * buffered + */ + ep_doublebuffer = 1; + buffer_size = packet_size * 2; + break; + } + + /* check to see if our packet buffer RAM is exhausted */ + if ((ep_ptr + buffer_size) > UDC_MAX_FIFO_SIZE) { + serial_printf("out of packet RAM for ep 0x%02x buf size %d", + ep_addr, buffer_size); + buffer_size = packet_size = 0; + } + + /* force a default configuration for endpoint 0 since it is + * always enabled + */ + if (!ep && ((packet_size < 8) || (packet_size > 64))) { + buffer_size = packet_size = 64; + ep_size = 3; + } + + outb(ep & 0xF, UDC_INDEX); + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { + /* IN endpoint */ + outb((ep_doublebuffer << 4) | (ep_size & 0xf), + UDC_TXFIFOSZ); + outw(ep_ptr >> 3, UDC_TXFIFOADDR); + if (!ep) { /* This only apply for ep != 0 */ + outw(packet_size & 0x3FF, UDC_TXMAXP); + } + } else { + /* OUT endpoint */ + outb((ep_doublebuffer << 4) | (ep_size & 0xf), + UDC_RXFIFOSZ); + outw(ep_ptr >> 3, UDC_RXFIFOADDR); + if (!ep) { /* This only apply for ep != 0 */ + outw(packet_size & 0x3FF, UDC_RXMAXP); + } + } + ep_ptr += buffer_size; + } +} + +static void musb_ep0_tx(struct usb_endpoint_instance *endpoint) +{ + unsigned int size = 0; + struct urb *urb = endpoint->tx_urb; + + outb(0, UDC_INDEX); + + if (urb) { + + if ((size = + MIN(urb->actual_length - endpoint->sent, + endpoint->tx_packetSize))) { + + musb_fifo_write(0, urb->buffer + endpoint->sent, size); + } + endpoint->last = size; + + if (((endpoint->sent + size) == ep0_urb->device_request.wLength) + || (size != endpoint->tx_packetSize)) { + ep0status = DATA_COMPLETE; + /* Transmit packet and set data end */ + outw(0xA, UDC_CSR0); + } else { + outw(0x2, UDC_CSR0); /* Transmit packet */ + } + } +} + +static void musb_ep0_handler(struct usb_endpoint_instance *endpoint) +{ + u16 csr0; + + outb(0, UDC_INDEX); + + /* Check errors */ + csr0 = inw(UDC_CSR0); + + if (csr0 & 0x4) { /* Sent stall */ + outw(csr0 & ~0x4, UDC_CSR0); /* Clear stall */ + serial_printf("%s: stall received on EP0!, csr0 %hx\n", + __FUNCTION__, csr0); + csr0 = inw(UDC_CSR0); + serial_printf("state %d -> %d (IDLE), csr0 0x%hx\n", + ep0status, IDLE, csr0); + ep0status = IDLE; + } + + if (csr0 & 0x10) { /* Setup end */ + outw(0x80, UDC_CSR0); /* Clear setup end */ + serial_printf("%s: setup END early happened! status is %d\n", + __FUNCTION__, ep0status); + ep0status = IDLE; + return; + } + + switch (ep0status) { + case DATA_COMPLETE: + if (do_set_address) { + /* + * We need to set the address only after + * the status stage is complete + */ + outb(udc_device->address, UDC_FADDR); + do_set_address = 0; + } + ep0status = IDLE; + /* Fallthrough */ + case IDLE: /* Receiving a setup packet */ + if (csr0 & 0x1) { + insl(UDC_FIFO0, + (unsigned int *) &ep0_urb->device_request, 2); + + /* If we have data, then don't go to IDLE state */ + if (ep0_urb->device_request.wLength) { + ep0status = DATA_STAGE; + + outw(0x40, UDC_CSR0); /* Clear RXPKTRDY */ + if ((ep0_urb->device_request. + bmRequestType & USB_REQ_DIRECTION_MASK) + == USB_REQ_DEVICE2HOST) { + + /* Try to process setup packet */ + if (ep0_recv_setup(ep0_urb)) { + /* + * Not a setup packet, stall + * next EP0 transaction + */ + outw(0x20, UDC_CSR0); + serial_printf("not a setup packed 1, stalling\n"); + ep0status = IDLE; + return; + } + /* + * If we are sending data, do it now, as + * ep0_recv_setup should have prepare + * them + */ + endpoint->tx_urb = ep0_urb; + endpoint->sent = 0; + + musb_ep0_tx(endpoint); + } else { + endpoint->rcv_urb = ep0_urb; + ep0_urb->actual_length = 0; + } + } else { /* Processing zero-length packet */ + /* + * The www.linux-usb.org/usbtest 'test 14' + * fails with error for zero length request. + * If the SETUP packet requests ZERO length data + * from device-to-host, the TXPKTRDY bit needs + * to be set in TXCSR otherwise the STATUS stage + * of control transfer will never complete. + */ + if ((ep0_urb->device_request. + bmRequestType & USB_REQ_DIRECTION_MASK) + == USB_REQ_DEVICE2HOST) { + /* + * Clear RXPKTRDY and DATAEND and + * TXPKTRDY + */ + outw(0x4A, UDC_CSR0); + } else { + /* Clear RXPKTRDY and DATAEND */ + outw(0x48, UDC_CSR0); + } + + /* Try to process setup packet */ + if (ep0_recv_setup(ep0_urb)) { + /* + * Not a setup packet, stall next EP0 + * transaction + */ + outw(0x20, UDC_CSR0); + serial_printf("not a setup packed 2, stalling\n"); + ep0status = IDLE; + return; + } + + switch (ep0_urb->device_request.bRequest) { + case USB_REQ_SET_ADDRESS: + usbd_device_event_irq(udc_device, + DEVICE_ADDRESS_ASSIGNED, 0); + do_set_address = 1; + break; + case USB_REQ_SET_CONFIGURATION: + usbd_device_event_irq(udc_device, + DEVICE_CONFIGURED, 0); + break; + } + + ep0status = DATA_COMPLETE; + } + } + break; + case DATA_STAGE: + if ((ep0_urb->device_request. + bmRequestType & USB_REQ_DIRECTION_MASK) + == USB_REQ_DEVICE2HOST) { + if (!(csr0 & 0x2)) { /* There packet was send? */ + endpoint->sent += endpoint->last; + /* + * If we finished sending data we would not + * be on the DATA_STAGE + */ + musb_ep0_tx(endpoint); + } + } else { + /* Receiving data */ + u16 length = inw(UDC_COUNT0); + + if (length) { + if (ep0_urb->actual_length + length > + ep0_urb->device_request.wLength) + length = + ep0_urb->device_request.wLength - + ep0_urb->actual_length; + + endpoint->last = length; + + musb_fifo_read(0, &ep0_urb-> + buffer[ep0_urb->actual_length], length); + ep0_urb->actual_length += length; + } + + /* + * We finish if we received the amount of data expected, + * or less of the packet size + */ + if ((ep0_urb->actual_length == + ep0_urb->device_request.wLength) || + (endpoint->last != endpoint->tx_packetSize)) { + ep0status = DATA_COMPLETE; + /* Clear RXPKTRDY and DATAEND */ + outw(0x48, UDC_CSR0); + /* This will process the incoming data */ + if (ep0_recv_setup(ep0_urb)) { + /* + * Not a setup packet, stall next EP0 + * transaction + */ + outw(0x20, UDC_CSR0); + serial_printf("not a setup packed 3, stalling\n"); + return; + } + } else + outw(0x40, UDC_CSR0); /* Clear RXPKTRDY */ + } + break; + } +} + +static void musb_ep_tx(struct usb_endpoint_instance *endpoint) +{ + unsigned int size = 0, epnumber = + endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK; + struct urb *urb = endpoint->tx_urb; + + outb(epnumber, UDC_INDEX); + if (urb) { + if ((size = + MIN(urb->actual_length - endpoint->sent, + endpoint->tx_packetSize))) { + musb_fifo_write(epnumber, urb->buffer + endpoint->sent, + size); + } + endpoint->last = size; + endpoint->state = 1; /* Transmit hardware is busy */ + + outw(inw(UDC_TXCSR) | 0x1, UDC_TXCSR); /* Transmit packet */ + } +} + + +static void musb_tx_handler(struct usb_endpoint_instance *endpoint) +{ + unsigned int epnumber = + endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK; + u16 txcsr; + + outb(epnumber, UDC_INDEX); + + /* Check errors */ + txcsr = inw(UDC_TXCSR); + + if (txcsr & 0x4) { /* Clear underrun */ + txcsr &= ~0x4; + } + if (txcsr & 0x20) { /* SENTSTALL */ + outw(txcsr & ~0x20, UDC_TXCSR); /* Clear stall */ + serial_printf("musb_tx_handler: SENTSTALL, txcsr 0x%hx\n", + txcsr); + return; + } + + if (endpoint->tx_urb && !(txcsr & 0x1)) { /* The packet was send? */ + if ((endpoint->sent + endpoint->last == endpoint->tx_urb-> + actual_length) /* Send a zero length packet? */ + && (endpoint->last == endpoint->tx_packetSize)) { + /* Prepare to transmit a zero-length packet. */ + endpoint->sent += endpoint->last; + musb_ep_tx(endpoint); + } else if (endpoint->tx_urb->actual_length) { + /* retire the data that was just sent */ + usbd_tx_complete(endpoint); + endpoint->state = 0; /* Transmit hardware is free */ + + /* + * Check to see if we have more data ready to transmit + * now. + */ + if (endpoint->tx_urb && endpoint->tx_urb-> + actual_length) { + musb_ep_tx(endpoint); + } + } + } +} + +static void musb_rx_handler(struct usb_endpoint_instance *endpoint) +{ + unsigned int epnumber = + endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK; + u16 rxcsr; + u16 length; + + outb(epnumber, UDC_INDEX); + + /* Check errors */ + rxcsr = inw(UDC_RXCSR); + + if (!(rxcsr & 0x1)) /* There is a package received? */ + return; + + if (rxcsr & 0x40) { /* SENTSTALL */ + outw(rxcsr & ~0x40, UDC_RXCSR); /* Clear stall */ + serial_printf("musb_rx_handler: SENTSTALL, rxcsr 0x%hx\n", + rxcsr); + return; + } + + length = inw(UDC_RXCOUNT); + + if (endpoint->rcv_urb) { + /* Receiving data */ + if (length) { + musb_fifo_read(epnumber, &endpoint->rcv_urb-> + buffer[endpoint->rcv_urb->actual_length], + length); + outw(rxcsr & ~0x1, UDC_RXCSR); /* Clear RXPKTRDY */ + usbd_rcv_complete(endpoint, length, 0); + } + } else { + serial_printf("%s: no receive URB!\n", __FUNCTION__); + } +} + +static void musb_reset(void) +{ + usbd_device_event_irq(udc_device, DEVICE_HUB_CONFIGURED, 0); + usbd_device_event_irq(udc_device, DEVICE_RESET, 0); + ep0status = IDLE; + do_set_address = 0; +} + +/* Public functions - called by usbdcore, usbtty, etc. */ +void udc_irq(void) +{ + unsigned char int_usb = inb(UDC_INTRUSB); + unsigned short int_tx = inw(UDC_INTRTX); + unsigned short int_rx = inw(UDC_INTRRX); + int ep; + + if (int_usb) { + if (int_usb & 0x4) { /* Reset */ + /* The controller clears FADDR, INDEX, and FIFOs */ + musb_reset(); + } + if (int_usb & 0x20) { /* Disconnected */ + usbd_device_event_irq(udc_device, DEVICE_HUB_RESET, 0); + } + if (int_usb & 0x1) + usbd_device_event_irq(udc_device, + DEVICE_BUS_INACTIVE, 0); + if (int_usb & 0x2) + usbd_device_event_irq(udc_device, + DEVICE_BUS_ACTIVITY, 0); + } + + /* Note: IRQ values auto clear so read just before processing */ + if (int_rx) { /* OUT endpoints */ + ep = 1; + int_rx >>= 1; + while (int_rx) { + if (int_rx & 1) + musb_rx_handler(udc_device->bus->endpoint_array + + ep); + int_rx >>= 1; + ep++; + } + } + if (int_tx) { /* IN endpoints */ + if (int_tx & 1) + musb_ep0_handler(udc_device->bus->endpoint_array); + + ep = 1; + int_tx >>= 1; + while (int_tx) { + if (int_tx & 1) + musb_tx_handler(udc_device->bus->endpoint_array + + ep); + int_tx >>= 1; + ep++; + } + } +} + +/* Turn on the USB connection */ +void udc_connect(void) +{ + outb(0x1, UDC_DEVCTL); + + if (!(inb(UDC_DEVCTL) & 0x80)) { + serial_printf("Error, the USB hardware is not on B mode\n"); + outb(0x0, UDC_DEVCTL); + return; + } +} + +/* Turn off the USB connection */ +void udc_disconnect(void) +{ + if (!(inb(UDC_DEVCTL) & 0x80)) { + serial_printf("Error, the USB hardware is not on B mode"); + return; + } + + outb(0x0, UDC_DEVCTL); +} + +int udc_endpoint_write(struct usb_endpoint_instance *endpoint) +{ + /* Transmit only if the hardware is available */ + if (endpoint->tx_urb && endpoint->state == 0) + musb_ep_tx(endpoint); + + return 0; +} + +/* + * udc_setup_ep - setup endpoint + * + * Associate a physical endpoint with endpoint_instance + */ +void udc_setup_ep(struct usb_device_instance *device, unsigned int ep, + struct usb_endpoint_instance *endpoint) +{ + int ep_addr; + int attributes; + + /* + * We dont' have a way to identify if the endpoint definitions changed, + * so we have to always reconfigure the FIFOs to avoid problems + */ + musb_fifos_configure(device); + + ep_addr = endpoint->endpoint_address; + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { + /* IN endpoint */ + attributes = endpoint->tx_attributes; + } else { + /* OUT endpoint */ + attributes = endpoint->rcv_attributes; + } + + outb(ep & 0xF, UDC_INDEX); + if ((ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { + /* IN endpoint */ + if (!ep) { /* This only apply for ep != 0 */ + /* Empty fifo twice on case of previous double buffer */ + outw(1<<3, UDC_TXCSR); + outw(1<<3, UDC_TXCSR); + + if (attributes & USB_ENDPOINT_XFER_ISOC) + outw(inw(UDC_TXCSR) | (1 << 13) | (1 << 14) | + 0x4, UDC_TXCSR); + else + outw((inw(UDC_TXCSR) | (1 << 13) | 0x4) & + ~(1 << 14), UDC_TXCSR); + } + /* Enable interrupt */ + outw(inw(UDC_INTRTXE) | (1 << ep), UDC_INTRTXE); + } else { + /* OUT endpoint */ + if (!ep) { /* This only apply for ep != 0 */ + if (attributes & USB_ENDPOINT_XFER_ISOC) + outw((inw(UDC_RXCSR) | (1 << 14)) & ~(1 << 13), + UDC_RXCSR); + else + outw(inw(UDC_RXCSR) & ~(1 << 14) & ~(1 << 13), + UDC_RXCSR); + } + /* Enable interrupt */ + outw(inw(UDC_INTRRXE) | (1 << ep), UDC_INTRRXE); + } +} + +/* + * udc_startup_events - 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 MUSB client controller has the capability to detect when the + * USB cable is connected to a powered USB bus, so we will defer the + * DEVICE_HUB_CONFIGURED and DEVICE_RESET events until later. + */ + + /* 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); + } + + /* Enable control interrupts */ + outb(0xf7, UDC_INTRUSBE); +} + +void udc_set_nak(int epid) +{ +/* + * On MUSB the NAKing is controlled by the USB controller buffers, + * so as long as we don't read data from the FIFO, the controller will NAK. + * Nothing to see here, move along... + */ +} + +void udc_unset_nak(int epid) +{ +/* + * On MUSB the NAKing is controlled by the USB controller buffers, + * so as long as we don't read data from the FIFO, the controller will NAK. + * Nothing to see here, move along... + */ +} + +/* Start to initialize h/w stuff */ +int udc_init(void) +{ + /* Clock is initialized on the board code */ + +#if 0 + /* XXX: this is platform specific, move to udc_musb_platform_init */ + /* MUSB soft-reset */ + outl(2, UDC_SYSCONFIG); + /* MUSB end any previous session */ + outb(0x0, UDC_DEVCTL); +#endif + + if (udc_musb_platform_init()) { + serial_printf("udc_init: platform init failed\n"); + return -1; + } + +#if 0 + /* XXX: this is platform specific, move to udc_musb_platform_init */ + outl(inl(UDC_FORCESTDBY) & ~1, UDC_FORCESTDBY); /* disable MSTANDBY */ + outl(inl(UDC_SYSCONFIG) | (2<<12), UDC_SYSCONFIG); /* ena SMARTSTDBY */ + outl(inl(UDC_SYSCONFIG) & ~1, UDC_SYSCONFIG); /* disable AUTOIDLE */ + outl(inl(UDC_SYSCONFIG) | (2<<3), UDC_SYSCONFIG); /* enable SMARTIDLE */ + outl(inl(UDC_SYSCONFIG) | 1, UDC_SYSCONFIG); /* enable AUTOIDLE */ + + /* Configure the PHY as PHY interface is 12-pin, 8-bit SDR ULPI */ + sr32((void *)UDC_INTERFSEL, 0, 1, 1); +#endif + +#if 0 + /* Turn off interrupts */ + outw(0x00, UDC_INTRTXE); + outw(0x00, UDC_INTRRXE); + +#if CONFIG_MUSB_FULL_SPEED + /* + * Use Full speed for debugging proposes, useful so most USB + * analyzers can catch the transactions + */ + outb(0, UDC_POWER); + serial_printf("MUSB: using full speed\n"); +#else + serial_printf("MUSB: using high speed\n"); +#endif +#endif + + return 0; +} |