/*
 * Copyright (c) 2019 Intel Corporation
 * Copyright (c) 2021 Microchip Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT microchip_xec_i2c_v2

#include <kernel.h>
#include <soc.h>
#include <errno.h>
#include <drivers/clock_control.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include <drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#include <drivers/pinmux.h>
#include <sys/printk.h>
#include <sys/sys_io.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(i2c_mchp, CONFIG_I2C_LOG_LEVEL);

#define SPEED_100KHZ_BUS	0
#define SPEED_400KHZ_BUS	1
#define SPEED_1MHZ_BUS		2

#define EC_OWN_I2C_ADDR		0x7F
#define RESET_WAIT_US		20

/* I2C timeout is  10 ms (WAIT_INTERVAL * WAIT_COUNT) */
#define WAIT_INTERVAL		50
#define WAIT_COUNT		200
#define STOP_WAIT_COUNT		500
#define PIN_CFG_WAIT		50

/* I2C Read/Write bit pos */
#define I2C_READ_WRITE_POS	0

/* I2C recover SCL low retries */
#define I2C_RECOVER_SCL_LOW_RETRIES	10
/* I2C recover SDA low retries */
#define I2C_RECOVER_SDA_LOW_RETRIES	3
/* I2C recovery bit bang delay */
#define I2C_RECOVER_BB_DELAY_US		5
/* I2C recovery SCL sample delay */
#define I2C_RECOVER_SCL_DELAY_US	50

/* I2C SCL and SDA lines(signals) */
#define I2C_LINES_SCL_HI	BIT(0)
#define I2C_LINES_SDA_HI	BIT(1)
#define I2C_LINES_BOTH_HI	(I2C_LINES_SCL_HI | I2C_LINES_SDA_HI)

#define I2C_START		0U
#define I2C_RPT_START		1U

#define I2C_ENI_DIS		0U
#define I2C_ENI_EN		1U

#define I2C_WAIT_PIN_DEASSERT	0U
#define I2C_WAIT_PIN_ASSERT	1U

#define I2C_XEC_CTRL_WR_DLY	8

#define I2C_XEC_STATE_STOPPED	1U
#define I2C_XEC_STATE_OPEN	2U

#define I2C_XEC_OK		0
#define I2C_XEC_ERR_LAB		1
#define I2C_XEC_ERR_BUS		2
#define I2C_XEC_ERR_TMOUT	3

#define XEC_GPIO_CTRL_BASE	DT_REG_ADDR(DT_NODELABEL(gpio_000_036))

struct xec_speed_cfg {
	uint32_t bus_clk;
	uint32_t data_timing;
	uint32_t start_hold_time;
	uint32_t config;
	uint32_t timeout_scale;
};

struct i2c_xec_config {
	uint32_t port_sel;
	uint32_t base_addr;
	uint8_t girq;
	uint8_t girq_pos;
	uint8_t pcr_idx;
	uint8_t pcr_bitpos;
	void (*irq_config_func)(void);
};

struct i2c_xec_data {
	uint8_t state;
	uint8_t read_discard;
	uint8_t speed_id;
	struct i2c_slave_config *target_cfg;
	bool target_attached;
	bool target_read;
	uint32_t i2c_compl;
	uint8_t i2c_ctrl;
	uint8_t i2c_addr;
	uint8_t i2c_status;
};

/* Recommended programming values based on 16MHz
 * i2c_baud_clk_period/bus_clk_period - 2 = (low_period + hi_period)
 * bus_clk_reg (16MHz/100KHz -2) = 0x4F + 0x4F
 *             (16MHz/400KHz -2) = 0x0F + 0x17
 *             (16MHz/1MHz -2) = 0x05 + 0x09
 */
static const struct xec_speed_cfg xec_cfg_params[] = {
	[SPEED_100KHZ_BUS] = {
		.bus_clk            = 0x00004F4F,
		.data_timing        = 0x0C4D5006,
		.start_hold_time    = 0x0000004D,
		.config             = 0x01FC01ED,
		.timeout_scale      = 0x4B9CC2C7,
	},
	[SPEED_400KHZ_BUS] = {
		.bus_clk            = 0x00000F17,
		.data_timing        = 0x040A0A06,
		.start_hold_time    = 0x0000000A,
		.config             = 0x01000050,
		.timeout_scale      = 0x159CC2C7,
	},
	[SPEED_1MHZ_BUS] = {
		.bus_clk            = 0x00000509,
		.data_timing        = 0x04060601,
		.start_hold_time    = 0x00000006,
		.config             = 0x10000050,
		.timeout_scale      = 0x089CC2C7,
	},
};

struct xec_i2c_port {
	uint8_t scl_pin;
	uint8_t scl_func;
	uint8_t sda_pin;
	uint8_t sda_func;
};

