/*
 * Mentor USB OTG Core host controller driver.
 *
 * Copyright (c) 2008 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
 *
 * Author: Thomas Abraham t-abraham@ti.com, Texas Instruments
 */

#include <common.h>
#include <usb.h>
#include "musb_hcd.h"

/* MSC control transfers */
#define USB_MSC_BBB_RESET 	0xFF
#define USB_MSC_BBB_GET_MAX_LUN	0xFE

/* Endpoint configuration information */
static const struct musb_epinfo epinfo[3] = {
	{MUSB_BULK_EP, 1, 512}, /* EP1 - Bluk Out - 512 Bytes */
	{MUSB_BULK_EP, 0, 512}, /* EP1 - Bluk In  - 512 Bytes */
	{MUSB_INTR_EP, 0, 64}   /* EP2 - Interrupt IN - 64 Bytes */
};

/* --- Virtual Root Hub ---------------------------------------------------- */
#ifdef MUSB_NO_MULTIPOINT
static int rh_devnum;
static u32 port_status;

/* Device descriptor */
static const u8 root_hub_dev_des[] = {
	0x12,			/*  __u8  bLength; */
	0x01,			/*  __u8  bDescriptorType; Device */
	0x00,			/*  __u16 bcdUSB; v1.1 */
	0x02,
	0x09,			/*  __u8  bDeviceClass; HUB_CLASSCODE */
	0x00,			/*  __u8  bDeviceSubClass; */
	0x00,			/*  __u8  bDeviceProtocol; */
	0x08,			/*  __u8  bMaxPacketSize0; 8 Bytes */
	0x00,			/*  __u16 idVendor; */
	0x00,
	0x00,			/*  __u16 idProduct; */
	0x00,
	0x00,			/*  __u16 bcdDevice; */
	0x00,
	0x00,			/*  __u8  iManufacturer; */
	0x01,			/*  __u8  iProduct; */
	0x00,			/*  __u8  iSerialNumber; */
	0x01			/*  __u8  bNumConfigurations; */
};

/* Configuration descriptor */
static const u8 root_hub_config_des[] = {
	0x09,			/*  __u8  bLength; */
	0x02,			/*  __u8  bDescriptorType; Configuration */
	0x19,			/*  __u16 wTotalLength; */
	0x00,
	0x01,			/*  __u8  bNumInterfaces; */
	0x01,			/*  __u8  bConfigurationValue; */
	0x00,			/*  __u8  iConfiguration; */
	0x40,			/*  __u8  bmAttributes;
				   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
	0x00,			/*  __u8  MaxPower; */

	/* interface */
	0x09,			/*  __u8  if_bLength; */
	0x04,			/*  __u8  if_bDescriptorType; Interface */
	0x00,			/*  __u8  if_bInterfaceNumber; */
	0x00,			/*  __u8  if_bAlternateSetting; */
	0x01,			/*  __u8  if_bNumEndpoints; */
	0x09,			/*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
	0x00,			/*  __u8  if_bInterfaceSubClass; */
	0x00,			/*  __u8  if_bInterfaceProtocol; */
	0x00,			/*  __u8  if_iInterface; */

	/* endpoint */
	0x07,			/*  __u8  ep_bLength; */
	0x05,			/*  __u8  ep_bDescriptorType; Endpoint */
	0x81,			/*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
	0x03,			/*  __u8  ep_bmAttributes; Interrupt */
	0x00,			/*  __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
	0x02,
	0xff			/*  __u8  ep_bInterval; 255 ms */
};

static const unsigned char root_hub_str_index0[] = {
	0x04,			/*  __u8  bLength; */
	0x03,			/*  __u8  bDescriptorType; String-descriptor */
	0x09,			/*  __u8  lang ID */
	0x04,			/*  __u8  lang ID */
};

static const unsigned char root_hub_str_index1[] = {
	0x1c,			/*  __u8  bLength; */
	0x03,			/*  __u8  bDescriptorType; String-descriptor */
	'M',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'U',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'S',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'B',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	' ',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'R',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'o',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'o',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	't',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	' ',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'H',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'u',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
	'b',			/*  __u8  Unicode */
	0,			/*  __u8  Unicode */
};
#endif

/*
 * This function writes the data toggle value.
 */
static void write_toggle(struct usb_device *dev, u8 ep, u8 dir_out)
{
	u16 toggle = usb_gettoggle(dev, ep, dir_out);
	u16 csr;

	if (dir_out) {
		csr = readw(&musbr->txcsr);
		if (!toggle) {
			if (csr & MUSB_TXCSR_MODE)
				csr = MUSB_TXCSR_CLRDATATOG;
			else
				csr = 0;
			writew(csr, &musbr->txcsr);
		} else {
			csr |= MUSB_TXCSR_H_WR_DATATOGGLE;
			writew(csr, &musbr->txcsr);
			csr |= (toggle << MUSB_TXCSR_H_DATATOGGLE_SHIFT);
			writew(csr, &musbr->txcsr);
		}
	} else {
		if (!toggle) {
			csr = readw(&musbr->txcsr);
			if (csr & MUSB_TXCSR_MODE)
				csr = MUSB_RXCSR_CLRDATATOG;
			else
				csr = 0;
			writew(csr, &musbr->rxcsr);
		} else {
			csr = readw(&musbr->rxcsr);
			csr |= MUSB_RXCSR_H_WR_DATATOGGLE;
			writew(csr, &musbr->rxcsr);
			csr |= (toggle << MUSB_S_RXCSR_H_DATATOGGLE);
			writew(csr, &musbr->rxcsr);
		}
	}
}

