/*
 * Copyright (c) 2020 ITE Corporation. All Rights Reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ite_it8xxx2_i2c

#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include <drivers/pinmux.h>
#include <errno.h>
#include <logging/log.h>
		LOG_MODULE_REGISTER(i2c_ite_it8xxx2);
#include "i2c-priv.h"
#include <soc.h>
#include <soc_dt.h>
#include <sys/util.h>

#define I2C_STANDARD_PORT_COUNT 3
/* Default PLL frequency. */
#define PLL_CLOCK 48000000

/*
 * Structure i2c_alts_cfg is about the alternate function
 * setting of i2c, this config will be used at initial
 * time and recover bus.
 */
struct i2c_alts_cfg {
	/* Pinmux control group */
	const struct device *pinctrls;
	/* GPIO pin */
	uint8_t pin;
	/* Alternate function */
	uint8_t alt_fun;
};

struct i2c_it8xxx2_config {
	void (*irq_config_func)(void);
	uint32_t bitrate;
	uint8_t *base;
	uint8_t i2c_irq_base;
	uint8_t port;
	/* I2C alternate configuration */
	const struct i2c_alts_cfg *alts_list;
	/* GPIO handle */
	const struct device *gpio_dev;
};

enum i2c_pin_fun {
	SCL = 0,
	SDA,
};

enum i2c_ch_status {
	I2C_CH_NORMAL = 0,
	I2C_CH_REPEAT_START,
	I2C_CH_WAIT_READ,
	I2C_CH_WAIT_NEXT_XFER,
};

struct i2c_it8xxx2_data {
	enum i2c_ch_status i2ccs;
	struct i2c_msg *msgs;
	struct k_mutex mutex;
	struct k_sem device_sync_sem;
	/* Index into output data */
	size_t widx;
	/* Index into input data */
	size_t ridx;
	/* operation freq of i2c */
	uint32_t bus_freq;
	/* Error code, if any */
	uint32_t err;
	/* address of device */
	uint16_t addr_16bit;
	/* Frequency setting */
	uint8_t freq;
	/* wait for stop bit interrupt */
	uint8_t stop;
};

enum enhanced_i2c_transfer_direct {
	TX_DIRECT,
	RX_DIRECT,
};

enum enhanced_i2c_ctl {
	/* Hardware reset */
	E_HW_RST = 0x01,
	/* Stop */
	E_STOP = 0x02,
	/* Start & Repeat start */
	E_START = 0x04,
	/* Acknowledge */
	E_ACK = 0x08,
	/* State reset */
	E_STS_RST = 0x10,
	/* Mode select */
	E_MODE_SEL = 0x20,
	/* I2C interrupt enable */
	E_INT_EN = 0x40,
	/* 0 : Standard mode , 1 : Receive mode */
	E_RX_MODE = 0x80,
	/* State reset and hardware reset */
	E_STS_AND_HW_RST = (E_STS_RST | E_HW_RST),
	/* Generate start condition and transmit slave address */
	E_START_ID = (E_INT_EN | E_MODE_SEL | E_ACK | E_START | E_HW_RST),
	/* Generate stop condition */
	E_FINISH = (E_INT_EN | E_MODE_SEL | E_ACK | E_STOP | E_HW_RST),
};

enum enhanced_i2c_host_status {
	/* ACK receive */
	E_HOSTA_ACK = 0x01,
	/* Interrupt pending */
	E_HOSTA_INTP = 0x02,
	/* Read/Write */
	E_HOSTA_RW = 0x04,
	/* Time out error */
	E_HOSTA_TMOE = 0x08,
	/* Arbitration lost */
	E_HOSTA_ARB = 0x10,
	/* Bus busy */
	E_HOSTA_BB = 0x20,
	/* Address match */
	E_HOSTA_AM = 0x40,
	/* Byte done status */
	E_HOSTA_BDS = 0x80,
	/* time out or lost arbitration */
	E_HOSTA_ANY_ERROR = (E_HOSTA_TMOE | E_HOSTA_ARB),
	/* Byte transfer done and ACK receive */
	E_HOSTA_BDS_AND_ACK = (E_HOSTA_BDS | E_HOSTA_ACK),
};

enum i2c_reset_cause {
	I2C_RC_NO_IDLE_FOR_START = 1,
	I2C_RC_TIMEOUT,
};

/* Start smbus session from idle state */
#define I2C_MSG_START BIT(5)

#define I2C_LINE_SCL_HIGH BIT(0)
#define I2C_LINE_SDA_HIGH BIT(1)
#define I2C_LINE_IDLE (I2C_LINE_SCL_HIGH | I2C_LINE_SDA_HIGH)