/* Indexed by port number */
static const struct xec_i2c_port xec_i2c_ports[] = {
	{ 0004, 1, 0003, 1 },
	{ 0131, 1, 0130, 1 },
	{ 0155, 1, 0154, 1 },
	{ 0010, 1, 0007, 1 },
	{ 0144, 1, 0143, 1 },
	{ 0142, 1, 0141, 1 },
	{ 0140, 1, 0132, 1 },
	{ 0013, 1, 0012, 1 },
#ifdef CONFIG_SOC_SERIES_MEC172X
	{ 0230, 1, 0231, 1 },
#else
	{ 0212, 1, 0211, 1 },
#endif
	{ 0146, 1, 0145, 1 },
	{ 0107, 3, 0030, 2 },
	{ 0062, 2, 0000, 3 },
	{ 0027, 3, 0026, 3 },
	{ 0065, 2, 0066, 2 },
	{ 0071, 2, 0070, 2 },
	{ 0150, 1, 0147, 1 },
};

/* returns b[0]=SCL pin state, b[1]=SDA pin state */
static uint32_t xec_i2c_port_lines(uint8_t port)
{
	uintptr_t base = (uintptr_t)XEC_GPIO_CTRL_BASE;
	uint32_t lines = 0;

	if (port < ARRAY_SIZE(xec_i2c_ports)) {
		const struct xec_i2c_port *p = &xec_i2c_ports[port];
		uintptr_t ctrl_addr = base + p->scl_pin * 4;

		lines = (sys_read32(ctrl_addr) >> 24) & BIT(0);
		ctrl_addr = base + p->scl_pin * 4;
		lines |= ((sys_read32(ctrl_addr) >> 23) & BIT(1));
	}

	return lines;
}

#define XEC_I2C_PIN_PRE_CFG1						\
	(MCHP_GPIO_CTRL_OUTV_HI | MCHP_GPIO_CTRL_MUX_GPIO |		\
	 MCHP_GPIO_CTRL_DIR_OUTPUT | MCHP_GPIO_CTRL_BUFT_OPENDRAIN |	\
	 MCHP_GPIO_CTRL_IDET_DISABLE | MCHP_GPIO_CTRL_PUD_NONE)

static int xec_i2c_port_cfg(uint8_t port, uint8_t enable)
{
	if (port >= ARRAY_SIZE(xec_i2c_ports)) {
		return -EINVAL;
	}

	const struct xec_i2c_port *p = &xec_i2c_ports[port];
	uintptr_t scl_addr = (uintptr_t)XEC_GPIO_CTRL_BASE + p->scl_pin * 4;
	uintptr_t sda_addr = (uintptr_t)XEC_GPIO_CTRL_BASE + p->sda_pin * 4;

	if (enable) {
		sys_write32(XEC_I2C_PIN_PRE_CFG1, sda_addr);
		sys_write32(XEC_I2C_PIN_PRE_CFG1, scl_addr);

		k_busy_wait(PIN_CFG_WAIT);

		sys_write32(sys_read32(sda_addr) |
			    ((uint32_t)(p->sda_func) << MCHP_GPIO_CTRL_MUX_POS),
			    sda_addr);
		sys_write32(sys_read32(scl_addr) |
			    ((uint32_t)(p->scl_func) << MCHP_GPIO_CTRL_MUX_POS),
			    scl_addr);
	} else {
		sys_write32(MCHP_GPIO_CTRL_DIS_PIN, scl_addr);
		sys_write32(MCHP_GPIO_CTRL_DIS_PIN, sda_addr);
	}

	return 0;
}

static void i2c_ctl_wr(const struct device *dev, uint8_t ctrl)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;

	data->i2c_ctrl = ctrl;
	regs->CTRLSTS = ctrl;
	for (int i = 0; i < I2C_XEC_CTRL_WR_DLY; i++) {
		regs->BLKID = ctrl;
	}
}

static int i2c_xec_reset_config(const struct device *dev);

static int wait_bus_free(const struct device *dev, uint32_t nwait)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	uint32_t count = nwait;
	uint8_t sts = 0;

	while (count--) {
		sts = regs->CTRLSTS;
		data->i2c_status = sts;
		if (sts & MCHP_I2C_SMB_STS_NBB) {
			break; /* bus is free */
		}
		k_busy_wait(WAIT_INTERVAL);
	}

	/* NBB -> 1 not busy can occur for STOP, BER, or LAB */
	if (sts == (MCHP_I2C_SMB_STS_PIN | MCHP_I2C_SMB_STS_NBB)) {
		/* No service requested(PIN=1), NotBusy(NBB=1), and no errors */
		return 0;
	}

	if (sts & MCHP_I2C_SMB_STS_BER) {
		return I2C_XEC_ERR_BUS;
	}

	if (sts & MCHP_I2C_SMB_STS_LAB) {
		return I2C_XEC_ERR_LAB;
	}

	return I2C_XEC_ERR_TMOUT;
}

/*
 * returns state of I2C SCL and SDA lines.
 * b[0] = SCL, b[1] = SDA
 */
