/*
 * Copyright (c) 2023 ITE Technology Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it82xx2_usb

#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/drivers/pinctrl.h>
#include <soc.h>
#include <soc_dt.h>
#include <string.h>
#include <zephyr/irq.h>
#include <zephyr/pm/policy.h>
#include <zephyr/drivers/interrupt_controller/wuc_ite_it8xxx2.h>
#include <zephyr/dt-bindings/interrupt-controller/it8xxx2-wuc.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(usb_dc_it82xx2, CONFIG_USB_DRIVER_LOG_LEVEL);

/* USB Device Controller Registers Bits & Constants */
#define IT8XXX2_USB_IRQ			DT_INST_IRQ_BY_IDX(0, 0, irq)
#define IT8XXX2_WU90_IRQ		DT_INST_IRQ_BY_IDX(0, 1, irq)

#define MAX_NUM_ENDPOINTS		16
#define FIFO_NUM			3
#define SETUP_DATA_CNT			8
#define DC_ADDR_NULL			0x00
#define DC_ADDR_MASK			0x7F

/* The related definitions of the register EP STATUS:
 * 0x41/0x45/0x49/0x4D
 */
#define EP_STATUS_ERROR			0x0F

/* The related definitions of the register dc_line_status: 0x51 */
#define RX_LINE_STATE_MASK		(RX_LINE_FULL_SPD | RX_LINE_LOW_SPD)
#define RX_LINE_LOW_SPD			0x02
#define RX_LINE_FULL_SPD		0x01
#define RX_LINE_RESET			0x00

/* EPN Extend Control 2 Register Mask Definition */
#define READY_BITS			0x0F
#define COMPLETED_TRANS			0xF0

/* EP Definitions */
#define EP_VALID_MASK			0x0F
#define EP_INVALID_MASK			~(USB_EP_DIR_MASK | EP_VALID_MASK)

/* Bit [1:0] represents the TRANSACTION_TYPE as follows: */
enum it82xx2_transaction_types {
	DC_SETUP_TRANS,
	DC_IN_TRANS,
	DC_OUTDATA_TRANS,
	DC_ALL_TRANS
};

/* The bit definitions of the register EP RX/TX FIFO Control:
 * EP_RX_FIFO_CONTROL: 0X64/0x84/0xA4/0xC4
 * EP_TX_FIFO_CONTROL: 0X74/0x94/0xB4/0xD4
 */
#define FIFO_FORCE_EMPTY		BIT(0)

/* The bit definitions of the register Host/Device Control: 0XE0 */
#define RESET_CORE			BIT(1)

/* Bit definitions of the register Port0/Port1 MISC Control: 0XE4/0xE8 */
#define PULL_DOWN_EN			BIT(4)

/* Bit definitions of the register EPN0N1_EXTEND_CONTROL_REG: 0X98 ~ 0X9D */
#define EPN1_OUTDATA_SEQ		BIT(4)
#define EPN0_ISO_ENABLE			BIT(2)
#define EPN0_SEND_STALL			BIT(1)
#define EPN0_OUTDATA_SEQ		BIT(0)

/* ENDPOINT[3..0]_STATUS_REG */
#define DC_STALL_SENT			BIT(5)

/* DC_INTERRUPT_STATUS_REG */
#define DC_TRANS_DONE			BIT(0)
#define DC_RESUME_INT			BIT(1)
#define DC_RESET_EVENT			BIT(2)
#define DC_SOF_RECEIVED			BIT(3)
#define DC_NAK_SENT_INT			BIT(4)

/* DC_CONTROL_REG */
#define DC_GLOBAL_ENABLE		BIT(0)
#define DC_TX_LINE_STATE_DM		BIT(1)
#define DC_DIRECT_CONTROL		BIT(3)
#define DC_FULL_SPEED_LINE_POLARITY	BIT(4)
#define DC_FULL_SPEED_LINE_RATE		BIT(5)
#define DC_CONNECT_TO_HOST		BIT(6) /* internal pull-up */

/* ENDPOINT[3..0]_CONTROL_REG */
#define ENDPOINT_EN			BIT(0)
#define ENDPOINT_RDY			BIT(1)
#define EP_OUTDATA_SEQ			BIT(2)
#define EP_SEND_STALL			BIT(3)
#define EP_ISO_ENABLE			BIT(4)
#define EP_DIRECTION			BIT(5)

enum it82xx2_ep_status {
	EP_INIT,
	EP_CHECK,
	EP_CONFIG,
	EP_CONFIG_IN,
	EP_CONFIG_OUT,
};

enum it82xx2_trans_type {
	SETUP_TOKEN,
	IN_TOKEN,
	OUT_TOKEN,
};

enum it82xx2_setup_stage {
	INIT_ST,
	SETUP_ST,
	DIN_ST,
	DOUT_ST,
	STATUS_ST,
	STALL_SEND,
};

enum it82xx2_extend_ep_ctrl {
	/* EPN0N1_EXTEND_CONTROL_REG */
	EXT_EP_ISO_DISABLE,
	EXT_EP_ISO_ENABLE,
	EXT_EP_SEND_STALL,
	EXT_EP_CLEAR_STALL,
	EXT_EP_CHECK_STALL,
	EXT_EP_DATA_SEQ_1,
	EXT_EP_DATA_SEQ_0,
	EXT_EP_DATA_SEQ_INV,
	/* EPN_EXTEND_CONTROL1_REG */
	EXT_EP_DIR_IN,
	EXT_EP_DIR_OUT,
	EXT_EP_ENABLE,
	EXT_EP_DISABLE,
	/* EPN_EXTEND_CONTROL2_REG */
	EXT_EP_READY,
};

struct usb_it8xxx2_wuc {
	/* WUC control device structure */
	const struct device *wucs;
	/* WUC pin mask */
	uint8_t mask;
};

struct usb_it82xx2_config {
	struct usb_it82xx2_regs *const base;
	const struct pinctrl_dev_config *pcfg;
	const struct usb_it8xxx2_wuc *wuc_list;
};

static const struct usb_it8xxx2_wuc usb_wuc0[IT8XXX2_DT_INST_WUCCTRL_LEN(0)] =
		IT8XXX2_DT_WUC_ITEMS_LIST(0);

PINCTRL_DT_INST_DEFINE(0);

static const struct usb_it82xx2_config ucfg0 = {
	.base = (struct usb_it82xx2_regs *)DT_INST_REG_ADDR(0),
	.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
	.wuc_list = usb_wuc0
};

struct it82xx2_endpoint_data {
	usb_dc_ep_callback cb_in;
	usb_dc_ep_callback cb_out;
	enum it82xx2_ep_status ep_status;
	enum usb_dc_ep_transfer_type ep_type;
	uint16_t remaining; /* remaining bytes */
	uint16_t mps;
};