static int i2c_parsing_return_value(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;

	if (!data->err)
		return 0;

	/* Connection timed out */
	if (data->err == ETIMEDOUT)
		return -ETIMEDOUT;

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		/* The device does not respond ACK */
		if (data->err == HOSTA_NACK)
			return -ENXIO;
		else
			return -EIO;
	} else {
		/* The device does not respond ACK */
		if (data->err == E_HOSTA_ACK)
			return -ENXIO;
		else
			return -EIO;
	}
}

static int i2c_get_line_levels(const struct device *dev)
{
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;
	int pin_sts = 0;

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		return IT83XX_SMB_SMBPCTL(base) & 0x03;
	}

	if (IT83XX_I2C_TOS(base) & IT8XXX2_I2C_SCL_IN) {
		pin_sts |= I2C_LINE_SCL_HIGH;
	}

	if (IT83XX_I2C_TOS(base) & IT8XXX2_I2C_SDA_IN) {
		pin_sts |= I2C_LINE_SDA_HIGH;
	}

	return pin_sts;
}

static int i2c_is_busy(const struct device *dev)
{
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		return (IT83XX_SMB_HOSTA(base) &
					(HOSTA_HOBY | HOSTA_ALL_WC_BIT));
	}

	return (IT83XX_I2C_STR(base) & E_HOSTA_BB);
}

static int i2c_bus_not_available(const struct device *dev)
{
	if (i2c_is_busy(dev) ||
		(i2c_get_line_levels(dev) != I2C_LINE_IDLE)) {
		return -EIO;
	}

	return 0;
}

static void i2c_reset(const struct device *dev)
{
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		/* bit1, kill current transaction. */
		IT83XX_SMB_HOCTL(base) = 0x2;
		IT83XX_SMB_HOCTL(base) = 0;
		/* W/C host status register */
		IT83XX_SMB_HOSTA(base) = HOSTA_ALL_WC_BIT;
	} else {
		/* State reset and hardware reset */
		IT83XX_I2C_CTR(base) = E_STS_AND_HW_RST;
	}
}

/*
 * Set i2c standard port (A, B, or C) runs at 400kHz by using timing registers
 * (offset 0h ~ 7h).
 */
static void i2c_standard_port_timing_regs_400khz(uint8_t port)
{
	/* Port clock frequency depends on setting of timing registers. */
	IT83XX_SMB_SCLKTS(port) = 0;
	/* Suggested setting of timing registers of 400kHz. */
	IT83XX_SMB_4P7USL = 0x6;
	IT83XX_SMB_4P0USL = 0;
	IT83XX_SMB_300NS = 0x1;
	IT83XX_SMB_250NS = 0x2;
	IT83XX_SMB_45P3USL = 0x6a;
	IT83XX_SMB_45P3USH = 0x1;
	IT83XX_SMB_4P7A4P0H = 0;
}

/* Set clock frequency for i2c port A, B , or C */
static void i2c_standard_port_set_frequency(const struct device *dev,
					int freq_khz, int freq_set)
{
	const struct i2c_it8xxx2_config *config = dev->config;

	/*
	 * If port's clock frequency is 400kHz, we use timing registers
	 * for setting. So we can adjust tlow to meet timing.
	 * The others use basic 50/100/1000 KHz setting.
	 */
	if (freq_khz == 400) {
		i2c_standard_port_timing_regs_400khz(config->port);
	} else {
		IT83XX_SMB_SCLKTS(config->port) = freq_set;
	}

	/* This field defines the SMCLK0/1/2 clock/data low timeout. */
	IT83XX_SMB_25MS = I2C_CLK_LOW_TIMEOUT;
}

/* Set clock frequency for i2c port D, E , or F */
static void i2c_enhanced_port_set_frequency(const struct device *dev,
				int freq_khz)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint32_t clk_div, psr;
	uint8_t *base = config->base;

	/*
	 * Let psr(Prescale) = IT83XX_I2C_PSR(p_ch)
	 * Then, 1 SCL cycle = 2 x (psr + 2) x SMBus clock cycle
	 * SMBus clock = PLL_CLOCK / clk_div
	 * SMBus clock cycle = 1 / SMBus clock
	 * 1 SCL cycle = 1 / (1000 x freq)
	 * 1 / (1000 x freq) =
	 *			2 x (psr + 2) x (1 / (PLL_CLOCK / clk_div))
	 * psr = ((PLL_CLOCK / clk_div) x
	 *			(1 / (1000 x freq)) x (1 / 2)) - 2
	 */
	if (freq_khz) {
		/* Get SMBus clock divide value */
		clk_div = (SCDCR2 & 0x0F) + 1U;
		/* Calculate PSR value */
		psr = (PLL_CLOCK / (clk_div * (2U * 1000U * freq_khz))) - 2U;
		/* Set psr value under 0xFD */
		if (psr > 0xFD) {
			psr = 0xFD;
		}

		/* Set I2C Speed */
		IT83XX_I2C_PSR(base) = psr & 0xFF;
		IT83XX_I2C_HSPR(base) = psr & 0xFF;
		/* Backup */
		data->freq = psr & 0xFF;
	}

}