static uint32_t get_lines(const struct device *dev)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	uint8_t port = regs->CFG & MCHP_I2C_SMB_CFG_PORT_SEL_MASK;

	return xec_i2c_port_lines(port);
}

static int i2c_xec_reset_config(const struct device *dev)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;

	data->state = I2C_XEC_STATE_STOPPED;
	data->read_discard = 0;

	/* Assert RESET and clr others */
	regs->CFG = MCHP_I2C_SMB_CFG_RESET;
	k_busy_wait(RESET_WAIT_US);
	/* clear reset, set filter enable, select port */
	regs->CFG = 0;
	regs->CFG = MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO |
		    MCHP_I2C_SMB_CFG_FLUSH_SRBUF_WO |
		    MCHP_I2C_SMB_CFG_FLUSH_MXBUF_WO |
		    MCHP_I2C_SMB_CFG_FLUSH_MRBUF_WO;

	mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);

	/* PIN=1 to clear all status except NBB and synchronize */
	i2c_ctl_wr(dev, MCHP_I2C_SMB_CTRL_PIN);

	/*
	 * Controller implements two peripheral addresses for itself.
	 * It always monitors whether an external controller issues START
	 * plus target address. We should write valid peripheral addresses
	 * that do not match any peripheral on the bus.
	 * An alternative is to use the default 0 value which is the
	 * general call address and disable the general call match
	 * enable in the configuration register.
	 */
	regs->OWN_ADDR = EC_OWN_I2C_ADDR | (EC_OWN_I2C_ADDR << 8);
#ifdef CONFIG_I2C_SLAVE
	if (data->target_cfg) {
		regs->OWN_ADDR = data->target_cfg->address;
	}
#endif
	/* Port number and filter enable MUST be written before enabling */
	regs->CFG |= BIT(14); /* disable general call */
	regs->CFG |= MCHP_I2C_SMB_CFG_FEN;
	regs->CFG |= (cfg->port_sel & MCHP_I2C_SMB_CFG_PORT_SEL_MASK);

	/*
	 * Before enabling the controller program the desired bus clock,
	 * repeated start hold time, data timing, and timeout scaling
	 * registers.
	 */
	regs->BUSCLK = xec_cfg_params[data->speed_id].bus_clk;
	regs->RSHTM = xec_cfg_params[data->speed_id].start_hold_time;
	regs->DATATM = xec_cfg_params[data->speed_id].data_timing;
	regs->TMOUTSC = xec_cfg_params[data->speed_id].timeout_scale;

	/*
	 * PIN=1 clears all status except NBB
	 * ESO=1 enables output drivers
	 * ACK=1 enable ACK generation when data/address is clocked in.
	 */
	i2c_ctl_wr(dev, MCHP_I2C_SMB_CTRL_PIN |
			MCHP_I2C_SMB_CTRL_ESO |
			MCHP_I2C_SMB_CTRL_ACK);

	/* Enable controller */
	regs->CFG |= MCHP_I2C_SMB_CFG_ENAB;
	k_busy_wait(RESET_WAIT_US);

	/* wait for NBB=1, BER, LAB, or timeout */
	int rc = wait_bus_free(dev, WAIT_COUNT);

	return rc;
}

/*
 * If SCL is low sample I2C_RECOVER_SCL_LOW_RETRIES times with a 5 us delay
 * between samples. If SCL remains low then return -EBUSY
 * If SCL is High and SDA is low then loop up to I2C_RECOVER_SDA_LOW_RETRIES
 * times driving the pins:
 * Drive SCL high
 * delay I2C_RECOVER_BB_DELAY_US
 * Generate 9 clock pulses on SCL checking SDA before each falling edge of SCL
 *   If SDA goes high exit clock loop else to all 9 clocks
 * Drive SDA low, delay 5 us, release SDA, delay 5 us
 * Both lines are high then exit SDA recovery loop
 * Both lines should not be driven
 * Check both lines: if any bad return error else return success
 * NOTE 1: Bit-bang mode uses a HW MUX to switch the lines away from the I2C
 * controller logic to BB logic.
 * NOTE 2: Bit-bang mode requires HW timeouts to be disabled.
 * NOTE 3: Bit-bang mode requires the controller's configuration enable bit
 * to be set.
 * NOTE 4: The controller must be reset after using bit-bang mode.
 */
