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

#include <soc.h>
#include <string.h>
#include <drivers/usb/usb_dc.h>
#include <soc.h>
#include <device.h>
#include "usb_dc_mcux.h"
#include "usb_device_ehci.h"

#ifdef CONFIG_HAS_MCUX_CACHE
#include <fsl_cache.h>
#endif

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

#define CONTROLLER_ID kUSB_ControllerEhci0

static void usb_isr_handler(void);
extern void USB_DeviceEhciIsrFunction(void *deviceHandle);

/* the setup transfer state */
#define SETUP_DATA_STAGE_DONE (0)
#define SETUP_DATA_STAGE_IN (1)
#define SETUP_DATA_STAGE_OUT (2)
/* Then endpoint number/index calculation */
#define EP_ADDR2IDX(ep)     ((ep) & ~USB_EP_DIR_MASK)
#define EP_ADDR2DIR(ep)     ((ep) & USB_EP_DIR_MASK)
#define EP_ABS_IDX(ep)   (((ep) & ~USB_EP_DIR_MASK) * 2 + (((ep) & USB_EP_DIR_MASK) >> 7))
#define NUM_OF_EP_MAX           DT_USBD_MCUX_EHCI_NUM_BIDIR_EP
/* The minimum value is 1 */
#define EP_BUF_NUMOF_BLOCKS     ((NUM_OF_EP_MAX + 3) / 4)
/* The max MPS is 1023 for FS, 1024 for HS. */
#if defined(CONFIG_NOCACHE_MEMORY)
#define EP_BUF_NONCACHED
__nocache K_MEM_POOL_DEFINE(ep_buf_pool, 16, 1024, EP_BUF_NUMOF_BLOCKS, 4);
#else
K_MEM_POOL_DEFINE(ep_buf_pool, 16, 1024, EP_BUF_NUMOF_BLOCKS, 4);
#endif

static usb_ep_ctrl_data_t s_ep_ctrl[NUM_OF_EP_MAX];
static usb_device_struct_t s_Device;

#if ((defined(USB_DEVICE_CONFIG_EHCI)) && (USB_DEVICE_CONFIG_EHCI > 0U))
/* EHCI device driver interface */
static const usb_device_controller_interface_struct_t s_UsbDeviceEhciInterface = {
	USB_DeviceEhciInit, USB_DeviceEhciDeinit, USB_DeviceEhciSend,
	USB_DeviceEhciRecv, USB_DeviceEhciCancel, USB_DeviceEhciControl
};
#endif

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

	return 0;
}

int usb_dc_attach(void)
{
	s_Device.eps = &s_ep_ctrl[0];
	if (s_Device.attached) {
		LOG_WRN("already attached");
		return 0;
	}
	s_Device.interface = (const usb_device_controller_interface_struct_t *)(&s_UsbDeviceEhciInterface);
	if (kStatus_USB_Success != s_Device.interface->deviceInit(CONTROLLER_ID, &s_Device, &s_Device.controllerHandle)) {
		return -EINVAL;
	}

	/* Connect and enable USB interrupt */
	IRQ_CONNECT(DT_USBD_MCUX_EHCI_IRQ, DT_USBD_MCUX_EHCI_IRQ_PRI,
		    usb_isr_handler, 0, 0);
	irq_enable(DT_USBD_MCUX_EHCI_IRQ);
	s_Device.attached = 1;
	LOG_DBG("attached");
	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlRun, NULL);
	return 0;
}

int usb_dc_detach(void)
{
	LOG_DBG("detached.");
	if (s_Device.controllerHandle != NULL) {
		s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlStop, NULL);
		s_Device.interface->deviceDeinit(s_Device.controllerHandle);
		s_Device.controllerHandle = NULL;
	}
	s_Device.attached = 0;
	return 0;
}

