/* SPDX-License-Identifier: Apache-2.0 */
/*
 * Copyright © 2023 Calian Ltd.  All rights reserved.
 *
 * Driver for the Xilinx AXI IIC Bus Interface.
 * This is an FPGA logic core as described by Xilinx document PG090.
 */

#include <errno.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/util.h>
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>

LOG_MODULE_REGISTER(i2c_xilinx_axi, CONFIG_I2C_LOG_LEVEL);

#include "i2c-priv.h"
#include "i2c_xilinx_axi.h"

struct i2c_xilinx_axi_config {
	mem_addr_t base;
	void (*irq_config_func)(const struct device *dev);
	/* Whether device has working dynamic read (broken prior to core rev. 2.1) */
	bool dyn_read_working;
};

struct i2c_xilinx_axi_data {
	struct k_event irq_event;
	/* Serializes between ISR and other calls */
	struct k_spinlock lock;
	/* Provides exclusion against multiple concurrent requests */
	struct k_mutex mutex;

#if defined(CONFIG_I2C_TARGET)
	struct i2c_target_config *target_cfg;
	bool target_reading;
	bool target_read_aborted;
	bool target_writing;
#endif
};

#if defined(CONFIG_I2C_TARGET)

#define I2C_XILINX_AXI_TARGET_INTERRUPTS                                                           \
	(ISR_ADDR_TARGET | ISR_NOT_ADDR_TARGET | ISR_RX_FIFO_FULL | ISR_TX_FIFO_EMPTY |            \
	 ISR_TX_ERR_TARGET_COMP)

static int i2c_xilinx_axi_target_register(const struct device *dev, struct i2c_target_config *cfg)
{
	const struct i2c_xilinx_axi_config *config = dev->config;
	struct i2c_xilinx_axi_data *data = dev->data;
	k_spinlock_key_t key;
	uint32_t int_enable;
	uint32_t int_status;
	int ret;

	if (cfg->flags & I2C_TARGET_FLAGS_ADDR_10_BITS) {
		/* Optionally supported in core, but not implemented in driver yet */
		return -EOPNOTSUPP;
	}

	k_mutex_lock(&data->mutex, K_FOREVER);
	key = k_spin_lock(&data->lock);

	if (data->target_cfg) {
		ret = -EBUSY;
		goto out_unlock;
	}

	data->target_cfg = cfg;

	int_status = sys_read32(config->base + REG_ISR);
	if (int_status & I2C_XILINX_AXI_TARGET_INTERRUPTS) {
		sys_write32(int_status & I2C_XILINX_AXI_TARGET_INTERRUPTS, config->base + REG_ISR);
	}

	sys_write32(CR_EN, config->base + REG_CR);
	int_enable = sys_read32(config->base + REG_IER);
	int_enable |= ISR_ADDR_TARGET;
	sys_write32(int_enable, config->base + REG_IER);

	sys_write32(cfg->address << 1, config->base + REG_ADR);
	sys_write32(0, config->base + REG_RX_FIFO_PIRQ);

	ret = 0;

out_unlock:
	k_spin_unlock(&data->lock, key);
	LOG_DBG("Target register ret=%d", ret);
	k_mutex_unlock(&data->mutex);
	return ret;
}

static int i2c_xilinx_axi_target_unregister(const struct device *dev, struct i2c_target_config *cfg)
{
	const struct i2c_xilinx_axi_config *config = dev->config;
	struct i2c_xilinx_axi_data *data = dev->data;
	k_spinlock_key_t key;
	uint32_t int_enable;
	int ret;

	k_mutex_lock(&data->mutex, K_FOREVER);
	key = k_spin_lock(&data->lock);

	if (!data->target_cfg) {
		ret = -EINVAL;
		goto out_unlock;
	}

	if (data->target_reading || data->target_writing) {
		ret = -EBUSY;
		goto out_unlock;
	}

	data->target_cfg = NULL;
	sys_write32(0, config->base + REG_ADR);

	sys_write32(CR_EN, config->base + REG_CR);
	int_enable = sys_read32(config->base + REG_IER);
	int_enable &= ~I2C_XILINX_AXI_TARGET_INTERRUPTS;
	sys_write32(int_enable, config->base + REG_IER);

	ret = 0;

out_unlock:
	k_spin_unlock(&data->lock, key);
	LOG_DBG("Target unregister ret=%d", ret);
	k_mutex_unlock(&data->mutex);
	return ret;
}