static int i2c_xec_recover_bus(const struct device *dev)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	int i, j, ret;

	LOG_ERR("I2C attempt bus recovery\n");

	/* reset controller to a known state */
	regs->CFG = MCHP_I2C_SMB_CFG_RESET;
	k_busy_wait(RESET_WAIT_US);
	regs->CFG = BIT(14) | MCHP_I2C_SMB_CFG_FEN |
		    (cfg->port_sel & MCHP_I2C_SMB_CFG_PORT_SEL_MASK);
	regs->CFG |= MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO |
		     MCHP_I2C_SMB_CFG_FLUSH_SRBUF_WO |
		     MCHP_I2C_SMB_CFG_FLUSH_MXBUF_WO |
		     MCHP_I2C_SMB_CFG_FLUSH_MRBUF_WO;
	regs->CTRLSTS = MCHP_I2C_SMB_CTRL_PIN;
	regs->BBCTRL = MCHP_I2C_SMB_BB_EN | MCHP_I2C_SMB_BB_CL |
		       MCHP_I2C_SMB_BB_DAT;
	regs->CFG |= MCHP_I2C_SMB_CFG_ENAB;

	if (!(regs->BBCTRL & MCHP_I2C_SMB_BB_CLKI_RO)) {
		for (i = 0;; i++) {
			if (i >= I2C_RECOVER_SCL_LOW_RETRIES) {
				ret = -EBUSY;
				goto recov_exit;
			}
			k_busy_wait(I2C_RECOVER_SCL_DELAY_US);
			if (regs->BBCTRL & MCHP_I2C_SMB_BB_CLKI_RO) {
				break; /* SCL went High */
			}
		}
	}

	if (regs->BBCTRL & MCHP_I2C_SMB_BB_DATI_RO) {
		ret = 0;
		goto recov_exit;
	}

	ret = -EBUSY;
	/* SDA recovery */
	for (i = 0; i < I2C_RECOVER_SDA_LOW_RETRIES; i++) {
		/* SCL output mode and tri-stated */
		regs->BBCTRL = MCHP_I2C_SMB_BB_EN |
			       MCHP_I2C_SMB_BB_SCL_DIR_OUT |
			       MCHP_I2C_SMB_BB_CL |
			       MCHP_I2C_SMB_BB_DAT;
		k_busy_wait(I2C_RECOVER_BB_DELAY_US);

		for (j = 0; j < 9; j++) {
			if (regs->BBCTRL & MCHP_I2C_SMB_BB_DATI_RO) {
				break;
			}
			/* drive SCL low */
			regs->BBCTRL = MCHP_I2C_SMB_BB_EN |
				       MCHP_I2C_SMB_BB_SCL_DIR_OUT |
				       MCHP_I2C_SMB_BB_DAT;
			k_busy_wait(I2C_RECOVER_BB_DELAY_US);
			/* release SCL: pulled high by external pull-up */
			regs->BBCTRL = MCHP_I2C_SMB_BB_EN |
				       MCHP_I2C_SMB_BB_SCL_DIR_OUT |
				       MCHP_I2C_SMB_BB_CL |
				       MCHP_I2C_SMB_BB_DAT;
			k_busy_wait(I2C_RECOVER_BB_DELAY_US);
		}

		/* SCL is High. Produce rising edge on SCL for STOP */
		regs->BBCTRL = MCHP_I2C_SMB_BB_EN | MCHP_I2C_SMB_BB_CL |
				MCHP_I2C_SMB_BB_SDA_DIR_OUT; /* drive low */
		k_busy_wait(I2C_RECOVER_BB_DELAY_US);
		regs->BBCTRL = MCHP_I2C_SMB_BB_EN | MCHP_I2C_SMB_BB_CL |
				MCHP_I2C_SMB_BB_DAT; /* release SCL */
		k_busy_wait(I2C_RECOVER_BB_DELAY_US);

		/* check if SCL and SDA are both high */
		uint8_t bb = regs->BBCTRL &
			(MCHP_I2C_SMB_BB_CLKI_RO | MCHP_I2C_SMB_BB_DATI_RO);

		if (bb == (MCHP_I2C_SMB_BB_CLKI_RO | MCHP_I2C_SMB_BB_DATI_RO)) {
			ret = 0; /* successful recovery */
			goto recov_exit;
		}
	}

recov_exit:
	/* BB mode disable reconnects SCL and SDA to I2C logic. */
	regs->BBCTRL = 0;
	regs->CTRLSTS = MCHP_I2C_SMB_CTRL_PIN; /* clear status */
	i2c_xec_reset_config(dev); /* reset controller */

	return ret;
}

#ifdef CONFIG_I2C_SLAVE
/*
 * Restart I2C controller as target for ACK of address match.
 * Setting PIN clears all status in I2C.Status register except NBB.
 */
static void restart_target(const struct device *dev)
{
	i2c_ctl_wr(dev, MCHP_I2C_SMB_CTRL_PIN | MCHP_I2C_SMB_CTRL_ESO |
			MCHP_I2C_SMB_CTRL_ACK | MCHP_I2C_SMB_CTRL_ENI);
}

/*
 * Configure I2C controller acting as target to NACK the next received byte.
 * NOTE: Firmware must re-enable ACK generation before the start of the next
 * transaction otherwise the controller will NACK its target addresses.
 */
static void target_config_for_nack(const struct device *dev)
{
	i2c_ctl_wr(dev, MCHP_I2C_SMB_CTRL_PIN | MCHP_I2C_SMB_CTRL_ESO |
			MCHP_I2C_SMB_CTRL_ENI);
}
#endif

