/* usb_dc_dw.c - USB DesignWare device controller driver */

/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief USB DesignWare device controller driver
 *
 * USB DesignWare device controller driver. The driver implements the low
 * level control routines to deal directly with the hardware.
 */

#include <string.h>
#include <stdio.h>
#include <misc/byteorder.h>
#include <usb/usb_device.h>
#include "usb_dw_registers.h"
#include <soc.h>
#ifdef CONFIG_QMSI
#include "clk.h"
#endif

#define LOG_LEVEL CONFIG_USB_DRIVER_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(usb_dc_dw);

/* convert from endpoint address to hardware endpoint index */
#define USB_DW_EP_ADDR2IDX(ep)  ((ep) & ~USB_EP_DIR_MASK)
/* get direction from endpoint address */
#define USB_DW_EP_ADDR2DIR(ep)  ((ep) & USB_EP_DIR_MASK)
/* convert from hardware endpoint index and direction to endpoint address */
#define USB_DW_EP_IDX2ADDR(idx, dir)    ((idx) | ((dir) & USB_EP_DIR_MASK))

/* Number of SETUP back-to-back packets */
#define USB_DW_SUP_CNT (1)

/*
 * USB endpoint private structure.
 */
struct usb_ep_ctrl_prv {
	u8_t ep_ena;
	u8_t fifo_num;
	u32_t fifo_size;
	u16_t mps;         /* Max ep pkt size */
	usb_dc_ep_callback cb;/* Endpoint callback function */
	u32_t data_len;
};

/*
 * USB controller private structure.
 */
struct usb_dw_ctrl_prv {
	usb_dc_status_callback status_cb;
	struct usb_ep_ctrl_prv in_ep_ctrl[USB_DW_IN_EP_NUM];
	struct usb_ep_ctrl_prv out_ep_ctrl[USB_DW_OUT_EP_NUM];
	int n_tx_fifos;
	u8_t attached;
};


static struct usb_dw_ctrl_prv usb_dw_ctrl;

static inline void usb_dw_int_unmask(void)
{
#if defined(CONFIG_SOC_QUARK_SE_C1000)
	QM_INTERRUPT_ROUTER->usb_0_int_mask &= ~BIT(0);
#endif
}

static void usb_dw_reg_dump(void)
{
	u8_t i;

	LOG_DBG("USB registers:  GOTGCTL : 0x%x  GOTGINT : 0x%x  GAHBCFG : "
		"0x%x", USB_DW->gotgctl, USB_DW->gotgint, USB_DW->gahbcfg);
	LOG_DBG("  GUSBCFG : 0x%x  GINTSTS : 0x%x  GINTMSK : 0x%x",
		USB_DW->gusbcfg, USB_DW->gintsts, USB_DW->gintmsk);
	LOG_DBG("  DCFG    : 0x%x  DCTL    : 0x%x  DSTS    : 0x%x",
		USB_DW->dcfg, USB_DW->dctl, USB_DW->dsts);
	LOG_DBG("  DIEPMSK : 0x%x  DOEPMSK : 0x%x  DAINT   : 0x%x",
		USB_DW->diepmsk, USB_DW->doepmsk, USB_DW->daint);
	LOG_DBG("  DAINTMSK: 0x%x  GHWCFG1 : 0x%x  GHWCFG2 : 0x%x",
		USB_DW->daintmsk, USB_DW->ghwcfg1, USB_DW->ghwcfg2);
	LOG_DBG("  GHWCFG3 : 0x%x  GHWCFG4 : 0x%x",
		USB_DW->ghwcfg3, USB_DW->ghwcfg4);

	for (i = 0U; i < USB_DW_OUT_EP_NUM; i++) {
		LOG_DBG("\n  EP %d registers:    DIEPCTL : 0x%x    DIEPINT : "
			"0x%x", i, USB_DW->in_ep_reg[i].diepctl,
			USB_DW->in_ep_reg[i].diepint);
		LOG_DBG("    DIEPTSIZ: 0x%x    DIEPDMA : 0x%x    DOEPCTL : "
			"0x%x", USB_DW->in_ep_reg[i].dieptsiz,
			USB_DW->in_ep_reg[i].diepdma,
			USB_DW->out_ep_reg[i].doepctl);
		LOG_DBG("    DOEPINT : 0x%x    DOEPTSIZ: 0x%x    DOEPDMA : "
			"0x%x", USB_DW->out_ep_reg[i].doepint,
			USB_DW->out_ep_reg[i].doeptsiz,
			USB_DW->out_ep_reg[i].doepdma);
	}
}

static u8_t usb_dw_ep_is_valid(u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	/* Check if ep enabled */
	if ((USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) &&
	    ep_idx < USB_DW_OUT_EP_NUM) {
		return 1;
	} else if ((USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) &&
	    ep_idx < USB_DW_IN_EP_NUM) {
		return 1;
	}

	return 0;
}

static u8_t usb_dw_ep_is_enabled(u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	/* Check if ep enabled */
	if ((USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) &&
	    usb_dw_ctrl.out_ep_ctrl[ep_idx].ep_ena) {
		return 1;
	} else if ((USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) &&
	    usb_dw_ctrl.in_ep_ctrl[ep_idx].ep_ena) {
		return 1;
	}

	return 0;
}