/*
 * This function checks if RxStall has occured on the endpoint. If a RxStall
 * has occured, the RxStall is cleared and 1 is returned. If RxStall has
 * not occured, 0 is returned.
 */
static u8 check_stall(u8 ep, u8 dir_out)
{
	u16 csr;

	/* For endpoint 0 */
	if (!ep) {
		csr = readw(&musbr->txcsr);
		if (csr & MUSB_CSR0_H_RXSTALL) {
			csr &= ~MUSB_CSR0_H_RXSTALL;
			writew(csr, &musbr->txcsr);
			return 1;
		}
	} else { /* For non-ep0 */
		if (dir_out) { /* is it tx ep */
			csr = readw(&musbr->txcsr);
			if (csr & MUSB_TXCSR_H_RXSTALL) {
				csr &= ~MUSB_TXCSR_H_RXSTALL;
				writew(csr, &musbr->txcsr);
				return 1;
			}
		} else { /* is it rx ep */
			csr = readw(&musbr->rxcsr);
			if (csr & MUSB_RXCSR_H_RXSTALL) {
				csr &= ~MUSB_RXCSR_H_RXSTALL;
				writew(csr, &musbr->rxcsr);
				return 1;
			}
		}
	}
	return 0;
}

/*
 * waits until ep0 is ready. Returns 0 if ep is ready, -1 for timeout
 * error and -2 for stall.
 */
static int wait_until_ep0_ready(struct usb_device *dev, u32 bit_mask)
{
	u16 csr;
	int result = 1;
	int timeout = CONFIG_MUSB_TIMEOUT;

	while (result > 0) {
		csr = readw(&musbr->txcsr);
		if (csr & MUSB_CSR0_H_ERROR) {
			csr &= ~MUSB_CSR0_H_ERROR;
			writew(csr, &musbr->txcsr);
			dev->status = USB_ST_CRC_ERR;
			result = -1;
			break;
		}

		switch (bit_mask) {
		case MUSB_CSR0_TXPKTRDY:
			if (!(csr & MUSB_CSR0_TXPKTRDY)) {
				if (check_stall(MUSB_CONTROL_EP, 0)) {
					dev->status = USB_ST_STALLED;
					result = -2;
				} else
					result = 0;
			}
			break;

		case MUSB_CSR0_RXPKTRDY:
			if (check_stall(MUSB_CONTROL_EP, 0)) {
				dev->status = USB_ST_STALLED;
				result = -2;
			} else
				if (csr & MUSB_CSR0_RXPKTRDY)
					result = 0;
			break;

		case MUSB_CSR0_H_REQPKT:
			if (!(csr & MUSB_CSR0_H_REQPKT)) {
				if (check_stall(MUSB_CONTROL_EP, 0)) {
					dev->status = USB_ST_STALLED;
					result = -2;
				} else
					result = 0;
			}
			break;
		}

		/* Check the timeout */
		if (--timeout)
			udelay(1);
		else {
			dev->status = USB_ST_CRC_ERR;
			result = -1;
			break;
		}
	}

	return result;
}

/*
 * waits until tx ep is ready. Returns 1 when ep is ready and 0 on error.
 */
static u8 wait_until_txep_ready(struct usb_device *dev, u8 ep)
{
	u16 csr;
	int timeout = CONFIG_MUSB_TIMEOUT;

	do {
		if (check_stall(ep, 1)) {
			dev->status = USB_ST_STALLED;
			return 0;
		}

		csr = readw(&musbr->txcsr);
		if (csr & MUSB_TXCSR_H_ERROR) {
			dev->status = USB_ST_CRC_ERR;
			return 0;
		}

		/* Check the timeout */
		if (--timeout)
			udelay(1);
		else {
			dev->status = USB_ST_CRC_ERR;
			return -1;
		}

	} while (csr & MUSB_TXCSR_TXPKTRDY);
	return 1;
}

/*
 * waits until rx ep is ready. Returns 1 when ep is ready and 0 on error.
 */