static int i2c_it8xxx2_configure(const struct device *dev,
				uint32_t dev_config_raw)
{
	const struct i2c_it8xxx2_config *config = dev->config;
	struct i2c_it8xxx2_data *const data = dev->data;
	uint32_t freq, freq_set;

	if (!(I2C_MODE_MASTER & dev_config_raw)) {
		return -EINVAL;
	}

	if (I2C_ADDR_10_BITS & dev_config_raw) {
		return -EINVAL;
	}

	data->bus_freq = I2C_SPEED_GET(dev_config_raw);

	switch (data->bus_freq) {
	case I2C_SPEED_STANDARD:
		freq = 100;
		freq_set = 2;
		break;
	case I2C_SPEED_FAST:
		freq = 400;
		freq_set = 3;
		break;
	case I2C_SPEED_FAST_PLUS:
		freq = 1000;
		freq_set = 4;
		break;
	default:
		return -EINVAL;
	}

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		i2c_standard_port_set_frequency(dev, freq, freq_set);
	} else {
		i2c_enhanced_port_set_frequency(dev, freq);
	}

	return 0;
}

static int i2c_it8xxx2_get_config(const struct device *dev,
				  uint32_t *dev_config)
{
	struct i2c_it8xxx2_data *const data = dev->data;
	uint32_t speed;

	if (!data->bus_freq) {
		LOG_ERR("The bus frequency is not initially configured.");
		return -EIO;
	}

	switch (data->bus_freq) {
	case I2C_SPEED_STANDARD:
		speed = I2C_SPEED_SET(I2C_SPEED_STANDARD);
		break;
	case I2C_SPEED_FAST:
		speed = I2C_SPEED_SET(I2C_SPEED_FAST);
		break;
	case I2C_SPEED_FAST_PLUS:
		speed = I2C_SPEED_SET(I2C_SPEED_FAST_PLUS);
		break;
	default:
		return -ERANGE;
	}

	*dev_config = (I2C_MODE_MASTER | speed);

	return 0;
}

static int enhanced_i2c_error(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;
	uint32_t i2c_str = IT83XX_I2C_STR(base);

	if (i2c_str & E_HOSTA_ANY_ERROR) {
		data->err = i2c_str & E_HOSTA_ANY_ERROR;
	/* device does not respond ACK */
	} else if ((i2c_str & E_HOSTA_BDS_AND_ACK) == E_HOSTA_BDS) {
		if (IT83XX_I2C_CTR(base) & E_ACK)
			data->err = E_HOSTA_ACK;
	}

	return data->err;
}

static void enhanced_i2c_start(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	/* State reset and hardware reset */
	IT83XX_I2C_CTR(base) = E_STS_AND_HW_RST;
	/* Set i2c frequency */
	IT83XX_I2C_PSR(base) = data->freq;
	IT83XX_I2C_HSPR(base) = data->freq;
	/*
	 * Set time out register.
	 * I2C D/E/F clock/data low timeout.
	 */
	IT83XX_I2C_TOR(base) = I2C_CLK_LOW_TIMEOUT;
	/* bit1: Enable enhanced i2c module */
	IT83XX_I2C_CTR1(base) = BIT(1);
}

static void i2c_pio_trans_data(const struct device *dev,
				enum enhanced_i2c_transfer_direct direct,
				uint16_t trans_data, int first_byte)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;
	uint32_t nack = 0;

	if (first_byte) {
		/* First byte must be slave address. */
		IT83XX_I2C_DTR(base) = trans_data |
					(direct == RX_DIRECT ? BIT(0) : 0);
		/* start or repeat start signal. */
		IT83XX_I2C_CTR(base) = E_START_ID;
	} else {
		if (direct == TX_DIRECT) {
			/* Transmit data */
			IT83XX_I2C_DTR(base) = (uint8_t)trans_data;
		} else {
			/*
			 * Receive data.
			 * Last byte should be NACK in the end of read cycle
			 */
			if (((data->ridx + 1) == data->msgs->len) &&
				(data->msgs->flags & I2C_MSG_STOP)) {
				nack = 1;
			}
		}
		/* Set hardware reset to start next transmission */
		IT83XX_I2C_CTR(base) = E_INT_EN | E_MODE_SEL |
				E_HW_RST | (nack ? 0 : E_ACK);
	}
}