static inline void usb_dw_udelay(u32_t us)
{
	k_busy_wait(us);
}

static int usb_dw_reset(void)
{
	u32_t cnt = 0U;

	/* Wait for AHB master idle state. */
	while (!(USB_DW->grstctl & USB_DW_GRSTCTL_AHB_IDLE)) {
		usb_dw_udelay(1);
		if (++cnt > USB_DW_CORE_RST_TIMEOUT_US) {
			LOG_ERR("USB reset HANG! AHB Idle GRSTCTL=0x%08x",
				USB_DW->grstctl);
			return -EIO;
		}
	}

	/* Core Soft Reset */
	cnt = 0U;
	USB_DW->grstctl |= USB_DW_GRSTCTL_C_SFT_RST;
	do {
		if (++cnt > USB_DW_CORE_RST_TIMEOUT_US) {
			LOG_DBG("USB reset HANG! Soft Reset GRSTCTL=0x%08x",
				USB_DW->grstctl);
			return -EIO;
		}
		usb_dw_udelay(1);
	} while (USB_DW->grstctl & USB_DW_GRSTCTL_C_SFT_RST);

	/* Wait for 3 PHY Clocks */
	usb_dw_udelay(100);

	return 0;
}

static int usb_dw_clock_enable(void)
{
#if defined(CONFIG_SOC_QUARK_SE_C1000)
	/* 7.2.7 USB Clock Operation */
	clk_sys_set_mode(CLK_SYS_CRYSTAL_OSC, CLK_SYS_DIV_1);

	/* Enable the USB Clock */
	QM_SCSS_CCU->ccu_mlayer_ahb_ctl |= QM_CCU_USB_CLK_EN;

	/* Set up the PLL. */
	QM_USB_PLL_CFG0 = QM_USB_PLL_CFG0_DEFAULT | QM_USB_PLL_PDLD;

	/* Wait for the PLL lock */
	while (0 == (QM_USB_PLL_CFG0 & QM_USB_PLL_LOCK)) {
	}
#endif
	return 0;
}

static void usb_dw_clock_disable(void)
{
#if defined(CONFIG_SOC_QUARK_SE_C1000)
	/* Disable the USB Clock */
	QM_SCSS_CCU->ccu_mlayer_ahb_ctl &= ~QM_CCU_USB_CLK_EN;

	/* Disable the PLL */
	QM_USB_PLL_CFG0 &= ~QM_USB_PLL_PDLD;
#endif
}

static int usb_dw_num_dev_eps(void)
{
	return (USB_DW->ghwcfg2 >> 10) & 0xf;
}

static void usb_dw_flush_tx_fifo(int ep)
{
	int fnum = usb_dw_ctrl.in_ep_ctrl[ep].fifo_num;

	USB_DW->grstctl = (fnum << 6) | (1<<5);
	while (USB_DW->grstctl & (1<<5))
		;
}

static int usb_dw_tx_fifo_avail(int ep)
{
	return USB_DW->in_ep_reg[ep].dtxfsts &
		USB_DW_DTXFSTS_TXF_SPC_AVAIL_MASK;
}

/* Choose a FIFO number for an IN endpoint */
static int usb_dw_set_fifo(u8_t ep)
{
	int ep_idx = USB_DW_EP_ADDR2IDX(ep);
	volatile u32_t *reg = &USB_DW->in_ep_reg[ep_idx].diepctl;
	u32_t val;
	int fifo = 0;
	int ded_fifo = !!(USB_DW->ghwcfg4 & USB_DW_HWCFG4_DEDFIFOMODE);

	if (!ded_fifo) {
		/* No support for shared-FIFO mode yet, existing
		 * Zephyr hardware doesn't use it
		 */
		return -ENOTSUP;
	}

	/* In dedicated-FIFO mode, all IN endpoints must have a unique
	 * FIFO number associated with them in the TXFNUM field of
	 * DIEPCTLx, with EP0 always being assigned to FIFO zero (the
	 * reset default, so we don't touch it).
	 *
	 * FIXME: would be better (c.f. the dwc2 driver in Linux) to
	 * choose a FIFO based on the hardware depth: we want the
	 * smallest one that fits our configured maximum packet size
	 * for the endpoint.  This just picks the next available one.
	 */
	if (ep_idx != 0) {
		fifo = ++usb_dw_ctrl.n_tx_fifos;

		if (fifo >= usb_dw_num_dev_eps()) {
			return -EINVAL;
		}

		reg = &USB_DW->in_ep_reg[ep_idx].diepctl;
		val = *reg & ~USB_DW_DEPCTL_TXFNUM_MASK;
		val |= fifo << USB_DW_DEPCTL_TXFNUM_OFFSET;
		*reg = val;
	}

	usb_dw_ctrl.in_ep_ctrl[ep_idx].fifo_num = fifo;

	usb_dw_flush_tx_fifo(ep_idx);

	val = usb_dw_tx_fifo_avail(ep_idx);
	usb_dw_ctrl.in_ep_ctrl[ep_idx].fifo_size = val;

	return 0;
}

