/*
 * Copyright 2018-2023, NXP
 * Copyright (c) 2019 PHYTEC Messtechnik GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_mcux_usbd

#include <soc.h>
#include <string.h>
#include <zephyr/drivers/usb/usb_dc.h>
#include <zephyr/usb/usb_device.h>
#include <soc.h>
#include <zephyr/device.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/pinctrl.h>
#include "usb.h"
#include "usb_device.h"
#include "usb_device_config.h"
#include "usb_device_dci.h"

#ifdef CONFIG_USB_DC_NXP_EHCI
#include "usb_device_ehci.h"
#endif
#ifdef CONFIG_USB_DC_NXP_LPCIP3511
#include "usb_device_lpcip3511.h"
#endif
#ifdef CONFIG_HAS_MCUX_CACHE
#include <fsl_cache.h>
#endif

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

static void usb_isr_handler(void);

/* the setup transfer state */
#define SETUP_DATA_STAGE_DONE	(0)
#define SETUP_DATA_STAGE_IN	(1)
#define SETUP_DATA_STAGE_OUT	(2)

/*
 * Endpoint absolute index calculation:
 *
 * MCUX EHCI USB device controller supports a specific
 * number of bidirectional endpoints. Bidirectional means
 * that an endpoint object is represented to the outside
 * as an OUT and an IN Endpoint with its own buffers
 * and control structures.
 *
 * EP_ABS_IDX refers to the corresponding control
 * structure, for example:
 *
 *  EP addr | ep_idx | ep_abs_idx
 * -------------------------------
 *  0x00    | 0x00   | 0x00
 *  0x80    | 0x00   | 0x01
 *  0x01    | 0x01   | 0x02
 *  0x81    | 0x01   | 0x03
 *  ....    | ....   | ....
 *
 * The NUM_OF_EP_MAX (and number of s_ep_ctrl) should be double
 * of num_bidir_endpoints.
 */
#define EP_ABS_IDX(ep)		(USB_EP_GET_IDX(ep) * 2 + \
					(USB_EP_GET_DIR(ep) >> 7))
#define NUM_OF_EP_MAX		(DT_INST_PROP(0, num_bidir_endpoints) * 2)
#define CONTROLLER_ID		(DT_INST_ENUM_IDX(0, usb_controller_index))

/* We do not need a buffer for the write side on platforms that have USB RAM.
 * The SDK driver will copy the data buffer to be sent to USB RAM.
 */
#ifdef CONFIG_USB_DC_NXP_LPCIP3511
#define EP_BUF_NUMOF_BLOCKS	(NUM_OF_EP_MAX / 2)
#else
#define EP_BUF_NUMOF_BLOCKS	NUM_OF_EP_MAX
#endif

/* The max MPS is 1023 for FS, 1024 for HS. */
#if defined(CONFIG_NOCACHE_MEMORY)
#define EP_BUF_NONCACHED
K_HEAP_DEFINE_NOCACHE(ep_buf_pool, 1024 * EP_BUF_NUMOF_BLOCKS);
#else
K_HEAP_DEFINE(ep_buf_pool, 1024 * EP_BUF_NUMOF_BLOCKS);
#endif

struct usb_ep_ctrl_data {
	usb_device_callback_message_struct_t transfer_message;
	struct k_mem_block block;
	usb_dc_ep_callback callback;
	uint16_t ep_mps;
	uint8_t ep_enabled : 1;
	uint8_t ep_occupied : 1;
};

struct usb_dc_state {
	usb_device_struct_t dev_struct;
	/* Controller handle */
	usb_dc_status_callback status_cb;
	struct usb_ep_ctrl_data *eps;
	bool attached;
	uint8_t setup_data_stage;
	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_USB_MCUX_THREAD_STACK_SIZE);

	struct k_thread thread;
};

static struct usb_ep_ctrl_data s_ep_ctrl[NUM_OF_EP_MAX];
static struct usb_dc_state dev_state;

/* Message queue for the usb thread */
K_MSGQ_DEFINE(usb_dc_msgq, sizeof(usb_device_callback_message_struct_t),
	CONFIG_USB_DC_MSG_QUEUE_LEN, 4);

#if defined(CONFIG_USB_DC_NXP_EHCI)
/* EHCI device driver interface */
static const usb_device_controller_interface_struct_t mcux_usb_iface = {
	USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
	USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
};