struct usb_it82xx2_data {
	struct it82xx2_endpoint_data ep_data[MAX_NUM_ENDPOINTS];
	enum it82xx2_setup_stage st_state; /* Setup State */

	/* EP0 status */
	enum it82xx2_trans_type last_token;

	/* EP0 status */
	enum it82xx2_trans_type now_token;

	uint8_t attached;
	uint8_t addr;
	bool no_data_ctrl;
	bool suspended;
	usb_dc_status_callback usb_status_cb;

	/* Check the EP interrupt status for (ep > 0) */
	bool ep_ready[3];

	struct k_sem ep_sem[3];
};

/* Mapped to the bit definitions in the EPN_EXTEND_CONTROL1 Register
 * (D6h to DDh) for configuring the FIFO direction and for enabling/disabling
 * the endpoints.
 */
static uint8_t ext_ep_bit_shift[12] = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3};

/* The ep_fifo_res[ep_idx % FIFO_NUM] where the FIFO_NUM is 3 represents the
 * EP mapping because when (ep_idx % FIFO_NUM) is 3, it actually means the EP0.
 */
static const uint8_t ep_fifo_res[3] = {3, 1, 2};

/* Mapping the enum it82xx2_extend_ep_ctrl code to their corresponding bit in
 * the EP45/67/89/1011/1213/1415 Extended Control Registers.
 */
static const uint8_t ext_ctrl_tbl[7] = {
	EPN0_ISO_ENABLE,
	EPN0_ISO_ENABLE,
	EPN0_SEND_STALL,
	EPN0_SEND_STALL,
	EPN0_SEND_STALL,
	EPN0_OUTDATA_SEQ,
	EPN0_OUTDATA_SEQ,
};

/* Indexing of the following control codes:
 * EXT_EP_DIR_IN, EXT_EP_DIR_OUT, EXT_EP_ENABLE, EXT_EP_DISABLE
 */
static const uint8_t epn_ext_ctrl_tbl[4] = {1, 0, 1, 0};

static struct usb_it82xx2_data udata0;

static struct usb_it82xx2_regs *it82xx2_get_usb_regs(void)
{
	const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(usb0));
	const struct usb_it82xx2_config *cfg = dev->config;
	struct usb_it82xx2_regs *const usb_regs = cfg->base;

	return usb_regs;
}

/* WU90 (USB D+) Enable/Disable */
static void it82xx2_enable_wu90_irq(const struct device *dev, bool enable)
{
	const struct usb_it82xx2_config *cfg = dev->config;

	if (enable) {
		irq_enable(IT8XXX2_WU90_IRQ);
	} else {
		irq_disable(IT8XXX2_WU90_IRQ);
		/* Clear pending interrupt */
		it8xxx2_wuc_clear_status(cfg->wuc_list[0].wucs,
					cfg->wuc_list[0].mask);
	}
}

static void it82xx2_wu90_isr(const struct device *dev)
{
	it82xx2_enable_wu90_irq(dev, false);
	LOG_DBG("USB D+ (WU90) Triggered");
}

/* WU90 (USB D+) Initializations */
static void it8xxx2_usb_dc_wuc_init(const struct device *dev)
{
	const struct usb_it82xx2_config *cfg = dev->config;

	/* Initializing the WUI */
	it8xxx2_wuc_set_polarity(cfg->wuc_list[0].wucs,
				cfg->wuc_list[0].mask,
				WUC_TYPE_EDGE_FALLING);
	it8xxx2_wuc_clear_status(cfg->wuc_list[0].wucs,
				cfg->wuc_list[0].mask);

	/* Enabling the WUI */
	it8xxx2_wuc_enable(cfg->wuc_list[0].wucs, cfg->wuc_list[0].mask);

	/* Connect WU90 (USB D+) interrupt but make it disabled initally */
	IRQ_CONNECT(IT8XXX2_WU90_IRQ, 0, it82xx2_wu90_isr, 0, 0);
	irq_disable(IT8XXX2_WU90_IRQ);

}

/* Function it82xx2_get_ep_fifo_ctrl_reg_idx(uint8_t ep_idx):
 *
 * Calculate the register offset index which determines the corresponding
 * EP FIFO Ctrl Registers which is defined as ep_fifo_ctrl[reg_idx] here
 *
 * The ep_fifo_res[ep_idx % FIFO_NUM] represents the EP mapping because when
 * (ep_idx % FIFO_NUM) is 3, it actually means the EP0.
 */
static uint8_t it82xx2_get_ep_fifo_ctrl_reg_idx(uint8_t ep_idx)
{

	uint8_t reg_idx = (ep_idx < EP8) ?
		((ep_fifo_res[ep_idx % FIFO_NUM] - 1) * 2) :
		((ep_fifo_res[ep_idx % FIFO_NUM] - 1) * 2 + 1);

	return reg_idx;
}

/* Function it82xx2_get_ep_fifo_ctrl_reg_val(uint8_t ep_idx):
 *
 * Calculate the register value written to the ep_fifo_ctrl which is defined as
 * ep_fifo_ctrl[reg_idx] here for selecting the corresponding control bit.
 */
static uint8_t it82xx2_get_ep_fifo_ctrl_reg_val(uint8_t ep_idx)
{
	uint8_t reg_val = (ep_idx < EP8) ?
		(1 << ep_idx) : (1 << (ep_idx - EP8));

	return reg_val;
}

/*
 * Functions it82xx2_epn0n1_ext_ctrl_cfg() and epn0n1_ext_ctrl_cfg_seq_inv()
 * provide the entrance of configuring the EPN0N1 Extended Ctrl Registers.
 *
 * The variable set_clr determines if we set/clear the corresponding bit.
 */
static void it82xx2_epn0n1_ext_ctrl_cfg(uint8_t reg_idx, uint8_t bit_mask,
			bool set_clr)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	volatile uint8_t *epn0n1_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;

	(set_clr) ? (epn0n1_ext_ctrl[reg_idx] |= bit_mask) :
		(epn0n1_ext_ctrl[reg_idx] &= ~(bit_mask));
}

static void it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(uint8_t reg_idx,
			uint8_t bit_mask, bool set_clr)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	volatile uint8_t *epn0n1_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;

	bool check = (set_clr) ?
		(epn0n1_ext_ctrl[reg_idx] & EPN0_OUTDATA_SEQ) :
		(epn0n1_ext_ctrl[reg_idx] & EPN1_OUTDATA_SEQ);

	(check) ? (epn0n1_ext_ctrl[reg_idx] &= ~(bit_mask)) :
		(epn0n1_ext_ctrl[reg_idx] |= bit_mask);
}

/* Return the status of STALL bit in the EPN0N1 Extend Control Registers */
static bool it82xx2_epn01n1_check_stall(uint8_t reg_idx, uint8_t bit_mask)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	volatile uint8_t *epn0n1_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_9X].ext_4_15.epn0n1_ext_ctrl;

	return !!(epn0n1_ext_ctrl[reg_idx] & bit_mask);
}