static int usb_dw_ep_set(u8_t ep,
	u32_t ep_mps, enum usb_dc_ep_type ep_type)
{
	volatile u32_t *p_depctl;
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	LOG_DBG("%s ep %x, mps %d, type %d", __func__, ep, ep_mps, ep_type);

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		p_depctl = &USB_DW->out_ep_reg[ep_idx].doepctl;
		usb_dw_ctrl.out_ep_ctrl[ep_idx].mps = ep_mps;
	} else {
		p_depctl = &USB_DW->in_ep_reg[ep_idx].diepctl;
		usb_dw_ctrl.in_ep_ctrl[ep_idx].mps = ep_mps;
	}

	if (!ep_idx) {
		/* Set max packet size for EP0 */
		*p_depctl &= ~USB_DW_DEPCTL0_MSP_MASK;
		switch (ep_mps) {
		case 8:
			*p_depctl |= USB_DW_DEPCTL0_MSP_8 <<
			    USB_DW_DEPCTL_MSP_OFFSET;
			break;
		case 16:
			*p_depctl |= USB_DW_DEPCTL0_MSP_16 <<
			    USB_DW_DEPCTL_MSP_OFFSET;
			break;
		case 32:
			*p_depctl |= USB_DW_DEPCTL0_MSP_32 <<
			    USB_DW_DEPCTL_MSP_OFFSET;
			break;
		case 64:
			*p_depctl |= USB_DW_DEPCTL0_MSP_64 <<
			    USB_DW_DEPCTL_MSP_OFFSET;
			break;
		default:
			return -EINVAL;
		}
		/* No need to set EP0 type */
	} else {
		/* Set max packet size for EP */
		if (ep_mps > (USB_DW_DEPCTLn_MSP_MASK >>
		    USB_DW_DEPCTL_MSP_OFFSET)) {
			return -EINVAL;
		}

		*p_depctl &= ~USB_DW_DEPCTLn_MSP_MASK;
		*p_depctl |= ep_mps << USB_DW_DEPCTL_MSP_OFFSET;

		/* Set endpoint type */
		*p_depctl &= ~USB_DW_DEPCTL_EP_TYPE_MASK;
		switch (ep_type) {
		case USB_DC_EP_CONTROL:
			*p_depctl |= USB_DW_DEPCTL_EP_TYPE_CONTROL <<
			    USB_DW_DEPCTL_EP_TYPE_OFFSET;
			break;
		case USB_DC_EP_BULK:
			*p_depctl |= USB_DW_DEPCTL_EP_TYPE_BULK <<
			    USB_DW_DEPCTL_EP_TYPE_OFFSET;
			break;
		case USB_DC_EP_INTERRUPT:
			*p_depctl |= USB_DW_DEPCTL_EP_TYPE_INTERRUPT <<
			    USB_DW_DEPCTL_EP_TYPE_OFFSET;
			break;
		default:
			return -EINVAL;
		}

		/* sets the Endpoint Data PID to DATA0 */
		*p_depctl |= USB_DW_DEPCTL_SETDOPID;
	}

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) {
		int ret = usb_dw_set_fifo(ep);

		if (ret) {
			return ret;
		}
	}

	return 0;
}

static void usb_dw_prep_rx(const u8_t ep, u8_t setup)
{
	enum usb_dw_out_ep_idx ep_idx = USB_DW_EP_ADDR2IDX(ep);
	u32_t ep_mps = usb_dw_ctrl.out_ep_ctrl[ep_idx].mps;

	/* Set max RX size to EP mps so we get an interrupt
	 * each time a packet is received
	 */

	USB_DW->out_ep_reg[ep_idx].doeptsiz =
	    (USB_DW_SUP_CNT << USB_DW_DOEPTSIZ_SUP_CNT_OFFSET) |
	    (1 << USB_DW_DEPTSIZ_PKT_CNT_OFFSET) | ep_mps;

    /* Clear NAK and enable ep */
	if (!setup) {
		USB_DW->out_ep_reg[ep_idx].doepctl |= USB_DW_DEPCTL_CNAK;
	}
	USB_DW->out_ep_reg[ep_idx].doepctl |= USB_DW_DEPCTL_EP_ENA;

	LOG_DBG("USB OUT EP%d armed", ep_idx);
}