static int wait_pin(const struct device *dev, bool pin_assert, uint32_t nwait)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;

	for (;;) {
		k_busy_wait(WAIT_INTERVAL);

		data->i2c_compl = regs->COMPL;
		data->i2c_status = regs->CTRLSTS;

		if (data->i2c_status & MCHP_I2C_SMB_STS_BER) {
			return I2C_XEC_ERR_BUS;
		}

		if (data->i2c_status & MCHP_I2C_SMB_STS_LAB) {
			return I2C_XEC_ERR_LAB;
		}

		if (!(data->i2c_status & MCHP_I2C_SMB_STS_PIN)) {
			if (pin_assert) {
				return 0;
			}
		} else if (!pin_assert) {
			return 0;
		}

		if (nwait) {
			--nwait;
		} else {
			break;
		}
	}

	return I2C_XEC_ERR_TMOUT;
}

static int gen_start(const struct device *dev, uint8_t addr8,
		     bool is_repeated)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	uint8_t ctrl = MCHP_I2C_SMB_CTRL_ESO | MCHP_I2C_SMB_CTRL_STA |
		       MCHP_I2C_SMB_CTRL_ACK;

	data->i2c_addr = addr8;

	if (is_repeated) {
		i2c_ctl_wr(dev, ctrl);
		regs->I2CDATA = addr8;
	} else {
		ctrl |= MCHP_I2C_SMB_CTRL_PIN;
		regs->I2CDATA = addr8;
		i2c_ctl_wr(dev, ctrl);
	}

	return 0;
}

static int gen_stop(const struct device *dev)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	uint8_t ctrl = MCHP_I2C_SMB_CTRL_PIN | MCHP_I2C_SMB_CTRL_ESO |
		       MCHP_I2C_SMB_CTRL_STO | MCHP_I2C_SMB_CTRL_ACK;

	data->i2c_ctrl = ctrl;
	regs->CTRLSTS = ctrl;

	return 0;
}

static int do_stop(const struct device *dev, uint32_t nwait)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	int ret;

	data->state = I2C_XEC_STATE_STOPPED;
	data->read_discard = 0;

	gen_stop(dev);
	ret = wait_bus_free(dev, nwait);
	if (ret) {
		uint32_t lines = get_lines(dev);

		if (lines != I2C_LINES_BOTH_HI) {
			i2c_xec_recover_bus(dev);
		} else {
			ret = i2c_xec_reset_config(dev);
		}
	}

	if (ret == 0) {
		/* stop success: prepare for next transaction */
		regs->CTRLSTS = MCHP_I2C_SMB_CTRL_PIN | MCHP_I2C_SMB_CTRL_ESO |
				MCHP_I2C_SMB_CTRL_ACK;
	}

	return ret;
}

static int do_start(const struct device *dev, uint8_t addr8, bool is_repeated)
{
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	int ret;

	gen_start(dev, addr8, is_repeated);
	ret = wait_pin(dev, I2C_WAIT_PIN_ASSERT, WAIT_COUNT);
	if (ret) {
		i2c_xec_reset_config(dev);
		return ret;
	}

	/* PIN 1->0: check for NACK */
	if (data->i2c_status & MCHP_I2C_SMB_STS_LRB_AD0) {
		gen_stop(dev);
		ret = wait_bus_free(dev, WAIT_COUNT);
		if (ret) {
			i2c_xec_reset_config(dev);
		}
		return -EIO;
	}

	return 0;
}

static int i2c_xec_configure(const struct device *dev,
			     uint32_t dev_config_raw)
{
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);

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

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

	switch (I2C_SPEED_GET(dev_config_raw)) {
	case I2C_SPEED_STANDARD:
		data->speed_id = SPEED_100KHZ_BUS;
		break;
	case I2C_SPEED_FAST:
		data->speed_id = SPEED_400KHZ_BUS;
		break;
	case I2C_SPEED_FAST_PLUS:
		data->speed_id = SPEED_1MHZ_BUS;
		break;
	default:
		return -EINVAL;
	}

	int ret = i2c_xec_reset_config(dev);

	return ret;
}