static u8 wait_until_rxep_ready(struct usb_device *dev, u8 ep)
{
	u16 csr;
	int timeout = CONFIG_MUSB_TIMEOUT;

	do {
		if (check_stall(ep, 0)) {
			dev->status = USB_ST_STALLED;
			return 0;
		}

		csr = readw(&musbr->rxcsr);
		if (csr & MUSB_RXCSR_H_ERROR) {
			dev->status = USB_ST_CRC_ERR;
			return 0;
		}

		/* Check the timeout */
		if (--timeout)
			udelay(1);
		else {
			dev->status = USB_ST_CRC_ERR;
			return -1;
		}

	} while (!(csr & MUSB_RXCSR_RXPKTRDY));
	return 1;
}

/*
 * This function performs the setup phase of the control transfer
 */
static int ctrlreq_setup_phase(struct usb_device *dev, struct devrequest *setup)
{
	int result;
	u16 csr;

	/* write the control request to ep0 fifo */
	write_fifo(MUSB_CONTROL_EP, sizeof(struct devrequest), (void *)setup);

	/* enable transfer of setup packet */
	csr = readw(&musbr->txcsr);
	csr |= (MUSB_CSR0_TXPKTRDY|MUSB_CSR0_H_SETUPPKT);
	writew(csr, &musbr->txcsr);

	/* wait until the setup packet is transmitted */
	result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
	dev->act_len = 0;
	return result;
}

/*
 * This function handles the control transfer in data phase
 */
static int ctrlreq_in_data_phase(struct usb_device *dev, u32 len, void *buffer)
{
	u16 csr;
	u32 rxlen = 0;
	u32 nextlen = 0;
	u8  maxpktsize = (1 << dev->maxpacketsize) * 8;
	u8  *rxbuff = (u8 *)buffer;
	u8  rxedlength;
	int result;

	while (rxlen < len) {
		/* Determine the next read length */
		nextlen = ((len-rxlen) > maxpktsize) ? maxpktsize : (len-rxlen);

		/* Set the ReqPkt bit */
		csr = readw(&musbr->txcsr);
		writew(csr | MUSB_CSR0_H_REQPKT, &musbr->txcsr);
		result = wait_until_ep0_ready(dev, MUSB_CSR0_RXPKTRDY);
		if (result < 0)
			return result;

		/* Actual number of bytes received by usb */
		rxedlength = readb(&musbr->rxcount);

		/* Read the data from the RxFIFO */
		read_fifo(MUSB_CONTROL_EP, rxedlength, &rxbuff[rxlen]);

		/* Clear the RxPktRdy Bit */
		csr = readw(&musbr->txcsr);
		csr &= ~MUSB_CSR0_RXPKTRDY;
		writew(csr, &musbr->txcsr);

		/* short packet? */
		if (rxedlength != nextlen) {
			dev->act_len += rxedlength;
			break;
		}
		rxlen += nextlen;
		dev->act_len = rxlen;
	}
	return 0;
}

/*
 * This function handles the control transfer out data phase
 */
static int ctrlreq_out_data_phase(struct usb_device *dev, u32 len, void *buffer)
{
	u16 csr;
	u32 txlen = 0;
	u32 nextlen = 0;
	u8  maxpktsize = (1 << dev->maxpacketsize) * 8;
	u8  *txbuff = (u8 *)buffer;
	int result = 0;

	while (txlen < len) {
		/* Determine the next write length */
		nextlen = ((len-txlen) > maxpktsize) ? maxpktsize : (len-txlen);

		/* Load the data to send in FIFO */
		write_fifo(MUSB_CONTROL_EP, txlen, &txbuff[txlen]);

		/* Set TXPKTRDY bit */
		csr = readw(&musbr->txcsr);
		writew(csr | MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY,
					&musbr->txcsr);
		result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
		if (result < 0)
			break;

		txlen += nextlen;
		dev->act_len = txlen;
	}
	return result;
}

/*
 * This function handles the control transfer out status phase
 */
static int ctrlreq_out_status_phase(struct usb_device *dev)
{
	u16 csr;
	int result;

	/* Set the StatusPkt bit */
	csr = readw(&musbr->txcsr);
	csr |= (MUSB_CSR0_H_DIS_PING | MUSB_CSR0_TXPKTRDY |
			MUSB_CSR0_H_STATUSPKT);
	writew(csr, &musbr->txcsr);

	/* Wait until TXPKTRDY bit is cleared */
	result = wait_until_ep0_ready(dev, MUSB_CSR0_TXPKTRDY);
	return result;
}

/*
 * This function handles the control transfer in status phase
 */
static int ctrlreq_in_status_phase(struct usb_device *dev)
{
	u16 csr;
	int result;

	/* Set the StatusPkt bit and ReqPkt bit */
	csr = MUSB_CSR0_H_DIS_PING | MUSB_CSR0_H_REQPKT | MUSB_CSR0_H_STATUSPKT;
	writew(csr, &musbr->txcsr);
	result = wait_until_ep0_ready(dev, MUSB_CSR0_H_REQPKT);

	/* clear StatusPkt bit and RxPktRdy bit */
	csr = readw(&musbr->txcsr);
	csr &= ~(MUSB_CSR0_RXPKTRDY | MUSB_CSR0_H_STATUSPKT);
	writew(csr, &musbr->txcsr);
	return result;
}