/* Configuring the EPN Extended Ctrl Registers. */
static void it82xx2_epn_ext_ctrl_cfg1(uint8_t reg_idx, uint8_t bit_mask,
			bool set_clr)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct epn_ext_ctrl_regs *epn_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;

	(set_clr) ? (epn_ext_ctrl[reg_idx].epn_ext_ctrl1 |= bit_mask) :
		(epn_ext_ctrl[reg_idx].epn_ext_ctrl1 &= ~(bit_mask));
}

static void it82xx2_epn_ext_ctrl_cfg2(uint8_t reg_idx, uint8_t bit_mask,
			bool set_clr)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct epn_ext_ctrl_regs *epn_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;

	(set_clr) ? (epn_ext_ctrl[reg_idx].epn_ext_ctrl2 |= bit_mask) :
		(epn_ext_ctrl[reg_idx].epn_ext_ctrl2 &= ~(bit_mask));
}

/* From 98h to 9Dh, the EP45/67/89/1011/1213/1415 Extended Control Registers
 * are defined, and their bits definitions are as follows:
 *
 * Bit    Description
 *  7     Reserved
 *  6     EPPOINT5_ISO_ENABLE
 *  5     EPPOINT5_SEND_STALL
 *  4     EPPOINT5_OUT_DATA_SEQUENCE
 *  3     Reserved
 *  2     EPPOINT4_ISO_ENABLE
 *  1     EPPOINT4_SEND_STALL
 *  0     EPPOINT4_OUT_DATA_SEQUENCE
 *
 * Apparently, we can tell that the EP4 and EP5 share the same register, and
 * the EP6 and EP7 share the same one, and the other EPs are defined in the
 * same way.
 *
 * In the function it82xx2_usb_extend_ep_ctrl() we will obtain the mask/flag
 * according to the bits definitions mentioned above. As for the control code,
 * please refer to the definition of enum it82xx2_extend_ep_ctrl.
 */
static int it82xx2_usb_extend_ep_ctrl(uint8_t ep_idx,
			enum it82xx2_extend_ep_ctrl ctrl)
{
	uint8_t reg_idx, mask;
	bool flag;

	if (ep_idx < EP4) {
		return -EINVAL;
	}

	if ((ctrl >= EXT_EP_DIR_IN) && (ctrl < EXT_EP_READY)) {
		/* From EXT_EP_DIR_IN to EXT_EP_DISABLE */
		reg_idx = ep_fifo_res[ep_idx % FIFO_NUM];
		mask = 1 << (ext_ep_bit_shift[ep_idx - 4] * 2 + 1);
		flag = epn_ext_ctrl_tbl[ctrl - EXT_EP_DIR_IN];
		it82xx2_epn_ext_ctrl_cfg1(reg_idx, mask, flag);

	} else if ((ctrl >= EXT_EP_ISO_DISABLE) && (ctrl < EXT_EP_DIR_IN)) {
		/* From EXT_EP_ISO_DISABLE to EXT_EP_DATA_SEQ_0 */
		reg_idx = (ep_idx - 4) >> 1;
		flag = !!(ep_idx & 1);
		mask = flag ? (ext_ctrl_tbl[ctrl] << 4) : (ext_ctrl_tbl[ctrl]);

		if (ctrl == EXT_EP_CHECK_STALL) {
			return it82xx2_epn01n1_check_stall(reg_idx, mask);
		} else if (ctrl == EXT_EP_DATA_SEQ_INV) {
			it82xx2_epn0n1_ext_ctrl_cfg_seq_inv(
				reg_idx, mask, flag);
		} else {
			it82xx2_epn0n1_ext_ctrl_cfg(reg_idx, mask, flag);
		}
	} else if (ctrl == EXT_EP_READY) {
		reg_idx = (ep_idx - 4) >> 1;
		mask = 1 << (ext_ep_bit_shift[ep_idx - 4]);
		it82xx2_epn_ext_ctrl_cfg2(reg_idx, mask, true);
	} else {
		LOG_ERR("Invalid Control Code of Endpoint");
		return -EINVAL;
	}

	return 0;
}

static int it82xx2_usb_dc_ip_init(uint8_t p_action)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();

	if (p_action == 0) {
		/* Reset Device Controller */
		usb_regs->host_device_control = RESET_CORE;
		k_msleep(1);
		usb_regs->port0_misc_control &= ~(PULL_DOWN_EN);
		usb_regs->port1_misc_control &= ~(PULL_DOWN_EN);
		/* clear reset bit */
		usb_regs->host_device_control = 0;
	}

	usb_regs->dc_control =
		DC_GLOBAL_ENABLE | DC_FULL_SPEED_LINE_POLARITY |
		DC_FULL_SPEED_LINE_RATE | DC_CONNECT_TO_HOST;

	usb_regs->dc_interrupt_status =
		DC_TRANS_DONE | DC_RESET_EVENT | DC_SOF_RECEIVED;

	usb_regs->dc_interrupt_mask = 0x00;
	usb_regs->dc_interrupt_mask =
		DC_TRANS_DONE | DC_RESET_EVENT;

	usb_regs->dc_address = DC_ADDR_NULL;

	return 0;
}

static int it82xx2_usb_dc_attach_init(void)
{
	struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;
	/*
	 * Disable USB debug path , prevent CPU enter
	 * JTAG mode and then reset by USB command.
	 */
	gctrl_regs->GCTRL_MCCR &= ~(IT8XXX2_GCTRL_MCCR_USB_EN);
	gctrl_regs->gctrl_pmer2 |= IT8XXX2_GCTRL_PMER2_USB_PAD_EN;

	/* Disabling WU90 (USB D+) of WUI */
	irq_disable(IT8XXX2_WU90_IRQ);

	return it82xx2_usb_dc_ip_init(0);
}

/* Check the condition that SETUP_TOKEN following OUT_TOKEN and return it */
static bool it82xx2_check_setup_following_out(void)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;

	return ((ep_regs[EP0].ep_transtype_sts & DC_ALL_TRANS) == 0 ||
		(udata0.last_token == IN_TOKEN &&
		ff_regs[EP0].ep_rx_fifo_dcnt_lsb == SETUP_DATA_CNT));
}

