/*
 * 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)
 *
 * -------------------------------------------------------------------------
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <usbdevice.h>
#include <usb/udc.h>
#include "../gadget/ep0.h"
#include "musb_core.h"
#if defined(CONFIG_USB_OMAP3)
#include "omap3.h"
#elif defined(CONFIG_USB_AM35X)
#include "am35x.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;

	/* Power off MUSB */
	power = readb(&musbr->power);
	power &= ~MUSB_POWER_SOFTCONN;
	writeb(power, &musbr->power);

	/* Read intr to clear */
	readb(&musbr->intrusb);
	readw(&musbr->intrrx);
	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;
	u8 peri_rxcsr = readw(&musbr->ep[ep].epN.rxcsr);

	if (!(peri_rxcsr & MUSB_RXCSR_RXPKTRDY)) {
		if (debug_level > 0)
			serial_printf("ERROR : %s %d without MUSB_RXCSR_RXPKTRDY set\n",
				      __PRETTY_FUNCTION__, ep);
		return;
	}

	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], ARRAY_SIZE(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;
}
