/*
 * Copyright (c) 2008, Google Inc.
 * All rights reserved.
 *
 * Copyright (c) 2009-2011, Code Aurora Forum. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE 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.
 */

#include <string.h>
#include <stdlib.h>
#include <debug.h>
#include <platform/iomap.h>
#include <platform/irqs.h>
#include <platform/interrupts.h>
#include <platform/timer.h>
#include <kernel/thread.h>
#include <reg.h>

#include <dev/udc.h>

#include "hsusb.h"

/* common code - factor out into a shared file */

struct udc_descriptor {
	struct udc_descriptor *next;
	unsigned short tag; /* ((TYPE << 8) | NUM) */
	unsigned short len; /* total length */
	unsigned char data[0];
};

struct udc_descriptor *udc_descriptor_alloc(unsigned type, unsigned num, unsigned len)
{
	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->data[0] = len;
	desc->data[1] = type;

	return desc;
}

static struct udc_descriptor *desc_list = 0;
static unsigned next_string_id = 1;

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

unsigned udc_string_desc_alloc(const char *str)
{
	unsigned len;
	struct udc_descriptor *desc;
	unsigned char *data;

	if (next_string_id > 255)
		return 0;

	if (!str)
		return 0;

	len = strlen(str);
	desc = udc_descriptor_alloc(TYPE_STRING, next_string_id, len * 2 + 2);
	if (!desc)
		return 0;
	next_string_id++;

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

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

/* end of common code */

__WEAK void hsusb_clock_init(void)
{
	return;
}

#if 1
#define DBG(x...) do {} while(0)
#else
#define DBG(x...) dprintf(INFO, x)
#endif

#define usb_status(a,b)

struct usb_request {
	struct udc_request req;
	struct ept_queue_item *item;
};

struct udc_endpoint
{
	struct udc_endpoint *next;
	unsigned bit;
	struct ept_queue_head *head;
	struct usb_request *req;
	unsigned char num;
	unsigned char in;
	unsigned short maxpkt;
};

struct udc_endpoint *ept_list = 0;
struct ept_queue_head *epts = 0;

static int usb_online = 0;
static int usb_highspeed = 0;

static struct udc_device *the_device;
static struct udc_gadget *the_gadget;
static unsigned test_mode = 0;

struct udc_endpoint *_udc_endpoint_alloc(unsigned num, unsigned in, unsigned max_pkt)
{
	struct udc_endpoint *ept;
	unsigned cfg;

	ept = malloc(sizeof(*ept));

	ept->maxpkt = max_pkt;
	ept->num = num;
	ept->in = !!in;
	ept->req = 0;

	cfg = CONFIG_MAX_PKT(max_pkt) | CONFIG_ZLT;

	if(ept->in) {
		ept->bit = EPT_TX(ept->num);
	} else {
		ept->bit = EPT_RX(ept->num);
		if(num == 0)
			cfg |= CONFIG_IOS;
	}

	ept->head = epts + (num * 2) + (ept->in);
	ept->head->config = cfg;

	ept->next = ept_list;
	ept_list = ept;

	DBG("ept%d %s @%p/%p max=%d bit=%x\n",
            num, in ? "in":"out", ept, ept->head, max_pkt, ept->bit);

	return ept;
}

static unsigned ept_alloc_table = EPT_TX(0) | EPT_RX(0);

struct udc_endpoint *udc_endpoint_alloc(unsigned type, unsigned maxpkt)
{
	struct udc_endpoint *ept;
	unsigned n;
	unsigned in;

	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++) {
		unsigned bit = in ? EPT_TX(n) : EPT_RX(n);
		if (ept_alloc_table & bit)
			continue;
		ept = _udc_endpoint_alloc(n, in, maxpkt);
		if (ept)
			ept_alloc_table |= bit;
		return ept;
	}
	return 0;
}

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