extern void USB_DeviceEhciIsrFunction(void *deviceHandle);

#elif defined(CONFIG_USB_DC_NXP_LPCIP3511)
/* LPCIP3511 device driver interface */
static const usb_device_controller_interface_struct_t mcux_usb_iface = {
	USB_DeviceLpc3511IpInit, USB_DeviceLpc3511IpDeinit, USB_DeviceLpc3511IpSend,
	USB_DeviceLpc3511IpRecv, USB_DeviceLpc3511IpCancel, USB_DeviceLpc3511IpControl
};

extern void USB_DeviceLpcIp3511IsrFunction(void *deviceHandle);

#endif

int usb_dc_reset(void)
{
	if (dev_state.dev_struct.controllerHandle != NULL) {
		dev_state.dev_struct.controllerInterface->deviceControl(
						dev_state.dev_struct.controllerHandle,
						kUSB_DeviceControlStop, NULL);
		dev_state.dev_struct.controllerInterface->deviceDeinit(
						dev_state.dev_struct.controllerHandle);
		dev_state.dev_struct.controllerHandle = NULL;
	}

	return 0;
}

int usb_dc_attach(void)
{
	usb_status_t status;

	dev_state.eps = &s_ep_ctrl[0];
	if (dev_state.attached) {
		LOG_WRN("Already attached");
		return 0;
	}

	dev_state.dev_struct.controllerInterface = &mcux_usb_iface;
	status = dev_state.dev_struct.controllerInterface->deviceInit(CONTROLLER_ID,
						&dev_state.dev_struct,
						&dev_state.dev_struct.controllerHandle);
	if (kStatus_USB_Success != status) {
		return -EIO;
	}

	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
		    usb_isr_handler, 0, 0);
	irq_enable(DT_INST_IRQN(0));
	dev_state.attached = true;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
						dev_state.dev_struct.controllerHandle,
						kUSB_DeviceControlRun, NULL);

	LOG_DBG("Attached");

	return 0;
}

int usb_dc_detach(void)
{
	usb_status_t status;

	if (dev_state.dev_struct.controllerHandle == NULL) {
		LOG_WRN("Device not attached");
		return 0;
	}

	status = dev_state.dev_struct.controllerInterface->deviceControl(
						   dev_state.dev_struct.controllerHandle,
						   kUSB_DeviceControlStop,
						   NULL);
	if (kStatus_USB_Success != status) {
		return -EIO;
	}

	status = dev_state.dev_struct.controllerInterface->deviceDeinit(
						   dev_state.dev_struct.controllerHandle);
	if (kStatus_USB_Success != status) {
		return -EIO;
	}

	dev_state.dev_struct.controllerHandle = NULL;
	dev_state.attached = false;
	LOG_DBG("Detached");

	return 0;
}

int usb_dc_set_address(const uint8_t addr)
{
	usb_status_t status;

	dev_state.dev_struct.deviceAddress = addr;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
		dev_state.dev_struct.controllerHandle,
		kUSB_DeviceControlPreSetDeviceAddress,
		&dev_state.dev_struct.deviceAddress);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to set device address");
		return -EINVAL;
	}
	return 0;
}

int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data *const cfg)
{
	uint8_t ep_abs_idx =  EP_ABS_IDX(cfg->ep_addr);
	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);

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

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

	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
{
	uint8_t ep_abs_idx =  EP_ABS_IDX(cfg->ep_addr);
	usb_device_endpoint_init_struct_t ep_init;
	struct usb_ep_ctrl_data *eps = &dev_state.eps[ep_abs_idx];
	usb_status_t status;
	uint8_t ep;

	ep_init.zlt = 0U;
	ep_init.endpointAddress = cfg->ep_addr;
	ep_init.maxPacketSize = cfg->ep_mps;
	ep_init.transferType = cfg->ep_type;

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

	if (dev_state.eps[ep_abs_idx].ep_enabled) {
		LOG_WRN("Endpoint already configured");
		return 0;
	}

	ep = cfg->ep_addr;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlEndpointDeinit, &ep);
	if (kStatus_USB_Success != status) {
		LOG_WRN("Failed to un-initialize endpoint (status=%d)", (int)status);
	}

#ifdef CONFIG_USB_DC_NXP_LPCIP3511
	/* Allocate buffers used during read operation */
	if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