int usb_dc_set_address(const u8_t addr)
{
	LOG_DBG("");
	s_Device.address = addr;
	return 0;
}

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

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

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

	if (ep_idx & BIT(0)) {
		if (EP_ADDR2DIR(cfg->ep_addr) != USB_EP_DIR_IN) {
			LOG_INF("pre-selected as IN endpoint");
			return -1;
		}
	} else {
		if (EP_ADDR2DIR(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)
{
	u8_t ep_abs_idx =  EP_ABS_IDX(cfg->ep_addr);
	usb_device_endpoint_init_struct_t epInit;
	struct k_mem_block *block;
	struct usb_ep_ctrl_data *eps = &s_Device.eps[ep_abs_idx];

	epInit.zlt = 0U;
	epInit.endpointAddress = cfg->ep_addr;
	epInit.maxPacketSize = cfg->ep_mps;
	epInit.transferType = cfg->ep_type;
	s_Device.eps[ep_abs_idx].ep_type = cfg->ep_type;

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

	block = &(eps->block);
	if (block->data) {
		k_mem_pool_free(block);
		block->data = NULL;
	}

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

	s_Device.eps[ep_abs_idx].ep_mps = cfg->ep_mps;
	if (s_Device.eps[ep_abs_idx].ep_enabled) {
		s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlEndpointDeinit, (void *)(&cfg->ep_addr));
	}
	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlEndpointInit, &epInit);

	/* if it is controlendpoint, controller will prime setup
	 * here set the occupied flag.
	 */
	if ((EP_ADDR2IDX(cfg->ep_addr) == USB_CONTROL_ENDPOINT) && (EP_ADDR2DIR(cfg->ep_addr) == USB_EP_DIR_OUT)) {
		s_Device.eps[ep_abs_idx].ep_occupied = true;
	}
	s_Device.eps[ep_abs_idx].ep_enabled = true;
	return 0;
}

int usb_dc_ep_set_stall(const u8_t ep)
{
	u8_t endpoint = ep;

	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlEndpointStall, &endpoint);
	return 0;
}

int usb_dc_ep_clear_stall(const u8_t ep)
{
	u8_t endpoint = ep;

	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlEndpointUnstall, &endpoint);
	return 0;
}

int usb_dc_ep_is_stalled(const u8_t ep, u8_t *const stalled)
{
	if (!stalled) {
		return -EINVAL;
	}
	*stalled = 0;
	/* Get the endpoint status */
	usb_device_endpoint_status_struct_t endpointStatus;

	endpointStatus.endpointAddress = ep;
	endpointStatus.endpointStatus = kUSB_DeviceEndpointStateIdle;
	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlGetEndpointStatus, &endpointStatus);
	*stalled = endpointStatus.endpointStatus;
	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 ep_abs_idx = EP_ABS_IDX(ep);

	/* endpoint0 OUT is primed by controller driver when configure this
	 *  endpoint.
	 */
	if (!ep_abs_idx) {
		return 0;
	}
	if (s_Device.eps[ep_abs_idx].ep_occupied) {
		LOG_WRN("endpoint 0x%x already enabled", ep);
		return -EALREADY;
	}

	if ((EP_ADDR2IDX(ep) != USB_CONTROL_ENDPOINT) && (EP_ADDR2DIR(ep) == USB_EP_DIR_OUT)) {
		s_Device.interface->deviceRecv(s_Device.controllerHandle,
					       ep,
					       (u8_t *)s_Device.eps[ep_abs_idx].block.data,
					       (uint32_t)s_Device.eps[ep_abs_idx].ep_mps);
		s_Device.eps[ep_abs_idx].ep_occupied = true;
	} else {
		/* control enpoint just be enabled before enumeration,
		 * when running here, setup has been primed.
		 */
		s_Device.eps[ep_abs_idx].ep_occupied = true;
	}

	return 0;
}

int usb_dc_ep_disable(const u8_t ep)
{
	u8_t ep_abs_idx = EP_ABS_IDX(ep);

	s_Device.interface->deviceCancel(s_Device.controllerHandle, ep);
	s_Device.eps[ep_abs_idx].ep_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) {
		LOG_ERR("Wrong endpoint index/address");
		return -EINVAL;
	}

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

	return 0;
}