static void endpoint_enable(struct udc_endpoint *ept, unsigned yes)
{
	unsigned n = readl(USB_ENDPTCTRL(ept->num));

	if(yes) {
		if(ept->in) {
			n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK);
		} else {
			n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK);
		}

		if(ept->num != 0) {
			/* XXX should be more dynamic... */
			if(usb_highspeed) {
				ept->head->config = CONFIG_MAX_PKT(512) | CONFIG_ZLT;
			} else {
				ept->head->config = CONFIG_MAX_PKT(64) | CONFIG_ZLT;
			}
		}
	}
	writel(n, USB_ENDPTCTRL(ept->num));
}

struct udc_request *udc_request_alloc(void)
{
	struct usb_request *req;
	req = malloc(sizeof(*req));
	req->req.buf = 0;
	req->req.length = 0;
	req->item = memalign(32, 32);
	return &req->req;
}

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

int udc_request_queue(struct udc_endpoint *ept, struct udc_request *_req)
{
	struct usb_request *req = (struct usb_request *) _req;
	struct ept_queue_item *item = req->item;
	unsigned phys = (unsigned) req->req.buf;

	item->next = TERMINATE;
	item->info = INFO_BYTES(req->req.length) | INFO_IOC | INFO_ACTIVE;
	item->page0 = phys;
	item->page1 = (phys & 0xfffff000) + 0x1000;

	enter_critical_section();
	ept->head->next = (unsigned) item;
	ept->head->info = 0;
	ept->req = req;

	arch_clean_invalidate_cache_range((addr_t) ept, sizeof(struct udc_endpoint));
	arch_clean_invalidate_cache_range((addr_t) ept->head, sizeof(struct ept_queue_head));
	arch_clean_invalidate_cache_range((addr_t) ept->req, sizeof(struct usb_request));
	arch_clean_invalidate_cache_range((addr_t) req->req.buf, req->req.length);
	arch_clean_invalidate_cache_range((addr_t) ept->req->item, sizeof(struct ept_queue_item));

	DBG("ept%d %s queue req=%p\n",
            ept->num, ept->in ? "in" : "out", req);

	writel(ept->bit, USB_ENDPTPRIME);
	exit_critical_section();
	return 0;
}

static void handle_ept_complete(struct udc_endpoint *ept)
{
	struct ept_queue_item *item;
	unsigned actual;
	int status;
	struct usb_request *req;

	DBG("ept%d %s complete req=%p\n",
            ept->num, ept->in ? "in" : "out", ept->req);

	arch_clean_invalidate_cache_range((addr_t) ept, sizeof(struct udc_endpoint));
	arch_clean_invalidate_cache_range((addr_t) ept->req, sizeof(struct usb_request));

	req = ept->req;
	if(req) {
		ept->req = 0;

		item = req->item;

		/* For some reason we are getting the notification for
		 * transfer completion before the active bit has cleared.
		 * HACK: wait for the ACTIVE bit to clear:
		 */
		do
		{
			/* Must clean/invalidate cached item data before checking
			 * the status every time.
			 */
			arch_clean_invalidate_cache_range((addr_t) item, sizeof(struct ept_queue_item));
		} while (readl(&(item->info)) & INFO_ACTIVE);

		arch_clean_invalidate_cache_range((addr_t) req->req.buf, req->req.length);

		if(item->info & 0xff) {
			actual = 0;
			status = -1;
			dprintf(INFO, "EP%d/%s FAIL nfo=%x pg0=%x\n",
				ept->num, ept->in ? "in" : "out", item->info, item->page0);
		} else {
			actual = req->req.length - ((item->info >> 16) & 0x7fff);
			status = 0;
		}
		if(req->req.complete)
			req->req.complete(&req->req, actual, status);
	}
}

static const char *reqname(unsigned 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";
	default: return "*UNKNOWN*";
	}
}

static struct udc_endpoint *ep0in, *ep0out;
static struct udc_request *ep0req;