#endif
		struct k_mem_block *block;

		block = &(eps->block);
		if (block->data) {
			k_heap_free(&ep_buf_pool, block->data);
			block->data = NULL;
		}

		block->data = k_heap_alloc(&ep_buf_pool, cfg->ep_mps, K_NO_WAIT);
		if (block->data == NULL) {
			LOG_ERR("Failed to allocate memory");
			return -ENOMEM;
		}

		memset(block->data, 0, cfg->ep_mps);
#ifdef CONFIG_USB_DC_NXP_LPCIP3511
	}
#endif

	dev_state.eps[ep_abs_idx].ep_mps = cfg->ep_mps;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlEndpointInit, &ep_init);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to initialize endpoint");
		return -EIO;
	}

	/*
	 * If it is control endpoint, controller will prime setup
	 * here set the occupied flag.
	 */
	if ((USB_EP_GET_IDX(cfg->ep_addr) == USB_CONTROL_ENDPOINT) &&
	    (USB_EP_DIR_IS_OUT(cfg->ep_addr))) {
		dev_state.eps[ep_abs_idx].ep_occupied = true;
	}
	dev_state.eps[ep_abs_idx].ep_enabled = true;

	return 0;
}

int usb_dc_ep_set_stall(const uint8_t ep)
{
	uint8_t endpoint = ep;
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	usb_status_t status;

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

	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlEndpointStall, &endpoint);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to stall endpoint");
		return -EIO;
	}

	return 0;
}

int usb_dc_ep_clear_stall(const uint8_t ep)
{
	uint8_t endpoint = ep;
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	usb_status_t status;

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

	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlEndpointUnstall, &endpoint);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to clear stall");
		return -EIO;
	}

	if ((USB_EP_GET_IDX(ep) != USB_CONTROL_ENDPOINT) &&
	    (USB_EP_DIR_IS_OUT(ep))) {
		status = dev_state.dev_struct.controllerInterface->deviceRecv(
				dev_state.dev_struct.controllerHandle, ep,
				(uint8_t *)dev_state.eps[ep_abs_idx].block.data,
				(uint32_t)dev_state.eps[ep_abs_idx].ep_mps);
		if (kStatus_USB_Success != status) {
			LOG_ERR("Failed to enable reception on 0x%02x", ep);
			return -EIO;
		}

		dev_state.eps[ep_abs_idx].ep_occupied = true;
	}

	return 0;
}

int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *const stalled)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	usb_device_endpoint_status_struct_t ep_status;
	usb_status_t status;

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

	if (!stalled) {
		return -EINVAL;
	}

	*stalled = 0;
	ep_status.endpointAddress = ep;
	ep_status.endpointStatus = kUSB_DeviceEndpointStateIdle;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlGetEndpointStatus, &ep_status);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to get endpoint status");
		return -EIO;
	}

	*stalled = (uint8_t)ep_status.endpointStatus;

	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_abs_idx = EP_ABS_IDX(ep);
	usb_status_t status;

	/*
	 * endpoint 0 OUT is primed by controller driver when configure this
	 * endpoint.
	 */
	if (!ep_abs_idx) {
		return 0;
	}

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

	if (dev_state.eps[ep_abs_idx].ep_occupied) {
		LOG_WRN("endpoint 0x%x already enabled", ep);
		return -EALREADY;
	}

	if ((USB_EP_GET_IDX(ep) != USB_CONTROL_ENDPOINT) &&
	    (USB_EP_DIR_IS_OUT(ep))) {
		status = dev_state.dev_struct.controllerInterface->deviceRecv(
				dev_state.dev_struct.controllerHandle, ep,
				(uint8_t *)dev_state.eps[ep_abs_idx].block.data,
				(uint32_t)dev_state.eps[ep_abs_idx].ep_mps);
		if (kStatus_USB_Success != status) {
			LOG_ERR("Failed to enable reception on 0x%02x", ep);
			return -EIO;
		}

		dev_state.eps[ep_abs_idx].ep_occupied = true;
	} else {
		/*
		 * control endpoint just be enabled before enumeration,
		 * when running here, setup has been primed.
		 */
		dev_state.eps[ep_abs_idx].ep_occupied = true;
	}

	return 0;
}

