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

#define DT_DRV_COMPAT microchip_xec_i2c

#include <zephyr/drivers/clock_control.h>
#include <zephyr/kernel.h>
#include <soc.h>
#include <errno.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/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
#define BUS_IDLE_US_DFLT	5

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

/* Line High Timeout is 2.5 ms (WAIT_LINE_HIGH_USEC * WAIT_LINE_HIGH_COUNT) */
#define WAIT_LINE_HIGH_USEC	25
#define WAIT_LINE_HIGH_COUNT	100

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

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_id;
	uint8_t girq_bit;
	struct gpio_dt_spec sda_gpio;
	struct gpio_dt_spec scl_gpio;
	const struct pinctrl_dev_config *pcfg;
	void (*irq_config_func)(void);
};

struct i2c_xec_data {
	uint32_t pending_stop;
	uint32_t error_seen;
	uint32_t timeout_seen;
	uint32_t previously_in_read;
	uint32_t speed_id;
	struct i2c_target_config *slave_cfg;
	bool slave_attached;
	bool slave_read;
};

/* 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_xec_reset_config(const struct device *dev)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);

	uint32_t ba = config->base_addr;

	/* Assert RESET and clr others */
	MCHP_I2C_SMB_CFG(ba) = MCHP_I2C_SMB_CFG_RESET;

	k_busy_wait(RESET_WAIT_US);

	/* Bus reset */
	MCHP_I2C_SMB_CFG(ba) = 0;

	/* Write 0x80. i.e Assert PIN bit, ESO = 0 and Interrupts
	 * disabled (ENI)
	 */
	MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_PIN;

	/* Enable controller and I2C filters */
	MCHP_I2C_SMB_CFG(ba) = MCHP_I2C_SMB_CFG_GC_EN |
				MCHP_I2C_SMB_CFG_ENAB |
				MCHP_I2C_SMB_CFG_FEN |
				(config->port_sel &
				 MCHP_I2C_SMB_CFG_PORT_SEL_MASK);

	/* Configure bus clock register, Data Timing register,
	 * Repeated Start Hold Time register,
	 * and Timeout Scaling register
	 */
	MCHP_I2C_SMB_BUS_CLK(ba) = xec_cfg_params[data->speed_id].bus_clk;
	MCHP_I2C_SMB_DATA_TM(ba) = xec_cfg_params[data->speed_id].data_timing;
	MCHP_I2C_SMB_RSHT(ba) =
		xec_cfg_params[data->speed_id].start_hold_time;
	MCHP_I2C_SMB_TMTSC(ba) = xec_cfg_params[data->speed_id].timeout_scale;

	MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_PIN |
				   MCHP_I2C_SMB_CTRL_ESO |
				   MCHP_I2C_SMB_CTRL_ACK;

	k_busy_wait(RESET_WAIT_US);
}

static int xec_spin_yield(int *counter)
{
	*counter = *counter + 1;

	if (*counter > WAIT_COUNT) {
		return -ETIMEDOUT;
	}

	k_busy_wait(WAIT_INTERVAL);

	return 0;
}

static void cleanup_registers(uint32_t ba)
{
	uint32_t cfg = MCHP_I2C_SMB_CFG(ba);

	cfg |= MCHP_I2C_SMB_CFG_FLUSH_MXBUF_WO;
	MCHP_I2C_SMB_CFG(ba) = cfg;
	cfg &= ~MCHP_I2C_SMB_CFG_FLUSH_MXBUF_WO;

	cfg |= MCHP_I2C_SMB_CFG_FLUSH_MRBUF_WO;
	MCHP_I2C_SMB_CFG(ba) = cfg;
	cfg &= ~MCHP_I2C_SMB_CFG_FLUSH_MRBUF_WO;

	cfg |= MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO;
	MCHP_I2C_SMB_CFG(ba) = cfg;
	cfg &= ~MCHP_I2C_SMB_CFG_FLUSH_SXBUF_WO;

	cfg |= MCHP_I2C_SMB_CFG_FLUSH_SRBUF_WO;
	MCHP_I2C_SMB_CFG(ba) = cfg;
	cfg &= ~MCHP_I2C_SMB_CFG_FLUSH_SRBUF_WO;
}

