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

#define DT_DRV_COMPAT ite_it8xxx2_i2c

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

#define DEV_CFG(dev) \
		((const struct i2c_it8xxx2_config * const)(dev)->config)
#define DEV_DATA(dev) \
		((struct i2c_it8xxx2_data * const)(dev)->data)

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

struct i2c_it8xxx2_config {
	void (*irq_config_func)(void);
	uint32_t bitrate;
	uint8_t *base;
	uint8_t i2c_irq_base;
	uint8_t port;
};

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_sem device_sync_sem;
	/* Index into output data */
	size_t widx;
	/* Index into input data */
	size_t ridx;
	/* 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)

struct i2c_pin {
	volatile uint8_t *mirror_clk;
	volatile uint8_t *mirror_data;
	uint8_t clk_mask;
	uint8_t data_mask;
};

static const struct i2c_pin i2c_pin_regs[] = {
	{ &GPDMRB, &GPDMRB,	0x08, 0x10},
	{ &GPDMRC, &GPDMRC,	0x02, 0x04},
	{ &GPDMRF, &GPDMRF,	0x40, 0x80},
	{ &GPDMRH, &GPDMRH,	0x02, 0x04},
	{ &GPDMRE, &GPDMRE,	0x01, 0x80},
	{ &GPDMRA, &GPDMRA,	0x10, 0x20},
};

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

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

	if (*i2c_pin_regs[config->port].mirror_clk &
					i2c_pin_regs[config->port].clk_mask) {
		pin_sts |= I2C_LINE_SCL_HIGH;
	}
	if (*i2c_pin_regs[config->port].mirror_data &
					i2c_pin_regs[config->port].data_mask) {
		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_CFG(dev);
	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 void i2c_reset(const struct device *dev, int cause)
{
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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;
	}
	printk("I2C ch%d reset cause %d\n", config->port, cause);
}

/*
 * 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_CFG(dev);

	/*
	 * 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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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_CFG(dev);
	uint32_t freq, freq_set;

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

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

	switch (I2C_SPEED_GET(dev_config_raw)) {
	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 enhanced_i2c_error(const struct device *dev)
{
	struct i2c_it8xxx2_data *data = DEV_DATA(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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);
	} 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);
			}
			/* 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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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);
	} 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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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_CFG(dev);
	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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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 | 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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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;
		/* 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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	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 = DEV_DATA(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);

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

	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;

		/* Make sure we're in a good state to start */
		if ((msgs->flags & I2C_MSG_START) && (i2c_is_busy(dev)
			|| (i2c_get_line_levels(dev) != I2C_LINE_IDLE))) {
			/* reset i2c port */
			i2c_reset(dev, I2C_RC_NO_IDLE_FOR_START);
		}
		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 */
		k_sem_take(&data->device_sync_sem, K_FOREVER);
	}

	/* reset i2c channel status */
	if (data->err) {
		data->i2ccs = I2C_CH_NORMAL;
	}

	return data->err;
}

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

	/* 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(dev);
	const struct i2c_it8xxx2_config *config = DEV_CFG(dev);
	uint8_t *base = config->base;
	uint32_t bitrate_cfg, offset = 0;
	int error;

	k_sem_init(&data->device_sync_sem, 0, UINT_MAX);

	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;
		/* Enable SMBus D channel */
		GCR2 |= SMB3E;
		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);

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

	return 0;
}

static const struct i2c_driver_api i2c_it8xxx2_driver_api = {
	.configure = i2c_it8xxx2_configure,
	.transfer = i2c_it8xxx2_transfer,
};

#define I2C_ITE_IT8XXX2_INIT(idx)                                              \
	static void i2c_it8xxx2_config_func_##idx(void);                       \
									       \
	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),                           \
	};                                                                     \
	\
	static struct i2c_it8xxx2_data i2c_it8xxx2_data_##idx;	               \
	\
	DEVICE_DT_INST_DEFINE(idx,				               \
			&i2c_it8xxx2_init, &device_pm_control_nop,             \
			&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)