static int usb_dw_tx(u8_t ep, const u8_t *const data,
		u32_t data_len)
{
	enum usb_dw_in_ep_idx ep_idx = USB_DW_EP_ADDR2IDX(ep);
	u32_t max_xfer_size, max_pkt_cnt, pkt_cnt, avail_space;
	u32_t ep_mps = usb_dw_ctrl.in_ep_ctrl[ep_idx].mps;
	unsigned int key;
	u32_t i;

	/* Wait for FIFO space available */
	do {
		avail_space = usb_dw_tx_fifo_avail(ep_idx);
		if (avail_space == usb_dw_ctrl.in_ep_ctrl[ep_idx].fifo_size) {
			break;
		}
		/* Make sure we don't hog the CPU */
		k_yield();
	} while (1);

	key = irq_lock();

	avail_space *= 4U;
	if (!avail_space) {
		LOG_ERR("USB IN EP%d no space available, DTXFSTS %x", ep_idx,
			USB_DW->in_ep_reg[ep_idx].dtxfsts);
		irq_unlock(key);
		return -EAGAIN;
	}

	/* For now tx-fifo sizes are not configured (cf usb_dw_set_fifo). Here
	 * we force available fifo size to be a multiple of ep mps in order to
	 * prevent splitting data incorrectly.
	 */
	avail_space -= avail_space % ep_mps;

	if (data_len > avail_space) {
		data_len = avail_space;
	}

	if (data_len != 0U) {
		/* Get max packet size and packet count for ep */
		if (ep_idx == USB_DW_IN_EP_0) {
			max_pkt_cnt =
			    USB_DW_DIEPTSIZ0_PKT_CNT_MASK >>
			    USB_DW_DEPTSIZ_PKT_CNT_OFFSET;
			max_xfer_size =
			    USB_DW_DEPTSIZ0_XFER_SIZE_MASK >>
			    USB_DW_DEPTSIZ_XFER_SIZE_OFFSET;
		} else {
			max_pkt_cnt =
			    USB_DW_DIEPTSIZn_PKT_CNT_MASK >>
			    USB_DW_DEPTSIZ_PKT_CNT_OFFSET;
			max_xfer_size =
			    USB_DW_DEPTSIZn_XFER_SIZE_MASK >>
			    USB_DW_DEPTSIZ_XFER_SIZE_OFFSET;
		}

		/* Check if transfer len is too big */
		if (data_len > max_xfer_size) {
			LOG_WRN("USB IN EP%d len too big (%d->%d)", ep_idx,
				data_len, max_xfer_size);
			data_len = max_xfer_size;
		}

		/*
		 * Program the transfer size and packet count as follows:
		 *
		 * transfer size = N * ep_maxpacket + short_packet
		 * pktcnt = N + (short_packet exist ? 1 : 0)
		 */

		pkt_cnt = (data_len + ep_mps - 1) / ep_mps;

		if (pkt_cnt > max_pkt_cnt) {
			LOG_WRN("USB IN EP%d pkt count too big (%d->%d)",
				ep_idx, pkt_cnt, pkt_cnt);
			pkt_cnt = max_pkt_cnt;
			data_len = pkt_cnt * ep_mps;
		}
	} else {
		/* Zero length packet */
		pkt_cnt = 1U;
	}

	/* Set number of packets and transfer size */
	USB_DW->in_ep_reg[ep_idx].dieptsiz =
	    (pkt_cnt << USB_DW_DEPTSIZ_PKT_CNT_OFFSET) | data_len;

	/* Clear NAK and enable ep */
	USB_DW->in_ep_reg[ep_idx].diepctl |= (USB_DW_DEPCTL_EP_ENA |
					      USB_DW_DEPCTL_CNAK);

	/*
	 * Write data to FIFO, make sure that we are protected against
	 * other USB register accesses.  According to "DesignWare Cores
	 * USB 1.1/2.0 Device Subsystem-AHB/VCI Databook": "During FIFO
	 * access, the application must not access the UDC/Subsystem
	 * registers or vendor registers (for ULPI mode). After starting
	 * to access a FIFO, the application must complete the transaction
	 * before accessing the register."
	 */
	for (i = 0U; i < data_len; i += 4U) {
		u32_t val = data[i];

		if (i + 1 < data_len) {
			val |= ((u32_t)data[i+1]) << 8;
		}
		if (i + 2 < data_len) {
			val |= ((u32_t)data[i+2]) << 16;
		}
		if (i + 3 < data_len) {
			val |= ((u32_t)data[i+3]) << 24;
		}
		USB_DW_EP_FIFO(ep_idx) = val;
	}
	irq_unlock(key);

	LOG_DBG("USB IN EP%d write %u bytes", ep_idx, data_len);

	return data_len;
}

static int usb_dw_init(void)
{
	u8_t ep;
	int ret;

	ret = usb_dw_reset();
	if (ret) {
		return ret;
	}

#ifdef CONFIG_USB_DW_USB_2_0
	/* set the PHY interface to be 16-bit UTMI */
	USB_DW->gusbcfg = (USB_DW->gusbcfg & ~USB_DW_GUSBCFG_PHY_IF_MASK) |
		USB_DW_GUSBCFG_PHY_IF_16_BIT;

	/* Set USB2.0 High Speed */
	USB_DW->dcfg |= USB_DW_DCFG_DEV_SPD_USB2_HS;
#else
	/* Set device speed to Full Speed */
	USB_DW->dcfg |= USB_DW_DCFG_DEV_SPD_FS;
#endif

	/* Set NAK for all OUT EPs */
	for (ep = 0U; ep < USB_DW_OUT_EP_NUM; ep++) {
		USB_DW->out_ep_reg[ep].doepctl = USB_DW_DEPCTL_SNAK;
	}

	/* Enable global interrupts */
	USB_DW->gintmsk = USB_DW_GINTSTS_OEP_INT |
	    USB_DW_GINTSTS_IEP_INT |
	    USB_DW_GINTSTS_ENUM_DONE |
	    USB_DW_GINTSTS_USB_RST |
	    USB_DW_GINTSTS_WK_UP_INT |
	    USB_DW_GINTSTS_USB_SUSP;

	/* Enable global interrupt */
	USB_DW->gahbcfg |= USB_DW_GAHBCFG_GLB_INTR_MASK;

    /* Disable soft disconnect */
	USB_DW->dctl &= ~USB_DW_DCTL_SFT_DISCON;

	usb_dw_reg_dump();

	return 0;
}