#ifdef CONFIG_I2C_TARGET
static void restart_slave(uint32_t ba)
{
	MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_PIN |
				   MCHP_I2C_SMB_CTRL_ESO |
				   MCHP_I2C_SMB_CTRL_ACK |
				   MCHP_I2C_SMB_CTRL_ENI;
}
#endif

static void recover_from_error(const struct device *dev)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	uint32_t ba = config->base_addr;

	cleanup_registers(ba);
	i2c_xec_reset_config(dev);
}

static int wait_bus_free(const struct device *dev)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	int ret;
	int counter = 0;
	uint32_t ba = config->base_addr;

	while (!(MCHP_I2C_SMB_STS_RO(ba) & MCHP_I2C_SMB_STS_NBB)) {
		ret = xec_spin_yield(&counter);

		if (ret < 0) {
			return ret;
		}
	}

	/* Check for bus error */
	if (MCHP_I2C_SMB_STS_RO(ba) & MCHP_I2C_SMB_STS_BER) {
		recover_from_error(dev);
		return -EBUSY;
	}

	return 0;
}

/*
 * Wait with timeout for I2C controller to finish transmit/receive of one
 * byte(address or data).
 * When transmit/receive operation is started the I2C PIN status is 1. Upon
 * normal completion I2C PIN status asserts(0).
 * We loop checking I2C status for the following events:
 * Bus Error:
 *      Reset controller and return -EBUSY
 * Lost Arbitration:
 *      Return -EPERM. We lost bus to another controller. No reset.
 * PIN == 0: I2C Status LRB is valid and contains ACK/NACK data on 9th clock.
 *      ACK return 0 (success)
 *      NACK Issue STOP, wait for bus minimum idle time, return -EIO.
 * Timeout:
 *      Reset controller and return -ETIMEDOUT
 *
 * NOTE: After generating a STOP the controller will not generate a START until
 * Bus Minimum Idle time has expired.
 */
static int wait_completion(const struct device *dev)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	int ret;
	int counter = 0;
	uint32_t ba = config->base_addr;

	while (1) {
		uint8_t status = MCHP_I2C_SMB_STS_RO(ba);

		/* Is bus error ? */
		if (status & MCHP_I2C_SMB_STS_BER) {
			recover_from_error(dev);
			return -EBUSY;
		}

		/* Is Lost arbitration ? */
		status = MCHP_I2C_SMB_STS_RO(ba);
		if (status & MCHP_I2C_SMB_STS_LAB) {
			recover_from_error(dev);
			return -EPERM;
		}

		status = MCHP_I2C_SMB_STS_RO(ba);
		/* PIN -> 0 indicates I2C is done */
		if (!(status & MCHP_I2C_SMB_STS_PIN)) {
			/* PIN == 0. LRB contains state of 9th bit */
			if (status & MCHP_I2C_SMB_STS_LRB_AD0) { /* NACK? */
				/* Send STOP */
				MCHP_I2C_SMB_CTRL_WO(ba) =
						MCHP_I2C_SMB_CTRL_PIN |
						MCHP_I2C_SMB_CTRL_ESO |
						MCHP_I2C_SMB_CTRL_STO |
						MCHP_I2C_SMB_CTRL_ACK;
				k_busy_wait(BUS_IDLE_US_DFLT);
				return -EIO;
			}
			break; /* success: ACK */
		}

		ret = xec_spin_yield(&counter);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}

/*
 * Call GPIO driver to read state of pins.
 * Return boolean true if both lines HIGH else return boolean false
 */
static bool check_lines_high(const struct device *dev)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const)(dev->config);
	gpio_port_value_t sda = 0, scl = 0;

	if (gpio_port_get_raw(config->sda_gpio.port, &sda)) {
		LOG_ERR("gpio_port_get_raw for %s SDA failed", dev->name);
		return false;
	}

	/* both pins could be on same GPIO group */
	if (config->sda_gpio.port == config->scl_gpio.port) {
		scl = sda;
	} else {
		if (gpio_port_get_raw(config->scl_gpio.port, &scl)) {
			LOG_ERR("gpio_port_get_raw for %s SCL failed",
				dev->name);
			return false;
		}
	}

	return (sda & BIT(config->sda_gpio.pin)) && (scl & BIT(config->scl_gpio.pin));

}

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_CONTROLLER)) {
		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;
	}

	i2c_xec_reset_config(dev);

	return 0;
}