static int it82xx2_setup_done(uint8_t ep_ctrl, uint8_t idx)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;

	LOG_DBG("SETUP(%d)", idx);
	/* wrong trans*/
	if (ep_ctrl & EP_SEND_STALL) {
		ep_regs[idx].ep_ctrl &= ~EP_SEND_STALL;
		udata0.st_state = STALL_SEND;
		ff_regs[idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
		LOG_DBG("Clear Stall Bit & RX FIFO");
		return -EINVAL;
	}
	/* handle status interrupt */
	/* status out */
	if (udata0.st_state == DIN_ST) {
		LOG_DBG("Status OUT");
		udata0.last_token = udata0.now_token;
		udata0.now_token = OUT_TOKEN;
		udata0.st_state = STATUS_ST;
		udata0.ep_data[idx].cb_out(idx, USB_DC_EP_DATA_OUT);

	} else if (udata0.st_state == DOUT_ST || udata0.st_state == SETUP_ST) {
		/* Status IN*/
		LOG_DBG("Status IN");
		udata0.last_token = udata0.now_token;
		udata0.now_token = IN_TOKEN;
		udata0.st_state = STATUS_ST;
		udata0.ep_data[idx].cb_in(idx | 0x80, USB_DC_EP_DATA_IN);
	}

	udata0.last_token = udata0.now_token;
	udata0.now_token = SETUP_TOKEN;
	udata0.st_state = SETUP_ST;

	ep_regs[idx].ep_ctrl |= EP_OUTDATA_SEQ;
	udata0.ep_data[idx].cb_out(USB_EP_DIR_OUT, USB_DC_EP_SETUP);

	/* Set ready bit to no-data control in */
	if (udata0.no_data_ctrl) {
		ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
		LOG_DBG("(%d): Set Ready Bit for no-data control", __LINE__);

		udata0.no_data_ctrl = false;
	}

	return 0;
}

static int it82xx2_in_done(uint8_t ep_ctrl, uint8_t idx)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	/* stall send check */
	if (ep_ctrl & EP_SEND_STALL) {
		ep_regs[EP0].ep_ctrl &= ~EP_SEND_STALL;
		udata0.st_state = STALL_SEND;
		LOG_DBG("Clear Stall Bit");
		return -EINVAL;
	}

	if (udata0.st_state >= STATUS_ST) {
		return -EINVAL;
	}

	LOG_DBG("IN(%d)(%d)", idx, !!(ep_regs[idx].ep_ctrl & EP_OUTDATA_SEQ));

	udata0.last_token = udata0.now_token;
	udata0.now_token = IN_TOKEN;

	if (udata0.addr != DC_ADDR_NULL &&
		udata0.addr != usb_regs->dc_address) {
		usb_regs->dc_address = udata0.addr;
		LOG_DBG("Address Is Set Successfully");
	}

	/* set setup stage */
	if (udata0.st_state == DOUT_ST) {
		udata0.st_state = STATUS_ST;
		/* no data status in */
	} else if (udata0.ep_data[EP0].remaining == 0 &&
	udata0.st_state == SETUP_ST) {
		udata0.st_state = STATUS_ST;
	} else {
		udata0.st_state = DIN_ST;
	}

	if (!!(ep_regs[idx].ep_ctrl & EP_OUTDATA_SEQ)) {
		ep_regs[idx].ep_ctrl &= ~EP_OUTDATA_SEQ;
	} else {
		ep_regs[idx].ep_ctrl |= EP_OUTDATA_SEQ;
	}
	udata0.ep_data[idx].cb_in(idx | 0x80, USB_DC_EP_DATA_IN);

	/* set ready bit for status out */
	LOG_DBG("Remaining Bytes: %d, Stage: %d",
	udata0.ep_data[EP0].remaining, udata0.st_state);

	if (udata0.st_state == DIN_ST && udata0.ep_data[EP0].remaining == 0) {
		ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
		LOG_DBG("Set EP%d Ready (%d)", idx, __LINE__);
	}

	return 0;
}

static int it82xx2_out_done(uint8_t idx)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	/* ep0 wrong enter check */
	if (udata0.st_state >= STATUS_ST) {
		return -EINVAL;
	}

	LOG_DBG("OUT(%d)", idx);

	udata0.last_token = udata0.now_token;
	udata0.now_token = OUT_TOKEN;

	if (udata0.st_state == SETUP_ST) {
		udata0.st_state = DOUT_ST;
	} else {
		udata0.st_state = STATUS_ST;
	}

	udata0.ep_data[idx].cb_out(idx, USB_DC_EP_DATA_OUT);

	/* SETUP_TOKEN follow OUT_TOKEN */
	if (it82xx2_check_setup_following_out()) {
		LOG_WRN("[%s] OUT => SETUP", __func__);
		udata0.last_token = udata0.now_token;
		udata0.now_token = SETUP_TOKEN;
		udata0.st_state = SETUP_ST;
		ep_regs[EP0].ep_ctrl |= EP_OUTDATA_SEQ;
		udata0.ep_data[EP0].cb_out(USB_EP_DIR_OUT, USB_DC_EP_SETUP);

		/* NOTE: set ready bit to no-data control in */
		if (udata0.no_data_ctrl) {
			ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
			LOG_DBG("Set Ready Bit for no-data control");
			udata0.no_data_ctrl = false;
		}
	}

	return 0;
}

/* Functions it82xx2_ep_in_out_config():
 * Dealing with the ep_ctrl configurations in this subroutine when it's
 * invoked in the it82xx2_usb_dc_trans_done().
 */
static void it82xx2_ep_in_out_config(uint8_t idx)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct epn_ext_ctrl_regs *epn_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;

	uint8_t ep_trans = (epn_ext_ctrl[idx].epn_ext_ctrl2 >> 4) & READY_BITS;

	if (udata0.ep_data[ep_trans].ep_status == EP_CONFIG_IN) {
		if (ep_trans < 4) {
			if (!!(ep_regs[idx].ep_ctrl & EP_OUTDATA_SEQ)) {
				ep_regs[idx].ep_ctrl &= ~EP_OUTDATA_SEQ;
			} else {
				ep_regs[idx].ep_ctrl |= EP_OUTDATA_SEQ;
			}
		} else {
			it82xx2_usb_extend_ep_ctrl(ep_trans,
				EXT_EP_DATA_SEQ_INV);
		}

		if (udata0.ep_data[ep_trans].cb_in) {
			udata0.ep_data[ep_trans].cb_in(ep_trans | 0x80,
				USB_DC_EP_DATA_IN);
		}

		k_sem_give(&udata0.ep_sem[idx - 1]);

	} else {
		if (udata0.ep_data[ep_trans].cb_out) {
			udata0.ep_data[ep_trans].cb_out(ep_trans,
				USB_DC_EP_DATA_OUT);
		}
	}
}

