/*
 * Faraday USB 2.0 OTG Controller
 *
 * (C) Copyright 2010 Faraday Technology
 * Dante Su <dantesu@faraday-tech.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <config.h>
#include <net.h>
#include <malloc.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <linux/types.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>

#include <usb/fotg210.h>

#define CFG_NUM_ENDPOINTS		4
#define CFG_EP0_MAX_PACKET_SIZE	64
#define CFG_EPX_MAX_PACKET_SIZE	512

#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 2) /* 250 ms */

struct fotg210_chip;

struct fotg210_ep {
	struct usb_ep ep;

	uint maxpacket;
	uint id;
	uint stopped;

	struct list_head                      queue;
	struct fotg210_chip                  *chip;
	const struct usb_endpoint_descriptor *desc;
};

struct fotg210_request {
	struct usb_request req;
	struct list_head   queue;
	struct fotg210_ep *ep;
};

struct fotg210_chip {
	struct usb_gadget         gadget;
	struct usb_gadget_driver *driver;
	struct fotg210_regs      *regs;
	uint8_t                   irq;
	uint16_t                  addr;
	int                       pullup;
	enum usb_device_state     state;
	struct fotg210_ep         ep[1 + CFG_NUM_ENDPOINTS];
};

static struct usb_endpoint_descriptor ep0_desc = {
	.bLength = sizeof(struct usb_endpoint_descriptor),
	.bDescriptorType = USB_DT_ENDPOINT,
	.bEndpointAddress = USB_DIR_IN,
	.bmAttributes = USB_ENDPOINT_XFER_CONTROL,
};

static inline int fifo_to_ep(struct fotg210_chip *chip, int id, int in)
{
	return (id < 0) ? 0 : ((id & 0x03) + 1);
}

static inline int ep_to_fifo(struct fotg210_chip *chip, int id)
{
	return (id <= 0) ? -1 : ((id - 1) & 0x03);
}

static inline int ep_reset(struct fotg210_chip *chip, uint8_t ep_addr)
{
	int ep = ep_addr & USB_ENDPOINT_NUMBER_MASK;
	struct fotg210_regs *regs = chip->regs;

	if (ep_addr & USB_DIR_IN) {
		/* reset endpoint */
		setbits_le32(&regs->iep[ep - 1], IEP_RESET);
		mdelay(1);
		clrbits_le32(&regs->iep[ep - 1], IEP_RESET);
		/* clear endpoint stall */
		clrbits_le32(&regs->iep[ep - 1], IEP_STALL);
	} else {
		/* reset endpoint */
		setbits_le32(&regs->oep[ep - 1], OEP_RESET);
		mdelay(1);
		clrbits_le32(&regs->oep[ep - 1], OEP_RESET);
		/* clear endpoint stall */
		clrbits_le32(&regs->oep[ep - 1], OEP_STALL);
	}

	return 0;
}

