/*
 * 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/pinctrl.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(SOC_I2C_SCL_POS)
#define I2C_LINES_SDA_HI	BIT(SOC_I2C_SDA_POS)
#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;
	const struct pinctrl_dev_config *pcfg;
	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,
	},
};

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
 * Call soc specific routine to read GPIO pad input.
 * Why? We can get the pins from our PINCTRL info but
 * we do not know which pin is I2C clock and which pin
 * is I2C data. There's no ordering in PINCTRL DT unless
 * we impose an order.
 */
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;
	uint32_t lines = 0u;

	soc_i2c_port_lines_get(port, &lines);

	return lines;
}

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(const struct device *dev)
{
#ifdef CONFIG_I2C_SLAVE
	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 = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
	if (ret != 0) {
		LOG_ERR("XEC I2C pinctrl setup failed (%d)", 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)						\
									\
	PINCTRL_DT_INST_DEFINE(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,		\
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(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)