static void it82xx2_usb_dc_trans_done(uint8_t ep_ctrl, uint8_t ep_trans_type)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct epn_ext_ctrl_regs *epn_ext_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_DX].ext_0_3.epn_ext_ctrl;

	int ret;

	for (uint8_t idx = 0 ; idx < EP4 ; idx++) {
		ep_ctrl = ep_regs[idx].ep_ctrl;

		/* check ready bit ,will be 0 when trans done */
		if ((ep_ctrl & ENDPOINT_EN) && !(ep_ctrl & ENDPOINT_RDY)) {
			if (idx == EP0) {
				ep_trans_type = ep_regs[idx].ep_transtype_sts &
					DC_ALL_TRANS;

				/* set up*/
				if (ep_trans_type == DC_SETUP_TRANS) {
					ret = it82xx2_setup_done(ep_ctrl, idx);

					if (ret != 0) {
						continue;
					}
				} else if (ep_trans_type == DC_IN_TRANS) {
					/* in */
					ret = it82xx2_in_done(ep_ctrl, idx);

					if (ret != 0) {
						continue;
					}
				} else if (ep_trans_type == DC_OUTDATA_TRANS) {
					/* out */
					ret = it82xx2_out_done(idx);

					if (ret != 0) {
						continue;
					}
				}
			} else {
				/* prevent wrong entry */
				if (!udata0.ep_ready[idx - 1]) {
					continue;
				}

				if ((epn_ext_ctrl[idx].epn_ext_ctrl2 &
					COMPLETED_TRANS) == 0) {
					continue;
				}

				udata0.ep_ready[idx - 1] = false;
				it82xx2_ep_in_out_config(idx);
			}
		}
	}
}

static void it82xx2_usb_dc_isr(void)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();

	uint8_t status = usb_regs->dc_interrupt_status &
		usb_regs->dc_interrupt_mask; /* mask non enable int */
	uint8_t ep_ctrl, ep_trans_type;

	/* reset */
	if (status & DC_RESET_EVENT) {
		if ((usb_regs->dc_line_status & RX_LINE_STATE_MASK) ==
			RX_LINE_RESET) {
			usb_dc_reset();
			usb_regs->dc_interrupt_status = DC_RESET_EVENT;

			if (udata0.usb_status_cb) {
				(*(udata0.usb_status_cb))(USB_DC_RESET, NULL);
			}

			return;

		} else {
			usb_regs->dc_interrupt_status = DC_RESET_EVENT;
		}
	}
	/* resume,not test */
	if (status & DC_RESUME_INT) {
		udata0.suspended = false;
		usb_regs->dc_interrupt_mask &= ~DC_RESUME_INT;
		usb_regs->dc_interrupt_status = DC_RESUME_INT;
		if (udata0.usb_status_cb) {
			(*(udata0.usb_status_cb))(USB_DC_RESUME, NULL);
		}

		return;
	}
	/* transaction done */
	if (status & DC_TRANS_DONE) {
		/* clear interrupt before new transaction */
		usb_regs->dc_interrupt_status = DC_TRANS_DONE;
		it82xx2_usb_dc_trans_done(ep_ctrl, ep_trans_type);
		return;
	}

}

/*
 * USB Device Controller API
 */
int usb_dc_attach(void)
{
	int ret;

	pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);

	if (udata0.attached) {
		LOG_DBG("Already Attached");
		return 0;
	}

	LOG_DBG("Attached");
	ret = it82xx2_usb_dc_attach_init();

	if (ret) {
		return ret;
	}

	for (int idx = 0 ; idx < MAX_NUM_ENDPOINTS ; idx++) {
		udata0.ep_data[idx].ep_status = EP_INIT;
	}

	udata0.attached = 1U;

	/* init ep ready status */
	udata0.ep_ready[0] = false;
	udata0.ep_ready[1] = false;
	udata0.ep_ready[2] = false;

	k_sem_init(&udata0.ep_sem[0], 1, 1);
	k_sem_init(&udata0.ep_sem[1], 1, 1);
	k_sem_init(&udata0.ep_sem[2], 1, 1);

	/* Connect and enable USB interrupt */
	IRQ_CONNECT(IT8XXX2_USB_IRQ, 0, it82xx2_usb_dc_isr, 0, 0);
	irq_enable(IT8XXX2_USB_IRQ);

	return 0;
}

int usb_dc_detach(void)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();

	pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);

	if (!udata0.attached) {
		LOG_DBG("Already Detached");
		return 0;
	}

	LOG_DBG("Detached");
	irq_disable(IT8XXX2_USB_IRQ);

	/* stop pull-up D+ D-*/
	usb_regs->dc_control &= ~DC_CONNECT_TO_HOST;
	udata0.attached = 0U;

	/* Enabling WU90 (USB D+) of WUI */
	irq_enable(IT8XXX2_WU90_IRQ);

	return 0;
}

int usb_dc_reset(void)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;

	int idx;

	LOG_DBG("USB Device Reset");

	ff_regs[EP0].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
	ff_regs[EP0].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;

	for (idx = 1 ; idx < EP4 ; idx++) {
		if (udata0.ep_data[idx].ep_status > EP_CHECK) {
			ff_regs[idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;
			ff_regs[idx].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;
		}
	}

	ep_regs[EP0].ep_ctrl = ENDPOINT_EN;
	usb_regs->dc_address = DC_ADDR_NULL;
	udata0.addr = DC_ADDR_NULL;
	usb_regs->dc_interrupt_status = DC_NAK_SENT_INT | DC_SOF_RECEIVED;

	if (udata0.usb_status_cb) {
		(*(udata0.usb_status_cb))(USB_DC_RESET, NULL);
	}

	return 0;
}

int usb_dc_set_address(const uint8_t addr)
{
	LOG_DBG("Set Address(0x%02x) to Data", addr);
	udata0.addr = addr & DC_ADDR_MASK;
	return 0;
}

void usb_dc_set_status_callback(const usb_dc_status_callback cb)
{
	udata0.usb_status_cb = cb;
}

int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
{
	uint8_t ep_idx = cfg->ep_addr & EP_VALID_MASK;
	bool in = !!((cfg->ep_addr) & USB_EP_DIR_MASK);

	if ((cfg->ep_addr & EP_INVALID_MASK) != 0) {
		return -EINVAL;
	}

	if ((cfg->ep_type == USB_DC_EP_CONTROL) && ep_idx > EP0) {
		LOG_ERR("Invalid Endpoint Configuration");
		return -EINVAL;
	}

	if (ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_WRN("Invalid Endpoint Number 0x%02x", cfg->ep_addr);
		return -EINVAL;
	}

	if ((ep_idx != 0) && (!in && ep_idx % FIFO_NUM != 2)) {
		LOG_WRN("Invalid Endpoint Number 0x%02x", cfg->ep_addr);
		return -EINVAL;
	}

	if ((ep_idx != 0) && (in && ep_idx % FIFO_NUM == 2)) {
		LOG_WRN("Invalid Endpoint Number 0x%02x", cfg->ep_addr);
		return -EINVAL;
	}

	if (udata0.ep_data[ep_idx].ep_status > 0) {
		LOG_WRN("EP%d have been used", ep_idx);
		return -EINVAL;
	}

	if (ep_idx > EP0) {
		udata0.ep_data[ep_idx].mps = cfg->ep_mps;
	}

	udata0.ep_data[ep_idx].ep_status = EP_CHECK;
	LOG_DBG("Check cap(%02x)", cfg->ep_addr);

	return 0;
}