/* I2C Controller transmit: polling implementation */
static int ctrl_tx(const struct device *dev, struct i2c_msg *msg, uint16_t addr)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	int ret = 0;
	uint8_t mflags = msg->flags;
	uint8_t addr8 = (uint8_t)((addr & 0x7FU) << 1);

	if (data->state == I2C_XEC_STATE_STOPPED) {
		data->i2c_addr = addr8;
		/* Is bus free and controller ready? */
		ret = wait_bus_free(dev, WAIT_COUNT);
		if (ret) {
			ret = i2c_xec_recover_bus(dev);
			if (ret) {
				return ret;
			}
		}

		ret = do_start(dev, addr8, I2C_START);
		if (ret) {
			return ret;
		}

		data->state = I2C_XEC_STATE_OPEN;

	} else if (mflags & I2C_MSG_RESTART) {
		data->i2c_addr = addr8;
		ret = do_start(dev, addr8, I2C_RPT_START);
		if (ret) {
			return ret;
		}
	}

	for (size_t n = 0; n < msg->len; n++) {
		regs->I2CDATA = msg->buf[n];
		ret = wait_pin(dev, I2C_WAIT_PIN_ASSERT, WAIT_COUNT);
		if (ret) {
			i2c_xec_reset_config(dev);
			return ret;
		}
		if (data->i2c_status & MCHP_I2C_SMB_STS_LRB_AD0) { /* NACK? */
			do_stop(dev, STOP_WAIT_COUNT);
			return -EIO;
		}
	}

	if (mflags & I2C_MSG_STOP) {
		ret = do_stop(dev, STOP_WAIT_COUNT);
	}

	return ret;
}

/*
 * I2C Controller receive: polling implementation
 * Transmitting a target address with BIT[0] == 1 causes the controller
 * to enter controller-read mode where every read of I2CDATA generates
 * clocks for the next byte. When we generate START or Repeated-START
 * and transmit an address the address is also clocked in during
 * address transmission. The address must read and discarded.
 * Read of I2CDATA returns data currently in I2C read buffer, sets
 * I2CSTATUS.PIN = 1, and !!generates clocks for the next
 * byte!!
 * For this controller to NACK the last byte we must clear the
 * I2C CTRL register ACK bit BEFORE reading the next to last
 * byte. Before reading the last byte we configure I2C CTRL to generate a STOP
 * and then read the last byte from I2 DATA.
 * When controller is in STOP mode it will not generate clocks when I2CDATA is
 * read. UGLY HW DESIGN.
 * We will NOT attempt to follow this HW design for Controller read except
 * when all information is available: STOP message flag set AND number of
 * bytes to read including dummy is >= 2. General usage can result in the
 * controller not NACK'ing the last byte.
 */
static int ctrl_rx(const struct device *dev, struct i2c_msg *msg, uint16_t addr)
{
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;
	int ret = 0;
	size_t data_len = msg->len;
	uint8_t mflags = msg->flags;
	uint8_t addr8 = (uint8_t)(((addr & 0x7FU) << 1) | BIT(0));
	uint8_t temp = 0;

	if (data->state == I2C_XEC_STATE_STOPPED) {
		data->i2c_addr = addr8;
		/* Is bus free and controller ready? */
		ret = wait_bus_free(dev, WAIT_COUNT);
		if (ret) {
			i2c_xec_reset_config(dev);
			return ret;
		}

		ret = do_start(dev, addr8, I2C_START);
		if (ret) {
			return ret;
		}

		data->state = I2C_XEC_STATE_OPEN;

		/* controller clocked address into I2CDATA */
		data->read_discard = 1U;

	} else if (mflags & I2C_MSG_RESTART) {
		data->i2c_addr = addr8;
		ret = do_start(dev, addr8, I2C_RPT_START);
		if (ret) {
			return ret;
		}

		/* controller clocked address into I2CDATA */
		data->read_discard = 1U;
	}

	if (!data_len) { /* requested message length is 0 */
		ret = 0;
		if (mflags & I2C_MSG_STOP) {
			data->state = I2C_XEC_STATE_STOPPED;
			data->read_discard = 0;
			ret = do_stop(dev, STOP_WAIT_COUNT);
		}
		return ret;
	}

	if (data->read_discard) {
		data_len++;
	}

	uint8_t *p8 = &msg->buf[0];

	while (data_len) {
		if (mflags & I2C_MSG_STOP) {
			if (data_len == 2) {
				i2c_ctl_wr(dev, MCHP_I2C_SMB_CTRL_ESO);
			} else if (data_len == 1) {
				break;
			}
		}
		temp = regs->I2CDATA; /* generates clocks */
		if (data->read_discard) {
			data->read_discard = 0;
		} else {
			*p8++ = temp;
		}
		ret = wait_pin(dev, I2C_WAIT_PIN_ASSERT, WAIT_COUNT);
		if (ret) {
			i2c_xec_reset_config(dev);
			return ret;
		}
		data_len--;
	}

	if (mflags & I2C_MSG_STOP) {
		data->state = I2C_XEC_STATE_STOPPED;
		data->read_discard = 0;
		ret = do_stop(dev, STOP_WAIT_COUNT);
		if (ret == 0) {
			*p8 = regs->I2CDATA;
		}
	}

	return ret;
}