static int fotg210_reset(struct fotg210_chip *chip)
{
	struct fotg210_regs *regs = chip->regs;
	uint32_t i;

	chip->state = USB_STATE_POWERED;

	/* chip enable */
	writel(DEVCTRL_EN, &regs->dev_ctrl);

	/* device address reset */
	chip->addr = 0;
	writel(0, &regs->dev_addr);

	/* set idle counter to 7ms */
	writel(7, &regs->idle);

	/* disable all interrupts */
	writel(IMR_MASK, &regs->imr);
	writel(GIMR_MASK, &regs->gimr);
	writel(GIMR0_MASK, &regs->gimr0);
	writel(GIMR1_MASK, &regs->gimr1);
	writel(GIMR2_MASK, &regs->gimr2);

	/* clear interrupts */
	writel(ISR_MASK, &regs->isr);
	writel(0, &regs->gisr);
	writel(0, &regs->gisr0);
	writel(0, &regs->gisr1);
	writel(0, &regs->gisr2);

	/* chip reset */
	setbits_le32(&regs->dev_ctrl, DEVCTRL_RESET);
	mdelay(10);
	if (readl(&regs->dev_ctrl) & DEVCTRL_RESET) {
		printf("fotg210: chip reset failed\n");
		return -1;
	}

	/* CX FIFO reset */
	setbits_le32(&regs->cxfifo, CXFIFO_CXFIFOCLR);
	mdelay(10);
	if (readl(&regs->cxfifo) & CXFIFO_CXFIFOCLR) {
		printf("fotg210: ep0 fifo reset failed\n");
		return -1;
	}

	/* create static ep-fifo map (EP1 <-> FIFO0, EP2 <-> FIFO1 ...) */
	writel(EPMAP14_DEFAULT, &regs->epmap14);
	writel(EPMAP58_DEFAULT, &regs->epmap58);
	writel(FIFOMAP_DEFAULT, &regs->fifomap);
	writel(0, &regs->fifocfg);
	for (i = 0; i < 8; ++i) {
		writel(CFG_EPX_MAX_PACKET_SIZE, &regs->iep[i]);
		writel(CFG_EPX_MAX_PACKET_SIZE, &regs->oep[i]);
	}

	/* FIFO reset */
	for (i = 0; i < 4; ++i) {
		writel(FIFOCSR_RESET, &regs->fifocsr[i]);
		mdelay(10);
		if (readl(&regs->fifocsr[i]) & FIFOCSR_RESET) {
			printf("fotg210: fifo%d reset failed\n", i);
			return -1;
		}
	}

	/* enable only device interrupt and triggered at level-high */
	writel(IMR_IRQLH | IMR_HOST | IMR_OTG, &regs->imr);
	writel(ISR_MASK, &regs->isr);
	/* disable EP0 IN/OUT interrupt */
	writel(GIMR0_CXOUT | GIMR0_CXIN, &regs->gimr0);
	/* disable EPX IN+SPK+OUT interrupts */
	writel(GIMR1_MASK, &regs->gimr1);
	/* disable wakeup+idle+dma+zlp interrupts */
	writel(GIMR2_WAKEUP | GIMR2_IDLE | GIMR2_DMAERR | GIMR2_DMAFIN
		| GIMR2_ZLPRX | GIMR2_ZLPTX, &regs->gimr2);
	/* enable all group interrupt */
	writel(0, &regs->gimr);

	/* suspend delay = 3 ms */
	writel(3, &regs->idle);

	/* turn-on device interrupts */
	setbits_le32(&regs->dev_ctrl, DEVCTRL_GIRQ_EN);

	return 0;
}

static inline int fotg210_cxwait(struct fotg210_chip *chip, uint32_t mask)
{
	struct fotg210_regs *regs = chip->regs;
	int ret = -1;
	ulong ts;

	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
		if ((readl(&regs->cxfifo) & mask) != mask)
			continue;
		ret = 0;
		break;
	}

	if (ret)
		printf("fotg210: cx/ep0 timeout\n");

	return ret;
}