static void usb_dw_handle_reset(void)
{
	LOG_DBG("USB RESET event");

	/* Inform upper layers */
	if (usb_dw_ctrl.status_cb) {
		usb_dw_ctrl.status_cb(USB_DC_RESET, NULL);
	}

	/* Clear device address during reset. */
	USB_DW->dcfg &= ~USB_DW_DCFG_DEV_ADDR_MASK;

	/* enable global EP interrupts */
	USB_DW->doepmsk = 0U;
	USB_DW->gintmsk |= USB_DW_GINTSTS_RX_FLVL;
	USB_DW->diepmsk |= USB_DW_DIEPINT_XFER_COMPL;
}

static void usb_dw_handle_enum_done(void)
{
	u32_t speed;

	speed = (USB_DW->dsts & ~USB_DW_DSTS_ENUM_SPD_MASK) >>
	    USB_DW_DSTS_ENUM_SPD_OFFSET;

	LOG_DBG("USB ENUM DONE event, %s speed detected",
		speed == USB_DW_DSTS_ENUM_LS ? "Low" : "Full");

	/* Inform upper layers */
	if (usb_dw_ctrl.status_cb) {
		usb_dw_ctrl.status_cb(USB_DC_CONNECTED, NULL);
	}
}

/* USB ISR handler */
static void usb_dw_isr_handler(void)
{
	u32_t int_status, ep_int_status;
	u8_t ep_idx;
	usb_dc_ep_callback ep_cb;

	/*  Read interrupt status */
	while ((int_status = (USB_DW->gintsts & USB_DW->gintmsk))) {

		LOG_DBG("USB GINTSTS 0x%x", int_status);

		if (int_status & USB_DW_GINTSTS_USB_RST) {
			/* Clear interrupt. */
			USB_DW->gintsts = USB_DW_GINTSTS_USB_RST;

			/* Reset detected */
			usb_dw_handle_reset();
		}

		if (int_status & USB_DW_GINTSTS_ENUM_DONE) {
			/* Clear interrupt. */
			USB_DW->gintsts = USB_DW_GINTSTS_ENUM_DONE;

			/* Enumeration done detected */
			usb_dw_handle_enum_done();
		}

		if (int_status & USB_DW_GINTSTS_USB_SUSP) {
			/* Clear interrupt. */
			USB_DW->gintsts = USB_DW_GINTSTS_USB_SUSP;

			if (usb_dw_ctrl.status_cb) {
				usb_dw_ctrl.status_cb(USB_DC_SUSPEND, NULL);
			}
		}

		if (int_status & USB_DW_GINTSTS_WK_UP_INT) {
			/* Clear interrupt. */
			USB_DW->gintsts = USB_DW_GINTSTS_WK_UP_INT;

			if (usb_dw_ctrl.status_cb) {
				usb_dw_ctrl.status_cb(USB_DC_RESUME, NULL);
			}
		}

		if (int_status & USB_DW_GINTSTS_RX_FLVL) {
			/* Packet in RX FIFO */
			u32_t status, xfer_size;
			u32_t grxstsp = USB_DW->grxstsp;

			ep_idx = grxstsp & USB_DW_GRXSTSR_EP_NUM_MASK;
			status = (grxstsp & USB_DW_GRXSTSR_PKT_STS_MASK) >>
			    USB_DW_GRXSTSR_PKT_STS_OFFSET;
			xfer_size = (grxstsp & USB_DW_GRXSTSR_PKT_CNT_MASK) >>
			    USB_DW_GRXSTSR_PKT_CNT_OFFSET;

			LOG_DBG("USB OUT EP%d: RX_FLVL status %d, size %d",
				ep_idx, status, xfer_size);
			usb_dw_ctrl.out_ep_ctrl[ep_idx].data_len = xfer_size;
			ep_cb = usb_dw_ctrl.out_ep_ctrl[ep_idx].cb;
			switch (status) {
			case USB_DW_GRXSTSR_PKT_STS_SETUP:
				/* Call the registered callback if any */
				if (ep_cb) {
					ep_cb(USB_DW_EP_IDX2ADDR(ep_idx,
					    USB_EP_DIR_OUT),
					    USB_DC_EP_SETUP);
					}
				break;
			case USB_DW_GRXSTSR_PKT_STS_OUT_DATA:
				if (ep_cb) {
					ep_cb(USB_DW_EP_IDX2ADDR(ep_idx,
					    USB_EP_DIR_OUT),
					    USB_DC_EP_DATA_OUT);
					}
				break;
			case USB_DW_GRXSTSR_PKT_STS_OUT_DATA_DONE:
			case USB_DW_GRXSTSR_PKT_STS_SETUP_DONE:
				break;
			default:
				break;
			}
		}

		if (int_status & USB_DW_GINTSTS_IEP_INT) {
			/* IN EP interrupt */
			for (ep_idx = 0U; ep_idx < USB_DW_IN_EP_NUM; ep_idx++) {
				if (USB_DW->daint &
				    USB_DW_DAINT_IN_EP_INT(ep_idx)) {
					/* Read IN EP interrupt status */
					ep_int_status =
					    USB_DW->in_ep_reg[ep_idx].diepint &
					    USB_DW->diepmsk;

					/* Clear IN EP interrupts */
					USB_DW->in_ep_reg[ep_idx].diepint =
					    ep_int_status;

					LOG_DBG("USB IN EP%d interrupt "
						"status: 0x%x", ep_idx,
						ep_int_status);

					ep_cb =
					    usb_dw_ctrl.in_ep_ctrl[ep_idx].cb;

					if ((ep_int_status &
					    USB_DW_DIEPINT_XFER_COMPL) &&
						ep_cb) {

						/* Call the registered
						 * callback
						 */
						ep_cb(USB_DW_EP_IDX2ADDR(ep_idx,
						    USB_EP_DIR_IN),
						    USB_DC_EP_DATA_IN);
					}
				}
			}
			/* Clear interrupt. */
			USB_DW->gintsts = USB_DW_GINTSTS_IEP_INT;
		}

		if (int_status & USB_DW_GINTSTS_OEP_INT) {
			/* No OUT interrupt expected in FIFO mode,
			 * just clear interruot
			 */
			for (ep_idx = 0U; ep_idx < USB_DW_OUT_EP_NUM; ep_idx++) {
				if (USB_DW->daint &
				    USB_DW_DAINT_OUT_EP_INT(ep_idx)) {
					/* Read OUT EP interrupt status */
					ep_int_status =
					    USB_DW->out_ep_reg[ep_idx].doepint &
					    USB_DW->doepmsk;

					/* Clear OUT EP interrupts */
					USB_DW->out_ep_reg[ep_idx].doepint =
					    ep_int_status;

					LOG_DBG("USB OUT EP%d interrupt "
						"status: 0x%x\n", ep_idx,
						ep_int_status);
				}
			}
			/* Clear interrupt. */
			USB_DW->gintsts = USB_DW_GINTSTS_OEP_INT;
		}
	}
}

