/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/* This file implements the UDC (usb device controller) layer to be used with
 * the new dwc controller.
 * It exposes APIs to initialize UDC (and thus usb) and perform data transfer
 * over usb.
 */

#include <reg.h>
#include <debug.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <arch/defines.h>
#include <dev/udc.h>
#include <platform/iomap.h>
#include <usb30_dwc.h>
#include <usb30_wrapper.h>
#include <usb30_udc.h>

//#define DEBUG_USB

#ifdef DEBUG_USB
#define DBG(...) dprintf(ALWAYS, __VA_ARGS__)
#else
#define DBG(...)
#endif

#define ERR(...) dprintf(ALWAYS, __VA_ARGS__)

/* control data transfer is max 512 bytes */
#define UDC_CONTROL_RX_BUF_SIZE     512
#define UDC_CONTROL_TX_BUF_SIZE     512

/* Buffer used by dwc driver to process events.
 * Must be multiple of 4: snps 6.2.7.2.
 */
#define UDC_DWC_EVENT_BUF_SIZE     4096

/* macro to parse setup request */
#define SETUP(type,request) (((type) << 8) | (request))

/* macro to generate bit representation of an EP */
#define EPT_TX(n) (1 << ((n) + 16))
#define EPT_RX(n) (1 << (n))

/* Local functions */
static struct udc_descriptor *udc_descriptor_alloc(uint32_t type,
												   uint32_t num,
												   uint32_t len,
												   udc_desc_spec_t spec);
static uint8_t udc_string_desc_alloc(udc_t *udc, const char *str);

static void udc_descriptor_register(udc_t *udc, struct udc_descriptor *desc);
static void udc_register_language_desc(udc_t *udc);
static void udc_register_bos_desc(udc_t *udc);
static void udc_register_device_desc_usb_20(udc_t *udc, struct udc_device *dev_info);
static void udc_register_device_desc_usb_30(udc_t *udc, struct udc_device *dev_info);
static void udc_register_config_desc_usb20(udc_t *udc, struct udc_gadget *gadget);
static void udc_register_config_desc_usb30(udc_t *udc, struct udc_gadget *gadget);

static void udc_ept_desc_fill(struct udc_endpoint *ept, uint8_t *data);
static void udc_ept_comp_desc_fill(struct udc_endpoint *ept, uint8_t *data);

static void udc_dwc_notify(void *context, dwc_notify_event_t event);
static int udc_handle_setup(void *context, uint8_t *data);

/* TODO: This must be the only global var in this file, for now.
 * Ideally, all APIs should be sending
 * this to us and this ptr should be kept outside of this code.
 * This needs change in the common udc APIs and thus keeping it here until that
 * is done.
 */
static udc_t *udc_dev = NULL;


/* TODO: need to find right place for the tcsr functions. */

/* UTMI MUX configuration to connect PHY to SNPS controller:
 * Configure primary HS phy mux to use UTMI interface
 * (connected to usb30 controller).
 */
void tcsr_hs_phy_mux_configure(void)
{
	uint32_t reg;

	reg = readl(USB2_PHY_SEL);

	writel(reg | 0x1, USB2_PHY_SEL);
}

void tcsr_hs_phy_mux_de_configure(void)
{
	writel(0x0, USB2_PHY_SEL);
}