static void ep0_setup_ack_complete(struct udc_endpoint *ep, struct usb_request *req)
{
	uint32_t mode;

	if(!test_mode)
		return;

	switch (test_mode)
	{
		case TEST_PACKET:
			dprintf(INFO,"Entering test mode for TST_PKT\n");
			mode = readl(USB_PORTSC) & (~PORTSC_PTC);
			writel(mode | PORTSC_PTC_TST_PKT, USB_PORTSC);
			break;

		case TEST_SE0_NAK:
			dprintf(INFO, "Entering test mode for SE0-NAK\n");
			mode = readl(USB_PORTSC) & (~PORTSC_PTC);
			writel(mode | PORTSC_PTC_SE0_NAK, USB_PORTSC);
			break;
	}

}

static void setup_ack(void)
{
	ep0req->complete = ep0_setup_ack_complete;
	ep0req->length = 0;
	udc_request_queue(ep0in, ep0req);
}

static void ep0in_complete(struct udc_request *req, unsigned actual, int status)
{
	DBG("ep0in_complete %p %d %d\n", req, actual, status);
	if(status == 0) {
		req->length = 0;
		req->complete = 0;
		udc_request_queue(ep0out, req);
	}
}

static void setup_tx(void *buf, unsigned len)
{
	DBG("setup_tx %p %d\n", buf, len);
	memcpy(ep0req->buf, buf, len);
	ep0req->complete = ep0in_complete;
	ep0req->length = len;
	udc_request_queue(ep0in, ep0req);
}

static unsigned char usb_config_value = 0;

#define SETUP(type,request) (((type) << 8) | (request))


static void handle_setup(struct udc_endpoint *ept)
{
	struct setup_packet s;

	arch_clean_invalidate_cache_range((addr_t) ept->head->setup_data, sizeof(struct ept_queue_head));
	memcpy(&s, ept->head->setup_data, sizeof(s));
	writel(ept->bit, USB_ENDPTSETUPSTAT);

	DBG("handle_setup type=0x%02x req=0x%02x val=%d idx=%d len=%d (%s)\n",
            s.type, s.request, s.value, s.index, s.length,
            reqname(s.request));

	switch (SETUP(s.type,s.request)) {
	case SETUP(DEVICE_READ, GET_STATUS): {
		unsigned zero = 0;
		if (s.length == 2) {
			setup_tx(&zero, 2);
			return;
		}
		break;
	}
	case SETUP(DEVICE_READ, GET_DESCRIPTOR): {
		struct udc_descriptor *desc;
		/* usb_highspeed? */
		for (desc = desc_list; desc; desc = desc->next) {
			if (desc->tag == s.value) {
				unsigned len = desc->len;
				if (len > s.length) len = s.length;
				setup_tx(desc->data, len);
				return;
			}
		}
		break;
	}
	case SETUP(DEVICE_READ, GET_CONFIGURATION):
		/* disabling this causes data transaction failures on OSX. Why? */
		if ((s.value == 0) && (s.index == 0) && (s.length == 1)) {
			setup_tx(&usb_config_value, 1);
			return;
		}
		break;
	case SETUP(DEVICE_WRITE, SET_CONFIGURATION):
		if (s.value == 1) {
			struct udc_endpoint *ept;
			/* enable endpoints */
			for (ept = ept_list; ept; ept = ept->next){
				if (ept->num == 0)
					continue;
				endpoint_enable(ept, s.value);
			}
			usb_config_value = 1;
			the_gadget->notify(the_gadget, UDC_EVENT_ONLINE);
		} else {
			writel(0, USB_ENDPTCTRL(1));
			usb_config_value = 0;
			the_gadget->notify(the_gadget, UDC_EVENT_OFFLINE);
		}
		setup_ack();
		usb_online = s.value ? 1 : 0;
		usb_status(s.value ? 1 : 0, usb_highspeed);
		return;
	case SETUP(DEVICE_WRITE, SET_ADDRESS):
		/* write address delayed (will take effect
		** after the next IN txn)
		*/
		writel((s.value << 25) | (1 << 24), USB_DEVICEADDR);
		setup_ack();
		return;
	case SETUP(INTERFACE_WRITE, SET_INTERFACE):
		/* if we ack this everything hangs */
		/* per spec, STALL is valid if there is not alt func */
		goto stall;
	case SETUP(DEVICE_WRITE, SET_FEATURE):
		test_mode = s.index;
		setup_ack();
		return;
	case SETUP(ENDPOINT_WRITE, CLEAR_FEATURE): {
		struct udc_endpoint *ept;
		unsigned num = s.index & 15;
		unsigned in = !!(s.index & 0x80);

		if ((s.value == 0) && (s.length == 0)) {
			DBG("clr feat %d %d\n", num, in);
			for (ept = ept_list; ept; ept = ept->next) {
				if ((ept->num == num) && (ept->in == in)) {
					endpoint_enable(ept, 1);
					setup_ack();
					return;
				}
			}
		}
		break;
	}
	}

	dprintf(INFO, "STALL %s %d %d %d %d %d\n",
		reqname(s.request),
		s.type, s.request, s.value, s.index, s.length);

stall:
	writel((1<<16) | (1 << 0), USB_ENDPTCTRL(ept->num));
}

