/* usb_dc_kinetis.c - Kinetis USBFSOTG usb device driver */

/*
 * Copyright (c) 2017 PHYTEC Messtechnik GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>
#include <string.h>
#include <stdio.h>
#include <kernel.h>
#include <misc/byteorder.h>
#include <usb/usb_dc.h>
#include <board.h>
#include <device.h>

#define SYS_LOG_LEVEL CONFIG_SYS_LOG_USB_DRIVER_LEVEL
#define SYS_LOG_DOMAIN "usb/usbfsotg"
#include <logging/sys_log.h>

#define NUM_OF_EP_MAX		CONFIG_USBD_KINETIS_NUM_BIDIR_EP

#define BD_OWN_MASK		(1 << 5)
#define BD_DATA01_MASK		(1 << 4)
#define BD_KEEP_MASK		(1 << 3)
#define BD_NINC_MASK		(1 << 2)
#define BD_DTS_MASK		(1 << 1)
#define BD_STALL_MASK		(1 << 0)

#define KINETIS_SETUP_TOKEN	0x0d
#define KINETIS_IN_TOKEN	0x09
#define KINETIS_OUT_TOKEN	0x01

#define USBFSOTG_PERID		0x04
#define USBFSOTG_REV		0x33

#define KINETIS_EP_NUMOF_MASK	0xf
#define KINETIS_ADDR2IDX(addr)	((addr) & (KINETIS_EP_NUMOF_MASK))

#define EP_ADDR2IDX(ep)		((ep) & ~USB_EP_DIR_MASK)
#define EP_ADDR2DIR(ep)		((ep) & USB_EP_DIR_MASK)

/*
 * Buffer Descriptor (BD) entry provides endpoint buffer control
 * information for USBFS controller. Every endpoint direction requires
 * two BD entries.
 */
struct buf_descriptor {
	union {
		u32_t bd_fields;

		struct {
			u32_t reserved_1_0 : 2;
			u32_t tok_pid : 4;
			u32_t data01 : 1;
			u32_t own : 1;
			u32_t reserved_15_8 : 8;
			u32_t bc : 16;
		} get __packed;

		struct {
			u32_t reserved_1_0 : 2;
			u32_t bd_ctrl : 6;
			u32_t reserved_15_8 : 8;
			u32_t bc : 16;
		} set __packed;

	} __packed;
	u32_t   buf_addr;
} __packed;

/*
 * Buffer Descriptor Table for the endpoints buffer management.
 * The driver configuration with 16 fully bidirectional endpoints would require
 * four BD entries per endpoint and 512 bytes of memory.
 */
static struct buf_descriptor __aligned(512) bdt[(NUM_OF_EP_MAX) * 2 * 2];

#define BD_IDX_EP0TX_EVEN		2
#define BD_IDX_EP0TX_ODD		3

#define EP_BUF_NUMOF_BLOCKS		(NUM_OF_EP_MAX / 2)

K_MEM_POOL_DEFINE(ep_buf_pool, 16, 512, EP_BUF_NUMOF_BLOCKS, 4);

struct usb_ep_ctrl_data {
	struct ep_status {
		u16_t in_enabled : 1;
		u16_t out_enabled : 1;
		u16_t in_data1 : 1;
		u16_t out_data1 : 1;
		u16_t in_odd : 1;
		u16_t out_odd : 1;
		u16_t in_stalled : 1;
		u16_t out_stalled : 1;
	} status;
	u16_t mps_in;
	u16_t mps_out;
	struct k_mem_block mblock_in;
	struct k_mem_block mblock_out;
	usb_dc_ep_callback cb_in;
	usb_dc_ep_callback cb_out;
};

#define USBD_THREAD_STACK_SIZE		1024

struct usb_device_data {
	usb_dc_status_callback status_cb;
	u8_t address;
	u32_t bd_active;
	struct usb_ep_ctrl_data ep_ctrl[NUM_OF_EP_MAX];
	bool attached;

	K_THREAD_STACK_MEMBER(thread_stack, USBD_THREAD_STACK_SIZE);
	struct k_thread thread;
};

static struct usb_device_data dev_data;

#define USB_DC_CB_TYPE_MGMT		0
#define USB_DC_CB_TYPE_EP		1