/* Initialize usb wrapper and dwc h/w blocks. */
static void usb30_init(void)
{
	usb_wrapper_dev_t* wrapper;
	usb_wrapper_config_t wrapper_config;

	dwc_dev_t *dwc;
	dwc_config_t dwc_config;

	/* initialize the usb wrapper h/w block */
	wrapper_config.qscratch_base = (void*) MSM_USB30_QSCRATCH_BASE;

	wrapper = usb_wrapper_init(&wrapper_config);
	ASSERT(wrapper);

	/* save the wrapper ptr */
	udc_dev->wrapper_dev = wrapper;

	/* initialize the dwc device block */
	dwc_config.base           = (void*) MSM_USB30_BASE;

	/* buffer must be aligned to buf size. snps 8.2.2 */
	dwc_config.event_buf      = memalign(lcm(CACHE_LINE, UDC_DWC_EVENT_BUF_SIZE),
										 ROUNDUP(UDC_DWC_EVENT_BUF_SIZE, CACHE_LINE));
	ASSERT(dwc_config.event_buf);

	dwc_config.event_buf_size = UDC_DWC_EVENT_BUF_SIZE;

	/* notify handler */
	dwc_config.notify_context = udc_dev;
	dwc_config.notify         = udc_dwc_notify;

	/* setup handler */
	dwc_config.setup_context = udc_dev;
	dwc_config.setup_handler = udc_handle_setup;

	dwc = dwc_init(&dwc_config);
	ASSERT(dwc);

	/* save the dwc dev ptr */
	udc_dev->dwc = dwc;


	/* USB3.0 core and phy initialization as described in HPG */

	/* section 4.4.1 Control sequence */
	usb_wrapper_dbm_mode(wrapper, DBM_MODE_BYPASS);

	/* section 4.4.1: use config 0 - all of RAM1 */
	usb_wrapper_ram_configure(wrapper);

	/* section 4.4.2: Initialization and configuration sequences */

	/* 1. UTMI Mux configuration */
	tcsr_hs_phy_mux_configure();

	/* 2. Put controller in reset */
	dwc_reset(dwc, 1);

	/* PHY reset (steps 3 - 7) must be done while dwc is in reset condition */

	/* 3. Reset SS PHY */
	usb_wrapper_ss_phy_reset(wrapper);

	/* HS PHY is reset as part of soft reset. No need for explicit reset. */

	/* 4. SS phy config */
	usb_wrapper_ss_phy_configure(wrapper);

	/* 5. HS phy init */
	usb_wrapper_hs_phy_init(wrapper);

	/* 5.d */
	dwc_usb2_phy_soft_reset(dwc);

	/* 6. hs phy config */
	usb_wrapper_hs_phy_configure(wrapper);

	/* 7. Reset PHY digital interface */
	dwc_phy_digital_reset(dwc);

	/* 8. Bring dwc controller out of reset */
	dwc_reset(dwc, 0);

	/* 9. */
	usb_wrapper_ss_phy_electrical_config(wrapper);

	/* 10. */
	usb_wrapper_workaround_10(wrapper);

	/* 11. */
	usb_wrapper_workaround_11(wrapper);

	/* 12. */
	dwc_ss_phy_workaround_12(dwc);

	/* 13. */
	usb_wrapper_workaround_13(wrapper);

	/* 14. needed only for host mode. ignored. */

	/* 15 - 20 */
	dwc_device_init(dwc);
}

/* udc_init: creates and registers various usb descriptor */
int udc_init(struct udc_device *dev_info)
{
	/* create and initialize udc instance */
	udc_dev = (udc_t*) malloc(sizeof(udc_t));
	ASSERT(udc_dev);

	/* initialize everything to 0 */
	memset(udc_dev, 0 , sizeof(udc_t));

	/* malloc control data buffers */
	udc_dev->ctrl_rx_buf = memalign(CACHE_LINE, ROUNDUP(UDC_CONTROL_RX_BUF_SIZE, CACHE_LINE));
	ASSERT(udc_dev->ctrl_rx_buf);

	udc_dev->ctrl_tx_buf = memalign(CACHE_LINE, ROUNDUP(UDC_CONTROL_TX_BUF_SIZE, CACHE_LINE));
	ASSERT(udc_dev->ctrl_tx_buf);

	/* initialize string id */
	udc_dev->next_string_id  = 1;

	/* Initialize ept data */
	/* alloc table to assume EP0 In/OUT are already allocated.*/
	udc_dev->ept_alloc_table = EPT_TX(0) | EPT_RX(0);
	udc_dev->ept_list        = NULL;

	usb30_init();

	/* register descriptors */
	udc_register_language_desc(udc_dev);
	udc_register_device_desc_usb_20(udc_dev, dev_info);
	udc_register_device_desc_usb_30(udc_dev, dev_info);
	udc_register_bos_desc(udc_dev);

	return 0;
}

/* application registers its gadget by calling this func.
 * gadget == interface descriptor
 */
int udc_register_gadget(struct udc_gadget *gadget)
{
	ASSERT(gadget);

	/* check if already registered */
	if (udc_dev->gadget)
	{
		ERR("\nonly one gadget supported\n");
		return -1;
	}

	/* create our configuration descriptors based on this gadget data */
	udc_register_config_desc_usb20(udc_dev, gadget);
	udc_register_config_desc_usb30(udc_dev, gadget);

	/* save the gadget */
	udc_dev->gadget = gadget;

	return 0;
}