unsigned ulpi_read(unsigned reg)
{
        /* initiate read operation */
	writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg),
               USB_ULPI_VIEWPORT);

        /* wait for completion */
	while(readl(USB_ULPI_VIEWPORT) & ULPI_RUN) ;

	return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT));
}

void ulpi_write(unsigned val, unsigned reg)
{
        /* initiate write operation */
	writel(ULPI_RUN | ULPI_WRITE |
               ULPI_ADDR(reg) | ULPI_DATA(val),
               USB_ULPI_VIEWPORT);

        /* wait for completion */
	while(readl(USB_ULPI_VIEWPORT) & ULPI_RUN) ;
}

#define USB_CLK             0x00902910
#define USB_PHY_CLK         0x00902E20
#define CLK_RESET_ASSERT    0x1
#define CLK_RESET_DEASSERT  0x0
#define CLK_RESET(x,y)  writel((y), (x));

static int msm_otg_xceiv_reset()
{
	CLK_RESET(USB_CLK, CLK_RESET_ASSERT);
	CLK_RESET(USB_PHY_CLK, CLK_RESET_ASSERT);
	mdelay(20);
	CLK_RESET(USB_PHY_CLK, CLK_RESET_DEASSERT);
	CLK_RESET(USB_CLK, CLK_RESET_DEASSERT);
	mdelay(20);

	/* select ULPI phy */
	writel(0x81000000, USB_PORTSC);
	return 0;
}

void board_usb_init(void);
void board_ulpi_init(void)
{
       	unsigned int reg;

#ifdef PLATFORM_MSM7X27A
	ulpi_read(0x31);
	dprintf(INFO," Value of ulpi read 0x31 is %08x\n", reg);
        /* todo : the write back value should be calculated according to
         * reg &= 0xF3 but sometimes the value that is read initially
         * doesnt look right
         */
	ulpi_write(0x4A, 0x31);
        reg = ulpi_read(0x31);
	dprintf(INFO," Value of ulpi read 0x31 after write is %08x\n", reg);

	reg = ulpi_read(0x32);
	dprintf(INFO," Value of ulpi read 0x32 is %08x\n", reg);
	ulpi_write(0x30,0x32);
	reg = ulpi_read(0x32);
	dprintf(INFO," Value of ulpi read 0x32 after write is %08x\n", reg);


	reg = ulpi_read(0x36);
	dprintf(INFO," Value of ulpi read 0x36 is %08x\n", reg);
	ulpi_write(reg|0x2,0x36);
	reg = ulpi_read(0x36);
	dprintf(INFO," Value of ulpi read 0x36 after write is %08x\n", reg);

#endif
#ifdef PLATFORM_MSM8X60

        reg = ulpi_read(0x32);
        dprintf(INFO," Value of ulpi read 0x32 is %08x\n", reg);
        ulpi_write(0x30,0x32);
        reg = ulpi_read(0x32);
        dprintf(INFO," Value of ulpi read 0x32 after write is %08x\n", reg);


        reg = ulpi_read(0x36);
        dprintf(INFO," Value of ulpi read 0x36 is %08x\n", reg);
        ulpi_write(reg|0x2,0x36);
        reg = ulpi_read(0x36);
        dprintf(INFO," Value of ulpi read 0x36 aafter write is %08x\n", reg);
#endif
}