int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data *const cfg)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	volatile uint8_t *ep_fifo_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_BX].fifo_ctrl.ep_fifo_ctrl;

	uint8_t ep_idx = (cfg->ep_addr) & EP_VALID_MASK;
	uint8_t reg_idx = it82xx2_get_ep_fifo_ctrl_reg_idx(ep_idx);
	uint8_t reg_val = it82xx2_get_ep_fifo_ctrl_reg_val(ep_idx);
	bool in = !!((cfg->ep_addr) & USB_EP_DIR_MASK);

	if ((cfg->ep_addr & EP_INVALID_MASK) != 0) {
		LOG_DBG("Invalid Address");
		return -EINVAL;
	}

	if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_DBG("Not attached / Invalid Endpoint: 0x%X", cfg->ep_addr);
		return -EINVAL;
	}

	if (!cfg->ep_mps) {
		LOG_DBG("Wrong EP or Descriptor");
		return -EINVAL;
	}

	udata0.ep_data[ep_idx].ep_status = EP_CONFIG;
	udata0.ep_data[ep_idx].mps = cfg->ep_mps;

	LOG_DBG("ep_status: %d, mps: %d",
		udata0.ep_data[ep_idx].ep_status, udata0.ep_data[ep_idx].mps);

	if (!(ep_idx > EP0)) {
		return 0;
	}

	if (ep_idx < EP4) {
		(in) ? (ep_regs[ep_idx].ep_ctrl |= EP_DIRECTION) :
			(ep_regs[ep_idx].ep_ctrl &= ~EP_DIRECTION);

	} else {

		(in) ? (it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DIR_IN)) :
			(it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DIR_OUT));

		if (in) {
			it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DATA_SEQ_0);
		}

		LOG_DBG("ep_status %d", udata0.ep_data[ep_idx].ep_status);
	}

	(in) ? (udata0.ep_data[ep_idx].ep_status = EP_CONFIG_IN) :
		(udata0.ep_data[ep_idx].ep_status = EP_CONFIG_OUT);

	ep_fifo_ctrl[reg_idx] |= reg_val;

	switch (cfg->ep_type) {

	case USB_DC_EP_CONTROL:
		return -EINVAL;

	case USB_DC_EP_ISOCHRONOUS:
		if (ep_idx < EP4) {
			ep_regs[ep_idx].ep_ctrl |= EP_ISO_ENABLE;
		} else {
			it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ISO_ENABLE);
		}

		break;

	case USB_DC_EP_BULK:
	case USB_DC_EP_INTERRUPT:
	default:
		if (ep_idx < EP4) {
			ep_regs[ep_idx].ep_ctrl &= ~EP_ISO_ENABLE;
		} else {
			it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ISO_DISABLE);
		}

		break;

	}

	udata0.ep_data[ep_idx].ep_type = cfg->ep_type;

	LOG_DBG("EP%d Configured: 0x%2X(%d)", ep_idx, !!(in), cfg->ep_type);
	return 0;
}

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

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

	if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_ERR("(%d)Not attached / Invalid endpoint: EP 0x%x",
			__LINE__, ep);
		return -EINVAL;
	}

	if (cb == NULL) {
		LOG_ERR("(%d): NO callback function", __LINE__);
		return -EINVAL;
	}

	LOG_DBG("EP%d set callback: %d", ep_idx, !!(ep & USB_EP_DIR_IN));

	(ep & USB_EP_DIR_IN) ?
		(udata0.ep_data[ep_idx].cb_in = cb) :
		(udata0.ep_data[ep_idx].cb_out = cb);

	return 0;
}

int usb_dc_ep_enable(const uint8_t ep)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;

	if ((ep & EP_INVALID_MASK) != 0) {
		LOG_DBG("Bit[6:4] has something invalid");
		return -EINVAL;
	}

	if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_ERR("Not attached / Invalid endpoint: EP 0x%x", ep_idx);
		return -EINVAL;
	}

	if (ep_idx < EP4) {
		LOG_DBG("ep_idx < 4");
		ep_regs[ep_idx].ep_ctrl |= ENDPOINT_EN;
		LOG_DBG("EP%d Enbabled %02x", ep_idx, ep_regs[ep_idx].ep_ctrl);
	} else {
		LOG_DBG("ep_idx >= 4");
		it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_ENABLE);
	}

	return 0;
}

int usb_dc_ep_disable(uint8_t ep)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;

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

	if (!udata0.attached || ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_ERR("Not attached / Invalid endpoint: EP 0x%x", ep_idx);
		return -EINVAL;
	}

	if (ep_idx < EP4) {
		ep_regs[ep_idx].ep_ctrl &= ~ENDPOINT_EN;
	} else {
		it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_DISABLE);
	}

	return 0;
}


int usb_dc_ep_set_stall(const uint8_t ep)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;
	struct gctrl_it8xxx2_regs *const gctrl_regs = GCTRL_IT8XXX2_REGS_BASE;

	if (((ep & EP_INVALID_MASK) != 0) || (ep_idx >= MAX_NUM_ENDPOINTS)) {
		return -EINVAL;
	}

	if (ep_idx < EP4) {
		ep_regs[ep_idx].ep_ctrl |= EP_SEND_STALL;
	} else {
		it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_SEND_STALL);
	}

	if (ep_idx == EP0) {
		ep_regs[EP0].ep_ctrl |= ENDPOINT_RDY;
		uint32_t idx = 0;
		/* polling if stall send for 3ms */
		while (idx < 198 &&
			!(ep_regs[EP0].ep_status & DC_STALL_SENT)) {
			/* wait 15.15us */
			gctrl_regs->GCTRL_WNCKR = 0;
			idx++;
		}

		if (idx < 198) {
			ep_regs[EP0].ep_ctrl &= ~EP_SEND_STALL;
		}

		udata0.no_data_ctrl = false;
		udata0.st_state = STALL_SEND;
	}

	LOG_DBG("EP(%d) ctrl: 0x%02x", ep_idx, ep_regs[ep_idx].ep_ctrl);
	LOG_DBG("EP(%d) Set Stall", ep_idx);

	return 0;
}

int usb_dc_ep_clear_stall(const uint8_t ep)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;

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

	if (ep_idx >= MAX_NUM_ENDPOINTS) {
		return -EINVAL;
	}

	ep_regs[ep_idx].ep_ctrl &= ~EP_SEND_STALL;
	LOG_DBG("EP(%d) clear stall", ep_idx);

	return 0;
}