/* udc_start: */
int udc_start(void)
{
	/* 19. run
	 * enable device to receive SOF packets and
	 * respond to control transfers on EP0 and generate events.
	 */
	dwc_device_run(udc_dev->dwc, 1);

	return 0;
}

/* Control data rx callback. Called by DWC layer when it receives control
 * data from host.
 */
void udc_control_rx_callback(void *context, unsigned actual, int status)
{
	udc_t *udc = (udc_t *) context;

	/* Force reload of buffer update by controller from memory */
	arch_invalidate_cache_range((addr_t) udc->ctrl_rx_buf, actual);

	/* TODO: for now, there is only one 3-stage write during 3.0 enumeration
	 * (SET_SEL), which causes this callback. Ideally, set_periodic() must
	 * be based on which control rx just happened.
	 * Also, the value of 0x65 should depend on the data received for SET_SEL.
	 * For now, this value works just fine.
	 */
	dwc_device_set_periodic_param(udc->dwc, 0x65);
}

/* lookup request name for debug purposes */
static const char *reqname(uint32_t r)
{
	switch (r) {
	case GET_STATUS:
		return "GET_STATUS";
	case CLEAR_FEATURE:
		return "CLEAR_FEATURE";
	case SET_FEATURE:
		return "SET_FEATURE";
	case SET_ADDRESS:
		return "SET_ADDRESS";
	case GET_DESCRIPTOR:
		return "GET_DESCRIPTOR";
	case SET_DESCRIPTOR:
		return "SET_DESCRIPTOR";
	case GET_CONFIGURATION:
		return "GET_CONFIGURATION";
	case SET_CONFIGURATION:
		return "SET_CONFIGURATION";
	case GET_INTERFACE:
		return "GET_INTERFACE";
	case SET_INTERFACE:
		return "SET_INTERFACE";
	case SET_SEL:
		return "SET_SEL";
	default:
		return "*UNKNOWN*";
	}
}

/* callback function called by DWC layer when a setup packed is received.
 * the return value tells dwc layer whether this setup pkt results in
 * a 2-stage or a 3-stage control transfer or stall.
 */