int usb_dc_attach(void)
{
	int ret;

	if (usb_dw_ctrl.attached) {
		return 0;
	}

	ret = usb_dw_clock_enable();
	if (ret) {
		return ret;
	}

	ret = usb_dw_init();
	if (ret) {
		return ret;
	}

	/* Connect and enable USB interrupt */
	IRQ_CONNECT(USB_DW_IRQ, CONFIG_USB_DW_IRQ_PRI,
	    usb_dw_isr_handler, 0, IOAPIC_EDGE | IOAPIC_HIGH);
	irq_enable(USB_DW_IRQ);

	usb_dw_int_unmask();

	usb_dw_ctrl.attached = 1U;

	return 0;
}

int usb_dc_detach(void)
{
	if (!usb_dw_ctrl.attached) {
		return 0;
	}

	usb_dw_clock_disable();

	irq_disable(USB_DW_IRQ);

	/* Enable soft disconnect */
	USB_DW->dctl |= USB_DW_DCTL_SFT_DISCON;

	usb_dw_ctrl.attached = 0U;

	return 0;
}

int usb_dc_reset(void)
{
	int ret;

	ret = usb_dw_reset();

	/* Clear private data */
	(void)memset(&usb_dw_ctrl, 0, sizeof(usb_dw_ctrl));

	return ret;
}

int usb_dc_set_address(const u8_t addr)
{
	if (addr > (USB_DW_DCFG_DEV_ADDR_MASK >> USB_DW_DCFG_DEV_ADDR_OFFSET)) {
		return -EINVAL;
	}

	USB_DW->dcfg &= ~USB_DW_DCFG_DEV_ADDR_MASK;
	USB_DW->dcfg |= addr << USB_DW_DCFG_DEV_ADDR_OFFSET;

	return 0;
}

int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(cfg->ep_addr);

	LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps,
		cfg->ep_type);

	if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx) {
		LOG_ERR("invalid endpoint configuration");
		return -1;
	}

	if (cfg->ep_mps > DW_USB_MAX_PACKET_SIZE) {
		LOG_WRN("unsupported packet size");
		return -1;
	}

	if ((USB_DW_EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT) &&
	    (ep_idx >= DW_USB_OUT_EP_NUM)) {
		LOG_WRN("OUT endpoint address out of range");
		return -1;
	}

	if ((USB_DW_EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_IN) &&
	    (ep_idx >= DW_USB_IN_EP_NUM)) {
		LOG_WRN("IN endpoint address out of range");
		return -1;
	}

	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const ep_cfg)
{
	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep_cfg->ep_addr)) {
		return -EINVAL;
	}

	usb_dw_ep_set(ep_cfg->ep_addr, ep_cfg->ep_mps, ep_cfg->ep_type);

	return 0;
}