int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;

	if ((!stalled) || ((ep & EP_INVALID_MASK) != 0) ||
		(ep_idx >= MAX_NUM_ENDPOINTS)) {
		return -EINVAL;
	}

	if (ep_idx < EP4) {
		*stalled =
			(0 != (ep_regs[ep_idx].ep_ctrl & EP_SEND_STALL));
	} else {
		*stalled = it82xx2_usb_extend_ep_ctrl(ep_idx,
			EXT_EP_CHECK_STALL);
	}

	return 0;
}

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

int usb_dc_ep_flush(uint8_t ep)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;
	bool in = !!(ep & USB_EP_DIR_MASK);

	if (((ep & EP_INVALID_MASK) != 0) || (ep_idx >= MAX_NUM_ENDPOINTS)) {
		return -EINVAL;
	}

	if (ep_idx > FIFO_NUM) {
		ep_idx = ep_fifo_res[ep_idx % FIFO_NUM];
	}

	in ? (ff_regs[ep_idx].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY) :
		(ff_regs[ep_idx].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY);

	return 0;
}

int usb_dc_ep_write(uint8_t ep, const uint8_t *buf,
				uint32_t data_len, uint32_t *ret_bytes)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;
	volatile uint8_t *ep_fifo_ctrl =
		usb_regs->fifo_regs[EP_EXT_REGS_BX].fifo_ctrl.ep_fifo_ctrl;

	uint8_t ep_idx = ep & EP_VALID_MASK;
	uint8_t reg_idx = it82xx2_get_ep_fifo_ctrl_reg_idx(ep_idx);
	uint8_t reg_val = it82xx2_get_ep_fifo_ctrl_reg_val(ep_idx);
	uint8_t ep_fifo = (ep_idx > EP0) ?
		(ep_fifo_res[ep_idx % FIFO_NUM]) : 0;
	uint32_t idx;

	if ((ep & EP_INVALID_MASK) != 0)
		return -EINVAL;

	/* status IN */
	if ((ep_idx == EP0) && (data_len == 0) &&
		(udata0.now_token == SETUP_TOKEN)) {
		return 0;
	}

	if (ep_idx >= MAX_NUM_ENDPOINTS) {
		return -EINVAL;
	}

	/* clear fifo before write*/
	if (ep_idx == EP0) {
		ff_regs[ep_idx].ep_tx_fifo_ctrl = FIFO_FORCE_EMPTY;
	}

	if ((ep_idx == EP0) && (udata0.st_state == SETUP_ST)) {
		udata0.st_state = DIN_ST;
	}

	/* select FIFO */
	if (ep_idx > EP0) {

		k_sem_take(&udata0.ep_sem[ep_fifo-1], K_FOREVER);

		/* select FIFO */
		ep_fifo_ctrl[reg_idx] |= reg_val;
	}

	if (data_len > udata0.ep_data[ep_idx].mps) {

		for (idx = 0 ; idx < udata0.ep_data[ep_idx].mps ; idx++) {
			ff_regs[ep_fifo].ep_tx_fifo_data = buf[idx];
		}

		*ret_bytes = udata0.ep_data[ep_idx].mps;
		udata0.ep_data[ep_idx].remaining =
			data_len - udata0.ep_data[ep_idx].mps;

		LOG_DBG("data_len: %d, Write Max Packets to TX FIFO(%d)",
			data_len, ep_idx);
	} else {
		for (idx = 0 ; idx < data_len ; idx++) {
			ff_regs[ep_fifo].ep_tx_fifo_data = buf[idx];
		}

		*ret_bytes = data_len;
		udata0.ep_data[ep_idx].remaining = 0;
		LOG_DBG("Write %d Packets to TX FIFO(%d)", data_len, ep_idx);
	}

	if (ep_idx > FIFO_NUM) {
		it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
	}

	ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;

	if (ep_fifo > EP0) {
		udata0.ep_ready[ep_fifo - 1] = true;
	}

	LOG_DBG("Set EP%d Ready(%d)", ep_idx, __LINE__);

	return 0;
}