static int fotg210_dma(struct fotg210_ep *ep, struct fotg210_request *req)
{
	struct fotg210_chip *chip = ep->chip;
	struct fotg210_regs *regs = chip->regs;
	uint32_t tmp, ts;
	uint8_t *buf  = req->req.buf + req->req.actual;
	uint32_t len  = req->req.length - req->req.actual;
	int fifo = ep_to_fifo(chip, ep->id);
	int ret = -EBUSY;

	/* 1. init dma buffer */
	if (len > ep->maxpacket)
		len = ep->maxpacket;

	/* 2. wait for dma ready (hardware) */
	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
		if (!(readl(&regs->dma_ctrl) & DMACTRL_START)) {
			ret = 0;
			break;
		}
	}
	if (ret) {
		printf("fotg210: dma busy\n");
		req->req.status = ret;
		return ret;
	}

	/* 3. DMA target setup */
	if (ep->desc->bEndpointAddress & USB_DIR_IN)
		flush_dcache_range((ulong)buf, (ulong)buf + len);
	else
		invalidate_dcache_range((ulong)buf, (ulong)buf + len);

	writel(virt_to_phys(buf), &regs->dma_addr);

	if (ep->desc->bEndpointAddress & USB_DIR_IN) {
		if (ep->id == 0) {
			/* Wait until cx/ep0 fifo empty */
			fotg210_cxwait(chip, CXFIFO_CXFIFOE);
			writel(DMAFIFO_CX, &regs->dma_fifo);
		} else {
			/* Wait until epx fifo empty */
			fotg210_cxwait(chip, CXFIFO_FIFOE(fifo));
			writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo);
		}
		writel(DMACTRL_LEN(len) | DMACTRL_MEM2FIFO, &regs->dma_ctrl);
	} else {
		uint32_t blen;

		if (ep->id == 0) {
			writel(DMAFIFO_CX, &regs->dma_fifo);
			do {
				blen = CXFIFO_BYTES(readl(&regs->cxfifo));
			} while (blen < len);
		} else {
			writel(DMAFIFO_FIFO(fifo), &regs->dma_fifo);
			blen = FIFOCSR_BYTES(readl(&regs->fifocsr[fifo]));
		}
		len  = (len < blen) ? len : blen;
		writel(DMACTRL_LEN(len) | DMACTRL_FIFO2MEM, &regs->dma_ctrl);
	}

	/* 4. DMA start */
	setbits_le32(&regs->dma_ctrl, DMACTRL_START);

	/* 5. DMA wait */
	ret = -EBUSY;
	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
		tmp = readl(&regs->gisr2);
		/* DMA complete */
		if (tmp & GISR2_DMAFIN) {
			ret = 0;
			break;
		}
		/* DMA error */
		if (tmp & GISR2_DMAERR) {
			printf("fotg210: dma error\n");
			break;
		}
		/* resume, suspend, reset */
		if (tmp & (GISR2_RESUME | GISR2_SUSPEND | GISR2_RESET)) {
			printf("fotg210: dma reset by host\n");
			break;
		}
	}

	/* 7. DMA target reset */
	if (ret)
		writel(DMACTRL_ABORT | DMACTRL_CLRFF, &regs->dma_ctrl);

	writel(0, &regs->gisr2);
	writel(0, &regs->dma_fifo);

	req->req.status = ret;
	if (!ret)
		req->req.actual += len;
	else
		printf("fotg210: ep%d dma error(code=%d)\n", ep->id, ret);

	return len;
}

/*
 * result of setup packet
 */
#define CX_IDLE		0
#define CX_FINISH	1
#define CX_STALL	2

