/*
 * 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 <zephyr/kernel.h>
#include <soc.h>
#include <errno.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/interrupt_controller/intc_mchp_xec_ecia.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(i2c_mchp, CONFIG_I2C_LOG_LEVEL);

#include "i2c-priv.h"

#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 idle_scale;
	uint32_t timeout_scale;
};

struct i2c_xec_config {
	uint32_t port_sel;
	uint32_t base_addr;
	uint32_t clock_freq;
	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,
		.idle_scale         = 0x01FC01ED,
		.timeout_scale      = 0x4B9CC2C7,
	},
	[SPEED_400KHZ_BUS] = {
		.bus_clk            = 0x00000F17,
		.data_timing        = 0x040A0A06,
		.start_hold_time    = 0x0000000A,
		.idle_scale         = 0x01000050,
		.timeout_scale      = 0x159CC2C7,
	},
	[SPEED_1MHZ_BUS] = {
		.bus_clk            = 0x00000509,
		.data_timing        = 0x04060601,
		.start_hold_time    = 0x00000006,
		.idle_scale         = 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;
	regs->IDLSC = xec_cfg_params[data->speed_id].idle_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;
	uint32_t bitrate_cfg;

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

	bitrate_cfg = i2c_map_dt_bitrate(cfg->clock_freq);
	if (!bitrate_cfg) {
		return -EINVAL;
	}

	/* Default configuration */
	ret = i2c_xec_configure(dev, I2C_MODE_MASTER | bitrate_cfg);
	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),			\
		.clock_freq = DT_INST_PROP(n, clock_frequency),		\
		.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)