static void i2c_xilinx_axi_target_isr(const struct i2c_xilinx_axi_config *config,
				      struct i2c_xilinx_axi_data *data, uint32_t int_status,
				      uint32_t *ints_to_clear, uint32_t *int_enable)
{
	if (int_status & ISR_ADDR_TARGET) {
		LOG_DBG("Addressed as target");
		*int_enable &= ~ISR_ADDR_TARGET;
		*int_enable |= ISR_NOT_ADDR_TARGET;
		*ints_to_clear |= ISR_NOT_ADDR_TARGET;

		if (sys_read32(config->base + REG_SR) & SR_SRW) {
			uint8_t read_byte;

			data->target_reading = true;
			*ints_to_clear |= ISR_TX_FIFO_EMPTY | ISR_TX_ERR_TARGET_COMP;
			*int_enable |= ISR_TX_FIFO_EMPTY | ISR_TX_ERR_TARGET_COMP;
			if ((*data->target_cfg->callbacks->read_requested)(data->target_cfg,
									   &read_byte)) {
				LOG_DBG("target read_requested rejected");
				data->target_read_aborted = true;
				read_byte = 0xFF;
			}
			sys_write32(read_byte, config->base + REG_TX_FIFO);
		} else {
			data->target_writing = true;
			*int_enable |= ISR_RX_FIFO_FULL;
			if ((*data->target_cfg->callbacks->write_requested)(data->target_cfg)) {
				uint32_t cr = sys_read32(config->base + REG_CR);

				LOG_DBG("target write_requested rejected");
				cr |= CR_TXAK;
				sys_write32(cr, config->base + REG_CR);
			}
		}
	} else if (int_status & ISR_NOT_ADDR_TARGET) {
		LOG_DBG("Not addressed as target");
		(*data->target_cfg->callbacks->stop)(data->target_cfg);
		data->target_reading = false;
		data->target_read_aborted = false;
		data->target_writing = false;

		sys_write32(CR_EN, config->base + REG_CR);
		*int_enable &= ~I2C_XILINX_AXI_TARGET_INTERRUPTS;
		*int_enable |= ISR_ADDR_TARGET;
		*ints_to_clear |= ISR_ADDR_TARGET;
	} else if (int_status & ISR_RX_FIFO_FULL) {
		const uint8_t written_byte =
			sys_read32(config->base + REG_RX_FIFO) & RX_FIFO_DATA_MASK;

		if ((*data->target_cfg->callbacks->write_received)(data->target_cfg,
								   written_byte)) {
			uint32_t cr = sys_read32(config->base + REG_CR);

			LOG_DBG("target write_received rejected");
			cr |= CR_TXAK;
			sys_write32(cr, config->base + REG_CR);
		}
	} else if (int_status & ISR_TX_ERR_TARGET_COMP) {
		if (data->target_reading) {
			/* Controller has NAKed the last byte read, so no more to send.
			 * Ignore TX FIFO empty so we don't write an extra byte.
			 */
			LOG_DBG("target read completed");
			*int_enable &= ~ISR_TX_FIFO_EMPTY;
			*ints_to_clear |= ISR_TX_FIFO_EMPTY;
		} else {
			LOG_WRN("Unexpected TX complete");
		}
	} else if (int_status & ISR_TX_FIFO_EMPTY) {
		if (data->target_reading) {
			uint8_t read_byte = 0xFF;

			if (!data->target_read_aborted &&
			    (*data->target_cfg->callbacks->read_processed)(data->target_cfg,
									   &read_byte)) {
				LOG_DBG("target read_processed rejected");
				data->target_read_aborted = true;
			}
			sys_write32(read_byte, config->base + REG_TX_FIFO);
		} else {
			LOG_WRN("Unexpected TX empty");
		}
	}
}
#endif

