/*
 * 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;
}