/*
 * determines the speed of the device (High/Full/Slow)
 */
static u8 get_dev_speed(struct usb_device *dev)
{
	return (dev->speed == USB_SPEED_HIGH) ? MUSB_TYPE_SPEED_HIGH :
		((dev->speed == USB_SPEED_LOW) ? MUSB_TYPE_SPEED_LOW :
						MUSB_TYPE_SPEED_FULL);
}

/*
 * configure the hub address and the port address.
 */
static void config_hub_port(struct usb_device *dev, u8 ep)
{
	u8 chid;
	u8 hub;

	/* Find out the nearest parent which is high speed */
	while (dev->parent->parent != NULL)
		if (get_dev_speed(dev->parent) !=  MUSB_TYPE_SPEED_HIGH)
			dev = dev->parent;
		else
			break;

	/* determine the port address at that hub */
	hub = dev->parent->devnum;
	for (chid = 0; chid < USB_MAXCHILDREN; chid++)
		if (dev->parent->children[chid] == dev)
			break;

#ifndef MUSB_NO_MULTIPOINT
	/* configure the hub address and the port address */
	writeb(hub, &musbr->tar[ep].txhubaddr);
	writeb((chid + 1), &musbr->tar[ep].txhubport);
	writeb(hub, &musbr->tar[ep].rxhubaddr);
	writeb((chid + 1), &musbr->tar[ep].rxhubport);
#endif
}

#ifdef MUSB_NO_MULTIPOINT

static void musb_port_reset(int do_reset)
{
	u8 power = readb(&musbr->power);

	if (do_reset) {
		power &= 0xf0;
		writeb(power | MUSB_POWER_RESET, &musbr->power);
		port_status |= USB_PORT_STAT_RESET;
		port_status &= ~USB_PORT_STAT_ENABLE;
		udelay(30000);
	} else {
		writeb(power & ~MUSB_POWER_RESET, &musbr->power);

		power = readb(&musbr->power);
		if (power & MUSB_POWER_HSMODE)
			port_status |= USB_PORT_STAT_HIGH_SPEED;

		port_status &= ~(USB_PORT_STAT_RESET | (USB_PORT_STAT_C_CONNECTION << 16));
		port_status |= USB_PORT_STAT_ENABLE
			| (USB_PORT_STAT_C_RESET << 16)
			| (USB_PORT_STAT_C_ENABLE << 16);
	}
}

/*
 * root hub control
 */