static void fotg210_setup(struct fotg210_chip *chip)
{
	int id, ret = CX_IDLE;
	uint32_t tmp[2];
	struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)tmp;
	struct fotg210_regs *regs = chip->regs;

	/*
	 * If this is the first Cx 8 byte command,
	 * we can now query USB mode (high/full speed; USB 2.0/USB 1.0)
	 */
	if (chip->state == USB_STATE_POWERED) {
		chip->state = USB_STATE_DEFAULT;
		if (readl(&regs->otgcsr) & OTGCSR_DEV_B) {
			/* Mini-B */
			if (readl(&regs->dev_ctrl) & DEVCTRL_HS) {
				puts("fotg210: HS\n");
				chip->gadget.speed = USB_SPEED_HIGH;
				/* SOF mask timer = 1100 ticks */
				writel(SOFMTR_TMR(1100), &regs->sof_mtr);
			} else {
				puts("fotg210: FS\n");
				chip->gadget.speed = USB_SPEED_FULL;
				/* SOF mask timer = 10000 ticks */
				writel(SOFMTR_TMR(10000), &regs->sof_mtr);
			}
		} else {
			printf("fotg210: mini-A?\n");
		}
	}

	/* switch data port to ep0 */
	writel(DMAFIFO_CX, &regs->dma_fifo);
	/* fetch 8 bytes setup packet */
	tmp[0] = readl(&regs->ep0_data);
	tmp[1] = readl(&regs->ep0_data);
	/* release data port */
	writel(0, &regs->dma_fifo);

	if (req->bRequestType & USB_DIR_IN)
		ep0_desc.bEndpointAddress = USB_DIR_IN;
	else
		ep0_desc.bEndpointAddress = USB_DIR_OUT;

	ret = CX_IDLE;

	if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
		switch (req->bRequest) {
		case USB_REQ_SET_CONFIGURATION:
			debug("fotg210: set_cfg(%d)\n", req->wValue & 0x00FF);
			if (!(req->wValue & 0x00FF)) {
				chip->state = USB_STATE_ADDRESS;
				writel(chip->addr, &regs->dev_addr);
			} else {
				chip->state = USB_STATE_CONFIGURED;
				writel(chip->addr | DEVADDR_CONF,
					&regs->dev_addr);
			}
			ret = CX_IDLE;
			break;

		case USB_REQ_SET_ADDRESS:
			debug("fotg210: set_addr(0x%04X)\n", req->wValue);
			chip->state = USB_STATE_ADDRESS;
			chip->addr  = req->wValue & DEVADDR_ADDR_MASK;
			ret = CX_FINISH;
			writel(chip->addr, &regs->dev_addr);
			break;

		case USB_REQ_CLEAR_FEATURE:
			debug("fotg210: clr_feature(%d, %d)\n",
				req->bRequestType & 0x03, req->wValue);
			switch (req->wValue) {
			case 0:    /* [Endpoint] halt */
				ep_reset(chip, req->wIndex);
				ret = CX_FINISH;
				break;
			case 1:    /* [Device] remote wake-up */
			case 2:    /* [Device] test mode */
			default:
				ret = CX_STALL;
				break;
			}
			break;

		case USB_REQ_SET_FEATURE:
			debug("fotg210: set_feature(%d, %d)\n",
				req->wValue, req->wIndex & 0xf);
			switch (req->wValue) {
			case 0:    /* Endpoint Halt */
				id = req->wIndex & 0xf;
				setbits_le32(&regs->iep[id - 1], IEP_STALL);
				setbits_le32(&regs->oep[id - 1], OEP_STALL);
				ret = CX_FINISH;
				break;
			case 1:    /* Remote Wakeup */
			case 2:    /* Test Mode */
			default:
				ret = CX_STALL;
				break;
			}
			break;

		case USB_REQ_GET_STATUS:
			debug("fotg210: get_status\n");
			ret = CX_STALL;
			break;

		case USB_REQ_SET_DESCRIPTOR:
			debug("fotg210: set_descriptor\n");
			ret = CX_STALL;
			break;

		case USB_REQ_SYNCH_FRAME:
			debug("fotg210: sync frame\n");
			ret = CX_STALL;
			break;
		}
	} /* if ((req->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) */

	if (ret == CX_IDLE && chip->driver->setup) {
		if (chip->driver->setup(&chip->gadget, req) < 0)
			ret = CX_STALL;
		else
			ret = CX_FINISH;
	}

	switch (ret) {
	case CX_FINISH:
		setbits_le32(&regs->cxfifo, CXFIFO_CXFIN);
		break;

	case CX_STALL:
		setbits_le32(&regs->cxfifo, CXFIFO_CXSTALL | CXFIFO_CXFIN);
		printf("fotg210: cx_stall!\n");
		break;

	case CX_IDLE:
		debug("fotg210: cx_idle?\n");
	default:
		break;
	}
}

/*
 * fifo - FIFO id
 * zlp  - zero length packet
 */
static void fotg210_recv(struct fotg210_chip *chip, int ep_id)
{
	struct fotg210_regs *regs = chip->regs;
	struct fotg210_ep *ep = chip->ep + ep_id;
	struct fotg210_request *req;
	int len;

	if (ep->stopped || (ep->desc->bEndpointAddress & USB_DIR_IN)) {
		printf("fotg210: ep%d recv, invalid!\n", ep->id);
		return;
	}

	if (list_empty(&ep->queue)) {
		printf("fotg210: ep%d recv, drop!\n", ep->id);
		return;
	}

	req = list_first_entry(&ep->queue, struct fotg210_request, queue);
	len = fotg210_dma(ep, req);
	if (len < ep->ep.maxpacket || req->req.length <= req->req.actual) {
		list_del_init(&req->queue);
		if (req->req.complete)
			req->req.complete(&ep->ep, &req->req);
	}

	if (ep->id > 0 && list_empty(&ep->queue)) {
		setbits_le32(&regs->gimr1,
			GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id)));
	}
}

/*
 * USB Gadget Layer
 */