static int enhanced_i2c_tran_read(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;
	uint8_t in_data = 0;

	if (data->msgs->flags & I2C_MSG_START) {
		/* clear start flag */
		data->msgs->flags &= ~I2C_MSG_START;
		enhanced_i2c_start(dev);
		/* Direct read  */
		data->i2ccs = I2C_CH_WAIT_READ;
		/* Send ID */
		i2c_pio_trans_data(dev, RX_DIRECT, data->addr_16bit << 1, 1);
	} else {
		if (data->i2ccs) {
			if (data->i2ccs == I2C_CH_WAIT_READ) {
				data->i2ccs = I2C_CH_NORMAL;
				/* Receive data */
				i2c_pio_trans_data(dev, RX_DIRECT, in_data, 0);

			/* data->msgs->flags == I2C_MSG_RESTART */
			} else {
				/* Write to read */
				data->i2ccs = I2C_CH_WAIT_READ;
				/* Send ID */
				i2c_pio_trans_data(dev, RX_DIRECT,
					data->addr_16bit << 1, 1);
			}
			/* Turn on irq before next direct read */
			irq_enable(config->i2c_irq_base);
		} else {
			if (data->ridx < data->msgs->len) {
				/* read data */
				*(data->msgs->buf++) = IT83XX_I2C_DRR(base);
				data->ridx++;
				/* done */
				if (data->ridx == data->msgs->len) {
					data->msgs->len = 0;
					if (data->msgs->flags & I2C_MSG_STOP) {
						data->i2ccs = I2C_CH_NORMAL;
						IT83XX_I2C_CTR(base) = E_FINISH;
						/* wait for stop bit interrupt */
						data->stop = 1;
						return 1;
					}
					/* End the transaction */
					data->i2ccs = I2C_CH_WAIT_READ;
					return 0;
				}
				/* read next byte */
				i2c_pio_trans_data(dev, RX_DIRECT, in_data, 0);
			}
		}
	}
	return 1;
}

static int enhanced_i2c_tran_write(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;
	uint8_t out_data;

	if (data->msgs->flags & I2C_MSG_START) {
		/* Clear start bit */
		data->msgs->flags &= ~I2C_MSG_START;
		enhanced_i2c_start(dev);
		/* Send ID */
		i2c_pio_trans_data(dev, TX_DIRECT, data->addr_16bit << 1, 1);
	} else {
		/* Host has completed the transmission of a byte */
		if (data->widx < data->msgs->len) {
			out_data = *(data->msgs->buf++);
			data->widx++;

			/* Send Byte */
			i2c_pio_trans_data(dev, TX_DIRECT, out_data, 0);
			if (data->i2ccs == I2C_CH_WAIT_NEXT_XFER) {
				data->i2ccs = I2C_CH_NORMAL;
				irq_enable(config->i2c_irq_base);
			}
		} else {
			/* done */
			data->msgs->len = 0;
			if (data->msgs->flags & I2C_MSG_STOP) {
				IT83XX_I2C_CTR(base) = E_FINISH;
				/* wait for stop bit interrupt */
				data->stop = 1;
			} else {
				/* Direct write with direct read */
				data->i2ccs = I2C_CH_WAIT_NEXT_XFER;
				return 0;
			}
		}
	}
	return 1;
}

static void i2c_r_last_byte(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	/*
	 * bit5, The firmware shall write 1 to this bit
	 * when the next byte will be the last byte for i2c read.
	 */
	if ((data->msgs->flags & I2C_MSG_STOP) &&
					(data->ridx == data->msgs->len - 1)) {
		IT83XX_SMB_HOCTL(base) |= 0x20;
	}
}

static void i2c_w2r_change_direction(const struct device *dev)
{
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	/* I2C switch direction */
	if (IT83XX_SMB_HOCTL2(base) & 0x08) {
		i2c_r_last_byte(dev);
		IT83XX_SMB_HOSTA(base) = HOSTA_NEXT_BYTE;
	} else {
		/*
		 * bit2, I2C switch direction wait.
		 * bit3, I2C switch direction enable.
		 */
		IT83XX_SMB_HOCTL2(base) |= 0x0C;
		IT83XX_SMB_HOSTA(base) = HOSTA_NEXT_BYTE;
		i2c_r_last_byte(dev);
		IT83XX_SMB_HOCTL2(base) &= ~0x04;
	}
}