int usb_dc_ep_set_stall(const u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		USB_DW->out_ep_reg[ep_idx].doepctl |= USB_DW_DEPCTL_STALL;
	} else {
		USB_DW->in_ep_reg[ep_idx].diepctl |= USB_DW_DEPCTL_STALL;
	}

	return 0;
}

int usb_dc_ep_clear_stall(const u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (!ep_idx) {
		/* Not possible to clear stall for EP0 */
		return -EINVAL;
	}

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		USB_DW->out_ep_reg[ep_idx].doepctl &= ~USB_DW_DEPCTL_STALL;
	} else {
		USB_DW->in_ep_reg[ep_idx].diepctl &= ~USB_DW_DEPCTL_STALL;
	}

	return 0;
}

int usb_dc_ep_halt(const u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);
	volatile u32_t *p_depctl;


	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (!ep_idx) {
		/* Cannot disable EP0, just set stall */
		usb_dc_ep_set_stall(ep);
	} else {
		if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
			p_depctl = &USB_DW->out_ep_reg[ep_idx].doepctl;
		} else {
			p_depctl = &USB_DW->in_ep_reg[ep_idx].diepctl;
		}

		/* Set STALL and disable endpoint if enabled */
		if (*p_depctl & USB_DW_DEPCTL_EP_ENA) {
			*p_depctl |= USB_DW_DEPCTL_EP_DIS | USB_DW_DEPCTL_STALL;
		} else {
			*p_depctl |= USB_DW_DEPCTL_STALL;
		}
	}

	return 0;
}

int usb_dc_ep_is_stalled(const u8_t ep, u8_t *const stalled)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (!stalled) {
		return -EINVAL;
	}

	*stalled = 0U;
	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		if (USB_DW->out_ep_reg[ep_idx].doepctl & USB_DW_DEPCTL_STALL) {
			*stalled = 1U;
		}
	} else {
		if (USB_DW->in_ep_reg[ep_idx].diepctl & USB_DW_DEPCTL_STALL) {
			*stalled = 1U;
		}
	}

	return 0;
}

int usb_dc_ep_enable(const u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	/* enable EP interrupts */
	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		USB_DW->daintmsk |= USB_DW_DAINT_OUT_EP_INT(ep_idx);
	} else {
		USB_DW->daintmsk |= USB_DW_DAINT_IN_EP_INT(ep_idx);
	}

	/* Activate Ep */
	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		USB_DW->out_ep_reg[ep_idx].doepctl |= USB_DW_DEPCTL_USB_ACT_EP;
		usb_dw_ctrl.out_ep_ctrl[ep_idx].ep_ena = 1U;
	} else {
		USB_DW->in_ep_reg[ep_idx].diepctl |= USB_DW_DEPCTL_USB_ACT_EP;
		usb_dw_ctrl.in_ep_ctrl[ep_idx].ep_ena = 1U;
	}

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT &&
		usb_dw_ctrl.out_ep_ctrl[ep_idx].cb != usb_transfer_ep_callback) {
		/* Start reading now, except for transfer managed eps */
		usb_dw_prep_rx(ep, 0);
	}

	return 0;
}

int usb_dc_ep_disable(const u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	/* Disable EP interrupts */
	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		USB_DW->daintmsk &= ~USB_DW_DAINT_OUT_EP_INT(ep_idx);
		USB_DW->doepmsk &= ~USB_DW_DOEPINT_SET_UP;
	} else {
		USB_DW->daintmsk &= ~USB_DW_DAINT_IN_EP_INT(ep_idx);
		USB_DW->diepmsk &= ~USB_DW_DIEPINT_XFER_COMPL;
		USB_DW->gintmsk &= ~USB_DW_GINTSTS_RX_FLVL;
	}

	/* De-activate, disable and set NAK for Ep */
	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		USB_DW->out_ep_reg[ep_idx].doepctl &=
		    ~(USB_DW_DEPCTL_USB_ACT_EP |
		    USB_DW_DEPCTL_EP_ENA |
		    USB_DW_DEPCTL_SNAK);
		usb_dw_ctrl.out_ep_ctrl[ep_idx].ep_ena = 0U;
	} else {
		USB_DW->in_ep_reg[ep_idx].diepctl &=
		    ~(USB_DW_DEPCTL_USB_ACT_EP |
		    USB_DW_DEPCTL_EP_ENA |
		    USB_DW_DEPCTL_SNAK);
		usb_dw_ctrl.in_ep_ctrl[ep_idx].ep_ena = 0U;
	}

	return 0;
}

int usb_dc_ep_flush(const u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);
	u32_t cnt;

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		/* RX FIFO is global and cannot be flushed per EP */
		return -EINVAL;
	}

	/* Each endpoint has dedicated Tx FIFO */
	USB_DW->grstctl |= ep_idx << USB_DW_GRSTCTL_TX_FNUM_OFFSET;
	USB_DW->grstctl |= USB_DW_GRSTCTL_TX_FFLSH;

	cnt = 0U;
	do {
		if (++cnt > USB_DW_CORE_RST_TIMEOUT_US) {
			LOG_ERR("USB TX FIFO flush HANG!");
			return -EIO;
		}
		usb_dw_udelay(1);
	} while (USB_DW->grstctl & USB_DW_GRSTCTL_TX_FFLSH);

	return 0;
}