static int fotg210_ep_enable(
	struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
{
	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
	struct fotg210_chip *chip = ep->chip;
	struct fotg210_regs *regs = chip->regs;
	int id = ep_to_fifo(chip, ep->id);
	int in = (desc->bEndpointAddress & USB_DIR_IN) ? 1 : 0;

	if (!_ep || !desc
		|| desc->bDescriptorType != USB_DT_ENDPOINT
		|| le16_to_cpu(desc->wMaxPacketSize) == 0) {
		printf("fotg210: bad ep or descriptor\n");
		return -EINVAL;
	}

	ep->desc = desc;
	ep->stopped = 0;

	if (in)
		setbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_IN));

	switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
	case USB_ENDPOINT_XFER_CONTROL:
		return -EINVAL;

	case USB_ENDPOINT_XFER_ISOC:
		setbits_le32(&regs->fifocfg,
			FIFOCFG(id, FIFOCFG_EN | FIFOCFG_ISOC));
		break;

	case USB_ENDPOINT_XFER_BULK:
		setbits_le32(&regs->fifocfg,
			FIFOCFG(id, FIFOCFG_EN | FIFOCFG_BULK));
		break;

	case USB_ENDPOINT_XFER_INT:
		setbits_le32(&regs->fifocfg,
			FIFOCFG(id, FIFOCFG_EN | FIFOCFG_INTR));
		break;
	}

	return 0;
}

static int fotg210_ep_disable(struct usb_ep *_ep)
{
	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
	struct fotg210_chip *chip = ep->chip;
	struct fotg210_regs *regs = chip->regs;
	int id = ep_to_fifo(chip, ep->id);

	ep->desc = NULL;
	ep->stopped = 1;

	clrbits_le32(&regs->fifocfg, FIFOCFG(id, FIFOCFG_CFG_MASK));
	clrbits_le32(&regs->fifomap, FIFOMAP(id, FIFOMAP_DIR_MASK));

	return 0;
}

static struct usb_request *fotg210_ep_alloc_request(
	struct usb_ep *_ep, gfp_t gfp_flags)
{
	struct fotg210_request *req = malloc(sizeof(*req));

	if (req) {
		memset(req, 0, sizeof(*req));
		INIT_LIST_HEAD(&req->queue);
	}
	return &req->req;
}

static void fotg210_ep_free_request(
	struct usb_ep *_ep, struct usb_request *_req)
{
	struct fotg210_request *req;

	req = container_of(_req, struct fotg210_request, req);
	free(req);
}

static int fotg210_ep_queue(
	struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
{
	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
	struct fotg210_chip *chip = ep->chip;
	struct fotg210_regs *regs = chip->regs;
	struct fotg210_request *req;

	req = container_of(_req, struct fotg210_request, req);
	if (!_req || !_req->complete || !_req->buf
		|| !list_empty(&req->queue)) {
		printf("fotg210: invalid request to ep%d\n", ep->id);
		return -EINVAL;
	}

	if (!chip || chip->state == USB_STATE_SUSPENDED) {
		printf("fotg210: request while chip suspended\n");
		return -EINVAL;
	}

	req->req.actual = 0;
	req->req.status = -EINPROGRESS;

	if (req->req.length == 0) {
		req->req.status = 0;
		if (req->req.complete)
			req->req.complete(&ep->ep, &req->req);
		return 0;
	}

	if (ep->id == 0) {
		do {
			int len = fotg210_dma(ep, req);
			if (len < ep->ep.maxpacket)
				break;
			if (ep->desc->bEndpointAddress & USB_DIR_IN)
				udelay(100);
		} while (req->req.length > req->req.actual);
	} else {
		if (ep->desc->bEndpointAddress & USB_DIR_IN) {
			do {
				int len = fotg210_dma(ep, req);
				if (len < ep->ep.maxpacket)
					break;
			} while (req->req.length > req->req.actual);
		} else {
			list_add_tail(&req->queue, &ep->queue);
			clrbits_le32(&regs->gimr1,
				GIMR1_FIFO_RX(ep_to_fifo(chip, ep->id)));
		}
	}

	if (ep->id == 0 || (ep->desc->bEndpointAddress & USB_DIR_IN)) {
		if (req->req.complete)
			req->req.complete(&ep->ep, &req->req);
	}

	return 0;
}

static int fotg210_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
{
	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
	struct fotg210_request *req;

	/* make sure it's actually queued on this endpoint */
	list_for_each_entry(req, &ep->queue, queue) {
		if (&req->req == _req)
			break;
	}
	if (&req->req != _req)
		return -EINVAL;

	/* remove the request */
	list_del_init(&req->queue);

	/* update status & invoke complete callback */
	if (req->req.status == -EINPROGRESS) {
		req->req.status = -ECONNRESET;
		if (req->req.complete)
			req->req.complete(_ep, &req->req);
	}

	return 0;
}

static int fotg210_ep_halt(struct usb_ep *_ep, int halt)
{
	struct fotg210_ep *ep = container_of(_ep, struct fotg210_ep, ep);
	struct fotg210_chip *chip = ep->chip;
	struct fotg210_regs *regs = chip->regs;
	int ret = -1;

	debug("fotg210: ep%d halt=%d\n", ep->id, halt);

	/* Endpoint STALL */
	if (ep->id > 0 && ep->id <= CFG_NUM_ENDPOINTS) {
		if (halt) {
			/* wait until all ep fifo empty */
			fotg210_cxwait(chip, 0xf00);
			/* stall */
			if (ep->desc->bEndpointAddress & USB_DIR_IN) {
				setbits_le32(&regs->iep[ep->id - 1],
					IEP_STALL);
			} else {
				setbits_le32(&regs->oep[ep->id - 1],
					OEP_STALL);
			}
		} else {
			if (ep->desc->bEndpointAddress & USB_DIR_IN) {
				clrbits_le32(&regs->iep[ep->id - 1],
					IEP_STALL);
			} else {
				clrbits_le32(&regs->oep[ep->id - 1],
					OEP_STALL);
			}
		}
		ret = 0;
	}

	return ret;
}

/*
 * activate/deactivate link with host.
 */
static void pullup(struct fotg210_chip *chip, int is_on)
{
	struct fotg210_regs *regs = chip->regs;

	if (is_on) {
		if (!chip->pullup) {
			chip->state = USB_STATE_POWERED;
			chip->pullup = 1;
			/* enable the chip */
			setbits_le32(&regs->dev_ctrl, DEVCTRL_EN);
			/* clear unplug bit (BIT0) */
			clrbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG);
		}
	} else {
		chip->state = USB_STATE_NOTATTACHED;
		chip->pullup = 0;
		chip->addr = 0;
		writel(chip->addr, &regs->dev_addr);
		/* set unplug bit (BIT0) */
		setbits_le32(&regs->phy_tmsr, PHYTMSR_UNPLUG);
		/* disable the chip */
		clrbits_le32(&regs->dev_ctrl, DEVCTRL_EN);
	}
}