static int i2c_xec_poll_write(const struct device *dev, struct i2c_msg msg,
			      uint16_t addr)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	uint32_t ba = config->base_addr;
	uint8_t i2c_timer = 0, byte;
	int ret;

	if (data->timeout_seen == 1) {
		/* Wait to see if the slave has released the CLK */
		ret = wait_completion(dev);
		if (ret) {
			data->timeout_seen = 1;
			LOG_ERR("%s: %s wait_completion failure %d\n",
				__func__, dev->name, ret);
			return ret;
		}
		data->timeout_seen = 0;

		/* If we are here, it means the slave has finally released
		 * the CLK. The master needs to end that transaction
		 * gracefully by sending a STOP on the bus.
		 */
		LOG_DBG("%s: %s Force Stop", __func__, dev->name);
		MCHP_I2C_SMB_CTRL_WO(ba) =
					MCHP_I2C_SMB_CTRL_PIN |
					MCHP_I2C_SMB_CTRL_ESO |
					MCHP_I2C_SMB_CTRL_STO |
					MCHP_I2C_SMB_CTRL_ACK;
		k_busy_wait(BUS_IDLE_US_DFLT);
		data->pending_stop = 0;

		/* If the timeout had occurred while the master was reading
		 * something from the slave, that read needs to be completed
		 * to clear the bus.
		 */
		if (data->previously_in_read == 1) {
			data->previously_in_read = 0;
			byte = MCHP_I2C_SMB_DATA(ba);
		}
		return -EBUSY;
	}

	if ((data->pending_stop == 0) || (data->error_seen == 1)) {
		/* Wait till clock and data lines are HIGH */
		while (check_lines_high(dev) == false) {
			if (i2c_timer >= WAIT_LINE_HIGH_COUNT) {
				LOG_DBG("%s: %s not high",
					__func__, dev->name);
				data->error_seen = 1;
				return -EBUSY;
			}
			k_busy_wait(WAIT_LINE_HIGH_USEC);
			i2c_timer++;
		}

		if (data->error_seen) {
			LOG_DBG("%s: Recovering %s previously in error",
				__func__, dev->name);
			data->error_seen = 0;
			recover_from_error(dev);
		}

		/* Wait until bus is free */
		ret = wait_bus_free(dev);
		if (ret) {
			data->error_seen = 1;
			LOG_DBG("%s: %s wait_bus_free failure %d",
				__func__, dev->name, ret);
			return ret;
		}

		/* Send slave address */
		MCHP_I2C_SMB_DATA(ba) = (addr & ~BIT(0));

		/* Send start and ack bits */
		MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_PIN |
				MCHP_I2C_SMB_CTRL_ESO | MCHP_I2C_SMB_CTRL_STA |
				MCHP_I2C_SMB_CTRL_ACK;

		ret = wait_completion(dev);
		switch (ret) {
		case 0:	/* Success */
			break;

		case -EIO:
			LOG_WRN("%s: No Addr ACK from Slave 0x%x on %s",
				__func__, addr >> 1, dev->name);
			return ret;

		default:
			data->error_seen = 1;
			LOG_ERR("%s: %s wait_comp error %d for addr send",
				__func__, dev->name, ret);
			return ret;
		}
	}

	/* Send bytes */
	for (int i = 0U; i < msg.len; i++) {
		MCHP_I2C_SMB_DATA(ba) = msg.buf[i];
		ret = wait_completion(dev);

		switch (ret) {
		case 0:	/* Success */
			break;

		case -EIO:
			LOG_ERR("%s: No Data ACK from Slave 0x%x on %s",
				__func__, addr >> 1, dev->name);
			return ret;

		case -ETIMEDOUT:
			data->timeout_seen = 1;
			LOG_ERR("%s: Clk stretch Timeout - Slave 0x%x on %s",
				__func__, addr >> 1, dev->name);
			return ret;

		default:
			data->error_seen = 1;
			LOG_ERR("%s: %s wait_completion error %d for data send",
				__func__, dev->name, ret);
			return ret;
		}
	}

	/* Handle stop bit for last byte to write */
	if (msg.flags & I2C_MSG_STOP) {
		/* Send stop and ack bits */
		MCHP_I2C_SMB_CTRL_WO(ba) =
				MCHP_I2C_SMB_CTRL_PIN |
				MCHP_I2C_SMB_CTRL_ESO |
				MCHP_I2C_SMB_CTRL_STO |
				MCHP_I2C_SMB_CTRL_ACK;
		data->pending_stop = 0;
	} else {
		data->pending_stop = 1;
	}

	return 0;
}