static int musb_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
			      void *buffer, int transfer_len,
			      struct devrequest *cmd)
{
	int leni = transfer_len;
	int len = 0;
	int stat = 0;
	u32 datab[4];
	const u8 *data_buf = (u8 *) datab;
	u16 bmRType_bReq;
	u16 wValue;
	u16 wIndex;
	u16 wLength;
	u16 int_usb;

	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
		debug("Root-Hub submit IRQ: NOT implemented\n");
		return 0;
	}

	bmRType_bReq = cmd->requesttype | (cmd->request << 8);
	wValue = swap_16(cmd->value);
	wIndex = swap_16(cmd->index);
	wLength = swap_16(cmd->length);

	debug("--- HUB ----------------------------------------\n");
	debug("submit rh urb, req=%x val=%#x index=%#x len=%d\n",
	    bmRType_bReq, wValue, wIndex, wLength);
	debug("------------------------------------------------\n");

	switch (bmRType_bReq) {
	case RH_GET_STATUS:
		debug("RH_GET_STATUS\n");

		*(__u16 *) data_buf = swap_16(1);
		len = 2;
		break;

	case RH_GET_STATUS | RH_INTERFACE:
		debug("RH_GET_STATUS | RH_INTERFACE\n");

		*(__u16 *) data_buf = swap_16(0);
		len = 2;
		break;

	case RH_GET_STATUS | RH_ENDPOINT:
		debug("RH_GET_STATUS | RH_ENDPOINT\n");

		*(__u16 *) data_buf = swap_16(0);
		len = 2;
		break;

	case RH_GET_STATUS | RH_CLASS:
		debug("RH_GET_STATUS | RH_CLASS\n");

		*(__u32 *) data_buf = swap_32(0);
		len = 4;
		break;

	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
		debug("RH_GET_STATUS | RH_OTHER | RH_CLASS\n");

		int_usb = readw(&musbr->intrusb);
		if (int_usb & MUSB_INTR_CONNECT) {
			port_status |= USB_PORT_STAT_CONNECTION
				| (USB_PORT_STAT_C_CONNECTION << 16);
			port_status |= USB_PORT_STAT_HIGH_SPEED
				| USB_PORT_STAT_ENABLE;
		}

		if (port_status & USB_PORT_STAT_RESET)
			musb_port_reset(0);

		*(__u32 *) data_buf = swap_32(port_status);
		len = 4;
		break;

	case RH_CLEAR_FEATURE | RH_ENDPOINT:
		debug("RH_CLEAR_FEATURE | RH_ENDPOINT\n");

		switch (wValue) {
		case RH_ENDPOINT_STALL:
			debug("C_HUB_ENDPOINT_STALL\n");
			len = 0;
			break;
		}
		port_status &= ~(1 << wValue);
		break;

	case RH_CLEAR_FEATURE | RH_CLASS:
		debug("RH_CLEAR_FEATURE | RH_CLASS\n");

		switch (wValue) {
		case RH_C_HUB_LOCAL_POWER:
			debug("C_HUB_LOCAL_POWER\n");
			len = 0;
			break;

		case RH_C_HUB_OVER_CURRENT:
			debug("C_HUB_OVER_CURRENT\n");
			len = 0;
			break;
		}
		port_status &= ~(1 << wValue);
		break;

	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
		debug("RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS\n");

		switch (wValue) {
		case RH_PORT_ENABLE:
			len = 0;
			break;

		case RH_PORT_SUSPEND:
			len = 0;
			break;

		case RH_PORT_POWER:
			len = 0;
			break;

		case RH_C_PORT_CONNECTION:
			len = 0;
			break;

		case RH_C_PORT_ENABLE:
			len = 0;
			break;

		case RH_C_PORT_SUSPEND:
			len = 0;
			break;

		case RH_C_PORT_OVER_CURRENT:
			len = 0;
			break;

		case RH_C_PORT_RESET:
			len = 0;
			break;

		default:
			debug("invalid wValue\n");
			stat = USB_ST_STALLED;
		}

		port_status &= ~(1 << wValue);
		break;

	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
		debug("RH_SET_FEATURE | RH_OTHER | RH_CLASS\n");

		switch (wValue) {
		case RH_PORT_SUSPEND:
			len = 0;
			break;

		case RH_PORT_RESET:
			musb_port_reset(1);
			len = 0;
			break;

		case RH_PORT_POWER:
			len = 0;
			break;

		case RH_PORT_ENABLE:
			len = 0;
			break;

		default:
			debug("invalid wValue\n");
			stat = USB_ST_STALLED;
		}

		port_status |= 1 << wValue;
		break;

	case RH_SET_ADDRESS:
		debug("RH_SET_ADDRESS\n");

		rh_devnum = wValue;
		len = 0;
		break;

	case RH_GET_DESCRIPTOR:
		debug("RH_GET_DESCRIPTOR: %x, %d\n", wValue, wLength);

		switch (wValue) {
		case (USB_DT_DEVICE << 8):	/* device descriptor */
			len = min_t(unsigned int,
				    leni, min_t(unsigned int,
						sizeof(root_hub_dev_des),
						wLength));
			data_buf = root_hub_dev_des;
			break;

		case (USB_DT_CONFIG << 8):	/* configuration descriptor */
			len = min_t(unsigned int,
				    leni, min_t(unsigned int,
						sizeof(root_hub_config_des),
						wLength));
			data_buf = root_hub_config_des;
			break;

		case ((USB_DT_STRING << 8) | 0x00):	/* string 0 descriptors */
			len = min_t(unsigned int,
				    leni, min_t(unsigned int,
						sizeof(root_hub_str_index0),
						wLength));
			data_buf = root_hub_str_index0;
			break;

		case ((USB_DT_STRING << 8) | 0x01):	/* string 1 descriptors */
			len = min_t(unsigned int,
				    leni, min_t(unsigned int,
						sizeof(root_hub_str_index1),
						wLength));
			data_buf = root_hub_str_index1;
			break;

		default:
			debug("invalid wValue\n");
			stat = USB_ST_STALLED;
		}

		break;

	case RH_GET_DESCRIPTOR | RH_CLASS: {
		u8 *_data_buf = (u8 *) datab;
		debug("RH_GET_DESCRIPTOR | RH_CLASS\n");

		_data_buf[0] = 0x09;	/* min length; */
		_data_buf[1] = 0x29;
		_data_buf[2] = 0x1;	/* 1 port */
		_data_buf[3] = 0x01;	/* per-port power switching */
		_data_buf[3] |= 0x10;	/* no overcurrent reporting */

		/* Corresponds to data_buf[4-7] */
		_data_buf[4] = 0;
		_data_buf[5] = 5;
		_data_buf[6] = 0;
		_data_buf[7] = 0x02;
		_data_buf[8] = 0xff;

		len = min_t(unsigned int, leni,
			    min_t(unsigned int, data_buf[0], wLength));
		break;
	}

	case RH_GET_CONFIGURATION:
		debug("RH_GET_CONFIGURATION\n");

		*(__u8 *) data_buf = 0x01;
		len = 1;
		break;

	case RH_SET_CONFIGURATION:
		debug("RH_SET_CONFIGURATION\n");

		len = 0;
		break;

	default:
		debug("*** *** *** unsupported root hub command *** *** ***\n");
		stat = USB_ST_STALLED;
	}

	len = min_t(int, len, leni);
	if (buffer != data_buf)
		memcpy(buffer, data_buf, len);

	dev->act_len = len;
	dev->status = stat;
	debug("dev act_len %d, status %lu\n", dev->act_len, dev->status);

	return stat;
}