static void i2c_xilinx_axi_isr(const struct device *dev)
{
	const struct i2c_xilinx_axi_config *config = dev->config;
	struct i2c_xilinx_axi_data *data = dev->data;
	const k_spinlock_key_t key = k_spin_lock(&data->lock);
	uint32_t int_enable = sys_read32(config->base + REG_IER);
	const uint32_t int_status = sys_read32(config->base + REG_ISR) & int_enable;
	uint32_t ints_to_clear = int_status;
	uint32_t ints_to_mask = int_status;

	LOG_DBG("ISR called for 0x%08" PRIxPTR ", status 0x%02x", config->base, int_status);

	if (int_status & ISR_ARB_LOST) {
		/* Must clear MSMS before clearing interrupt */
		uint32_t cr = sys_read32(config->base + REG_CR);

		cr &= ~CR_MSMS;
		sys_write32(cr, config->base + REG_CR);
	}

#if defined(CONFIG_I2C_TARGET)
	if (data->target_cfg && (int_status & I2C_XILINX_AXI_TARGET_INTERRUPTS)) {
		ints_to_mask &= ~(int_status & I2C_XILINX_AXI_TARGET_INTERRUPTS);
		i2c_xilinx_axi_target_isr(config, data, int_status, &ints_to_clear, &int_enable);
	}
#endif

	sys_write32(int_enable & ~ints_to_mask, config->base + REG_IER);
	/* Be careful, writing 1 to a bit that is not currently set in ISR will SET it! */
	sys_write32(ints_to_clear & sys_read32(config->base + REG_ISR), config->base + REG_ISR);

	k_spin_unlock(&data->lock, key);
	k_event_post(&data->irq_event, int_status);
}

static void i2c_xilinx_axi_reinit(const struct i2c_xilinx_axi_config *config)
{
	LOG_DBG("Controller reinit");
	sys_write32(SOFTR_KEY, config->base + REG_SOFTR);
	sys_write32(CR_TX_FIFO_RST, config->base + REG_CR);
	sys_write32(CR_EN, config->base + REG_CR);
	sys_write32(GIE_ENABLE, config->base + REG_GIE);
}

static int i2c_xilinx_axi_configure(const struct device *dev, uint32_t dev_config)
{
	const struct i2c_xilinx_axi_config *config = dev->config;

	LOG_INF("Configuring %s at 0x%08" PRIxPTR, dev->name, config->base);
	i2c_xilinx_axi_reinit(config);
	return 0;
}

static uint32_t i2c_xilinx_axi_wait_interrupt(const struct i2c_xilinx_axi_config *config,
					      struct i2c_xilinx_axi_data *data, uint32_t int_mask)
{
	const k_spinlock_key_t key = k_spin_lock(&data->lock);
	const uint32_t int_enable = sys_read32(config->base + REG_IER) | int_mask;
	uint32_t events;

	LOG_DBG("Set IER to 0x%02x", int_enable);
	sys_write32(int_enable, config->base + REG_IER);
	k_event_clear(&data->irq_event, int_mask);
	k_spin_unlock(&data->lock, key);

	events = k_event_wait(&data->irq_event, int_mask, false, K_MSEC(100));

	LOG_DBG("Got ISR events 0x%02x", events);
	if (!events) {
		LOG_ERR("Timeout waiting for ISR events 0x%02x, SR 0x%02x, ISR 0x%02x", int_mask,
			sys_read32(config->base + REG_SR), sys_read32(config->base + REG_ISR));
	}
	return events;
}

static void i2c_xilinx_axi_clear_interrupt(const struct i2c_xilinx_axi_config *config,
					   struct i2c_xilinx_axi_data *data, uint32_t int_mask)
{
	const k_spinlock_key_t key = k_spin_lock(&data->lock);
	const uint32_t int_status = sys_read32(config->base + REG_ISR);

	if (int_status & int_mask) {
		sys_write32(int_status & int_mask, config->base + REG_ISR);
	}
	k_spin_unlock(&data->lock, key);
}

static int i2c_xilinx_axi_wait_rx_full(const struct i2c_xilinx_axi_config *config,
				       struct i2c_xilinx_axi_data *data, uint32_t read_bytes)
{
	uint32_t events;

	i2c_xilinx_axi_clear_interrupt(config, data, ISR_RX_FIFO_FULL);
	if (!(sys_read32(config->base + REG_SR) & SR_RX_FIFO_EMPTY) &&
	    (sys_read32(config->base + REG_RX_FIFO_OCY) & RX_FIFO_OCY_MASK) + 1 >= read_bytes) {
		LOG_DBG("RX already full on checking, SR 0x%02x RXOCY 0x%02x",
			sys_read32(config->base + REG_SR),
			sys_read32(config->base + REG_RX_FIFO_OCY));
		return 0;
	}
	events = i2c_xilinx_axi_wait_interrupt(config, data, ISR_RX_FIFO_FULL | ISR_ARB_LOST);
	if (!events) {
		return -ETIMEDOUT;
	}
	if (events & ISR_ARB_LOST) {
		LOG_ERR("Arbitration lost on RX");
		return -ENXIO;
	}
	return 0;
}