struct cb_msg {
	u8_t ep;
	u8_t type;
	u32_t cb;
};

K_MSGQ_DEFINE(usb_dc_msgq, sizeof(struct cb_msg), 10, 4);
static void usb_kinetis_isr_handler(void);
static void usb_kinetis_thread_main(void *arg1, void *unused1, void *unused2);

/*
 * This function returns the BD element index based on
 * endpoint address and the odd bit.
 */
static inline u8_t get_bdt_idx(u8_t ep, u8_t odd)
{
	if (ep & USB_EP_DIR_IN) {
		return ((((KINETIS_ADDR2IDX(ep)) * 4) + 2  + (odd & 1)));
	}
	return ((((KINETIS_ADDR2IDX(ep)) * 4) + (odd & 1)));
}

static int kinetis_usb_init(void)
{
	/* enable USB voltage regulator */
	SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;

	USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
	k_busy_wait(2000);

	USB0->CTL = 0;
	/* enable USB module, AKA USBEN bit in CTL1 register */
	USB0->CTL |= USB_CTL_USBENSOFEN_MASK;

	if ((USB0->PERID != USBFSOTG_PERID) ||
	    (USB0->REV != USBFSOTG_REV)) {
		return -1;
	}

	USB0->BDTPAGE1 = (u8_t)(((u32_t)bdt) >> 8);
	USB0->BDTPAGE2 = (u8_t)(((u32_t)bdt) >> 16);
	USB0->BDTPAGE3 = (u8_t)(((u32_t)bdt) >> 24);

	/* clear interrupt flags */
	USB0->ISTAT = 0xFF;

	/* enable reset interrupt */
	USB0->INTEN = USB_INTEN_USBRSTEN_MASK;

	USB0->USBCTRL = USB_USBCTRL_PDE_MASK;

	k_thread_create(&dev_data.thread, dev_data.thread_stack,
			USBD_THREAD_STACK_SIZE,
			usb_kinetis_thread_main, NULL, NULL, NULL,
			K_PRIO_COOP(2), 0, K_NO_WAIT);

	/* Connect and enable USB interrupt */
	IRQ_CONNECT(CONFIG_USBD_KINETIS_IRQ, CONFIG_USBD_KINETIS_IRQ_PRI,
		    usb_kinetis_isr_handler, 0, 0);

	irq_enable(CONFIG_USBD_KINETIS_IRQ);

	SYS_LOG_DBG("");

	return 0;
}

int usb_dc_reset(void)
{
	for (u8_t i = 0; i < 16; i++) {
		USB0->ENDPOINT[i].ENDPT = 0;
	}
	memset(bdt, 0, sizeof(bdt));
	dev_data.bd_active = 0;
	dev_data.address = 0;

	USB0->CTL |= USB_CTL_ODDRST_MASK;
	USB0->CTL &= ~USB_CTL_ODDRST_MASK;

	/* Clear interrupt status flags */
	USB0->ISTAT = 0xFF;
	/* Clear error flags */
	USB0->ERRSTAT = 0xFF;
	/* Enable all error interrupt sources */
	USB0->ERREN = 0xFF;
	/* Reset default address */
	USB0->ADDR = 0x00;

	USB0->INTEN = (USB_INTEN_USBRSTEN_MASK |
		       USB_INTEN_TOKDNEEN_MASK |
		       USB_INTEN_SLEEPEN_MASK  |
		       USB_INTEN_SOFTOKEN_MASK |
		       USB_INTEN_STALLEN_MASK |
		       USB_INTEN_ERROREN_MASK);

	SYS_LOG_DBG("");

	return 0;
}

int usb_dc_attach(void)
{
	if (dev_data.attached) {
		SYS_LOG_WRN("already attached");
	}

	kinetis_usb_init();

	/*
	 * Call usb_dc_reset here because the device stack does not make it
	 * after USB_DC_RESET status event.
	 */
	usb_dc_reset();

	dev_data.attached = 1;
	SYS_LOG_DBG("attached");

	/* non-OTG device mode, enable DP Pullup */
	USB0->CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;

	return 0;
}

int usb_dc_detach(void)
{
	SYS_LOG_DBG("");
	/* disable USB and DP Pullup */
	USB0->CTL  &= ~USB_CTL_USBENSOFEN_MASK;
	USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;

	return 0;
}