static void musb_rh_init(void)
{
	rh_devnum = 0;
	port_status = 0;
}

#else

static void musb_rh_init(void) {}

#endif

/*
 * do a control transfer
 */
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
			int len, struct devrequest *setup)
{
	int devnum = usb_pipedevice(pipe);
	u8  devspeed;

#ifdef MUSB_NO_MULTIPOINT
	/* Control message is for the HUB? */
	if (devnum == rh_devnum) {
		int stat = musb_submit_rh_msg(dev, pipe, buffer, len, setup);
		if (stat)
			return stat;
	}
#endif

	/* select control endpoint */
	writeb(MUSB_CONTROL_EP, &musbr->index);
	readw(&musbr->txcsr);

#ifndef MUSB_NO_MULTIPOINT
	/* target addr and (for multipoint) hub addr/port */
	writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].txfuncaddr);
	writeb(devnum, &musbr->tar[MUSB_CONTROL_EP].rxfuncaddr);
#endif

	/* configure the hub address and the port number as required */
	devspeed = get_dev_speed(dev);
	if ((musb_ishighspeed()) && (dev->parent != NULL) &&
		(devspeed != MUSB_TYPE_SPEED_HIGH)) {
		config_hub_port(dev, MUSB_CONTROL_EP);
		writeb(devspeed << 6, &musbr->txtype);
	} else {
		writeb(musb_cfg.musb_speed << 6, &musbr->txtype);
#ifndef MUSB_NO_MULTIPOINT
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubaddr);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].txhubport);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubaddr);
		writeb(0, &musbr->tar[MUSB_CONTROL_EP].rxhubport);
#endif
	}

	/* Control transfer setup phase */
	if (ctrlreq_setup_phase(dev, setup) < 0)
		return 0;

	switch (setup->request) {
	case USB_REQ_GET_DESCRIPTOR:
	case USB_REQ_GET_CONFIGURATION:
	case USB_REQ_GET_INTERFACE:
	case USB_REQ_GET_STATUS:
	case USB_MSC_BBB_GET_MAX_LUN:
		/* control transfer in-data-phase */
		if (ctrlreq_in_data_phase(dev, len, buffer) < 0)
			return 0;
		/* control transfer out-status-phase */
		if (ctrlreq_out_status_phase(dev) < 0)
			return 0;
		break;

	case USB_REQ_SET_ADDRESS:
	case USB_REQ_SET_CONFIGURATION:
	case USB_REQ_SET_FEATURE:
	case USB_REQ_SET_INTERFACE:
	case USB_REQ_CLEAR_FEATURE:
	case USB_MSC_BBB_RESET:
		/* control transfer in status phase */
		if (ctrlreq_in_status_phase(dev) < 0)
			return 0;
		break;

	case USB_REQ_SET_DESCRIPTOR:
		/* control transfer out data phase */
		if (ctrlreq_out_data_phase(dev, len, buffer) < 0)
			return 0;
		/* control transfer in status phase */
		if (ctrlreq_in_status_phase(dev) < 0)
			return 0;
		break;

	default:
		/* unhandled control transfer */
		return -1;
	}

	dev->status = 0;
	dev->act_len = len;

#ifdef MUSB_NO_MULTIPOINT
	/* Set device address to USB_FADDR register */
	if (setup->request == USB_REQ_SET_ADDRESS)
		writeb(dev->devnum, &musbr->faddr);
#endif

	return len;
}