static int i2c_xilinx_axi_read_nondyn(const struct i2c_xilinx_axi_config *config,
				      struct i2c_xilinx_axi_data *data, struct i2c_msg *msg,
				      uint16_t addr)
{
	uint8_t *read_ptr = msg->buf;
	uint32_t bytes_left = msg->len;
	uint32_t cr = CR_EN | CR_MSMS;

	if (!bytes_left) {
		return -EINVAL;
	}
	if (bytes_left == 1) {
		/* Set TXAK bit now, to NAK after the first byte is received */
		cr |= CR_TXAK;
	}

	/**
	 * The Xilinx core's RX FIFO full logic seems rather broken in that the interrupt
	 * is triggered, and the I2C receive is throttled, only when the FIFO occupancy
	 * equals the PIRQ threshold, not when greater or equal. In the non-dynamic mode
	 * of operation, we need to stop the read prior to the last bytes being received
	 * from the target in order to set the TXAK bit and clear MSMS to terminate the
	 * receive properly.
	 * However, if we previously allowed multiple bytes into the RX FIFO, this requires
	 * reducing the PIRQ threshold to 0 (single byte) during the receive operation. This
	 * can cause the receive to unthrottle (since FIFO occupancy now exceeds PIRQ
	 * threshold) and depending on timing between the driver code and the core,
	 * this can cause the core to try to receive more data into the FIFO than desired
	 * and cause various unexpected results.
	 *
	 * To avoid this, we only receive one byte at a time in the non-dynamic mode.
	 * Dynamic mode doesn't have this issue as it provides the RX byte count to the
	 * controller specifically and the TXAK and MSMS bits are handled automatically.
	 */
	sys_write32(0, config->base + REG_RX_FIFO_PIRQ);

	if (msg->flags & I2C_MSG_RESTART) {
		cr |= CR_RSTA;

		sys_write32(cr, config->base + REG_CR);
		sys_write32((addr << 1) | I2C_MSG_READ, config->base + REG_TX_FIFO);
	} else {
		sys_write32((addr << 1) | I2C_MSG_READ, config->base + REG_TX_FIFO);
		sys_write32(cr, config->base + REG_CR);
	}

	while (bytes_left) {
		int ret = i2c_xilinx_axi_wait_rx_full(config, data, 1);

		if (ret) {
			return ret;
		}

		if (bytes_left == 2) {
			/* Set TXAK so the last byte is NAKed */
			cr |= CR_TXAK;
		} else if (bytes_left == 1 && (msg->flags & I2C_MSG_STOP)) {
			/* Before reading the last byte, clear MSMS to issue a stop if required */
			cr &= ~CR_MSMS;
		}
		cr &= ~CR_RSTA;
		sys_write32(cr, config->base + REG_CR);

		*read_ptr++ = sys_read32(config->base + REG_RX_FIFO) & RX_FIFO_DATA_MASK;
		bytes_left--;
	}
	return 0;
}

static int i2c_xilinx_axi_read_dyn(const struct i2c_xilinx_axi_config *config,
				   struct i2c_xilinx_axi_data *data, struct i2c_msg *msg,
				   uint16_t addr)
{
	uint8_t *read_ptr = msg->buf;
	uint32_t bytes_left = msg->len;
	uint32_t bytes_to_read = bytes_left;
	uint32_t cr = CR_EN;
	uint32_t len_word = bytes_left;

	if (!bytes_left || bytes_left > MAX_DYNAMIC_READ_LEN) {
		return -EINVAL;
	}
	if (msg->flags & I2C_MSG_RESTART) {
		cr |= CR_MSMS | CR_RSTA;
	}
	sys_write32(cr, config->base + REG_CR);

	if (bytes_to_read > FIFO_SIZE) {
		bytes_to_read = FIFO_SIZE;
	}
	sys_write32(bytes_to_read - 1, config->base + REG_RX_FIFO_PIRQ);
	sys_write32((addr << 1) | I2C_MSG_READ | TX_FIFO_START, config->base + REG_TX_FIFO);

	if (msg->flags & I2C_MSG_STOP) {
		len_word |= TX_FIFO_STOP;
	}
	sys_write32(len_word, config->base + REG_TX_FIFO);

	while (bytes_left) {
		int ret;

		bytes_to_read = bytes_left;
		if (bytes_to_read > FIFO_SIZE) {
			bytes_to_read = FIFO_SIZE;
		}

		sys_write32(bytes_to_read - 1, config->base + REG_RX_FIFO_PIRQ);
		ret = i2c_xilinx_axi_wait_rx_full(config, data, bytes_to_read);
		if (ret) {
			return ret;
		}

		while (bytes_to_read) {
			*read_ptr++ = sys_read32(config->base + REG_RX_FIFO) & RX_FIFO_DATA_MASK;
			bytes_to_read--;
			bytes_left--;
		}
	}
	return 0;
}