int usb_dc_set_address(const u8_t addr)
{
	SYS_LOG_DBG("");
	/*
	 * The device stack tries to set the address before
	 * sending the ACK with ZLP, which is totally stupid,
	 * as workaround the addresse will be buffered and
	 * placed later inside isr handler (see KINETIS_IN_TOKEN).
	 */
	dev_data.address = 0x80 | (addr & 0x7f);

	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
{
	u8_t idx_even = get_bdt_idx(cfg->ep_addr, 0);
	u8_t idx_odd = get_bdt_idx(cfg->ep_addr, 1);
	u8_t ep_idx = EP_ADDR2IDX(cfg->ep_addr);
	struct k_mem_block *block;
	struct usb_ep_ctrl_data *ep_ctrl = &dev_data.ep_ctrl[ep_idx];

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled ||
	    dev_data.ep_ctrl[ep_idx].status.out_enabled)) {
		SYS_LOG_WRN("endpoint already configured");
		return -EBUSY;
	}


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

	if (EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT) {
		block = &(ep_ctrl->mblock_out);
	} else {
		block = &(ep_ctrl->mblock_in);
	}

	if (bdt[idx_even].buf_addr) {
		k_mem_pool_free(block);
	}

	USB0->ENDPOINT[ep_idx].ENDPT = 0;
	memset(&bdt[idx_even], 0, sizeof(struct buf_descriptor));
	memset(&bdt[idx_odd], 0, sizeof(struct buf_descriptor));

	if (k_mem_pool_alloc(&ep_buf_pool, block, cfg->ep_mps * 2, 10) == 0) {
		memset(block->data, 0, cfg->ep_mps * 2);
	} else {
		SYS_LOG_ERR("Memory allocation time-out");
		return -ENOMEM;
	}

	bdt[idx_even].buf_addr = (u32_t)block->data;
	SYS_LOG_INF("idx_even %x", (u32_t)block->data);
	bdt[idx_odd].buf_addr = (u32_t)(block->data + cfg->ep_mps);
	SYS_LOG_INF("idx_odd %x", (u32_t)(block->data + cfg->ep_mps));

	if (cfg->ep_addr & USB_EP_DIR_IN) {
		dev_data.ep_ctrl[ep_idx].mps_in = cfg->ep_mps;
	} else {
		dev_data.ep_ctrl[ep_idx].mps_out = cfg->ep_mps;
	}

	bdt[idx_even].set.bc = cfg->ep_mps;
	bdt[idx_odd].set.bc = cfg->ep_mps;

	dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
	dev_data.ep_ctrl[ep_idx].status.in_data1 = false;

	switch (cfg->ep_type) {
	case USB_DC_EP_CONTROL:
		SYS_LOG_DBG("configure control endpoint");
		USB0->ENDPOINT[ep_idx].ENDPT |= (USB_ENDPT_EPHSHK_MASK |
						 USB_ENDPT_EPRXEN_MASK |
						 USB_ENDPT_EPTXEN_MASK);
		break;
	case USB_DC_EP_BULK:
	case USB_DC_EP_INTERRUPT:
		USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPHSHK_MASK;
		if (EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT) {
			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
		} else {
			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
		}
		break;
	case USB_DC_EP_ISOCHRONOUS:
		if (EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT) {
			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
		} else {
			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

int usb_dc_ep_set_stall(const u8_t ep)
{
	u8_t ep_idx = EP_ADDR2IDX(ep);
	u8_t bd_idx;

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	SYS_LOG_DBG("ep %x, idx %d", ep, ep_idx);

	if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		dev_data.ep_ctrl[ep_idx].status.out_stalled = 1;
		bd_idx = get_bdt_idx(ep,
				     ~dev_data.ep_ctrl[ep_idx].status.out_odd);
	} else {
		dev_data.ep_ctrl[ep_idx].status.in_stalled = 1;
		bd_idx = get_bdt_idx(ep,
				     dev_data.ep_ctrl[ep_idx].status.in_odd);
	}

	bdt[bd_idx].set.bd_ctrl = BD_STALL_MASK | BD_DTS_MASK | BD_OWN_MASK;

	return 0;
}

int usb_dc_ep_clear_stall(const u8_t ep)
{
	u8_t ep_idx = EP_ADDR2IDX(ep);
	u8_t bd_idx;

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	SYS_LOG_DBG("ep %x, idx %d", ep, ep_idx);
	USB0->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;

	if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		dev_data.ep_ctrl[ep_idx].status.out_stalled = 0;
		dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
		bd_idx = get_bdt_idx(ep,
				     ~dev_data.ep_ctrl[ep_idx].status.out_odd);
		bdt[bd_idx].set.bd_ctrl = 0;
		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
	} else {
		dev_data.ep_ctrl[ep_idx].status.in_stalled = 0;
		dev_data.ep_ctrl[ep_idx].status.in_data1 = false;
		bd_idx = get_bdt_idx(ep,
				     dev_data.ep_ctrl[ep_idx].status.in_odd);
		bdt[bd_idx].set.bd_ctrl = 0;
	}

	/* Resume TX token processing, see USBx_CTL field descriptions */
	if (ep == 0) {
		USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
	}

	return 0;
}

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

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	SYS_LOG_DBG("ep %x, idx %d", ep_idx, ep);
	if (!stalled) {
		return -EINVAL;
	}

	*stalled = 0;
	if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		*stalled = dev_data.ep_ctrl[ep_idx].status.out_stalled;
	} else {
		*stalled = dev_data.ep_ctrl[ep_idx].status.in_stalled;
	}

	if (SYS_LOG_LEVEL == SYS_LOG_LEVEL_INFO) {
		u8_t bd_idx = get_bdt_idx(ep,
				dev_data.ep_ctrl[ep_idx].status.in_odd);
		bd_idx = bd_idx;
		SYS_LOG_WRN("active bd ctrl: %x", bdt[bd_idx].set.bd_ctrl);
		bd_idx = get_bdt_idx(ep,
				~dev_data.ep_ctrl[ep_idx].status.in_odd);
		SYS_LOG_WRN("next bd ctrl: %x", bdt[bd_idx].set.bd_ctrl);
	}

	return 0;
}