static int fotg210_pullup(struct usb_gadget *_gadget, int is_on)
{
	struct fotg210_chip *chip;

	chip = container_of(_gadget, struct fotg210_chip, gadget);

	debug("fotg210: pullup=%d\n", is_on);

	pullup(chip, is_on);

	return 0;
}

static int fotg210_get_frame(struct usb_gadget *_gadget)
{
	struct fotg210_chip *chip;
	struct fotg210_regs *regs;

	chip = container_of(_gadget, struct fotg210_chip, gadget);
	regs = chip->regs;

	return SOFFNR_FNR(readl(&regs->sof_fnr));
}

static struct usb_gadget_ops fotg210_gadget_ops = {
	.get_frame = fotg210_get_frame,
	.pullup = fotg210_pullup,
};

static struct usb_ep_ops fotg210_ep_ops = {
	.enable         = fotg210_ep_enable,
	.disable        = fotg210_ep_disable,
	.queue          = fotg210_ep_queue,
	.dequeue        = fotg210_ep_dequeue,
	.set_halt       = fotg210_ep_halt,
	.alloc_request  = fotg210_ep_alloc_request,
	.free_request   = fotg210_ep_free_request,
};

static struct fotg210_chip controller = {
	.regs = (void __iomem *)CONFIG_FOTG210_BASE,
	.gadget = {
		.name = "fotg210_udc",
		.ops = &fotg210_gadget_ops,
		.ep0 = &controller.ep[0].ep,
		.speed = USB_SPEED_UNKNOWN,
		.is_dualspeed = 1,
		.is_otg = 0,
		.is_a_peripheral = 0,
		.b_hnp_enable = 0,
		.a_hnp_support = 0,
		.a_alt_hnp_support = 0,
	},
	.ep[0] = {
		.id = 0,
		.ep = {
			.name  = "ep0",
			.ops   = &fotg210_ep_ops,
		},
		.desc      = &ep0_desc,
		.chip      = &controller,
		.maxpacket = CFG_EP0_MAX_PACKET_SIZE,
	},
	.ep[1] = {
		.id = 1,
		.ep = {
			.name  = "ep1",
			.ops   = &fotg210_ep_ops,
		},
		.chip      = &controller,
		.maxpacket = CFG_EPX_MAX_PACKET_SIZE,
	},
	.ep[2] = {
		.id = 2,
		.ep = {
			.name  = "ep2",
			.ops   = &fotg210_ep_ops,
		},
		.chip      = &controller,
		.maxpacket = CFG_EPX_MAX_PACKET_SIZE,
	},
	.ep[3] = {
		.id = 3,
		.ep = {
			.name  = "ep3",
			.ops   = &fotg210_ep_ops,
		},
		.chip      = &controller,
		.maxpacket = CFG_EPX_MAX_PACKET_SIZE,
	},
	.ep[4] = {
		.id = 4,
		.ep = {
			.name  = "ep4",
			.ops   = &fotg210_ep_ops,
		},
		.chip      = &controller,
		.maxpacket = CFG_EPX_MAX_PACKET_SIZE,
	},
};