int udc_init(struct udc_device *dev)
{
	DBG("udc_init():\n");

	hsusb_clock_init();

#ifdef PLATFORM_MSM8X60
	/* Configure GPIOs for HS_USB */
	hsusb_gpio_init();
#endif

	epts = memalign(4096, 4096);

	dprintf(INFO, "USB init ept @ %p\n", epts);
	memset(epts, 0, 32 * sizeof(struct ept_queue_head));
	arch_clean_invalidate_cache_range((addr_t) epts, 32 * sizeof(struct ept_queue_head));

	//dprintf(INFO, "USB ID %08x\n", readl(USB_ID));
//    board_usb_init();

        /* select ULPI phy */
#ifdef PLATFORM_MSM8X60
	msm_otg_xceiv_reset();
#else
	writel(0x81000000, USB_PORTSC);
#endif
        /* RESET */
	writel(0x00080002, USB_USBCMD);

	thread_sleep(20);

        board_ulpi_init();

	writel((unsigned) epts, USB_ENDPOINTLISTADDR);

        /* select DEVICE mode */
	writel(0x02, USB_USBMODE);

	writel(0xffffffff, USB_ENDPTFLUSH);
	thread_sleep(20);

	ep0out = _udc_endpoint_alloc(0, 0, 64);
	ep0in = _udc_endpoint_alloc(0, 1, 64);
	ep0req = udc_request_alloc();
	ep0req->buf = malloc(4096);

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

	the_device = dev;
	return 0;
}

enum handler_return udc_interrupt(void *arg)
{
	struct udc_endpoint *ept;
	unsigned ret = INT_NO_RESCHEDULE;
	unsigned n = readl(USB_USBSTS);
	writel(n, USB_USBSTS);

	n &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI);

	DBG("\nudc_interrupt():\n");

	if (n == 0) {
		DBG("n = 0\n");
		return ret;
	}

	if (n & STS_URI) {
		DBG("STS_URI\n");

		writel(readl(USB_ENDPTCOMPLETE), USB_ENDPTCOMPLETE);
		writel(readl(USB_ENDPTSETUPSTAT), USB_ENDPTSETUPSTAT);
		writel(0xffffffff, USB_ENDPTFLUSH);
		writel(0, USB_ENDPTCTRL(1));
		dprintf(INFO, "-- reset --\n");
		usb_online = 0;
		usb_config_value = 0;
		the_gadget->notify(the_gadget, UDC_EVENT_OFFLINE);

		/* error out any pending reqs */
		for (ept = ept_list; ept; ept = ept->next) {
			/* ensure that ept_complete considers
			 * this to be an error state
			 */
			if (ept->req) {
				ept->req->item->info = INFO_HALTED;
				handle_ept_complete(ept);
			}
		}
		usb_status(0, usb_highspeed);
	}
	if (n & STS_SLI) {
		DBG("-- suspend --\n");
	}
	if (n & STS_PCI) {
		dprintf(INFO, "-- portchange --\n");
		unsigned spd = (readl(USB_PORTSC) >> 26) & 3;
		if(spd == 2) {
			usb_highspeed = 1;
		} else {
			usb_highspeed = 0;
		}
	}
	if (n & STS_UEI) {
		DBG("STS_UEI\n");
		dprintf(INFO, "<UEI %x>\n", readl(USB_ENDPTCOMPLETE));
	}
#if 0
	DBG("STS: ");
	if (n & STS_UEI) DBG("ERROR ");
	if (n & STS_SLI) DBG("SUSPEND ");
	if (n & STS_URI) DBG("RESET ");
	if (n & STS_PCI) DBG("PORTCHANGE ");
	if (n & STS_UI) DBG("USB ");
	DBG("\n");