int usb_dc_ep_disable(const uint8_t ep)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	usb_status_t status;

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

	status = dev_state.dev_struct.controllerInterface->deviceCancel(
						  dev_state.dev_struct.controllerHandle,
						  ep);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to disable ep 0x%02x", ep);
		return -EIO;
	}

	dev_state.eps[ep_abs_idx].ep_enabled = false;
	dev_state.eps[ep_abs_idx].ep_occupied = false;

	return 0;
}

int usb_dc_ep_flush(const uint8_t ep)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);

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

	LOG_DBG("Not implemented, idx 0x%02x, ep %u", ep_abs_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_abs_idx = EP_ABS_IDX(ep);
	uint8_t *buffer;
	uint32_t len_to_send = data_len;
	usb_status_t status;

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

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

	/* Copy the data for SoC's that do not have a USB RAM
	 * as the SDK driver will copy the data into USB RAM,
	 * if available.
	 */
#ifndef CONFIG_USB_DC_NXP_LPCIP3511
	buffer = (uint8_t *)dev_state.eps[ep_abs_idx].block.data;

	if (data_len > dev_state.eps[ep_abs_idx].ep_mps) {
		len_to_send = dev_state.eps[ep_abs_idx].ep_mps;
	}

	for (uint32_t n = 0; n < len_to_send; n++) {
		buffer[n] = data[n];
	}
#else
	buffer = (uint8_t *)data;
#endif

#if defined(CONFIG_HAS_MCUX_CACHE) && !defined(EP_BUF_NONCACHED)
	DCACHE_CleanByRange((uint32_t)buffer, len_to_send);
#endif
	status = dev_state.dev_struct.controllerInterface->deviceSend(
						dev_state.dev_struct.controllerHandle,
						ep, buffer, len_to_send);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to fill ep 0x%02x buffer", ep);
		return -EIO;
	}

	if (ret_bytes) {
		*ret_bytes = len_to_send;
	}

	return 0;
}

static void update_control_stage(usb_device_callback_message_struct_t *cb_msg,
				 uint32_t data_len, uint32_t max_data_len)
{
	struct usb_setup_packet *usbd_setup;

	usbd_setup = (struct usb_setup_packet *)cb_msg->buffer;

	if (cb_msg->isSetup) {
		if (usbd_setup->wLength == 0) {
			dev_state.setup_data_stage = SETUP_DATA_STAGE_DONE;
		} else if (usb_reqtype_is_to_host(usbd_setup)) {
			dev_state.setup_data_stage = SETUP_DATA_STAGE_IN;
		} else {
			dev_state.setup_data_stage = SETUP_DATA_STAGE_OUT;
		}
	} else {
		if (dev_state.setup_data_stage != SETUP_DATA_STAGE_DONE) {
			if ((data_len >= max_data_len) ||
			    (data_len < dev_state.eps[0].ep_mps)) {
				dev_state.setup_data_stage = SETUP_DATA_STAGE_DONE;
			}
		}
	}
}

int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
			uint32_t *read_bytes)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	uint32_t data_len;
	uint8_t *bufp = NULL;

	if (dev_state.eps[ep_abs_idx].ep_occupied) {
		LOG_ERR("Endpoint is occupied by the controller");
		return -EBUSY;
	}

	if ((ep_abs_idx >= NUM_OF_EP_MAX) ||
	    (USB_EP_GET_DIR(ep) != USB_EP_DIR_OUT)) {
		LOG_ERR("Wrong endpoint index/address/direction");
		return -EINVAL;
	}

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

	/*
	 * It is control setup, we should use message.buffer,
	 * this buffer is from internal setup array.
	 */
	bufp = dev_state.eps[ep_abs_idx].transfer_message.buffer;
	data_len = dev_state.eps[ep_abs_idx].transfer_message.length;
	if (data_len == USB_UNINITIALIZED_VAL_32) {
		if (read_bytes) {
			*read_bytes = 0;
		}
		return -EINVAL;
	}

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

	if (read_bytes) {
		*read_bytes = data_len;
	}

	if (USB_EP_GET_IDX(ep) == USB_ENDPOINT_CONTROL) {
		update_control_stage(&dev_state.eps[0].transfer_message,
				     data_len, max_data_len);
	}

	return 0;
}

