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

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

#define DT_DRV_COMPAT nxp_kinetis_usbd

#include <soc.h>
#include <string.h>
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/init.h>

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

#define NUM_OF_EP_MAX		DT_INST_PROP(0, num_bidir_endpoints)

#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))

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

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

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

	} __packed;
	uint32_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_HEAP_DEFINE(ep_buf_pool, 512 * EP_BUF_NUMOF_BLOCKS + 128);

struct ep_mem_block {
	void *data;
};

struct usb_ep_ctrl_data {
	struct ep_status {
		uint16_t in_enabled : 1;
		uint16_t out_enabled : 1;
		uint16_t in_data1 : 1;
		uint16_t out_data1 : 1;
		uint16_t in_odd : 1;
		uint16_t out_odd : 1;
		uint16_t in_stalled : 1;
		uint16_t out_stalled : 1;
	} status;
	uint16_t mps_in;
	uint16_t mps_out;
	struct ep_mem_block mblock_in;
	struct ep_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;
	uint8_t address;
	uint32_t bd_active;
	struct usb_ep_ctrl_data ep_ctrl[NUM_OF_EP_MAX];
	bool attached;

	K_KERNEL_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 {
	uint8_t ep;
	uint8_t type;
	uint32_t cb;
};

K_MSGQ_DEFINE(usb_dc_msgq, sizeof(struct cb_msg), 10, 4);
static void usb_kinetis_isr_handler(void);

/*
 * This function returns the BD element index based on
 * endpoint address and the odd bit.
 */
static inline uint8_t get_bdt_idx(uint8_t ep, uint8_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 = (uint8_t)(((uint32_t)bdt) >> 8);
	USB0->BDTPAGE2 = (uint8_t)(((uint32_t)bdt) >> 16);
	USB0->BDTPAGE3 = (uint8_t)(((uint32_t)bdt) >> 24);

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

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

	USB0->USBCTRL = USB_USBCTRL_PDE_MASK;



	LOG_DBG("");

	return 0;
}

int usb_dc_reset(void)
{
	for (uint8_t i = 0; i < 16; i++) {
		USB0->ENDPOINT[i].ENDPT = 0;
	}
	dev_data.bd_active = 0U;
	dev_data.address = 0U;

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

	LOG_DBG("");

	return 0;
}

int usb_dc_attach(void)
{
	if (dev_data.attached) {
		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;
	LOG_DBG("attached");

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

	return 0;
}

int usb_dc_detach(void)
{
	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 uint8_t addr)
{
	LOG_DBG("");

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

	/*
	 * The device stack tries to set the address before
	 * sending the ACK with ZLP, which is totally stupid,
	 * as workaround the address 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_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
{
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);

	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
		LOG_ERR("endpoint index/address out of range");
		return -EINVAL;
	}

	switch (cfg->ep_type) {
	case USB_DC_EP_CONTROL:
		if (cfg->ep_mps > USB_MAX_CTRL_MPS) {
			return -EINVAL;
		}
		return 0;
	case USB_DC_EP_BULK:
		if (cfg->ep_mps > USB_MAX_FS_BULK_MPS) {
			return -EINVAL;
		}
		break;
	case USB_DC_EP_INTERRUPT:
		if (cfg->ep_mps > USB_MAX_FS_INT_MPS) {
			return -EINVAL;
		}
		break;
	case USB_DC_EP_ISOCHRONOUS:
		if (cfg->ep_mps > USB_MAX_FS_ISO_MPS) {
			return -EINVAL;
		}
		break;
	default:
		LOG_ERR("Unknown endpoint type!");
		return -EINVAL;
	}

	if (ep_idx & BIT(0)) {
		if (USB_EP_GET_DIR(cfg->ep_addr) != USB_EP_DIR_IN) {
			LOG_INF("pre-selected as IN endpoint");
			return -1;
		}
	} else {
		if (USB_EP_GET_DIR(cfg->ep_addr) != USB_EP_DIR_OUT) {
			LOG_INF("pre-selected as OUT endpoint");
			return -1;
		}
	}

	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
{
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
	struct usb_ep_ctrl_data *ep_ctrl;
	struct ep_mem_block *block;
	uint8_t idx_even;
	uint8_t idx_odd;

	if (usb_dc_ep_check_cap(cfg)) {
		return -EINVAL;
	}

	idx_even = get_bdt_idx(cfg->ep_addr, 0);
	idx_odd = get_bdt_idx(cfg->ep_addr, 1);
	ep_ctrl = &dev_data.ep_ctrl[ep_idx];

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

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

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

	if (bdt[idx_even].buf_addr) {
		k_heap_free(&ep_buf_pool, block->data);
	}

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

	block->data = k_heap_alloc(&ep_buf_pool, cfg->ep_mps * 2U, K_MSEC(10));
	if (block->data != NULL) {
		(void)memset(block->data, 0, cfg->ep_mps * 2U);
	} else {
		LOG_ERR("Memory allocation time-out");
		return -ENOMEM;
	}

	bdt[idx_even].buf_addr = (uint32_t)block->data;
	LOG_INF("idx_even %x", (uint32_t)block->data);
	bdt[idx_odd].buf_addr = (uint32_t)((uint8_t *)block->data + cfg->ep_mps);
	LOG_INF("idx_odd %x", (uint32_t)((uint8_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:
		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 (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
			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 (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
			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 uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint8_t bd_idx;

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

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

	if (USB_EP_DIR_IS_OUT(ep)) {
		dev_data.ep_ctrl[ep_idx].status.out_stalled = 1U;
		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 = 1U;
		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 uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint8_t bd_idx;

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

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

	if (USB_EP_DIR_IS_OUT(ep)) {
		dev_data.ep_ctrl[ep_idx].status.out_stalled = 0U;
		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 = 0U;
		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
	} else {
		dev_data.ep_ctrl[ep_idx].status.in_stalled = 0U;
		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 = 0U;
	}

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

	return 0;
}

int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *const stalled)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

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

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

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

	uint8_t bd_idx = get_bdt_idx(ep,
			dev_data.ep_ctrl[ep_idx].status.in_odd);
	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);
	LOG_WRN("next bd ctrl: %x", bdt[bd_idx].set.bd_ctrl);

	return 0;
}

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

int usb_dc_ep_enable(const uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint8_t idx_even;
	uint8_t idx_odd;

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

	idx_even = get_bdt_idx(ep, 0);
	idx_odd = get_bdt_idx(ep, 1);

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

	if (USB_EP_DIR_IS_OUT(ep)) {
		bdt[idx_even].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
		bdt[idx_odd].set.bd_ctrl = 0U;
		dev_data.ep_ctrl[ep_idx].status.out_odd = 0U;
		dev_data.ep_ctrl[ep_idx].status.out_stalled = 0U;
		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 = 0U;
		bdt[idx_odd].bd_fields = 0U;
		dev_data.ep_ctrl[ep_idx].status.in_odd = 0U;
		dev_data.ep_ctrl[ep_idx].status.in_stalled = 0U;
		dev_data.ep_ctrl[ep_idx].status.in_data1 = false;
		dev_data.ep_ctrl[ep_idx].status.in_enabled = true;
	}

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

	return 0;
}

int usb_dc_ep_disable(const uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint8_t idx_even;
	uint8_t idx_odd;

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

	idx_even = get_bdt_idx(ep, 0);
	idx_odd = get_bdt_idx(ep, 1);

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

	bdt[idx_even].bd_fields = 0U;
	bdt[idx_odd].bd_fields = 0U;
	if (USB_EP_DIR_IS_OUT(ep)) {
		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 uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

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

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

	return 0;
}

int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data,
		    const uint32_t data_len, uint32_t * const ret_bytes)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint32_t len_to_send = data_len;
	uint8_t odd;
	uint8_t bd_idx;
	uint8_t *bufp;

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

	odd = dev_data.ep_ctrl[ep_idx].status.in_odd;
	bd_idx = get_bdt_idx(ep, odd);
	bufp = (uint8_t *)bdt[bd_idx].buf_addr;

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

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

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

	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 (uint32_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;

	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(uint8_t ep, uint8_t *data, uint32_t max_data_len,
			uint32_t *read_bytes)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint32_t data_len;
	uint8_t bd_idx;
	uint8_t *bufp;

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

	/* select the index of active endpoint buffer */
	bd_idx = get_bdt_idx(ep, dev_data.ep_ctrl[ep_idx].status.out_odd);
	bufp = (uint8_t *)bdt[bd_idx].buf_addr;

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

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

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

	while (bdt[bd_idx].get.own) {
		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) {
		LOG_WRN("Not enough room to copy all the data!");
		data_len = max_data_len;
	}

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

	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(uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);
	uint8_t bd_idx;

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

	bd_idx = get_bdt_idx(ep, dev_data.ep_ctrl[ep_idx].status.out_odd);

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

	if (bdt[bd_idx].get.own) {
		/* May occur when usb_transfer initializes the OUT transfer */
		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 == 0U) {
		USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
	}

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

	return 0;
}

int usb_dc_ep_read(const uint8_t ep, uint8_t *const data,
		   const uint32_t max_data_len, uint32_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;
	}

	LOG_DBG("");

	return 0;
}

int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

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

	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;
	}
	LOG_DBG("ep_idx %x", ep_idx);

	return 0;
}

void usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	LOG_DBG("");

	dev_data.status_cb = cb;
}

int usb_dc_ep_mps(const uint8_t ep)
{
	uint8_t ep_idx = USB_EP_GET_IDX(ep);

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

	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_control_endpoints(void)
{
	struct usb_dc_ep_cfg_data ep_cfg;

	/* Reconfigure control endpoint 0 after a reset */
	ep_cfg.ep_addr = USB_CONTROL_EP_OUT;
	ep_cfg.ep_mps = USB_CONTROL_EP_MPS;
	ep_cfg.ep_type = USB_DC_EP_CONTROL;
	usb_dc_ep_configure(&ep_cfg);
	ep_cfg.ep_addr = USB_CONTROL_EP_IN;
	usb_dc_ep_configure(&ep_cfg);

	/* Enable both endpoint directions */
	usb_dc_ep_enable(USB_CONTROL_EP_OUT);
	usb_dc_ep_enable(USB_CONTROL_EP_IN);
}

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


	if (istatus & USB_ISTAT_USBRST_MASK) {
		dev_data.address = 0U;
		USB0->ADDR = (uint8_t)0;
		/*
		 * Device reset is not possible because the stack does not
		 * configure the endpoints after the USB_DC_RESET event,
		 * therefore, we must re-enable the default control 0 endpoint
		 * after a reset event
		 */
		USB0->CTL |= USB_CTL_ODDRST_MASK;
		USB0->CTL &= ~USB_CTL_ODDRST_MASK;
		reenable_control_endpoints();
		msg.ep = 0U;
		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 = 0U;
		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) {

		uint8_t ep_idx = status >> USB_STAT_ENDP_SHIFT;
		uint8_t ep = ((status << 4) & USB_EP_DIR_IN) | ep_idx;
		uint8_t odd = (status & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
		uint8_t idx = get_bdt_idx(ep, odd);
		uint8_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 = 0U;
			bdt[BD_IDX_EP0TX_ODD].bd_fields = 0U;
			/*
			 * 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 = 0U;
			}

			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 = 0U;
		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 = 0U;
		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;
	uint8_t ep_idx;

	while (true) {
		k_msgq_get(&usb_dc_msgq, &msg, K_FOREVER);
		ep_idx = USB_EP_GET_IDX(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:
				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:
				LOG_ERR("unknown msg");
				break;
			}
		}
	}
}

static int usb_kinetis_init(void)
{

	(void)memset(bdt, 0, sizeof(bdt));
	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);
	k_thread_name_set(&dev_data.thread, "usb_kinetis");

	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
		    usb_kinetis_isr_handler, 0, 0);
	irq_enable(DT_INST_IRQN(0));

	return 0;
}

SYS_INIT(usb_kinetis_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