#endif
	if ((n & STS_UI) || (n & STS_UEI)) {
		DBG("STS_UI and UEI \n");
		n = readl(USB_ENDPTSETUPSTAT);
		if (n & EPT_RX(0)) {
			handle_setup(ep0out);
			ret = INT_RESCHEDULE;
		}

		n = readl(USB_ENDPTCOMPLETE);
		if (n != 0) {
			writel(n, USB_ENDPTCOMPLETE);
		}

		for (ept = ept_list; ept; ept = ept->next){
			if (n & ept->bit) {
				handle_ept_complete(ept);
				ret = INT_RESCHEDULE;
			}
		}
	}
	return ret;
}

int udc_register_gadget(struct udc_gadget *gadget)
{
	if (the_gadget) {
		dprintf(CRITICAL, "only one gadget supported\n");
		return -1;
	}
	the_gadget = gadget;
	return 0;
}

static void udc_ept_desc_fill(struct udc_endpoint *ept, unsigned char *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] = ept->in ? 0x00 : 0x01;
}

static unsigned udc_ifc_desc_size(struct udc_gadget *g)
{
	return 9 + g->ifc_endpoints * 7;
}

static void udc_ifc_desc_fill(struct udc_gadget *g, unsigned char *data)
{
	unsigned n;

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

	data += 9;
	for (n = 0; n < g->ifc_endpoints; n++) {
		udc_ept_desc_fill(g->ept[n], data);
		data += 7;
	}
}

int udc_start(void)
{
	struct udc_descriptor *desc;
	unsigned char *data;
	unsigned size;

	dprintf(ALWAYS, "udc_start()\n");

	if (!the_device) {
		dprintf(CRITICAL, "udc cannot start before init\n");
		return -1;
	}
	if (!the_gadget) {
		dprintf(CRITICAL, "udc has no gadget registered\n");
		return -1;
	}

	/* create our device descriptor */
	desc = udc_descriptor_alloc(TYPE_DEVICE, 0, 18);
	data = desc->data;
	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, &the_device->vendor_id, sizeof(short));
	memcpy(data + 10, &the_device->product_id, sizeof(short));
	memcpy(data + 12, &the_device->version_id, sizeof(short));
	data[14] = udc_string_desc_alloc(the_device->manufacturer);
	data[15] = udc_string_desc_alloc(the_device->product);
	data[16] = udc_string_desc_alloc(the_device->serialno);
	data[17] = 1; /* number of configurations */
	udc_descriptor_register(desc);

	/* create our configuration descriptor */
	size = 9 + udc_ifc_desc_size(the_gadget);
	desc = udc_descriptor_alloc(TYPE_CONFIGURATION, 0, size);
	data = desc->data;
	data[0] = 0x09;
	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] = 0x80; /* attributes */
	data[8] = 0x80; /* max power (250ma) -- todo fix this */
	udc_ifc_desc_fill(the_gadget, data + 9);
	udc_descriptor_register(desc);

	register_int_handler(INT_USB_HS, udc_interrupt, (void*) 0);
	writel(STS_URI | STS_SLI | STS_UI | STS_PCI, USB_USBINTR);
	unmask_interrupt(INT_USB_HS);

        /* go to RUN mode (D+ pullup enable) */
	writel(0x00080001, USB_USBCMD);


	return 0;
}

int udc_stop(void)
{
#ifdef PLATFORM_MSM8X60
	int val;
#endif
    writel(0, USB_USBINTR);
	mask_interrupt(INT_USB_HS);

        /* disable pullup */
	writel(0x00080000, USB_USBCMD);
#ifdef PLATFORM_MSM8X60
	/* Voting down PLL8 */
	val = readl(0x009034C0);
	val &= ~(1<<8);
	writel(val, 0x009034C0);
#endif
	thread_sleep(10);

	return 0;
}