/* Read data from an OUT endpoint */
int usb_dc_ep_read(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
			uint32_t *read_bytes)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;
	uint8_t ep_fifo = 0;
	uint16_t rx_fifo_len;

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

	if (ep_regs[ep_idx].ep_status & EP_STATUS_ERROR) {
		LOG_WRN("EP Error Flag: 0x%02x", ep_regs[ep_idx].ep_status);
	}

	if (max_data_len == 0) {

		*read_bytes = 0;

		if (ep_idx > EP0) {
			ep_regs[ep_idx].ep_ctrl |= ENDPOINT_RDY;
			LOG_DBG("Set EP%d Ready(%d)", ep_idx, __LINE__);
		}

		return 0;
	}

	if (ep_idx > EP0) {
		ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
	}

	rx_fifo_len = (uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_lsb +
		(((uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_msb) << 8);

	if (ep_idx == 0) {
	/* if ep0 check trans_type in OUT_TOKEN to
	 * prevent wrong read_bytes cause memory error
	 */
		if (udata0.st_state == STATUS_ST &&
			(ep_regs[EP0].ep_transtype_sts & DC_ALL_TRANS) == 0) {

			*read_bytes = 0;
			return 0;

		} else if (udata0.st_state == STATUS_ST) {
			/* status out but rx_fifo_len not zero */
			if (rx_fifo_len != 0) {
				LOG_ERR("Status OUT length not 0 (%d)",
					rx_fifo_len);
			}
			/* rx_fifo_len = 0; */
			*read_bytes = 0;

			return 0;
		} else if (rx_fifo_len == 0 &&
			udata0.now_token == SETUP_TOKEN) {
			/* RX fifo error workaround */

			/* wrong length(like 7),
			 * may read wrong packet so clear fifo then return -1
			 */
			LOG_ERR("Setup length 0, reset to 8");
			rx_fifo_len = 8;
		} else if (rx_fifo_len != 8 &&
			udata0.now_token == SETUP_TOKEN) {
			LOG_ERR("Setup length: %d", rx_fifo_len);
			/* clear rx fifo */
			ff_regs[EP0].ep_rx_fifo_ctrl = FIFO_FORCE_EMPTY;

			return -EIO;
		}
	}

	if (rx_fifo_len > max_data_len) {
		*read_bytes = max_data_len;
		for (int idx = 0 ; idx < max_data_len ; idx++) {
			buf[idx] = ff_regs[ep_fifo].ep_rx_fifo_data;
		}

		LOG_DBG("Read Max (%d) Packets", max_data_len);
	} else {

		*read_bytes = rx_fifo_len;

		for (int idx = 0 ; idx < rx_fifo_len ; idx++) {
			buf[idx] = ff_regs[ep_fifo].ep_rx_fifo_data;
		}

		if (ep_fifo == 0 &&
			udata0.now_token == SETUP_TOKEN) {
			LOG_DBG("RX buf: (%x)(%x)(%x)(%x)(%x)(%x)(%x)(%x)",
			buf[0], buf[1], buf[2], buf[3],
			buf[4], buf[5], buf[6], buf[7]);
		}

		if (ep_fifo > EP0) {
			ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
			it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
			LOG_DBG("(%d): Set EP%d Ready", __LINE__, ep_idx);
			udata0.ep_ready[ep_fifo - 1] = true;
		} else if (udata0.now_token == SETUP_TOKEN) {

			if (!(buf[0] & USB_EP_DIR_MASK)) {
			/* Host to device transfer check */
				if (buf[6] != 0 || buf[7] != 0) {
					/* clear tx fifo */
					ff_regs[EP0].ep_tx_fifo_ctrl =
					FIFO_FORCE_EMPTY;
					/* set status IN after data OUT */
					ep_regs[EP0].ep_ctrl |=
					ENDPOINT_RDY | EP_OUTDATA_SEQ;
					LOG_DBG("Set EP%d Ready(%d)",
						ep_idx, __LINE__);
				} else {
					/* no_data_ctrl status */

					/* clear tx fifo */
					ff_regs[EP0].ep_tx_fifo_ctrl =
					FIFO_FORCE_EMPTY;
					udata0.no_data_ctrl = true;
				}
			}
		}

	}

	return 0;
}

int usb_dc_ep_read_wait(uint8_t ep, uint8_t *buf, uint32_t max_data_len,
			uint32_t *read_bytes)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;
	struct it82xx2_usb_ep_fifo_regs *ff_regs = usb_regs->fifo_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;
	uint8_t ep_fifo = 0;
	uint16_t rx_fifo_len;

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

	if (ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_ERR("(%d): Wrong Endpoint Index/Address", __LINE__);
		return -EINVAL;
	}
	/* Check if OUT ep */
	if (!!(ep & USB_EP_DIR_MASK)) {
		LOG_ERR("Wrong Endpoint Direction");
		return -EINVAL;
	}

	if (ep_idx > EP0) {
		ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
	}

	if (ep_regs[ep_fifo].ep_status & EP_STATUS_ERROR) {
		LOG_WRN("EP error flag(%02x)", ep_regs[ep_fifo].ep_status);
	}

	rx_fifo_len = (uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_lsb +
		(((uint16_t)ff_regs[ep_fifo].ep_rx_fifo_dcnt_msb) << 8);

	LOG_DBG("ep_read_wait (EP: %d), len: %d", ep_idx, rx_fifo_len);

	*read_bytes = (rx_fifo_len > max_data_len) ?
		max_data_len : rx_fifo_len;

	for (int idx = 0 ; idx < *read_bytes ; idx++) {
		buf[idx] = ff_regs[ep_fifo].ep_rx_fifo_data;
	}

	LOG_DBG("Read %d packets", *read_bytes);

	if (ep_idx > EP0) {
		LOG_DBG("RX buf[0]: 0x%02X", buf[0]);
	}

	return 0;
}

int usb_dc_ep_read_continue(uint8_t ep)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();
	struct it82xx2_usb_ep_regs *ep_regs = usb_regs->usb_ep_regs;

	uint8_t ep_idx = ep & EP_VALID_MASK;
	uint8_t ep_fifo = 2;

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

	if (ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_ERR("(%d): Wrong Endpoint Index/Address", __LINE__);
		return -EINVAL;
	}

	/* Check if OUT ep */
	if (!!(ep & USB_EP_DIR_MASK)) {
		LOG_ERR("Wrong Endpoint Direction");
		return -EINVAL;
	}

	if (ep_idx > EP0) {
		ep_fifo = ep_fifo_res[ep_idx % FIFO_NUM];
	}

	it82xx2_usb_extend_ep_ctrl(ep_idx, EXT_EP_READY);
	ep_regs[ep_fifo].ep_ctrl |= ENDPOINT_RDY;
	udata0.ep_ready[ep_fifo - 1] = true;
	LOG_DBG("EP(%d) Read Continue", ep_idx);
	return 0;
}


int usb_dc_ep_mps(const uint8_t ep)
{
	uint8_t ep_idx = ep & EP_VALID_MASK;

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

	if (ep_idx >= MAX_NUM_ENDPOINTS) {
		LOG_ERR("(%d): Wrong Endpoint Index/Address", __LINE__);
		return -EINVAL;
	}
	/* Not configured, return length 0 */
	if (udata0.ep_data[ep_idx].ep_status < EP_CONFIG) {
		LOG_WRN("(%d)EP not set", __LINE__);
		return 0;
	}

	return udata0.ep_data[ep_idx].mps;
}

static bool it82xx2_check_suspend(void)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();

	if (usb_regs->dc_interrupt_status & DC_SOF_RECEIVED) {
		usb_regs->dc_interrupt_status =
			usb_regs->dc_interrupt_status;
	}
	/* Check suspend, no SOF in last 3ms */
	k_msleep(4);

	if (usb_regs->dc_interrupt_status & DC_SOF_RECEIVED) {
		return false;
	}

	usb_regs->dc_interrupt_status = DC_SOF_RECEIVED | DC_RESUME_INT;
	usb_regs->dc_interrupt_mask |= DC_RESUME_INT;
	udata0.suspended = true;

	if (udata0.usb_status_cb) {
		(*(udata0.usb_status_cb))(USB_DC_SUSPEND, NULL);
	}

	return true;
}

int usb_dc_wakeup_request(void)
{
	struct usb_it82xx2_regs *const usb_regs =
		(struct usb_it82xx2_regs *)it82xx2_get_usb_regs();

	if (udata0.suspended || it82xx2_check_suspend()) {

		usb_regs->dc_control =
			DC_GLOBAL_ENABLE | DC_FULL_SPEED_LINE_POLARITY |
			DC_FULL_SPEED_LINE_RATE | DC_DIRECT_CONTROL |
			DC_TX_LINE_STATE_DM | DC_CONNECT_TO_HOST;

		/* The remote wakeup device must hold the resume signal for */
		/* at least 1 ms but for no more than 15 ms                 */
		k_msleep(2);

		usb_regs->dc_control =
			DC_GLOBAL_ENABLE | DC_FULL_SPEED_LINE_POLARITY |
			DC_FULL_SPEED_LINE_RATE | DC_CONNECT_TO_HOST;

		if (udata0.suspended) {
			udata0.suspended = false;
			irq_disable(IT8XXX2_WU90_IRQ);
		}
	}
	return 0;
}

static int it82xx2_usb_dc_init(const struct device *dev)
{
	const struct usb_it82xx2_config *cfg = dev->config;

	int status = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);

	if (status < 0) {
		LOG_ERR("Failed to configure USB pins");
		return status;
	}

	/* Initializing WU90 (USB D+) */
	it8xxx2_usb_dc_wuc_init(dev);

	return 0;
}

DEVICE_DT_INST_DEFINE(0,
	&it82xx2_usb_dc_init,
	NULL,
	&udata0,
	&ucfg0,
	POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
	NULL);