static int i2c_xilinx_axi_wait_tx_done(const struct i2c_xilinx_axi_config *config,
				       struct i2c_xilinx_axi_data *data)
{
	const uint32_t finish_bits = ISR_BUS_NOT_BUSY | ISR_TX_FIFO_EMPTY;

	uint32_t events = i2c_xilinx_axi_wait_interrupt(
		config, data, finish_bits | ISR_TX_ERR_TARGET_COMP | ISR_ARB_LOST);
	if (!(events & finish_bits) || (events & ~finish_bits)) {
		if (!events) {
			return -ETIMEDOUT;
		}
		if (events & ISR_ARB_LOST) {
			LOG_ERR("Arbitration lost on TX");
			return -EAGAIN;
		}
		LOG_ERR("TX received NAK");
		return -ENXIO;
	}
	return 0;
}

static int i2c_xilinx_axi_wait_not_busy(const struct i2c_xilinx_axi_config *config,
					struct i2c_xilinx_axi_data *data)
{
	if (sys_read32(config->base + REG_SR) & SR_BB) {
		uint32_t events = i2c_xilinx_axi_wait_interrupt(config, data, ISR_BUS_NOT_BUSY);

		if (events != ISR_BUS_NOT_BUSY) {
			LOG_ERR("Bus stuck busy");
			i2c_xilinx_axi_reinit(config);
			return -EBUSY;
		}
	}
	return 0;
}

static int i2c_xilinx_axi_write(const struct i2c_xilinx_axi_config *config,
				struct i2c_xilinx_axi_data *data, const struct i2c_msg *msg,
				uint16_t addr)
{
	const uint8_t *write_ptr = msg->buf;
	uint32_t bytes_left = msg->len;
	uint32_t cr = CR_EN | CR_TX;
	uint32_t fifo_space = FIFO_SIZE - 1; /* account for address being written */

	if (msg->flags & I2C_MSG_RESTART) {
		cr |= CR_MSMS | CR_RSTA;
	}

	i2c_xilinx_axi_clear_interrupt(config, data, ISR_TX_ERR_TARGET_COMP | ISR_ARB_LOST);

	sys_write32(cr, config->base + REG_CR);
	sys_write32((addr << 1) | TX_FIFO_START, config->base + REG_TX_FIFO);

	/* TX FIFO empty detection is somewhat fragile because the status register
	 * TX_FIFO_EMPTY bit can be set prior to the transaction actually being
	 * complete, so we have to rely on the TX empty interrupt.
	 * However, delays in writing data to the TX FIFO could cause it
	 * to run empty in the middle of the process, causing us to get a spurious
	 * completion detection from the interrupt. Therefore we disable interrupts
	 * while the TX FIFO is being filled up to try to avoid this.
	 */

	while (bytes_left) {
		uint32_t bytes_to_send = bytes_left;
		const k_spinlock_key_t key = k_spin_lock(&data->lock);
		int ret;

		if (bytes_to_send > fifo_space) {
			bytes_to_send = fifo_space;
		}
		while (bytes_to_send) {
			uint32_t write_word = *write_ptr++;

			if (bytes_left == 1 && (msg->flags & I2C_MSG_STOP)) {
				write_word |= TX_FIFO_STOP;
			}
			sys_write32(write_word, config->base + REG_TX_FIFO);
			bytes_to_send--;
			bytes_left--;
		}
		i2c_xilinx_axi_clear_interrupt(config, data, ISR_TX_FIFO_EMPTY | ISR_BUS_NOT_BUSY);
		k_spin_unlock(&data->lock, key);

		ret = i2c_xilinx_axi_wait_tx_done(config, data);
		if (ret) {
			return ret;
		}
		fifo_space = FIFO_SIZE;
	}
	return 0;
}

