/*
 * 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);
			udelay(1);
			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);
		/*
		 * Write 1 and then 0 works for both W1C & RW.
		 *
		 * HW v1.11.0+: It's a W1C register (write 1 clear)
		 * HW v1.10.0-: It's a R/W register (write 0 clear)
		 */
		writel(st & GISR0_CXABORT, &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);
		/*
		 * Write 1 and then 0 works for both W1C & RW.
		 *
		 * HW v1.11.0+: It's a W1C register (write 1 clear)
		 * HW v1.10.0-: It's a R/W register (write 0 clear)
		 */
		writel(st, &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;
}