static int i2c_tran_read(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	if (data->msgs->flags & I2C_MSG_START) {
		/* i2c enable */
		IT83XX_SMB_HOCTL2(base) = 0x13;
		/*
		 * bit0, Direction of the host transfer.
		 * bit[1:7}, Address of the targeted slave.
		 */
		IT83XX_SMB_TRASLA(base) = (uint8_t)(data->addr_16bit << 1) | 0x01;
		/* clear start flag */
		data->msgs->flags &= ~I2C_MSG_START;
		/*
		 * bit0, Host interrupt enable.
		 * bit[2:4}, Extend command.
		 * bit5, The firmware shall write 1 to this bit
		 *       when the next byte will be the last byte.
		 * bit6, start.
		 */
		if ((data->msgs->len == 1) &&
					(data->msgs->flags & I2C_MSG_STOP)) {
			IT83XX_SMB_HOCTL(base) = 0x7D;
		} else {
			IT83XX_SMB_HOCTL(base) = 0x5D;
		}
	} else {
		if ((data->i2ccs == I2C_CH_REPEAT_START) ||
			(data->i2ccs == I2C_CH_WAIT_READ)) {
			if (data->i2ccs == I2C_CH_REPEAT_START) {
				/* write to read */
				i2c_w2r_change_direction(dev);
			} else {
				/* For last byte */
				i2c_r_last_byte(dev);
				/* W/C for next byte */
				IT83XX_SMB_HOSTA(base) = HOSTA_NEXT_BYTE;
			}
			data->i2ccs = I2C_CH_NORMAL;
			irq_enable(config->i2c_irq_base);
		} else if (IT83XX_SMB_HOSTA(base) & HOSTA_BDS) {
			if (data->ridx < data->msgs->len) {
				/* To get received data. */
				*(data->msgs->buf++) = IT83XX_SMB_HOBDB(base);
				data->ridx++;
				/* For last byte */
				i2c_r_last_byte(dev);
				/* done */
				if (data->ridx == data->msgs->len) {
					data->msgs->len = 0;
					if (data->msgs->flags & I2C_MSG_STOP) {
						/* W/C for finish */
						IT83XX_SMB_HOSTA(base) =
						HOSTA_NEXT_BYTE;

						data->stop = 1;
					} else {
						data->i2ccs = I2C_CH_WAIT_READ;
						return 0;
					}
				} else {
					/* W/C for next byte */
					IT83XX_SMB_HOSTA(base) =
							HOSTA_NEXT_BYTE;
				}
			}
		}
	}
	return 1;

}

static int i2c_tran_write(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	if (data->msgs->flags & I2C_MSG_START) {
		/* i2c enable */
		IT83XX_SMB_HOCTL2(base) = 0x13;
		/*
		 * bit0, Direction of the host transfer.
		 * bit[1:7}, Address of the targeted slave.
		 */
		IT83XX_SMB_TRASLA(base) = (uint8_t)data->addr_16bit << 1;
		/* Send first byte */
		IT83XX_SMB_HOBDB(base) = *(data->msgs->buf++);

		data->widx++;
		/* clear start flag */
		data->msgs->flags &= ~I2C_MSG_START;
		/*
		 * bit0, Host interrupt enable.
		 * bit[2:4}, Extend command.
		 * bit6, start.
		 */
		IT83XX_SMB_HOCTL(base) = 0x5D;
	} else {
		/* Host has completed the transmission of a byte */
		if (IT83XX_SMB_HOSTA(base) & HOSTA_BDS) {
			if (data->widx < data->msgs->len) {
				/* Send next byte */
				IT83XX_SMB_HOBDB(base) = *(data->msgs->buf++);

				data->widx++;
				/* W/C byte done for next byte */
				IT83XX_SMB_HOSTA(base) = HOSTA_NEXT_BYTE;

				if (data->i2ccs == I2C_CH_REPEAT_START) {
					data->i2ccs = I2C_CH_NORMAL;
					irq_enable(config->i2c_irq_base);
				}
			} else {
				/* done */
				data->msgs->len = 0;
				if (data->msgs->flags & I2C_MSG_STOP) {
					/* set I2C_EN = 0 */
					IT83XX_SMB_HOCTL2(base) = 0x11;
					/* W/C byte done for finish */
					IT83XX_SMB_HOSTA(base) =
							HOSTA_NEXT_BYTE;

					data->stop = 1;
				} else {
					data->i2ccs = I2C_CH_REPEAT_START;
					return 0;
				}
			}
		}
	}
	return 1;

}