static int i2c_xec_transfer(const struct device *dev, struct i2c_msg *msgs,
			    uint8_t num_msgs, uint16_t addr)
{
	struct i2c_xec_data *data = dev->data;
	int ret = 0;

#ifdef CONFIG_I2C_SLAVE
	if (data->target_attached) {
		LOG_ERR("Device is registered as target");
		return -EBUSY;
	}
#endif

	for (uint8_t i = 0; i < num_msgs; i++) {
		struct i2c_msg *m = &msgs[i];

		if ((m->flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			ret = ctrl_tx(dev, m, addr);
		} else {
			ret = ctrl_rx(dev, m, addr);
		}
		if (ret) {
			data->state = I2C_XEC_STATE_STOPPED;
			data->read_discard = 0;
			LOG_ERR("i2x_xfr: flags: %x error: %d", m->flags, ret);
			break;
		}
	}

	return ret;
}

static void i2c_xec_bus_isr(void *arg)
{
#ifdef CONFIG_I2C_SLAVE
	struct device *dev = (struct device *)arg;
	const struct i2c_xec_config *cfg =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data = dev->data;
	const struct i2c_slave_callbacks *target_cb =
		data->target_cfg->callbacks;
	struct i2c_smb_regs *regs = (struct i2c_smb_regs *)cfg->base_addr;

	int ret;
	uint32_t status;
	uint32_t compl_status;
	uint8_t val;

	uint8_t dummy = 0U;

	/* Get current status */
	status = regs->CTRLSTS;
	compl_status = regs->COMPL & MCHP_I2C_SMB_CMPL_RW1C_MASK;

	/* Idle interrupt enabled and active? */
	if ((regs->CFG & MCHP_I2C_SMB_CFG_ENIDI) &&
	    (compl_status & MCHP_I2C_SMB_CMPL_IDLE_RWC)) {
		regs->CFG &= ~MCHP_I2C_SMB_CFG_ENIDI;
		if (status & MCHP_I2C_SMB_STS_NBB) {
			restart_target(dev);
			goto clear_iag;
		}
	}

	if (!data->target_attached) {
		goto clear_iag;
	}

	/* Bus Error */
	if (status & MCHP_I2C_SMB_STS_BER) {
		if (target_cb->stop) {
			target_cb->stop(data->target_cfg);
		}
		restart_target(dev);
		goto clear_iag;
	}

	/* External stop */
	if (status & MCHP_I2C_SMB_STS_EXT_STOP) {
		if (target_cb->stop) {
			target_cb->stop(data->target_cfg);
		}
		restart_target(dev);
		goto clear_iag;
	}

	/* Address byte handling */
	if (status & MCHP_I2C_SMB_STS_AAS) {
		if (status & MCHP_I2C_SMB_STS_PIN) {
			goto clear_iag;
		}

		uint8_t rx_data = regs->I2CDATA;

		if (rx_data & BIT(I2C_READ_WRITE_POS)) {
			/* target transmitter mode */
			data->target_read = true;
			val = dummy;
			if (target_cb->read_requested) {
				target_cb->read_requested(
					data->target_cfg, &val);

				/* Application target transmit handler
				 * does not have data to send. In
				 * target transmit mode the external
				 * Controller is ACK's data we send.
				 * All we can do is keep sending dummy
				 * data. We assume read_requested does
				 * not modify the value pointed to by val
				 * if it has not data(returns error).
				 */
			}
			/*
			 * Writing I2CData causes this HW to release SCL
			 * ending clock stretching. The external Controller
			 * senses SCL released and begins generating clocks
			 * and capturing data driven by this controller
			 * on SDA. External Controller ACK's data until it
			 * wants no more then it will NACK.
			 */
			regs->I2CDATA = val;
			goto clear_iag; /* Exit ISR */
		} else {
			/* target receiver mode */
			data->target_read = false;
			if (target_cb->write_requested) {
				ret = target_cb->write_requested(
							data->target_cfg);
				if (ret) {
					/*
					 * Application handler can't accept
					 * data. Configure HW to NACK next
					 * data transmitted by external
					 * Controller.
					 * !!! TODO We must re-program our HW
					 * for address ACK before next
					 * transaction is begun !!!
					 */
					target_config_for_nack(dev);
				}
			}
			goto clear_iag; /* Exit ISR */
		}
	}

	if (data->target_read) { /* Target transmitter mode */

		/* Master has Nacked, then just write a dummy byte */
		status = regs->CTRLSTS;
		if (status & MCHP_I2C_SMB_STS_LRB_AD0) {

			/*
			 * ISSUE: HW will not detect external STOP in
			 * target transmit mode. Enable IDLE interrupt
			 * to catch PIN 0 -> 1 and NBB 0 -> 1.
			 */
			regs->CFG |= MCHP_I2C_SMB_CFG_ENIDI;

			/*
			 * dummy write causes this controller's PIN status
			 * to de-assert 0 -> 1. Data is not transmitted.
			 * SCL is not driven low by this controller.
			 */
			regs->I2CDATA = dummy;

			status = regs->CTRLSTS;

		} else {
			val = dummy;
			if (target_cb->read_processed) {
				target_cb->read_processed(
					data->target_cfg, &val);
			}
			regs->I2CDATA = val;
		}
	} else { /* target receiver mode */
		/*
		 * Reading the I2CData register causes this target to release
		 * SCL. The external Controller senses SCL released generates
		 * clocks for transmitting the next data byte.
		 * Reading I2C Data register causes PIN status 0 -> 1.
		 */
		val = regs->I2CDATA;
		if (target_cb->write_received) {
			/*
			 * Call back returns error if we should NACK
			 * next byte.
			 */
			ret = target_cb->write_received(data->target_cfg, val);
			if (ret) {
				/*
				 * Configure HW to NACK next byte. It will not
				 * generate clocks for another byte of data
				 */
				target_config_for_nack(dev);
			}
		}
	}

clear_iag:
	regs->COMPL = compl_status;
	mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);
#endif
}