static int udc_handle_setup(void *context, uint8_t *data)
{
	udc_t *udc = (udc_t *) context;
	uint32_t len;

	ASSERT(udc);

	dwc_dev_t *dwc = udc->dwc;
	ASSERT(dwc);

	struct setup_packet s = *((struct setup_packet*) data);

	DBG("\n SETUP request: \n type    = 0x%x \n request = 0x%x \n value  = 0x%x"
		" \n index   = 0x%x \n length  = 0x%x\n",
		s.type, s.request, s.value, s.index, s.length);

	switch (SETUP(s.type, s.request))
	{
	case SETUP(DEVICE_READ, GET_STATUS):
		{
			DBG("\n DEVICE_READ : GET_STATUS: value = %d index = %d"
				" length = %d", s.value, s.index, s.length);

			if (s.length == 2) {

				uint16_t zero = 0;
				len = 2;

				/* copy to tx buffer */
				memcpy(udc->ctrl_tx_buf, &zero, len);

				/* flush buffer to main memory before queueing the request */
				arch_clean_invalidate_cache_range((addr_t) udc->ctrl_tx_buf, len);

				dwc_transfer_request(udc->dwc,
									 0,
									 DWC_EP_DIRECTION_IN,
									 udc->ctrl_tx_buf,
									 len,
									 NULL,
									 NULL);

				return DWC_SETUP_3_STAGE;
			}
		}
		break;
	case SETUP(DEVICE_READ, GET_DESCRIPTOR):
		{
			DBG("\n DEVICE_READ : GET_DESCRIPTOR: value = %d", s.value);

			/* setup usb ep0-IN to send our device descriptor */
			struct udc_descriptor *desc;

			for (desc = udc->desc_list; desc; desc = desc->next)
			{
				/* tag must match the value AND
				 * if speed is SS, desc must comply with 30 spec OR
				 * if speed is not SS, desc must comply with 20 spec.
				 */
				if ((desc->tag == s.value) &&
					(((udc->speed == UDC_SPEED_SS) && (desc->spec & UDC_DESC_SPEC_30)) ||
					  ((udc->speed != UDC_SPEED_SS) && (desc->spec & UDC_DESC_SPEC_20)))
					)
				{
					if (desc->len > s.length)
						len = s.length;
					else
						len = desc->len;

					/* copy to tx buffer */
					memcpy(udc->ctrl_tx_buf, desc->data, len);

					/* flush buffer to main memory before queueing the request */
					arch_clean_invalidate_cache_range((addr_t) udc->ctrl_tx_buf, len);

					dwc_transfer_request(udc->dwc,
										 0,
										 DWC_EP_DIRECTION_IN,
										 udc->ctrl_tx_buf,
										 len,
										 NULL,
										 NULL);

					return DWC_SETUP_3_STAGE;
				}
			}
			DBG("\n Did not find matching descriptor: = 0x%x", s.value);
		}
		break;
	case SETUP(DEVICE_READ, GET_CONFIGURATION):
		{
			DBG("\n DEVICE_READ : GET_CONFIGURATION");

			if ((s.value == 0) && (s.index == 0) && (s.length == 1)) {

				len = 1;

				/* copy to tx buffer */
				memcpy(udc->ctrl_tx_buf, &udc->config_selected, len);

				/* flush buffer to main memory before queueing the request */
				arch_clean_invalidate_cache_range((addr_t) udc->ctrl_tx_buf, len);

				dwc_transfer_request(udc->dwc,
									 0,
									 DWC_EP_DIRECTION_IN,
									 udc->ctrl_tx_buf,
									 len,
									 NULL,
									 NULL);

				return DWC_SETUP_3_STAGE;
			}
			else
			{
				ASSERT(0);
			}
		}
		break;
	case SETUP(DEVICE_WRITE, SET_CONFIGURATION):
		{
			DBG("\n DEVICE_WRITE : SET_CONFIGURATION");

			/* select configuration 1 */
			if (s.value == 1) {
				struct udc_endpoint *ept;
				/* enable endpoints */
				for (ept = udc->ept_list; ept; ept = ept->next) {
					if (ept->num == 0)
						continue;
					else
					{
						/* add this ep to dwc ep list */
						dwc_ep_t ep;

						ep.number        = ept->num;
						ep.dir           = ept->in;
						ep.type          = EP_TYPE_BULK; /* the only one supported */
						ep.max_pkt_size  = ept->maxpkt;
						ep.burst_size    = ept->maxburst;
						ep.zlp           = 0;             /* TODO: zlp could be made part of ept */
						ep.trb_count     = ept->trb_count;
						ep.trb           = ept->trb;

						dwc_device_add_ep(dwc, ep);
					}
				}

				/* now that we have saved the non-control EP details, set config */
				dwc_device_set_configuration(dwc);

				/* inform client that we are configured. */
				udc->gadget->notify(udc_dev->gadget, UDC_EVENT_ONLINE);

				udc->config_selected = 1;

				return DWC_SETUP_2_STAGE;
			}
			else if (s.value == 0)
			{
				/* 0 == de-configure. */
				udc->config_selected = 0;
				DBG("\n\n CONFIG = 0 !!!!!!!!!\n\n");
				return DWC_SETUP_2_STAGE;
				/* TODO: do proper handling for de-config */
			}
			else
			{
				ERR("\n CONFIG = %d not supported\n", s.value);
				ASSERT(0);
			}
		}
		break;
	case SETUP(DEVICE_WRITE, SET_ADDRESS):
		{
			DBG("\n DEVICE_WRITE : SET_ADDRESS");

			dwc_device_set_addr(dwc, s.value);
			return DWC_SETUP_2_STAGE;
		}
		break;
	case SETUP(INTERFACE_WRITE, SET_INTERFACE):
		{
			DBG("\n DEVICE_WRITE : SET_INTERFACE");
			/* if we ack this everything hangs */
			/* per spec, STALL is valid if there is not alt func */
			goto stall;
		}
		break;
	case SETUP(DEVICE_WRITE, SET_FEATURE):
		{
			DBG("\n DEVICE_WRITE : SET_FEATURE");
			goto stall;
		}
		break;
	case SETUP(DEVICE_WRITE, CLEAR_FEATURE):
		{
			DBG("\n DEVICE_WRITE : CLEAR_FEATURE");
			goto stall;
		}
		break;
	case SETUP(ENDPOINT_WRITE, CLEAR_FEATURE):
		{
			DBG("\n DEVICE_WRITE : CLEAR_FEATURE");
			goto stall;
		}
		break;
	case SETUP(DEVICE_WRITE, SET_SEL):
		{
			DBG("\n DEVICE_WRITE : SET_SEL");

			/* this is 3-stage write. need to receive data of s.length size. */
			if (s.length > 0) {
				dwc_transfer_request(udc->dwc,
									 0,
									 DWC_EP_DIRECTION_OUT,
									 udc->ctrl_rx_buf,
									 UDC_CONTROL_RX_BUF_SIZE,
									 udc_control_rx_callback,
									 (void *) udc);
				return DWC_SETUP_3_STAGE;
			}
			else
			{
				/* length must be non-zero */
				ASSERT(0);
			}
		}
		break;

	default:
		ERR("\n Unknown setup req.\n type = 0x%x value = %d index = %d"
			" length = %d\n", s.type, s.value, s.index, s.length);
		ASSERT(0);
	}

stall:
	ERR("\nSTALL. Unsupported setup req: %s %d %d %d %d %d\n",
		reqname(s.request), s.type, s.request, s.value, s.index, s.length);

	return DWC_SETUP_ERROR;
}