int usb_dc_ep_read_continue(uint8_t ep)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	usb_status_t status;

	if (ep_abs_idx >= NUM_OF_EP_MAX ||
	    USB_EP_GET_DIR(ep) != USB_EP_DIR_OUT) {
		LOG_ERR("Wrong endpoint index/address/direction");
		return -EINVAL;
	}

	if (dev_state.eps[ep_abs_idx].ep_occupied) {
		LOG_WRN("endpoint 0x%x already occupied", ep);
		return -EBUSY;
	}

	if (USB_EP_GET_IDX(ep) == USB_ENDPOINT_CONTROL) {
		if (dev_state.setup_data_stage == SETUP_DATA_STAGE_DONE) {
			return 0;
		}

		if (dev_state.setup_data_stage == SETUP_DATA_STAGE_IN) {
			dev_state.setup_data_stage = SETUP_DATA_STAGE_DONE;
		}
	}

	status = dev_state.dev_struct.controllerInterface->deviceRecv(
			    dev_state.dev_struct.controllerHandle, ep,
			    (uint8_t *)dev_state.eps[ep_abs_idx].block.data,
			    dev_state.eps[ep_abs_idx].ep_mps);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to enable reception on ep 0x%02x", ep);
		return -EIO;
	}

	dev_state.eps[ep_abs_idx].ep_occupied = true;

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

	return usb_dc_ep_read_continue(ep);
}

int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);

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

	if (!dev_state.attached) {
		return -EINVAL;
	}
	dev_state.eps[ep_abs_idx].callback = cb;

	return 0;
}

void usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	dev_state.status_cb = cb;
}

int usb_dc_ep_mps(const uint8_t ep)
{
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);

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

	return dev_state.eps[ep_abs_idx].ep_mps;
}

static void handle_bus_reset(void)
{
	usb_device_endpoint_init_struct_t ep_init;
	uint8_t ep_abs_idx = 0;
	usb_status_t status;

	dev_state.dev_struct.deviceAddress = 0;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlSetDefaultStatus, NULL);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to set default status");
	}

	for (int i = 0; i < NUM_OF_EP_MAX; i++) {
		dev_state.eps[i].ep_occupied = false;
		dev_state.eps[i].ep_enabled = false;
	}

	ep_init.zlt = 0U;
	ep_init.transferType = USB_ENDPOINT_CONTROL;
	ep_init.maxPacketSize = USB_CONTROL_EP_MPS;
	ep_init.endpointAddress = USB_CONTROL_EP_OUT;

	ep_abs_idx =  EP_ABS_IDX(ep_init.endpointAddress);
	dev_state.eps[ep_abs_idx].ep_mps = USB_CONTROL_EP_MPS;

	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlEndpointInit, &ep_init);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to initialize control OUT endpoint");
	}

	dev_state.eps[ep_abs_idx].ep_occupied = false;
	dev_state.eps[ep_abs_idx].ep_enabled = true;

	ep_init.endpointAddress = USB_CONTROL_EP_IN;
	ep_abs_idx = EP_ABS_IDX(ep_init.endpointAddress);
	dev_state.eps[ep_abs_idx].ep_mps = USB_CONTROL_EP_MPS;
	status = dev_state.dev_struct.controllerInterface->deviceControl(
			dev_state.dev_struct.controllerHandle,
			kUSB_DeviceControlEndpointInit, &ep_init);
	if (kStatus_USB_Success != status) {
		LOG_ERR("Failed to initialize control IN endpoint");
	}

	dev_state.eps[ep_abs_idx].ep_occupied = false;
	dev_state.eps[ep_abs_idx].ep_enabled = true;
}