#ifdef CONFIG_I2C_SLAVE
static int i2c_xec_target_register(const struct device *dev,
				   struct i2c_slave_config *config)
{
	const struct i2c_xec_config *cfg = dev->config;
	struct i2c_xec_data *data = dev->data;
	int ret;

	if (!config) {
		return -EINVAL;
	}

	if (data->target_attached) {
		return -EBUSY;
	}

	/* Wait for any outstanding transactions to complete so that
	 * the bus is free
	 */
	ret = wait_bus_free(dev, WAIT_COUNT);
	if (ret) {
		return ret;
	}

	data->target_cfg = config;

	ret = i2c_xec_reset_config(dev);
	if (ret) {
		return ret;
	}

	restart_target(dev);

	data->target_attached = true;

	/* Clear before enabling girq bit */
	mchp_xec_ecia_girq_src_clr(cfg->girq, cfg->girq_pos);
	mchp_xec_ecia_girq_src_en(cfg->girq, cfg->girq_pos);

	return 0;
}

static int i2c_xec_target_unregister(const struct device *dev,
				     struct i2c_slave_config *config)
{
	const struct i2c_xec_config *cfg = dev->config;
	struct i2c_xec_data *data = dev->data;

	if (!data->target_attached) {
		return -EINVAL;
	}

	data->target_cfg = NULL;
	data->target_attached = false;

	mchp_xec_ecia_girq_src_dis(cfg->girq, cfg->girq_pos);

	return 0;
}
#endif

static const struct i2c_driver_api i2c_xec_driver_api = {
	.configure = i2c_xec_configure,
	.transfer = i2c_xec_transfer,
#ifdef CONFIG_I2C_SLAVE
	.slave_register = i2c_xec_target_register,
	.slave_unregister = i2c_xec_target_unregister,
#endif
};

static int i2c_xec_init(const struct device *dev)
{
	const struct i2c_xec_config *cfg = dev->config;
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	int ret;

	data->state = I2C_XEC_STATE_STOPPED;
	data->target_cfg = NULL;
	data->target_attached = false;

	ret = xec_i2c_port_cfg(cfg->port_sel, 1);
	if (ret) {
		return ret;
	}

	/* Default configuration */
	ret = i2c_xec_configure(dev,
				I2C_MODE_MASTER |
				I2C_SPEED_SET(I2C_SPEED_STANDARD));
	if (ret) {
		return ret;
	}

#ifdef CONFIG_I2C_SLAVE
	const struct i2c_xec_config *config =
	(const struct i2c_xec_config *const) (dev->config);

	config->irq_config_func();
#endif
	return 0;
}

#define I2C_XEC_DEVICE(n)						\
	static void i2c_xec_irq_config_func_##n(void);			\
									\
	static struct i2c_xec_data i2c_xec_data_##n;			\
	static const struct i2c_xec_config i2c_xec_config_##n = {	\
		.base_addr =						\
			DT_INST_REG_ADDR(n),				\
		.port_sel = DT_INST_PROP(n, port_sel),			\
		.girq = DT_INST_PROP_BY_IDX(n, girqs, 0),		\
		.girq_pos = DT_INST_PROP_BY_IDX(n, girqs, 1),		\
		.pcr_idx = DT_INST_PROP_BY_IDX(n, pcrs, 0),		\
		.pcr_bitpos = DT_INST_PROP_BY_IDX(n, pcrs, 1),		\
		.irq_config_func = i2c_xec_irq_config_func_##n,		\
	};								\
	I2C_DEVICE_DT_INST_DEFINE(n, i2c_xec_init, NULL,		\
		&i2c_xec_data_##n, &i2c_xec_config_##n,			\
		POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,			\
		&i2c_xec_driver_api);					\
									\
	static void i2c_xec_irq_config_func_##n(void)			\
	{                                                               \
		IRQ_CONNECT(DT_INST_IRQN(n),				\
			    DT_INST_IRQ(n, priority),			\
			    i2c_xec_bus_isr,				\
			    DEVICE_DT_INST_GET(n), 0);			\
		irq_enable(DT_INST_IRQN(n));				\
	}

DT_INST_FOREACH_STATUS_OKAY(I2C_XEC_DEVICE)