/* Callback function called by DWC layer when a request to transfer data
 * on non-control EP is completed.
 */
void udc_request_complete(void *context, uint32_t actual, int status)
{
	struct udc_request *req = ((udc_t *) context)->queued_req;

	DBG("\n UDC: udc_request_callback: xferred %d bytes status = %d\n",
		actual, status);

	/* clear the queued request. */
	((udc_t *) context)->queued_req = NULL;

	if (req->complete)
	{
		req->complete(req, actual, status);
	}

	DBG("\n UDC: udc_request_callback: done fastboot callback\n");
}

/* App interface to queue in data transfer requests for control and data ep */
int udc_request_queue(struct udc_endpoint *ept, struct udc_request *req)
{
	int ret;
    dwc_dev_t *dwc_dev = udc_dev->dwc;

	/* ensure device is initialized before queuing request */
	ASSERT(dwc_dev);

	/* if device is not configured, return error */
	if(udc_dev->config_selected == 0)
	{
		return -1;
	}

	/* only one request at a time is supported.
	 * check if a request is already queued.
	 */
	if(udc_dev->queued_req)
	{
		return -1;
	}

	DBG("\n udc_request_queue: entry: ep_usb_num = %d", ept->num);

	/* save the queued request. */
	udc_dev->queued_req = req;

	ret = dwc_transfer_request(dwc_dev,
							   ept->num,
							   ept->in ? DWC_EP_DIRECTION_IN : DWC_EP_DIRECTION_OUT,
							   req->buf,
							   req->length,
							   udc_request_complete,
							   (void *) udc_dev);

	DBG("\n udc_request_queue: exit: ep_usb_num = %d", ept->num);

	return ret;
}

/* callback function called by dwc layer if any dwc event occurs */
void udc_dwc_notify(void *context, dwc_notify_event_t event)
{
	udc_t *udc = (udc_t *) context;

	switch (event)
	{
	case DWC_NOTIFY_EVENT_CONNECTED_LS:
		udc->speed = UDC_SPEED_LS;
		break;
	case DWC_NOTIFY_EVENT_CONNECTED_FS:
		udc->speed = UDC_SPEED_FS;
		break;
	case DWC_NOTIFY_EVENT_CONNECTED_HS:
		udc->speed = UDC_SPEED_HS;
		break;
	case DWC_NOTIFY_EVENT_CONNECTED_SS:
		udc->speed = UDC_SPEED_SS;
		break;
	case DWC_NOTIFY_EVENT_DISCONNECTED:
	case DWC_NOTIFY_EVENT_OFFLINE:
		udc->config_selected = 0;
		if (udc->gadget && udc->gadget->notify)
			udc->gadget->notify(udc->gadget, UDC_EVENT_OFFLINE);
		break;
	default:
		ASSERT(0);
	}
}


/******************* Function related to descriptor allocation etc.************/

static struct udc_endpoint *_udc_endpoint_alloc(uint8_t num,
												uint8_t in,
												uint16_t max_pkt)
{
	struct udc_endpoint *ept;
	udc_t *udc = udc_dev;

	ept = malloc(sizeof(*ept));
	ASSERT(ept);

	ept->maxpkt     = max_pkt;
	ept->num        = num;
	ept->in         = !!in;
	ept->maxburst   = 4;      /* no performance improvement is seen beyond burst size of 4 */
	ept->trb_count  = 66;     /* each trb can transfer (16MB - 1). 65 for 1GB transfer + 1 for roundup/zero length pkt. */
	ept->trb        = memalign(lcm(CACHE_LINE, 16), ROUNDUP(ept->trb_count*sizeof(dwc_trb_t), CACHE_LINE)); /* TRB must be aligned to 16 */
	ASSERT(ept->trb);

	/* push it on top of ept_list */
	ept->next      = udc->ept_list;
	udc->ept_list  = ept;

	return ept;
}

