/*
 * Mentor USB OTG Core host controller driver.
 *
 * Copyright (c) 2008 Texas Instruments
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 * 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 int 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 int 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);
			
		csr |= MUSB_CSR0_TXPKTRDY;
#if !defined(CONFIG_SOC_DM365)
		csr |= MUSB_CSR0_H_DIS_PING;
#endif
		writew(csr, &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_TXPKTRDY | MUSB_CSR0_H_STATUSPKT);
#if !defined(CONFIG_SOC_DM365)
	csr |= MUSB_CSR0_H_DIS_PING;
#endif
	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_REQPKT | MUSB_CSR0_H_STATUSPKT;
#if !defined(CONFIG_SOC_DM365)
	csr |= MUSB_CSR0_H_DIS_PING;
#endif
	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) != 1) {
				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) != 1) {
				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, enum usb_init_type init, 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], ARRAY_SIZE(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) != 1) {
				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;
}