int usb_dc_ep_write(const u8_t ep, const u8_t *const data,
		const u32_t data_len, u32_t * const ret_bytes)
{
	int ret;

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	/* Check if IN ep */
	if (USB_DW_EP_ADDR2DIR(ep) != USB_EP_DIR_IN) {
		return -EINVAL;
	}

	/* Check if ep enabled */
	if (!usb_dw_ep_is_enabled(ep)) {
		return -EINVAL;
	}

	ret = usb_dw_tx(ep, data, data_len);
	if (ret < 0) {
		return ret;
	}

	if (ret_bytes) {
		*ret_bytes = ret;
	}

	return 0;
}

int usb_dc_ep_read_wait(u8_t ep, u8_t *data, u32_t max_data_len,
			u32_t *read_bytes)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);
	u32_t i, j, data_len, bytes_to_copy;

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		LOG_ERR("No valid endpoint");
		return -EINVAL;
	}

	/* Check if OUT ep */
	if (USB_DW_EP_ADDR2DIR(ep) != USB_EP_DIR_OUT) {
		LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	/* Allow to read 0 bytes */
	if (!data && max_data_len) {
		LOG_ERR("Wrong arguments");
		return -EINVAL;
	}

	/* Check if ep enabled */
	if (!usb_dw_ep_is_enabled(ep)) {
		LOG_ERR("Not enabled endpoint");
		return -EINVAL;
	}

	data_len = usb_dw_ctrl.out_ep_ctrl[ep_idx].data_len;

	if (!data && !max_data_len) {
		/* When both buffer and max data to read are zero return
		 * the available data in buffer
		 */
		if (read_bytes) {
			*read_bytes = data_len;
		}
		return 0;
	}


	if (data_len > max_data_len) {
		LOG_ERR("Not enough room to copy all the rcvd data!");
		bytes_to_copy = max_data_len;
	} else {
		bytes_to_copy = data_len;
	}

	LOG_DBG("Read EP%d, req %d, read %d bytes", ep, max_data_len,
		bytes_to_copy);

	/* Data in the FIFOs is always stored per 32-bit words */
	for (i = 0U; i < (bytes_to_copy & ~0x3); i += 4U) {
		*(u32_t *)(data + i) = USB_DW_EP_FIFO(ep_idx);
	}
	if (bytes_to_copy & 0x3) {
		/* Not multiple of 4 */
		u32_t last_dw = USB_DW_EP_FIFO(ep_idx);

		for (j = 0U; j < (bytes_to_copy & 0x3); j++) {
			*(data + i + j) =
				(sys_cpu_to_le32(last_dw) >> (j * 8U)) & 0xFF;
			}
	}

	usb_dw_ctrl.out_ep_ctrl[ep_idx].data_len -= bytes_to_copy;

	if (read_bytes) {
		*read_bytes = bytes_to_copy;
	}

	return 0;

}

int usb_dc_ep_read_continue(u8_t ep)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		LOG_ERR("No valid endpoint");
		return -EINVAL;
	}

	/* Check if OUT ep */
	if (USB_DW_EP_ADDR2DIR(ep) != USB_EP_DIR_OUT) {
		LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	if (!usb_dw_ctrl.out_ep_ctrl[ep_idx].data_len) {
		usb_dw_prep_rx(ep_idx, 0);
	}

	return 0;
}

int usb_dc_ep_read(const u8_t ep, u8_t *const data,
		const u32_t max_data_len, u32_t * const read_bytes)
{
	if (usb_dc_ep_read_wait(ep, data, max_data_len, read_bytes) != 0) {
		return -EINVAL;
	}

	if (!data && !max_data_len) {
		/* When both buffer and max data to read are zero the above
		 * call would fetch the data len and we simply return.
		 */
		return 0;
	}

	if (usb_dc_ep_read_continue(ep) != 0) {
		return -EINVAL;
	}

	return 0;
}

int usb_dc_ep_set_callback(const u8_t ep, const usb_dc_ep_callback cb)
{
	u8_t ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (!usb_dw_ctrl.attached && !usb_dw_ep_is_valid(ep)) {
		return -EINVAL;
	}

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_IN) {
		usb_dw_ctrl.in_ep_ctrl[ep_idx].cb = cb;
	} else {
		usb_dw_ctrl.out_ep_ctrl[ep_idx].cb = cb;
	}

	return 0;
}

int usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	usb_dw_ctrl.status_cb = cb;

	return 0;
}

int usb_dc_ep_mps(const u8_t ep)
{
	enum usb_dw_out_ep_idx ep_idx = USB_DW_EP_ADDR2IDX(ep);

	if (USB_DW_EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		return usb_dw_ctrl.out_ep_ctrl[ep_idx].mps;
	} else {
		return usb_dw_ctrl.in_ep_ctrl[ep_idx].mps;
	}
}