static int i2c_transaction(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		/* any error */
		if (IT83XX_SMB_HOSTA(base) & HOSTA_ANY_ERROR) {
			data->err = (IT83XX_SMB_HOSTA(base) & HOSTA_ANY_ERROR);
		} else {
			if (!data->stop) {
				if (data->msgs->flags & I2C_MSG_READ) {
					return i2c_tran_read(dev);
				} else {
					return i2c_tran_write(dev);
				}
			}
			/* wait finish */
			if (!(IT83XX_SMB_HOSTA(base) & HOSTA_FINTR)) {
				return 1;
			}
		}
		/* W/C */
		IT83XX_SMB_HOSTA(base) = HOSTA_ALL_WC_BIT;
		/* disable the SMBus host interface */
		IT83XX_SMB_HOCTL2(base) = 0x00;
	} else {

		/* no error */
		if (!(enhanced_i2c_error(dev))) {
			if (!data->stop) {
				/* i2c read */
				if (data->msgs->flags & I2C_MSG_READ) {
					return enhanced_i2c_tran_read(dev);
				/* i2c write */
				} else {
					return enhanced_i2c_tran_write(dev);
				}
			}
		}
		IT83XX_I2C_CTR(base) = E_STS_AND_HW_RST;
		IT83XX_I2C_CTR1(base) = 0;
	}
	data->stop = 0;
	/* done doing work */
	return 0;
}

static int i2c_it8xxx2_transfer(const struct device *dev, struct i2c_msg *msgs,
		uint8_t num_msgs, uint16_t addr)
{
	struct i2c_it8xxx2_data *data;
	const struct i2c_it8xxx2_config *config;
	int res;

	/* Check for NULL pointers */
	if (dev == NULL) {
		LOG_ERR("Device handle is NULL");
		return -EINVAL;
	}
	if (msgs == NULL) {
		LOG_ERR("Device message is NULL");
		return -EINVAL;
	}

	data = dev->data;
	config = dev->config;

	/* Lock mutex of i2c controller */
	k_mutex_lock(&data->mutex, K_FOREVER);
	/*
	 * If the transaction of write to read is divided into two
	 * transfers, the repeat start transfer uses this flag to
	 * exclude checking bus busy.
	 */
	if (data->i2ccs == I2C_CH_NORMAL) {
		/* Make sure we're in a good state to start */
		if (i2c_bus_not_available(dev)) {
			/* Recovery I2C bus */
			i2c_recover_bus(dev);
			/*
			 * After resetting I2C bus, if I2C bus is not available
			 * (No external pull-up), drop the transaction.
			 */
			if (i2c_bus_not_available(dev)) {
				/* Unlock mutex of i2c controller */
				k_mutex_unlock(&data->mutex);
				return -EIO;
			}
		}

		msgs->flags |= I2C_MSG_START;
	}

	for (int i = 0; i < num_msgs; i++) {

		data->widx = 0;
		data->ridx = 0;
		data->err = 0;
		data->msgs = &(msgs[i]);
		data->addr_16bit = addr;

		if (msgs->flags & I2C_MSG_START) {
			data->i2ccs = I2C_CH_NORMAL;
			/* enable i2c interrupt */
			irq_enable(config->i2c_irq_base);
		}
		/* Start transaction */
		i2c_transaction(dev);
		/* Wait for the transfer to complete */
		/* TODO: the timeout should be adjustable */
		res = k_sem_take(&data->device_sync_sem, K_MSEC(100));
		/*
		 * The irq will be enabled at the condition of start or
		 * repeat start of I2C. If timeout occurs without being
		 * wake up during suspend(ex: interrupt is not fired),
		 * the irq should be disabled immediately.
		 */
		irq_disable(config->i2c_irq_base);
		/*
		 * The transaction is dropped on any error(timeout, NACK, fail,
		 * bus error, device error).
		 */
		if (data->err)
			break;

		if (res != 0) {
			data->err = ETIMEDOUT;
			/* reset i2c port */
			i2c_reset(dev);
			printk("I2C ch%d:0x%X reset cause %d\n",
			       config->port, data->addr_16bit, I2C_RC_TIMEOUT);
			/* If this message is sent fail, drop the transaction. */
			break;
		}
	}

	/* reset i2c channel status */
	if (data->err || (msgs->flags & I2C_MSG_STOP)) {
		data->i2ccs = I2C_CH_NORMAL;
	}
	/* Unlock mutex of i2c controller */
	k_mutex_unlock(&data->mutex);

	return i2c_parsing_return_value(dev);
}