/* Called to create non-control in/out End Point structures by the APP */
struct udc_endpoint *udc_endpoint_alloc(unsigned type, unsigned maxpkt)
{
	struct udc_endpoint *ept;
	uint8_t in;
	uint8_t n;
	udc_t *udc = udc_dev;

	if (type == UDC_TYPE_BULK_IN) {
		in = 1;
	} else if (type == UDC_TYPE_BULK_OUT) {
		in = 0;
	} else {
		return 0;
	}

	for (n = 1; n < 16; n++) {
		uint32_t bit = in ? EPT_TX(n) : EPT_RX(n);
		if (udc->ept_alloc_table & bit)
			continue;
		ept = _udc_endpoint_alloc(n, in, maxpkt);
		if (ept)
			udc->ept_alloc_table |= bit;
		return ept;
	}
	return 0;
}


/* create config + interface + ep desc for 2.0 */
static void udc_register_config_desc_usb20(udc_t *udc,
										   struct udc_gadget *gadget)
{
	uint8_t  *data;
	uint16_t  size;
	struct udc_descriptor *desc;

	ASSERT(udc);
	ASSERT(gadget);

	/* create our configuration descriptor */

	/* size is the total size of (config + interface + all EPs) descriptor */
	size = UDC_DESC_SIZE_CONFIGURATION +
		   UDC_DESC_SIZE_INTERFACE +
		   (gadget->ifc_endpoints*UDC_DESC_SIZE_ENDPOINT);

	desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size, UDC_DESC_SPEC_20);

	data = desc->data;

	/* Config desc */
	data[0] = 0x09;
	data[1] = TYPE_CONFIGURATION;
	data[2] = size;
	data[3] = size >> 8;
	data[4] = 0x01;     /* number of interfaces */
	data[5] = 0x01;     /* configuration value */
	data[6] = 0x00;     /* configuration string */
	data[7] = 0xC0;     /* attributes: reserved and self-powered set */
	data[8] = 0x00;     /* max power: 0ma since we are self powered */
	data += 9;

	/* Interface desc */
	data[0] = 0x09;
	data[1] = TYPE_INTERFACE;
	data[2] = 0x00;     /* ifc number */
	data[3] = 0x00;     /* alt number */
	data[4] = gadget->ifc_endpoints;
	data[5] = gadget->ifc_class;
	data[6] = gadget->ifc_subclass;
	data[7] = gadget->ifc_protocol;
	data[8] = udc_string_desc_alloc(udc, gadget->ifc_string);
	data += 9;

	for (uint8_t n = 0; n < gadget->ifc_endpoints; n++) {
		udc_ept_desc_fill(gadget->ept[n], data);
		data += UDC_DESC_SIZE_ENDPOINT;
	}

	udc_descriptor_register(udc, desc);
}

/* create config + interface + ep desc for 3.0 */
static void udc_register_config_desc_usb30(udc_t *udc,
										   struct udc_gadget *gadget)
{
	uint8_t *data;
	uint16_t size;
	struct udc_descriptor *desc;

	ASSERT(udc);
	ASSERT(gadget);

	/* create our configuration descriptor */

	/* size is the total size of (config + interface + all EPs) descriptor */
	size = UDC_DESC_SIZE_CONFIGURATION +
		   UDC_DESC_SIZE_INTERFACE +
		   (gadget->ifc_endpoints*(UDC_DESC_SIZE_ENDPOINT + UDC_DESC_SIZE_ENDPOINT_COMP));

	desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size, UDC_DESC_SPEC_30);

	data = desc->data;

	/* Config desc */
	data[0] = 0x09;
	data[1] = TYPE_CONFIGURATION;
	data[2] = size;
	data[3] = size >> 8;
	data[4] = 0x01;     /* number of interfaces */
	data[5] = 0x01;     /* configuration value */
	data[6] = 0x00;     /* configuration string */
	data[7] = 0xC0;     /* attributes: reserved and self-powered set */
	data[8] = 0x00;     /* max power: 0ma since we are self powered */
	data += 9;

	/* Interface desc */
	data[0] = 0x09;
	data[1] = TYPE_INTERFACE;
	data[2] = 0x00;     /* ifc number */
	data[3] = 0x00;     /* alt number */
	data[4] = gadget->ifc_endpoints;
	data[5] = gadget->ifc_class;
	data[6] = gadget->ifc_subclass;
	data[7] = gadget->ifc_protocol;
	data[8] = udc_string_desc_alloc(udc, gadget->ifc_string);
	data += 9;

	for (uint8_t n = 0; n < gadget->ifc_endpoints; n++)
	{
		/* fill EP desc */
		udc_ept_desc_fill(gadget->ept[n], data);
		data += UDC_DESC_SIZE_ENDPOINT;

		/* fill EP companion desc */
		udc_ept_comp_desc_fill(gadget->ept[n], data);
		data += UDC_DESC_SIZE_ENDPOINT_COMP;
	}

	udc_descriptor_register(udc, desc);
}


static void udc_register_device_desc_usb_20(udc_t *udc,
											struct udc_device *dev_info)
{
	uint8_t *data;
	struct udc_descriptor *desc;

	/* create our device descriptor */
	desc = udc_descriptor_alloc(TYPE_DEVICE, 0, 18, UDC_DESC_SPEC_20);
	data = desc->data;

	/* data 0 and 1 is filled by descriptor alloc routine.
	 * fill in the remaining entries.
	 */
	data[2] = 0x00; /* usb spec minor rev */
	data[3] = 0x02; /* usb spec major rev */
	data[4] = 0x00; /* class */
	data[5] = 0x00; /* subclass */
	data[6] = 0x00; /* protocol */
	data[7] = 0x40; /* max packet size on ept 0 */

	memcpy(data + 8,  &dev_info->vendor_id,  sizeof(short));
	memcpy(data + 10, &dev_info->product_id, sizeof(short));
	memcpy(data + 12, &dev_info->version_id, sizeof(short));

	data[14] = udc_string_desc_alloc(udc, dev_info->manufacturer);
	data[15] = udc_string_desc_alloc(udc, dev_info->product);
	data[16] = udc_string_desc_alloc(udc, dev_info->serialno);
	data[17] = 1; /* number of configurations */

	udc_descriptor_register(udc, desc);
}

static void udc_register_device_desc_usb_30(udc_t *udc, struct udc_device *dev_info)
{
	uint8_t *data;
	struct udc_descriptor *desc;

	/* create our device descriptor */
	desc = udc_descriptor_alloc(TYPE_DEVICE, 0, 18, UDC_DESC_SPEC_30);
	data = desc->data;

	/* data 0 and 1 is filled by descriptor alloc routine.
	 * fill in the remaining entries.
	 */
	data[2] = 0x00; /* usb spec minor rev */
	data[3] = 0x03; /* usb spec major rev */
	data[4] = 0x00; /* class */
	data[5] = 0x00; /* subclass */
	data[6] = 0x00; /* protocol */
	data[7] = 0x09; /* max packet size on ept 0 */
	memcpy(data +  8, &dev_info->vendor_id,  sizeof(short));
	memcpy(data + 10, &dev_info->product_id, sizeof(short));
	memcpy(data + 12, &dev_info->version_id, sizeof(short));
	data[14] = udc_string_desc_alloc(udc, dev_info->manufacturer);
	data[15] = udc_string_desc_alloc(udc, dev_info->product);
	data[16] = udc_string_desc_alloc(udc, dev_info->serialno);
	data[17] = 1; /* number of configurations */

	udc_descriptor_register(udc, desc);
}