/*  send data to the host */
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_abs_idx = EP_ABS_IDX(ep);
	u8_t *buffer = (u8_t *)s_Device.eps[ep_abs_idx].block.data;
	u32_t len_to_send;

	if (data_len > s_Device.eps[ep_abs_idx].ep_mps) {
		len_to_send = s_Device.eps[ep_abs_idx].ep_mps;
	} else {
		len_to_send = data_len;
	}
	for (u32_t n = 0; n < len_to_send; n++) {
		buffer[n] = data[n];
	}

#if defined(CONFIG_HAS_MCUX_CACHE) && !defined(EP_BUF_NONCACHED)
	DCACHE_CleanByRange((uint32_t)buffer, len_to_send);
#endif
	s_Device.interface->deviceSend(s_Device.controllerHandle,
				       ep,
				       buffer,
				       len_to_send);
	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);
	u8_t ep_abs_idx = EP_ABS_IDX(ep);
	u32_t data_len;
	u8_t *bufp = NULL;

	while (s_Device.eps[ep_abs_idx].ep_occupied) {
		LOG_ERR("Endpoint is occupied by the controller");
		return -EBUSY;
	}
	if ((ep_idx >= NUM_OF_EP_MAX) || (EP_ADDR2DIR(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 = s_Device.eps[ep_abs_idx].transfer_message.buffer;
	data_len = s_Device.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 (u32_t i = 0; i < data_len; i++) {
			data[i] = bufp[i];
		}
	}
	if (read_bytes) {
		*read_bytes = data_len;
	}

	if (EP_ADDR2IDX(ep) == USB_ENDPOINT_CONTROL) {
		u8_t isSetup = s_Device.eps[0].transfer_message.isSetup;
		u8_t *buffer = s_Device.eps[0].transfer_message.buffer;

		if (isSetup) {
			if (((usb_setup_struct_t *)buffer)->wLength == 0) {
				s_Device.setupDataStage = SETUP_DATA_STAGE_DONE;
			} else if (((usb_setup_struct_t *)buffer)->bmRequestType & USB_REQUEST_TYPE_DIR_MASK) {
				s_Device.setupDataStage = SETUP_DATA_STAGE_IN;
			} else {
				s_Device.setupDataStage = SETUP_DATA_STAGE_OUT;
			}
		} else {
			if (s_Device.setupDataStage != SETUP_DATA_STAGE_DONE) {
				if ((data_len >= max_data_len) || (data_len < s_Device.eps[0].ep_mps)) {
					s_Device.setupDataStage = SETUP_DATA_STAGE_DONE;
				}
			}
		}
	}
	return 0;
}

int usb_dc_ep_read_continue(u8_t ep)
{
	/* select the index of the next endpoint buffer */
	u8_t ep_abs_idx = EP_ABS_IDX(ep);

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

	if (EP_ADDR2IDX(ep) == USB_ENDPOINT_CONTROL) {
		if (s_Device.setupDataStage == SETUP_DATA_STAGE_DONE) {
			return 0;
		}
		if (s_Device.setupDataStage == SETUP_DATA_STAGE_IN) {
			s_Device.setupDataStage = SETUP_DATA_STAGE_DONE;
		}
	}
	s_Device.interface->deviceRecv(s_Device.controllerHandle,
				       ep,
				       (u8_t *)s_Device.eps[ep_abs_idx].block.data,
				       s_Device.eps[ep_abs_idx].ep_mps);
	s_Device.eps[ep_abs_idx].ep_occupied = true;

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

	return 0;
}

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

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

	return 0;
}

void usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	s_Device.status_callback = cb;
}

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

	return s_Device.eps[ep_abs_idx].ep_mps;
}