static void i2c_it8xxx2_isr(void *arg)
{
	struct device *dev = (struct device *)arg;
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;

	/* If done doing work, wake up the task waiting for the transfer */
	if (!i2c_transaction(dev)) {
		k_sem_give(&data->device_sync_sem);
		irq_disable(config->i2c_irq_base);
	}
}

static int i2c_it8xxx2_init(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = dev->data;
	const struct i2c_it8xxx2_config *config = dev->config;
	uint8_t *base = config->base;
	uint32_t bitrate_cfg, offset = 0;
	int error;

	/* Initialize mutex and semaphore */
	k_mutex_init(&data->mutex);
	k_sem_init(&data->device_sync_sem, 0, K_SEM_MAX_LIMIT);

	switch ((uint32_t)base) {
	case DT_REG_ADDR(DT_NODELABEL(i2c0)):
		offset = CGC_OFFSET_SMBA;
		break;
	case DT_REG_ADDR(DT_NODELABEL(i2c1)):
		offset = CGC_OFFSET_SMBB;
		break;
	case DT_REG_ADDR(DT_NODELABEL(i2c2)):
		offset = CGC_OFFSET_SMBC;
		break;
	case DT_REG_ADDR(DT_NODELABEL(i2c3)):
		offset = CGC_OFFSET_SMBD;
		break;
	case DT_REG_ADDR(DT_NODELABEL(i2c4)):
		offset = CGC_OFFSET_SMBE;
		/* Enable SMBus E channel */
		PMER1 |= 0x01;
		break;
	case DT_REG_ADDR(DT_NODELABEL(i2c5)):
		offset = CGC_OFFSET_SMBF;
		/* Enable SMBus F channel */
		PMER1 |= 0x02;
		break;
	}

	/* Enable I2C function. */
	volatile uint8_t *reg = (volatile uint8_t *)
				(IT83XX_ECPM_BASE + (offset >> 8));
	uint8_t reg_mask = offset & 0xff;
	*reg &= ~reg_mask;

	if (config->port < I2C_STANDARD_PORT_COUNT) {
		/*
		 * bit0, The SMBus host interface is enabled.
		 * bit1, Enable to communicate with I2C device
		 *		  and support I2C-compatible cycles.
		 * bit4, This bit controls the reset mechanism
		 *		  of SMBus master to handle the SMDAT
		 *		  line low if 25ms reg timeout.
		 */
		IT83XX_SMB_HOCTL2(base) = 0x11;
		/*
		 * bit1, Kill SMBus host transaction.
		 * bit0, Enable the interrupt for the master interface.
		 */
		IT83XX_SMB_HOCTL(base) = 0x03;
		IT83XX_SMB_HOCTL(base) = 0x01;

		/* W/C host status register */
		IT83XX_SMB_HOSTA(base) = HOSTA_ALL_WC_BIT;
		IT83XX_SMB_HOCTL2(base) = 0x00;

	} else {
		/* Software reset */
		IT83XX_I2C_DHTR(base) |= 0x80;
		IT83XX_I2C_DHTR(base) &= 0x7F;
		/* State reset and hardware reset */
		IT83XX_I2C_CTR(base) = E_STS_AND_HW_RST;
		/* bit1, Module enable */
		IT83XX_I2C_CTR1(base) = 0;
	}

	bitrate_cfg = i2c_map_dt_bitrate(config->bitrate);
	error = i2c_it8xxx2_configure(dev, I2C_MODE_MASTER | bitrate_cfg);
	data->i2ccs = I2C_CH_NORMAL;

	if (error) {
		LOG_ERR("i2c: failure initializing");
		return error;
	}

	/* The pin is set to I2C alternate function of SCL */
	pinmux_pin_set(config->alts_list[SCL].pinctrls,
		       config->alts_list[SCL].pin,
		       config->alts_list[SCL].alt_fun);
	/* The pin is set to I2C alternate function of SDA */
	pinmux_pin_set(config->alts_list[SDA].pinctrls,
		       config->alts_list[SDA].pin,
		       config->alts_list[SDA].alt_fun);

	return 0;
}