int usb_gadget_handle_interrupts(void)
{
	struct fotg210_chip *chip = &controller;
	struct fotg210_regs *regs = chip->regs;
	uint32_t id, st, isr, gisr;

	isr  = readl(&regs->isr) & (~readl(&regs->imr));
	gisr = readl(&regs->gisr) & (~readl(&regs->gimr));
	if (!(isr & ISR_DEV) || !gisr)
		return 0;

	writel(ISR_DEV, &regs->isr);

	/* CX interrupts */
	if (gisr & GISR_GRP0) {
		st = readl(&regs->gisr0);
		writel(0, &regs->gisr0);

		if (st & GISR0_CXERR)
			printf("fotg210: cmd error\n");

		if (st & GISR0_CXABORT)
			printf("fotg210: cmd abort\n");

		if (st & GISR0_CXSETUP)    /* setup */
			fotg210_setup(chip);
		else if (st & GISR0_CXEND) /* command finish */
			setbits_le32(&regs->cxfifo, CXFIFO_CXFIN);
	}

	/* FIFO interrupts */
	if (gisr & GISR_GRP1) {
		st = readl(&regs->gisr1);
		for (id = 0; id < 4; ++id) {
			if (st & GISR1_RX_FIFO(id))
				fotg210_recv(chip, fifo_to_ep(chip, id, 0));
		}
	}

	/* Device Status Interrupts */
	if (gisr & GISR_GRP2) {
		st = readl(&regs->gisr2);
		writel(0, &regs->gisr2);

		if (st & GISR2_RESET)
			printf("fotg210: reset by host\n");
		else if (st & GISR2_SUSPEND)
			printf("fotg210: suspend/removed\n");
		else if (st & GISR2_RESUME)
			printf("fotg210: resume\n");

		/* Errors */
		if (st & GISR2_ISOCERR)
			printf("fotg210: iso error\n");
		if (st & GISR2_ISOCABT)
			printf("fotg210: iso abort\n");
		if (st & GISR2_DMAERR)
			printf("fotg210: dma error\n");
	}

	return 0;
}

int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
	int i, ret = 0;
	struct fotg210_chip *chip = &controller;

	if (!driver    || !driver->bind || !driver->setup) {
		puts("fotg210: bad parameter.\n");
		return -EINVAL;
	}

	INIT_LIST_HEAD(&chip->gadget.ep_list);
	for (i = 0; i < CFG_NUM_ENDPOINTS + 1; ++i) {
		struct fotg210_ep *ep = chip->ep + i;

		ep->ep.maxpacket = ep->maxpacket;
		INIT_LIST_HEAD(&ep->queue);

		if (ep->id == 0) {
			ep->stopped = 0;
		} else {
			ep->stopped = 1;
			list_add_tail(&ep->ep.ep_list, &chip->gadget.ep_list);
		}
	}

	if (fotg210_reset(chip)) {
		puts("fotg210: reset failed.\n");
		return -EINVAL;
	}

	ret = driver->bind(&chip->gadget);
	if (ret) {
		debug("fotg210: driver->bind() returned %d\n", ret);
		return ret;
	}
	chip->driver = driver;

	return ret;
}

int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
{
	struct fotg210_chip *chip = &controller;

	driver->unbind(&chip->gadget);
	chip->driver = NULL;

	pullup(chip, 0);

	return 0;
}