static int i2c_xec_poll_read(const struct device *dev, struct i2c_msg msg,
			     uint16_t addr)
{
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data =
		(struct i2c_xec_data *const) (dev->data);
	uint32_t ba = config->base_addr;
	uint8_t byte, ctrl, i2c_timer = 0;
	int ret;

	if (data->timeout_seen == 1) {
		/* Wait to see if the slave has released the CLK */
		ret = wait_completion(dev);
		if (ret) {
			data->timeout_seen = 1;
			LOG_ERR("%s: %s wait_completion failure %d\n",
				__func__, dev->name, ret);
			return ret;
		}
		data->timeout_seen = 0;

		/* If we are here, it means the slave has finally released
		 * the CLK. The master needs to end that transaction
		 * gracefully by sending a STOP on the bus.
		 */
		LOG_DBG("%s: %s Force Stop", __func__, dev->name);
		MCHP_I2C_SMB_CTRL_WO(ba) =
					MCHP_I2C_SMB_CTRL_PIN |
					MCHP_I2C_SMB_CTRL_ESO |
					MCHP_I2C_SMB_CTRL_STO |
					MCHP_I2C_SMB_CTRL_ACK;
		k_busy_wait(BUS_IDLE_US_DFLT);
		return -EBUSY;
	}

	if (!(msg.flags & I2C_MSG_RESTART) || (data->error_seen == 1)) {
		/* Wait till clock and data lines are HIGH */
		while (check_lines_high(dev) == false) {
			if (i2c_timer >= WAIT_LINE_HIGH_COUNT) {
				LOG_DBG("%s: %s not high",
					__func__, dev->name);
				data->error_seen = 1;
				return -EBUSY;
			}
			k_busy_wait(WAIT_LINE_HIGH_USEC);
			i2c_timer++;
		}

		if (data->error_seen) {
			LOG_DBG("%s: Recovering %s previously in error",
				__func__, dev->name);
			data->error_seen = 0;
			recover_from_error(dev);
		}

		/* Wait until bus is free */
		ret = wait_bus_free(dev);
		if (ret) {
			data->error_seen = 1;
			LOG_DBG("%s: %s wait_bus_free failure %d",
				__func__, dev->name, ret);
			return ret;
		}
	}

	/* MCHP I2C spec recommends that for repeated start to write to control
	 * register before writing to data register
	 */
	MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_ESO |
		MCHP_I2C_SMB_CTRL_STA | MCHP_I2C_SMB_CTRL_ACK;

	/* Send slave address */
	MCHP_I2C_SMB_DATA(ba) = (addr | BIT(0));

	ret = wait_completion(dev);
	switch (ret) {
	case 0:	/* Success */
		break;

	case -EIO:
		data->error_seen = 1;
		LOG_WRN("%s: No Addr ACK from Slave 0x%x on %s",
			__func__, addr >> 1, dev->name);
		return ret;

	case -ETIMEDOUT:
		data->previously_in_read = 1;
		data->timeout_seen = 1;
		LOG_ERR("%s: Clk stretch Timeout - Slave 0x%x on %s",
			__func__, addr >> 1, dev->name);
		return ret;

	default:
		data->error_seen = 1;
		LOG_ERR("%s: %s wait_completion error %d for address send",
			__func__, dev->name, ret);
		return ret;
	}

	if (msg.len == 1) {
		/* Send NACK for last transaction */
		MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_ESO;
	}

	/* Read dummy byte */
	byte = MCHP_I2C_SMB_DATA(ba);

	for (int i = 0U; i < msg.len; i++) {
		ret = wait_completion(dev);
		switch (ret) {
		case 0:	/* Success */
			break;

		case -EIO:
			LOG_ERR("%s: No Data ACK from Slave 0x%x on %s",
				__func__, addr >> 1, dev->name);
			return ret;

		case -ETIMEDOUT:
			data->previously_in_read = 1;
			data->timeout_seen = 1;
			LOG_ERR("%s: Clk stretch Timeout - Slave 0x%x on %s",
				__func__, addr >> 1, dev->name);
			return ret;

		default:
			data->error_seen = 1;
			LOG_ERR("%s: %s wait_completion error %d for data send",
				__func__, dev->name, ret);
			return ret;
		}

		if (i == (msg.len - 1)) {
			if (msg.flags & I2C_MSG_STOP) {
				/* Send stop and ack bits */
				ctrl = (MCHP_I2C_SMB_CTRL_PIN |
					MCHP_I2C_SMB_CTRL_ESO |
					MCHP_I2C_SMB_CTRL_STO |
					MCHP_I2C_SMB_CTRL_ACK);
				MCHP_I2C_SMB_CTRL_WO(ba) = ctrl;
				data->pending_stop = 0;
			}
		} else if (i == (msg.len - 2)) {
			/* Send NACK for last transaction */
			MCHP_I2C_SMB_CTRL_WO(ba) = MCHP_I2C_SMB_CTRL_ESO;
		}
		msg.buf[i] = MCHP_I2C_SMB_DATA(ba);
	}

	return 0;
}

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