static int i2c_xilinx_axi_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs,
				   uint16_t addr)
{
	const struct i2c_xilinx_axi_config *config = dev->config;
	struct i2c_xilinx_axi_data *data = dev->data;
	int ret;

	k_mutex_lock(&data->mutex, K_FOREVER);

	/**
	 * Reinitializing before each transfer shouldn't technically be needed, but
	 * seems to improve general reliability. The Linux driver also does this.
	 */
	i2c_xilinx_axi_reinit(config);

	ret = i2c_xilinx_axi_wait_not_busy(config, data);
	if (ret) {
		goto out_unlock;
	}

	if (!num_msgs) {
		goto out_unlock;
	}

	do {
		if (msgs->flags & I2C_MSG_ADDR_10_BITS) {
			/* Optionally supported in core, but not implemented in driver yet */
			ret = -EOPNOTSUPP;
			goto out_unlock;
		}
		if (msgs->flags & I2C_MSG_READ) {
			if (config->dyn_read_working && msgs->len <= MAX_DYNAMIC_READ_LEN) {
				ret = i2c_xilinx_axi_read_dyn(config, data, msgs, addr);
			} else {
				ret = i2c_xilinx_axi_read_nondyn(config, data, msgs, addr);
			}
		} else {
			ret = i2c_xilinx_axi_write(config, data, msgs, addr);
		}
		if (!ret && (msgs->flags & I2C_MSG_STOP)) {
			ret = i2c_xilinx_axi_wait_not_busy(config, data);
		}
		if (ret) {
			goto out_unlock;
		}
		msgs++;
		num_msgs--;
	} while (num_msgs);

out_unlock:
	k_mutex_unlock(&data->mutex);
	return ret;
}

static int i2c_xilinx_axi_init(const struct device *dev)
{
	const struct i2c_xilinx_axi_config *config = dev->config;
	struct i2c_xilinx_axi_data *data = dev->data;
	int error;

	k_event_init(&data->irq_event);
	k_mutex_init(&data->mutex);

	error = i2c_xilinx_axi_configure(dev, I2C_MODE_CONTROLLER);
	if (error) {
		return error;
	}

	config->irq_config_func(dev);

	LOG_INF("initialized");
	return 0;
}

static const struct i2c_driver_api i2c_xilinx_axi_driver_api = {
	.configure = i2c_xilinx_axi_configure,
	.transfer = i2c_xilinx_axi_transfer,
#if defined(CONFIG_I2C_TARGET)
	.target_register = i2c_xilinx_axi_target_register,
	.target_unregister = i2c_xilinx_axi_target_unregister,
#endif
};

#define I2C_XILINX_AXI_INIT(n, compat)                                                             \
	static void i2c_xilinx_axi_config_func_##compat##_##n(const struct device *dev);           \
                                                                                                   \
	static const struct i2c_xilinx_axi_config i2c_xilinx_axi_config_##compat##_##n = {         \
		.base = DT_INST_REG_ADDR(n),                                                       \
		.irq_config_func = i2c_xilinx_axi_config_func_##compat##_##n,                      \
		.dyn_read_working = DT_NODE_HAS_COMPAT(DT_DRV_INST(n), xlnx_xps_iic_2_1)};         \
                                                                                                   \
	static struct i2c_xilinx_axi_data i2c_xilinx_axi_data_##compat##_##n;                      \
                                                                                                   \
	I2C_DEVICE_DT_INST_DEFINE(n, i2c_xilinx_axi_init, NULL,                                    \
				  &i2c_xilinx_axi_data_##compat##_##n,                             \
				  &i2c_xilinx_axi_config_##compat##_##n, POST_KERNEL,              \
				  CONFIG_I2C_INIT_PRIORITY, &i2c_xilinx_axi_driver_api);           \
                                                                                                   \
	static void i2c_xilinx_axi_config_func_##compat##_##n(const struct device *dev)            \
	{                                                                                          \
		ARG_UNUSED(dev);                                                                   \
                                                                                                   \
		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), i2c_xilinx_axi_isr,         \
			    DEVICE_DT_INST_GET(n), 0);                                             \
                                                                                                   \
		irq_enable(DT_INST_IRQN(n));                                                       \
	}

#define DT_DRV_COMPAT xlnx_xps_iic_2_1
DT_INST_FOREACH_STATUS_OKAY_VARGS(I2C_XILINX_AXI_INIT, DT_DRV_COMPAT)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT xlnx_xps_iic_2_00_a
DT_INST_FOREACH_STATUS_OKAY_VARGS(I2C_XILINX_AXI_INIT, DT_DRV_COMPAT)