static void control_endpoint_enable(void)
{
	usb_device_endpoint_init_struct_t epInit;
	u8_t ep_abs_idx = 0;

	epInit.zlt = 0U;
	epInit.transferType = USB_ENDPOINT_CONTROL;
	epInit.maxPacketSize = EP0_MAX_PACKET_SIZE;

	epInit.endpointAddress = EP0_OUT;
	ep_abs_idx =  EP_ABS_IDX(epInit.endpointAddress);
	s_Device.eps[ep_abs_idx].ep_mps = EP0_MAX_PACKET_SIZE;

	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlEndpointInit, &epInit);
	s_Device.eps[ep_abs_idx].ep_occupied = false;
	s_Device.eps[ep_abs_idx].ep_enabled = true;

	epInit.endpointAddress = EP0_IN;
	ep_abs_idx = EP_ABS_IDX(epInit.endpointAddress);
	s_Device.eps[ep_abs_idx].ep_mps = EP0_MAX_PACKET_SIZE;
	s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlEndpointInit, &epInit);
	s_Device.eps[ep_abs_idx].ep_occupied = false;
	s_Device.eps[ep_abs_idx].ep_enabled = true;
}

/* Notify the up layer the KHCI status changed. */
void USB_DeviceNotificationTrigger(void *handle, void *msg)
{
	usb_device_callback_message_struct_t *message = (usb_device_callback_message_struct_t *)msg;

	switch (message->code) {
	case kUSB_DeviceNotifyBusReset:
		s_Device.address = 0;
		s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlSetDefaultStatus, NULL);
		for (int i = 0; i < NUM_OF_EP_MAX; i++) {
			s_Device.eps[i].ep_occupied = false;
			s_Device.eps[i].ep_enabled = false;
		}
		control_endpoint_enable();
		s_Device.status_callback(USB_DC_RESET, NULL);
		break;
	case kUSB_DeviceNotifyError:
		s_Device.status_callback(USB_DC_ERROR, NULL);
		break;
	case kUSB_DeviceNotifySuspend:
		s_Device.status_callback(USB_DC_SUSPEND, NULL);
		break;
	case kUSB_DeviceNotifyResume:
		s_Device.status_callback(USB_DC_RESUME, NULL);
		break;
	default:
	{
		u8_t ep_packet_type = 0;
		u8_t ep_abs_idx = EP_ABS_IDX(message->code);
		s_Device.eps[ep_abs_idx].transfer_message.length = message->length;
		s_Device.eps[ep_abs_idx].transfer_message.isSetup = message->isSetup;
		s_Device.eps[ep_abs_idx].transfer_message.code = message->code;
		s_Device.eps[ep_abs_idx].transfer_message.buffer = message->buffer;
		s_Device.eps[ep_abs_idx].ep_occupied = false;
		if (message->isSetup) {
			ep_packet_type = USB_DC_EP_SETUP;
		} else {
			/* IN TOKEN */
			if ((message->code & USB_REQUEST_TYPE_DIR_MASK) == USB_REQUEST_TYPE_DIR_IN) {
				/* control endpoint 0 and status stage for setAddr transfer */
				if ((s_Device.address != 0) && (ep_abs_idx == 1)) {
					/* SET ADDRESS in the status stage in the IN transfer*/
					s_Device.interface->deviceControl(s_Device.controllerHandle, kUSB_DeviceControlSetDeviceAddress, &s_Device.address);
					s_Device.address = 0;
				}
				ep_packet_type = USB_DC_EP_DATA_IN;
			}
			/* OUT TOKEN */
			else {
				ep_packet_type = USB_DC_EP_DATA_OUT;
			}
		}
		if (s_Device.eps[ep_abs_idx].callback) {
#if defined(CONFIG_HAS_MCUX_CACHE) && !defined(EP_BUF_NONCACHED)
			if (message->length) {
				DCACHE_InvalidateByRange((uint32_t)message->buffer,
							 message->length);
			}
#endif
			s_Device.eps[ep_abs_idx].callback(message->code,
							  ep_packet_type);
		}
	}
	}
}

static void usb_isr_handler(void)
{
	USB_DeviceEhciIsrFunction(&s_Device);
}