#ifdef CONFIG_I2C_TARGET
	struct i2c_xec_data *data = dev->data;

	if (data->slave_attached) {
		LOG_ERR("%s Device is registered as slave", dev->name);
		return -EBUSY;
	}
#endif

	addr <<= 1;
	for (int i = 0U; i < num_msgs; i++) {
		if ((msgs[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			ret = i2c_xec_poll_write(dev, msgs[i], addr);
			if (ret) {
				LOG_ERR("%s Write error: %d", dev->name, ret);
				return ret;
			}
		} else {
			ret = i2c_xec_poll_read(dev, msgs[i], addr);
			if (ret) {
				LOG_ERR("%s Read error: %d", dev->name, ret);
				return ret;
			}
		}
	}

	return 0;
}

static void i2c_xec_bus_isr(const struct device *dev)
{
#ifdef CONFIG_I2C_TARGET
	const struct i2c_xec_config *config =
		(const struct i2c_xec_config *const) (dev->config);
	struct i2c_xec_data *data = dev->data;
	const struct i2c_target_callbacks *slave_cb = data->slave_cfg->callbacks;
	uint32_t ba = config->base_addr;

	uint32_t status;
	uint8_t val;

	uint8_t dummy = 0U;

	if (!data->slave_attached) {
		return;
	}

	/* Get current status */
	status = MCHP_I2C_SMB_STS_RO(ba);

	/* Bus Error */
	if (status & MCHP_I2C_SMB_STS_BER) {
		if (slave_cb->stop) {
			slave_cb->stop(data->slave_cfg);
		}
		restart_slave(ba);
		goto clear_iag;
	}

	/* External stop */
	if (status & MCHP_I2C_SMB_STS_EXT_STOP) {
		if (slave_cb->stop) {
			slave_cb->stop(data->slave_cfg);
		}
		dummy = MCHP_I2C_SMB_DATA(ba);
		restart_slave(ba);
		goto clear_iag;
	}

	/* Address byte handling */
	if (status & MCHP_I2C_SMB_STS_AAS) {
		uint8_t slv_data = MCHP_I2C_SMB_DATA(ba);

		if (!(slv_data & BIT(I2C_READ_WRITE_POS))) {
			/* Slave receive  */
			data->slave_read = false;
			if (slave_cb->write_requested) {
				slave_cb->write_requested(data->slave_cfg);
			}
			goto clear_iag;
		} else {
			/* Slave transmit */
			data->slave_read = true;
			if (slave_cb->read_requested) {
				slave_cb->read_requested(data->slave_cfg, &val);
			}
			MCHP_I2C_SMB_DATA(ba) = val;
			goto clear_iag;
		}
	}

	/* Slave transmit */
	if (data->slave_read) {
		/* Master has Nacked, then just write a dummy byte */
		if (MCHP_I2C_SMB_STS_RO(ba) & MCHP_I2C_SMB_STS_LRB_AD0) {
			MCHP_I2C_SMB_DATA(ba) = dummy;
		} else {
			if (slave_cb->read_processed) {
				slave_cb->read_processed(data->slave_cfg, &val);
			}
			MCHP_I2C_SMB_DATA(ba) = val;
		}
	} else {
		val = MCHP_I2C_SMB_DATA(ba);
		/* TODO NACK Master */
		if (slave_cb->write_received) {
			slave_cb->write_received(data->slave_cfg, val);
		}
	}

clear_iag:
	MCHP_GIRQ_SRC(config->girq_id) = BIT(config->girq_bit);
#endif
}

#ifdef CONFIG_I2C_TARGET
static int i2c_xec_slave_register(const struct device *dev,
				  struct i2c_target_config *config)
{
	const struct i2c_xec_config *cfg = dev->config;
	struct i2c_xec_data *data = dev->data;
	uint32_t ba = cfg->base_addr;
	int ret;
	int counter = 0;

	if (!config) {
		return -EINVAL;
	}

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

	/* Wait for any outstanding transactions to complete so that
	 * the bus is free
	 */
	while (!(MCHP_I2C_SMB_STS_RO(ba) & MCHP_I2C_SMB_STS_NBB)) {
		ret = xec_spin_yield(&counter);

		if (ret < 0) {
			return ret;
		}
	}

	data->slave_cfg = config;

	/* Set own address */
	MCHP_I2C_SMB_OWN_ADDR(ba) = data->slave_cfg->address;
	restart_slave(ba);

	data->slave_attached = true;

	/* Clear before enabling girq bit */
	MCHP_GIRQ_SRC(cfg->girq_id) = BIT(cfg->girq_bit);
	MCHP_GIRQ_ENSET(cfg->girq_id) = BIT(cfg->girq_bit);

	return 0;
}

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

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

	data->slave_attached = false;

	MCHP_GIRQ_ENCLR(cfg->girq_id) = BIT(cfg->girq_bit);

	return 0;
}
#endif