static void udc_register_bos_desc(udc_t *udc)
{
	uint8_t *data;
	struct udc_descriptor *desc;

	/* create our device descriptor */
	desc = udc_descriptor_alloc(TYPE_BOS, 0, 15, UDC_DESC_SPEC_30); /* 15 is total length of bos + other descriptors inside it */
	data = desc->data;

	/* data 0 and 1 is filled by descriptor alloc routine.
	 * fill in the remaining entries.
	 */
	data[0] = 0x05;     /* BOS desc len */
	data[1] = TYPE_BOS; /* BOS desc type */
	data[2] = 0x0F;     /* total len of bos desc and its sub desc */
	data[3] = 0x00;     /* total len of bos desc and its sub desc */
	data[4] = 0x01;     /* num of sub desc inside bos */

	data[5]  = 0x0A;    /* desc len */
	data[6]  = 0x10;    /* Device Capability desc */
	data[7]  = 0x03;    /* 3 == SuperSpeed capable */
	data[8]  = 0x00;    /* Attribute: latency tolerance msg: No */
	data[9]  = 0x0F;    /* Supported Speeds (bit mask): LS, FS, HS, SS */
	data[10] = 0x00;    /* Reserved part of supported wSupportedSpeeds */
	data[11] = 0x01;    /* lowest supported speed with full functionality: FS */
	data[12] = 0x00;    /* U1 device exit latency */
	data[13] = 0x00;    /* U2 device exit latency (lsb) */
	data[14] = 0x00;    /* U2 device exit latency (msb) */

	udc_descriptor_register(udc, desc);
}

static void udc_register_language_desc(udc_t *udc)
{
	/* create and register a language table descriptor */
	/* language 0x0409 is US English */
	struct udc_descriptor *desc = udc_descriptor_alloc(TYPE_STRING,
													   0,
													   4,
													   UDC_DESC_SPEC_20 | UDC_DESC_SPEC_30);
	desc->data[2] = 0x09;
	desc->data[3] = 0x04;
	udc_descriptor_register(udc, desc);
}

static void udc_ept_desc_fill(struct udc_endpoint *ept, uint8_t *data)
{
	data[0] = 7;
	data[1] = TYPE_ENDPOINT;
	data[2] = ept->num | (ept->in ? 0x80 : 0x00);
	data[3] = 0x02; /* bulk -- the only kind we support */
	data[4] = ept->maxpkt;
	data[5] = ept->maxpkt >> 8;
	data[6] = 0; /* bInterval: must be 0 for bulk. */
}

static void udc_ept_comp_desc_fill(struct udc_endpoint *ept, uint8_t *data)
{
	data[0] = 6;               /* bLength */
	data[1] = TYPE_SS_EP_COMP; /* ep type */
	data[2] = ept->maxburst;   /* maxBurst */
	data[3] = 0x0;             /* maxStreams */
	data[4] = 0x0;             /* wBytesPerInterval */
	data[5] = 0x0;             /* wBytesPerInterval */
}

static uint8_t udc_string_desc_alloc(udc_t *udc, const char *str)
{
	uint32_t len;
	struct udc_descriptor *desc;
	uint8_t *data;

	if (udc->next_string_id > 255)
		return 0;

	if (!str)
		return 0;

	len = strlen(str);
	desc = udc_descriptor_alloc(TYPE_STRING,
								udc->next_string_id,
								len * 2 + 2,
								UDC_DESC_SPEC_20 | UDC_DESC_SPEC_30);
	if (!desc)
		return 0;
	udc->next_string_id++;

	/* expand ascii string to utf16 */
	data = desc->data + 2;
	while (len-- > 0) {
		*data++ = *str++;
		*data++ = 0;
	}

	udc_descriptor_register(udc, desc);
	return desc->tag & 0xff;
}


static struct udc_descriptor *udc_descriptor_alloc(uint32_t type,
												   uint32_t num,
												   uint32_t len,
												   udc_desc_spec_t spec)
{
	struct udc_descriptor *desc;
	if ((len > 255) || (len < 2) || (num > 255) || (type > 255))
		return 0;

	if (!(desc = malloc(sizeof(struct udc_descriptor) + len)))
		return 0;

	desc->next    = 0;
	desc->tag     = (type << 8) | num;
	desc->len     = len;
	desc->spec    = spec;

	/* descriptor data */
	desc->data[0] = len;
	desc->data[1] = type;

	return desc;
}

static void udc_descriptor_register(udc_t *udc, struct udc_descriptor *desc)
{
	desc->next     = udc->desc_list;
	udc->desc_list = desc;
}


struct udc_request *udc_request_alloc(void)
{
	struct udc_request *req;

	req = malloc(sizeof(*req));
	ASSERT(req);

	req->buf      = 0;
	req->length   = 0;
	req->complete = NULL;
	req->context  = 0;

	return req;
}

void udc_request_free(struct udc_request *req)
{
	free(req);
}

void udc_endpoint_free(struct udc_endpoint *ept)
{
	/* TODO */
}

int udc_stop(void)
{
	dwc_device_run(udc_dev->dwc, 0);

	return 0;
}