int usb_dc_ep_halt(const u8_t ep)
{
	return usb_dc_ep_set_stall(ep);
}

int usb_dc_ep_enable(const u8_t ep)
{
	u8_t idx_even = get_bdt_idx(ep, 0);
	u8_t idx_odd = get_bdt_idx(ep, 1);
	u8_t ep_idx = EP_ADDR2IDX(ep);

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled ||
	    dev_data.ep_ctrl[ep_idx].status.out_enabled)) {
		SYS_LOG_WRN("endpoint 0x%x already enabled", ep);
		return -EBUSY;
	}

	if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		bdt[idx_even].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
		bdt[idx_odd].set.bd_ctrl = 0;
		dev_data.ep_ctrl[ep_idx].status.out_odd = 0;
		dev_data.ep_ctrl[ep_idx].status.out_stalled = 0;
		dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
		dev_data.ep_ctrl[ep_idx].status.out_enabled = true;
	} else {
		bdt[idx_even].bd_fields = 0;
		bdt[idx_odd].bd_fields = 0;
		dev_data.ep_ctrl[ep_idx].status.in_odd = 0;
		dev_data.ep_ctrl[ep_idx].status.in_stalled = 0;
		dev_data.ep_ctrl[ep_idx].status.in_data1 = false;
		dev_data.ep_ctrl[ep_idx].status.in_enabled = true;
	}

	SYS_LOG_INF("ep 0x%x, ep_idx %d", ep, ep_idx);

	return 0;
}

int usb_dc_ep_disable(const u8_t ep)
{
	u8_t idx_even = get_bdt_idx(ep, 0);
	u8_t idx_odd = get_bdt_idx(ep, 1);
	u8_t ep_idx = EP_ADDR2IDX(ep);

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	SYS_LOG_INF("ep %x, idx %d", ep_idx, ep);

	bdt[idx_even].bd_fields = 0;
	bdt[idx_odd].bd_fields = 0;
	if (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT) {
		dev_data.ep_ctrl[ep_idx].status.out_enabled = false;
	} else {
		dev_data.ep_ctrl[ep_idx].status.in_enabled = false;
	}

	return 0;
}