/*
 * do a bulk transfer
 */
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
					void *buffer, int len)
{
	int dir_out = usb_pipeout(pipe);
	int ep = usb_pipeendpoint(pipe);
#ifndef MUSB_NO_MULTIPOINT
	int devnum = usb_pipedevice(pipe);
#endif
	u8  type;
	u16 csr;
	u32 txlen = 0;
	u32 nextlen = 0;
	u8  devspeed;

	/* select bulk endpoint */
	writeb(MUSB_BULK_EP, &musbr->index);

#ifndef MUSB_NO_MULTIPOINT
	/* write the address of the device */
	if (dir_out)
		writeb(devnum, &musbr->tar[MUSB_BULK_EP].txfuncaddr);
	else
		writeb(devnum, &musbr->tar[MUSB_BULK_EP].rxfuncaddr);
#endif

	/* configure the hub address and the port number as required */
	devspeed = get_dev_speed(dev);
	if ((musb_ishighspeed()) && (dev->parent != NULL) &&
		(devspeed != MUSB_TYPE_SPEED_HIGH)) {
		/*
		 * MUSB is in high speed and the destination device is full
		 * speed device. So configure the hub address and port
		 * address registers.
		 */
		config_hub_port(dev, MUSB_BULK_EP);
	} else {
#ifndef MUSB_NO_MULTIPOINT
		if (dir_out) {
			writeb(0, &musbr->tar[MUSB_BULK_EP].txhubaddr);
			writeb(0, &musbr->tar[MUSB_BULK_EP].txhubport);
		} else {
			writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubaddr);
			writeb(0, &musbr->tar[MUSB_BULK_EP].rxhubport);
		}
#endif
		devspeed = musb_cfg.musb_speed;
	}

	/* Write the saved toggle bit value */
	write_toggle(dev, ep, dir_out);

	if (dir_out) { /* bulk-out transfer */
		/* Program the TxType register */
		type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
			   (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
			   (ep & MUSB_TYPE_REMOTE_END);
		writeb(type, &musbr->txtype);

		/* Write maximum packet size to the TxMaxp register */
		writew(dev->epmaxpacketout[ep], &musbr->txmaxp);
		while (txlen < len) {
			nextlen = ((len-txlen) < dev->epmaxpacketout[ep]) ?
					(len-txlen) : dev->epmaxpacketout[ep];

#ifdef CONFIG_USB_BLACKFIN
			/* Set the transfer data size */
			writew(nextlen, &musbr->txcount);
#endif

			/* Write the data to the FIFO */
			write_fifo(MUSB_BULK_EP, nextlen,
					(void *)(((u8 *)buffer) + txlen));

			/* Set the TxPktRdy bit */
			csr = readw(&musbr->txcsr);
			writew(csr | MUSB_TXCSR_TXPKTRDY, &musbr->txcsr);

			/* Wait until the TxPktRdy bit is cleared */
			if (!wait_until_txep_ready(dev, MUSB_BULK_EP)) {
				readw(&musbr->txcsr);
				usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
				dev->act_len = txlen;
				return 0;
			}
			txlen += nextlen;
		}

		/* Keep a copy of the data toggle bit */
		csr = readw(&musbr->txcsr);
		usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_TXCSR_H_DATATOGGLE_SHIFT) & 1);
	} else { /* bulk-in transfer */
		/* Write the saved toggle bit value */
		write_toggle(dev, ep, dir_out);

		/* Program the RxType register */
		type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
			   (MUSB_TYPE_PROTO_BULK << MUSB_TYPE_PROTO_SHIFT) |
			   (ep & MUSB_TYPE_REMOTE_END);
		writeb(type, &musbr->rxtype);

		/* Write the maximum packet size to the RxMaxp register */
		writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);
		while (txlen < len) {
			nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
					(len-txlen) : dev->epmaxpacketin[ep];

			/* Set the ReqPkt bit */
			csr = readw(&musbr->rxcsr);
			writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);

			/* Wait until the RxPktRdy bit is set */
			if (!wait_until_rxep_ready(dev, MUSB_BULK_EP)) {
				csr = readw(&musbr->rxcsr);
				usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
				csr &= ~MUSB_RXCSR_RXPKTRDY;
				writew(csr, &musbr->rxcsr);
				dev->act_len = txlen;
				return 0;
			}

			/* Read the data from the FIFO */
			read_fifo(MUSB_BULK_EP, nextlen,
					(void *)(((u8 *)buffer) + txlen));

			/* Clear the RxPktRdy bit */
			csr =  readw(&musbr->rxcsr);
			csr &= ~MUSB_RXCSR_RXPKTRDY;
			writew(csr, &musbr->rxcsr);
			txlen += nextlen;
		}

		/* Keep a copy of the data toggle bit */
		csr = readw(&musbr->rxcsr);
		usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
	}

	/* bulk transfer is complete */
	dev->status = 0;
	dev->act_len = len;
	return 0;
}

/*
 * This function initializes the usb controller module.
 */
int usb_lowlevel_init(int index, void **controller)
{
	u8  power;
	u32 timeout;

	musb_rh_init();

	if (musb_platform_init() == -1)
		return -1;

	/* Configure all the endpoint FIFO's and start usb controller */
	musbr = musb_cfg.regs;
	musb_configure_ep(&epinfo[0],
			sizeof(epinfo) / sizeof(struct musb_epinfo));
	musb_start();

	/*
	 * Wait until musb is enabled in host mode with a timeout. There
	 * should be a usb device connected.
	 */
	timeout = musb_cfg.timeout;
	while (--timeout)
		if (readb(&musbr->devctl) & MUSB_DEVCTL_HM)
			break;

	/* if musb core is not in host mode, then return */
	if (!timeout)
		return -1;

	/* start usb bus reset */
	power = readb(&musbr->power);
	writeb(power | MUSB_POWER_RESET, &musbr->power);

	/* After initiating a usb reset, wait for about 20ms to 30ms */
	udelay(30000);

	/* stop usb bus reset */
	power = readb(&musbr->power);
	power &= ~MUSB_POWER_RESET;
	writeb(power, &musbr->power);

	/* Determine if the connected device is a high/full/low speed device */
	musb_cfg.musb_speed = (readb(&musbr->power) & MUSB_POWER_HSMODE) ?
			MUSB_TYPE_SPEED_HIGH :
			((readb(&musbr->devctl) & MUSB_DEVCTL_FSDEV) ?
			MUSB_TYPE_SPEED_FULL : MUSB_TYPE_SPEED_LOW);
	return 0;
}