static const struct i2c_driver_api i2c_xec_driver_api = {
	.configure = i2c_xec_configure,
	.transfer = i2c_xec_transfer,
#ifdef CONFIG_I2C_TARGET
	.slave_register = i2c_xec_slave_register,
	.slave_unregister = i2c_xec_slave_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->pending_stop = 0;
	data->slave_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;
	}

	if (!device_is_ready(cfg->sda_gpio.port)) {
		LOG_ERR("%s GPIO device is not ready for SDA GPIO", dev->name);
		return -ENODEV;
	}

	if (!device_is_ready(cfg->scl_gpio.port)) {
		LOG_ERR("%s GPIO device is not ready for SCL GPIO", dev->name);
		return -ENODEV;
	}

	/* Default configuration */
	ret = i2c_xec_configure(dev,
				I2C_MODE_CONTROLLER |
				I2C_SPEED_SET(I2C_SPEED_STANDARD));
	if (ret) {
		LOG_ERR("%s configure failed %d", dev->name, ret);
		return ret;
	}

#ifdef CONFIG_I2C_TARGET
	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_id = DT_INST_PROP(n, girq),			\
		.girq_bit = DT_INST_PROP(n, girq_bit),			\
		.sda_gpio = GPIO_DT_SPEC_INST_GET(n, sda_gpios),	\
		.scl_gpio = GPIO_DT_SPEC_INST_GET(n, scl_gpios),	\
		.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)