int usb_dc_ep_flush(const u8_t ep)
{
	u8_t ep_idx = EP_ADDR2IDX(ep);

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	SYS_LOG_DBG("ep %x, idx %d", ep_idx, ep);

	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)
{
	u8_t ep_idx = EP_ADDR2IDX(ep);
	bool odd = dev_data.ep_ctrl[ep_idx].status.in_odd;
	u8_t bd_idx = get_bdt_idx(ep, odd);
	u8_t *bufp = (u8_t *)bdt[bd_idx].buf_addr;
	u32_t len_to_send = data_len;

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	if (EP_ADDR2DIR(ep) != USB_EP_DIR_IN) {
		SYS_LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	if (dev_data.ep_ctrl[ep_idx].status.in_stalled) {
		SYS_LOG_WRN("endpoint is stalled");
		return -EBUSY;
	}

	while (bdt[bd_idx].get.own) {
		SYS_LOG_DBG("ep 0x%x is busy", ep);
		k_yield();
	}

	SYS_LOG_DBG("bd idx %x bufp %p odd %d", bd_idx, bufp, odd);

	if (data_len > dev_data.ep_ctrl[ep_idx].mps_in) {
		len_to_send = dev_data.ep_ctrl[ep_idx].mps_in;
	}

	bdt[bd_idx].set.bc = len_to_send;

	for (u32_t n = 0; n < len_to_send; n++) {
		bufp[n] = data[n];
	}

	dev_data.ep_ctrl[ep_idx].status.in_odd = ~odd;
	if (dev_data.ep_ctrl[ep_idx].status.in_data1) {
		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK |
					  BD_DATA01_MASK |
					  BD_OWN_MASK;
	} else {
		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
	}

	/* Toggle next Data1 */
	dev_data.ep_ctrl[ep_idx].status.in_data1 ^= 1;

	SYS_LOG_DBG("ep 0x%x write %d bytes from %d",
		    ep, len_to_send, data_len);

	if (ret_bytes) {
		*ret_bytes = len_to_send;
	}

	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 = EP_ADDR2IDX(ep);
	/* select the index of active endpoint buffer */
	u8_t bd_idx = get_bdt_idx(ep, dev_data.ep_ctrl[ep_idx].status.out_odd);
	u8_t *bufp = (u8_t *)bdt[bd_idx].buf_addr;
	u32_t data_len;

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	if (EP_ADDR2DIR(ep) != USB_EP_DIR_OUT) {
		SYS_LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	if (dev_data.ep_ctrl[ep_idx].status.out_stalled) {
		SYS_LOG_WRN("endpoint is stalled");
		return -EBUSY;
	}

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

	while (bdt[bd_idx].get.own) {
		SYS_LOG_ERR("Endpoint is occupied by the controller");
		return -EBUSY;
	}

	data_len  = bdt[bd_idx].get.bc;

	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) {
		SYS_LOG_WRN("Not enough room to copy all the data!");
		data_len = max_data_len;
	}

	if (data != NULL) {
		for (u32_t i = 0; i < data_len; i++) {
			data[i] = bufp[i];
		}
	}

	SYS_LOG_DBG("Read idx %d, req %d, read %d bytes",
		    bd_idx, max_data_len, data_len);

	if (read_bytes) {
		*read_bytes = data_len;
	}

	return 0;
}


int usb_dc_ep_read_continue(u8_t ep)
{
	u8_t ep_idx = EP_ADDR2IDX(ep);
	u8_t bd_idx = get_bdt_idx(ep, dev_data.ep_ctrl[ep_idx].status.out_odd);

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		SYS_LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

	if (EP_ADDR2DIR(ep) != USB_EP_DIR_OUT) {
		SYS_LOG_ERR("Wrong endpoint direction");
		return -EINVAL;
	}

	if (bdt[bd_idx].get.own) {
		/* May occur when usb_transfer initializes the OUT transfer */
		SYS_LOG_WRN("Current buffer is claimed by the controller");
		return 0;
	}

	/* select the index of the next endpoint buffer */
	bd_idx = get_bdt_idx(ep, ~dev_data.ep_ctrl[ep_idx].status.out_odd);
	/* Update next toggle bit */
	dev_data.ep_ctrl[ep_idx].status.out_data1 ^= 1;
	bdt[bd_idx].set.bc = dev_data.ep_ctrl[ep_idx].mps_out;

	/* Reset next buffer descriptor and set next toggle bit  */
	if (dev_data.ep_ctrl[ep_idx].status.out_data1) {
		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK |
					  BD_DATA01_MASK |
					  BD_OWN_MASK;
	} else {
		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
	}

	/* Resume TX token processing, see USBx_CTL field descriptions */
	if (ep_idx == 0) {
		USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
	}

	SYS_LOG_DBG("idx next %x", bd_idx);

	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)
{
	int retval = usb_dc_ep_read_wait(ep, data, max_data_len, read_bytes);

	if (retval) {
		return retval;
	}

	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;
	}

	SYS_LOG_DBG("");

	return 0;
}

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

	if (!dev_data.attached) {
		return -EINVAL;
	}

	if (ep & USB_EP_DIR_IN) {
		dev_data.ep_ctrl[ep_idx].cb_in = cb;
	} else {
		dev_data.ep_ctrl[ep_idx].cb_out = cb;
	}
	SYS_LOG_DBG("ep_idx %x", ep_idx);

	return 0;
}

int usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	dev_data.status_cb = cb;
	SYS_LOG_DBG("");

	return 0;
}

int usb_dc_ep_mps(const u8_t ep)
{
	u8_t ep_idx = EP_ADDR2IDX(ep);

	if (ep & USB_EP_DIR_IN) {
		return dev_data.ep_ctrl[ep_idx].mps_in;
	} else {
		return dev_data.ep_ctrl[ep_idx].mps_out;
	}
}

static inline void reenable_all_endpoints(void)
{
	for (u8_t ep_idx = 0; ep_idx < NUM_OF_EP_MAX; ep_idx++) {
		if (dev_data.ep_ctrl[ep_idx].status.out_enabled) {
			usb_dc_ep_enable(ep_idx);
		}
		if (dev_data.ep_ctrl[ep_idx].status.in_enabled) {
			usb_dc_ep_enable(ep_idx | USB_EP_DIR_IN);
		}
	}
}

static void usb_kinetis_isr_handler(void)
{
	u8_t istatus  = USB0->ISTAT;
	u8_t status  = USB0->STAT;
	struct cb_msg msg;


	if (istatus & USB_ISTAT_USBRST_MASK) {
		dev_data.address = 0;
		USB0->ADDR = (u8_t)0;
		/*
		 * Device reset is not possible because the stack does not
		 * configure the endpoints after the USB_DC_RESET event,
		 * therefore, reenable all endpoints and set they BDT into a
		 * defined state.
		 */
		USB0->CTL |= USB_CTL_ODDRST_MASK;
		USB0->CTL &= ~USB_CTL_ODDRST_MASK;
		reenable_all_endpoints();
		msg.ep = 0;
		msg.type = USB_DC_CB_TYPE_MGMT;
		msg.cb = USB_DC_RESET;
		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
	}

	if (istatus == USB_ISTAT_ERROR_MASK) {
		USB0->ERRSTAT = 0xFF;
		msg.ep = 0;
		msg.type = USB_DC_CB_TYPE_MGMT;
		msg.cb = USB_DC_ERROR;
		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
	}

	if (istatus & USB_ISTAT_STALL_MASK) {
		if (dev_data.ep_ctrl[0].status.out_stalled) {
			usb_dc_ep_clear_stall(0);
		}
		if (dev_data.ep_ctrl[0].status.in_stalled) {
			usb_dc_ep_clear_stall(0x80);
		}
	}

	if (istatus & USB_ISTAT_TOKDNE_MASK) {

		u8_t ep_idx = status >> USB_STAT_ENDP_SHIFT;
		u8_t ep = ((status << 4) & USB_EP_DIR_IN) | ep_idx;
		u8_t odd = (status & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
		u8_t idx = get_bdt_idx(ep, odd);
		u8_t token_pid = bdt[idx].get.tok_pid;

		msg.ep = ep;
		msg.type = USB_DC_CB_TYPE_EP;

		switch (token_pid) {
		case KINETIS_SETUP_TOKEN:
			dev_data.ep_ctrl[ep_idx].status.out_odd = odd;
			/* clear tx entries */
			bdt[BD_IDX_EP0TX_EVEN].bd_fields = 0;
			bdt[BD_IDX_EP0TX_ODD].bd_fields = 0;
			/*
			 * Set/Reset here the toggle bits for control endpoint
			 * because the device stack does not care about it.
			 */
			dev_data.ep_ctrl[ep_idx].status.in_data1 = true;
			dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
			dev_data.ep_ctrl[ep_idx].status.out_odd = odd;

			msg.cb = USB_DC_EP_SETUP;
			k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
			break;
		case KINETIS_OUT_TOKEN:
			dev_data.ep_ctrl[ep_idx].status.out_odd = odd;

			msg.cb = USB_DC_EP_DATA_OUT;
			k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
			break;
		case KINETIS_IN_TOKEN:
			/* SET ADDRESS workaround */
			if (dev_data.address & 0x80) {
				USB0->ADDR = dev_data.address & 0x7f;
				dev_data.address = 0;
			}

			msg.cb = USB_DC_EP_DATA_IN;
			k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
			break;
		default:
			break;
		}
	}

	if (istatus & USB_ISTAT_SLEEP_MASK) {
		/* Enable resume interrupt */
		USB0->INTEN |= USB_INTEN_RESUMEEN_MASK;
		msg.ep = 0;
		msg.type = USB_DC_CB_TYPE_MGMT;
		msg.cb = USB_DC_SUSPEND;
		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
	}

	if (istatus & USB_ISTAT_RESUME_MASK) {
		/* Disable resume interrupt */
		USB0->INTEN &= ~USB_INTEN_RESUMEEN_MASK;
		msg.ep = 0;
		msg.type = USB_DC_CB_TYPE_MGMT;
		msg.cb = USB_DC_RESUME;
		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
	}

	/* Clear interrupt status bits */
	USB0->ISTAT = istatus;
}

/*
 * This thread is only used to not run the USB device stack and endpoint
 * callbacks in the ISR context, which happens when an callback function
 * is called. TODO: something similar should be implemented in the USB
 * device stack so that it can be used by all drivers.
 */
static void usb_kinetis_thread_main(void *arg1, void *unused1, void *unused2)
{
	ARG_UNUSED(arg1);
	ARG_UNUSED(unused1);
	ARG_UNUSED(unused2);
	struct cb_msg msg;
	u8_t ep_idx;

	while (true) {
		k_msgq_get(&usb_dc_msgq, &msg, K_FOREVER);
		ep_idx = EP_ADDR2IDX(msg.ep);

		if (msg.type == USB_DC_CB_TYPE_EP) {
			switch (msg.cb) {
			case USB_DC_EP_SETUP:
				if (dev_data.ep_ctrl[ep_idx].cb_out) {
					dev_data.ep_ctrl[ep_idx].cb_out(msg.ep,
						USB_DC_EP_SETUP);
				}
				break;
			case USB_DC_EP_DATA_OUT:
				if (dev_data.ep_ctrl[ep_idx].cb_out) {
					dev_data.ep_ctrl[ep_idx].cb_out(msg.ep,
						USB_DC_EP_DATA_OUT);
				}
				break;
			case USB_DC_EP_DATA_IN:
				if (dev_data.ep_ctrl[ep_idx].cb_in) {
					dev_data.ep_ctrl[ep_idx].cb_in(msg.ep,
						USB_DC_EP_DATA_IN);
				}
				break;
			default:
				SYS_LOG_ERR("unknown msg");
				break;
			}
		} else if (dev_data.status_cb) {
			switch (msg.cb) {
			case USB_DC_RESET:
				dev_data.status_cb(USB_DC_RESET, NULL);
				break;
			case USB_DC_ERROR:
				dev_data.status_cb(USB_DC_ERROR, NULL);
				break;
			case USB_DC_SUSPEND:
				dev_data.status_cb(USB_DC_SUSPEND, NULL);
				break;
			case USB_DC_RESUME:
				dev_data.status_cb(USB_DC_RESUME, NULL);
				break;
			default:
				SYS_LOG_ERR("unknown msg");
				break;
			}
		}
	}
}