static void handle_transfer_msg(usb_device_callback_message_struct_t *cb_msg)
{
	uint8_t ep_status_code = 0;
	uint8_t ep = cb_msg->code;
	uint8_t ep_abs_idx = EP_ABS_IDX(ep);
	usb_status_t status;

	dev_state.eps[ep_abs_idx].ep_occupied = false;

	if (cb_msg->length == UINT32_MAX) {
		/*
		 * Probably called from USB_DeviceEhciCancel()
		 * LOG_WRN("Drop message for ep 0x%02x", ep);
		 */
		return;
	}

	if (cb_msg->isSetup) {
		ep_status_code = USB_DC_EP_SETUP;
	} else {
		/* IN TOKEN */
		if (USB_EP_DIR_IS_IN(ep)) {
			if ((dev_state.dev_struct.deviceAddress != 0) && (ep_abs_idx == 1)) {
				/*
				 * Set Address in the status stage in
				 * the IN transfer.
				 */
				status = dev_state.dev_struct.controllerInterface->deviceControl(
					dev_state.dev_struct.controllerHandle,
					kUSB_DeviceControlSetDeviceAddress,
					&dev_state.dev_struct.deviceAddress);
				if (kStatus_USB_Success != status) {
					LOG_ERR("Failed to set device address");
					return;
				}
				dev_state.dev_struct.deviceAddress = 0;
			}
			ep_status_code = USB_DC_EP_DATA_IN;
		}
		/* OUT TOKEN */
		else {
			ep_status_code = USB_DC_EP_DATA_OUT;
		}
	}

	if (dev_state.eps[ep_abs_idx].callback) {
#if defined(CONFIG_HAS_MCUX_CACHE) && !defined(EP_BUF_NONCACHED)
		if (cb_msg->length) {
			DCACHE_InvalidateByRange((uint32_t)cb_msg->buffer,
						 cb_msg->length);
		}
#endif
		dev_state.eps[ep_abs_idx].callback(ep, ep_status_code);
	} else {
		LOG_ERR("No cb pointer for endpoint 0x%02x", ep);
	}
}

/**
 * Similar to the kinetis driver, this thread is used to not run the USB device
 * stack/endpoint callbacks in the ISR context. This is because callbacks from
 * the USB stack may use mutexes, or other kernel functions not supported from
 * an interrupt context.
 */
static void usb_mcux_thread_main(void *arg1, void *arg2, void *arg3)
{
	ARG_UNUSED(arg1);
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	uint8_t ep_abs_idx;
	usb_device_callback_message_struct_t msg;

	while (1) {
		k_msgq_get(&usb_dc_msgq, &msg, K_FOREVER);
		switch (msg.code) {
		case kUSB_DeviceNotifyBusReset:
			handle_bus_reset();
			dev_state.status_cb(USB_DC_RESET, NULL);
			break;
		case kUSB_DeviceNotifyError:
			dev_state.status_cb(USB_DC_ERROR, NULL);
			break;
		case kUSB_DeviceNotifySuspend:
			dev_state.status_cb(USB_DC_SUSPEND, NULL);
			break;
		case kUSB_DeviceNotifyResume:
			dev_state.status_cb(USB_DC_RESUME, NULL);
			break;
		default:
			ep_abs_idx = EP_ABS_IDX(msg.code);

			if (ep_abs_idx >= NUM_OF_EP_MAX) {
				LOG_ERR("Wrong endpoint index/address");
				return;
			}

			memcpy(&dev_state.eps[ep_abs_idx].transfer_message, &msg,
			       sizeof(usb_device_callback_message_struct_t));
			handle_transfer_msg(&dev_state.eps[ep_abs_idx].transfer_message);
		}
	}
}

/* Notify the up layer the KHCI status changed. */
usb_status_t USB_DeviceNotificationTrigger(void *handle, void *msg)
{
	/* Submit to message queue */
	k_msgq_put(&usb_dc_msgq,
		(usb_device_callback_message_struct_t *)msg, K_NO_WAIT);
	return kStatus_USB_Success;
}

static void usb_isr_handler(void)
{
#if defined(CONFIG_USB_DC_NXP_EHCI)
	USB_DeviceEhciIsrFunction(&dev_state);
#elif defined(CONFIG_USB_DC_NXP_LPCIP3511)
	USB_DeviceLpcIp3511IsrFunction(&dev_state);
#endif
}

static int usb_mcux_init(void)
{
	int err;

	k_thread_create(&dev_state.thread, dev_state.thread_stack,
			CONFIG_USB_MCUX_THREAD_STACK_SIZE,
			usb_mcux_thread_main, NULL, NULL, NULL,
			K_PRIO_COOP(2), 0, K_NO_WAIT);
	k_thread_name_set(&dev_state.thread, "usb_mcux");

	PINCTRL_DT_INST_DEFINE(0);

	/* Apply pinctrl state */
	err = pinctrl_apply_state(PINCTRL_DT_INST_DEV_CONFIG_GET(0), PINCTRL_STATE_DEFAULT);
	if (err) {
		return err;
	}

	return 0;
}

SYS_INIT(usb_mcux_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