static int i2c_it8xxx2_recover_bus(const struct device *dev)
{
	const struct i2c_it8xxx2_config *config = dev->config;
	int i;

	/* Set SCL of I2C as GPIO pin */
	pinmux_pin_input_enable(config->alts_list[SCL].pinctrls,
				config->alts_list[SCL].pin,
				PINMUX_OUTPUT_ENABLED);
	/* Set SDA of I2C as GPIO pin */
	pinmux_pin_input_enable(config->alts_list[SDA].pinctrls,
				config->alts_list[SDA].pin,
				PINMUX_OUTPUT_ENABLED);

	/* Pull SCL and SDA pin to high */
	gpio_pin_set(config->gpio_dev, config->alts_list[SCL].pin, 1);
	gpio_pin_set(config->gpio_dev, config->alts_list[SDA].pin, 1);
	k_msleep(1);

	/* Start condition */
	gpio_pin_set(config->gpio_dev, config->alts_list[SDA].pin, 0);
	k_msleep(1);
	gpio_pin_set(config->gpio_dev, config->alts_list[SCL].pin, 0);
	k_msleep(1);

	/* 9 cycles of SCL with SDA held high */
	for (i = 0; i < 9; i++) {
		/* SDA */
		gpio_pin_set(config->gpio_dev, config->alts_list[SDA].pin, 1);
		/* SCL */
		gpio_pin_set(config->gpio_dev, config->alts_list[SCL].pin, 1);
		k_msleep(1);
		/* SCL */
		gpio_pin_set(config->gpio_dev, config->alts_list[SCL].pin, 0);
		k_msleep(1);
	}
	/* SDA */
	gpio_pin_set(config->gpio_dev, config->alts_list[SDA].pin, 0);
	k_msleep(1);

	/* Stop condition */
	gpio_pin_set(config->gpio_dev, config->alts_list[SCL].pin, 1);
	k_msleep(1);
	gpio_pin_set(config->gpio_dev, config->alts_list[SDA].pin, 1);
	k_msleep(1);

	/* Set GPIO back to I2C alternate function of SCL */
	pinmux_pin_set(config->alts_list[SCL].pinctrls,
		       config->alts_list[SCL].pin,
		       config->alts_list[SCL].alt_fun);
	/* Set GPIO back to I2C alternate function of SDA */
	pinmux_pin_set(config->alts_list[SDA].pinctrls,
		       config->alts_list[SDA].pin,
		       config->alts_list[SDA].alt_fun);

	/* reset i2c port */
	i2c_reset(dev);
	printk("I2C ch%d reset cause %d\n", config->port,
	       I2C_RC_NO_IDLE_FOR_START);

	return 0;
}

static const struct i2c_driver_api i2c_it8xxx2_driver_api = {
	.configure = i2c_it8xxx2_configure,
	.get_config = i2c_it8xxx2_get_config,
	.transfer = i2c_it8xxx2_transfer,
	.recover_bus = i2c_it8xxx2_recover_bus,
};

#define I2C_ITE_IT8XXX2_INIT(idx)                                              \
	static void i2c_it8xxx2_config_func_##idx(void);                       \
	static const struct i2c_alts_cfg                                       \
		i2c_alts_##idx[DT_INST_NUM_PINCTRLS_BY_IDX(idx, 0)] =          \
			IT8XXX2_DT_ALT_ITEMS_LIST(idx);                        \
									       \
	static const struct i2c_it8xxx2_config i2c_it8xxx2_cfg_##idx = {       \
		.base = (uint8_t *)(DT_INST_REG_ADDR(idx)),                    \
		.irq_config_func = i2c_it8xxx2_config_func_##idx,              \
		.bitrate = DT_INST_PROP(idx, clock_frequency),                 \
		.i2c_irq_base = DT_INST_IRQN(idx),                             \
		.port = DT_INST_PROP(idx, port_num),                           \
		.alts_list = i2c_alts_##idx,                                   \
		.gpio_dev = DEVICE_DT_GET(DT_INST_PHANDLE(idx, gpio_dev)),     \
	};                                                                     \
	\
	static struct i2c_it8xxx2_data i2c_it8xxx2_data_##idx;	               \
	\
	I2C_DEVICE_DT_INST_DEFINE(idx,				               \
			i2c_it8xxx2_init, NULL,				       \
			&i2c_it8xxx2_data_##idx,	                       \
			&i2c_it8xxx2_cfg_##idx, POST_KERNEL,		       \
			CONFIG_KERNEL_INIT_PRIORITY_DEVICE,                    \
			&i2c_it8xxx2_driver_api);                              \
	\
	static void i2c_it8xxx2_config_func_##idx(void)                        \
	{                                                                      \
		IRQ_CONNECT(DT_INST_IRQN(idx),                                 \
			0,                                                     \
			i2c_it8xxx2_isr,                                       \
			DEVICE_DT_INST_GET(idx), 0);                           \
	}

DT_INST_FOREACH_STATUS_OKAY(I2C_ITE_IT8XXX2_INIT)