/*
 * This function stops the operation of the davinci usb module.
 */
int usb_lowlevel_stop(int index)
{
	/* Reset the USB module */
	musb_platform_deinit();
	writeb(0, &musbr->devctl);
	return 0;
}

/*
 * This function supports usb interrupt transfers. Currently, usb interrupt
 * transfers are not supported.
 */
int submit_int_msg(struct usb_device *dev, unsigned long pipe,
				void *buffer, int len, int interval)
{
	int dir_out = usb_pipeout(pipe);
	int ep = usb_pipeendpoint(pipe);
#ifndef MUSB_NO_MULTIPOINT
	int devnum = usb_pipedevice(pipe);
#endif
	u8  type;
	u16 csr;
	u32 txlen = 0;
	u32 nextlen = 0;
	u8  devspeed;

	/* select interrupt endpoint */
	writeb(MUSB_INTR_EP, &musbr->index);

#ifndef MUSB_NO_MULTIPOINT
	/* write the address of the device */
	if (dir_out)
		writeb(devnum, &musbr->tar[MUSB_INTR_EP].txfuncaddr);
	else
		writeb(devnum, &musbr->tar[MUSB_INTR_EP].rxfuncaddr);
#endif

	/* configure the hub address and the port number as required */
	devspeed = get_dev_speed(dev);
	if ((musb_ishighspeed()) && (dev->parent != NULL) &&
		(devspeed != MUSB_TYPE_SPEED_HIGH)) {
		/*
		 * MUSB is in high speed and the destination device is full
		 * speed device. So configure the hub address and port
		 * address registers.
		 */
		config_hub_port(dev, MUSB_INTR_EP);
	} else {
#ifndef MUSB_NO_MULTIPOINT
		if (dir_out) {
			writeb(0, &musbr->tar[MUSB_INTR_EP].txhubaddr);
			writeb(0, &musbr->tar[MUSB_INTR_EP].txhubport);
		} else {
			writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubaddr);
			writeb(0, &musbr->tar[MUSB_INTR_EP].rxhubport);
		}
#endif
		devspeed = musb_cfg.musb_speed;
	}

	/* Write the saved toggle bit value */
	write_toggle(dev, ep, dir_out);

	if (!dir_out) { /* intrrupt-in transfer */
		/* Write the saved toggle bit value */
		write_toggle(dev, ep, dir_out);
		writeb(interval, &musbr->rxinterval);

		/* Program the RxType register */
		type = (devspeed << MUSB_TYPE_SPEED_SHIFT) |
			   (MUSB_TYPE_PROTO_INTR << MUSB_TYPE_PROTO_SHIFT) |
			   (ep & MUSB_TYPE_REMOTE_END);
		writeb(type, &musbr->rxtype);

		/* Write the maximum packet size to the RxMaxp register */
		writew(dev->epmaxpacketin[ep], &musbr->rxmaxp);

		while (txlen < len) {
			nextlen = ((len-txlen) < dev->epmaxpacketin[ep]) ?
					(len-txlen) : dev->epmaxpacketin[ep];

			/* Set the ReqPkt bit */
			csr = readw(&musbr->rxcsr);
			writew(csr | MUSB_RXCSR_H_REQPKT, &musbr->rxcsr);

			/* Wait until the RxPktRdy bit is set */
			if (!wait_until_rxep_ready(dev, MUSB_INTR_EP)) {
				csr = readw(&musbr->rxcsr);
				usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
				csr &= ~MUSB_RXCSR_RXPKTRDY;
				writew(csr, &musbr->rxcsr);
				dev->act_len = txlen;
				return 0;
			}

			/* Read the data from the FIFO */
			read_fifo(MUSB_INTR_EP, nextlen,
					(void *)(((u8 *)buffer) + txlen));

			/* Clear the RxPktRdy bit */
			csr =  readw(&musbr->rxcsr);
			csr &= ~MUSB_RXCSR_RXPKTRDY;
			writew(csr, &musbr->rxcsr);
			txlen += nextlen;
		}

		/* Keep a copy of the data toggle bit */
		csr = readw(&musbr->rxcsr);
		usb_settoggle(dev, ep, dir_out,
				(csr >> MUSB_S_RXCSR_H_DATATOGGLE) & 1);
	}

	/* interrupt transfer is complete */
	dev->irq_status = 0;
	dev->irq_act_len = len;
	dev->irq_handle(dev);
	dev->status = 0;
	dev->act_len = len;
	return 0;
}
