/*
 * Copyright (c) 2019 Derek Hageman <hageman@inthat.cloud>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT atmel_sam0_i2c

#include <errno.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#include <drivers/i2c.h>
#include <drivers/dma.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(i2c_sam0, CONFIG_I2C_LOG_LEVEL);

#include "i2c-priv.h"

#ifndef SERCOM_I2CM_CTRLA_MODE_I2C_MASTER
#define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER SERCOM_I2CM_CTRLA_MODE(5)
#endif

struct i2c_sam0_dev_config {
	SercomI2cm *regs;
	uint32_t bitrate;
#ifdef MCLK
	volatile uint32_t *mclk;
	uint32_t mclk_mask;
	uint16_t gclk_core_id;
#else
	uint32_t pm_apbcmask;
	uint16_t gclk_clkctrl_id;
#endif
	void (*irq_config_func)(const struct device *dev);

#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
	const struct device *dma_dev;
	uint8_t write_dma_request;
	uint8_t read_dma_request;
	uint8_t dma_channel;
#endif
};

struct i2c_sam0_msg {
	uint8_t *buffer;
	uint32_t size;
	uint32_t status;
};

struct i2c_sam0_dev_data {
	struct k_sem sem;
	struct i2c_sam0_msg msg;
	struct i2c_msg *msgs;
	uint8_t num_msgs;
};

#define DEV_NAME(dev) ((dev)->name)

static void wait_synchronization(SercomI2cm *regs)
{
#if defined(SERCOM_I2CM_SYNCBUSY_MASK)
	/* SYNCBUSY is a register */
	while ((regs->SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK) != 0) {
	}
#elif defined(SERCOM_I2CM_STATUS_SYNCBUSY)
	/* SYNCBUSY is a bit */
	while ((regs->STATUS.reg & SERCOM_I2CM_STATUS_SYNCBUSY) != 0) {
	}
#else
#error Unsupported device
#endif
}

static bool i2c_sam0_terminate_on_error(const struct device *dev)
{
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;

	if (!(i2c->STATUS.reg & (SERCOM_I2CM_STATUS_ARBLOST |
				 SERCOM_I2CM_STATUS_RXNACK |
#ifdef SERCOM_I2CM_STATUS_LENERR
				 SERCOM_I2CM_STATUS_LENERR |
#endif
#ifdef SERCOM_I2CM_STATUS_SEXTTOUT
				 SERCOM_I2CM_STATUS_SEXTTOUT |
#endif
#ifdef SERCOM_I2CM_STATUS_MEXTTOUT
				 SERCOM_I2CM_STATUS_MEXTTOUT |
#endif
				 SERCOM_I2CM_STATUS_LOWTOUT |
				 SERCOM_I2CM_STATUS_BUSERR))) {
		return false;
	}

#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
	if (cfg->dma_channel != 0xFF) {
		dma_stop(cfg->dma_dev, cfg->dma_channel);
	}
#endif

	data->msg.status = i2c->STATUS.reg;

	/*
	 * Clear all the flags that require an explicit clear
	 * (as opposed to being cleared by ADDR writes, etc)
	 */
	i2c->STATUS.reg = SERCOM_I2CM_STATUS_ARBLOST |
#ifdef SERCOM_I2CM_STATUS_LENERR
			  SERCOM_I2CM_STATUS_LENERR |
#endif
			  SERCOM_I2CM_STATUS_LOWTOUT |
			  SERCOM_I2CM_STATUS_BUSERR;
	wait_synchronization(i2c);

	i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
	k_sem_give(&data->sem);
	return true;
}

static void i2c_sam0_isr(const struct device *dev)
{
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;

	/* Get present interrupts and clear them */
	uint32_t status = i2c->INTFLAG.reg;

	i2c->INTFLAG.reg = status;

	if (i2c_sam0_terminate_on_error(dev)) {
		return;
	}

	/*
	 * Directly send/receive next message if it is in the same direction and
	 * the current message has no stop flag and the next message has no
	 * restart flag.
	 */
	const bool continue_next = (data->msg.size == 1) && (data->num_msgs > 1) &&
				   ((data->msgs[0].flags & I2C_MSG_RW_MASK) ==
				    (data->msgs[1].flags & I2C_MSG_RW_MASK)) &&
				   !(data->msgs[0].flags & I2C_MSG_STOP) &&
				   !(data->msgs[1].flags & I2C_MSG_RESTART) &&
				   ((status & (SERCOM_I2CM_INTFLAG_MB | SERCOM_I2CM_INTFLAG_SB)));

	if (status & SERCOM_I2CM_INTFLAG_MB) {
		if (!data->msg.size) {
			i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
			k_sem_give(&data->sem);
			return;
		}

		i2c->DATA.reg = *data->msg.buffer;
		data->msg.buffer++;
		data->msg.size--;
	} else if (status & SERCOM_I2CM_INTFLAG_SB) {
		if (!continue_next && (data->msg.size == 1)) {
			/*
			 * If this is the last byte, then prepare for an auto
			 * NACK before doing the actual read.  This does not
			 * require write synchronization.
			 */
			i2c->CTRLB.bit.ACKACT = 1;
		}

		*data->msg.buffer = i2c->DATA.reg;
		data->msg.buffer++;
		data->msg.size--;

		if (!continue_next && !data->msg.size) {
			i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
			k_sem_give(&data->sem);
			return;
		}
	}

	if (continue_next) {
		data->msgs++;
		data->num_msgs--;

		data->msg.buffer = data->msgs->buf;
		data->msg.size = data->msgs->len;
		data->msg.status = 0;
	}
}

#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN

static void i2c_sam0_dma_write_done(const struct device *dma_dev, void *arg,
				    uint32_t id, int error_code)
{
	const struct device *dev = arg;
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;

	ARG_UNUSED(dma_dev);
	ARG_UNUSED(id);

	int key = irq_lock();

	if (i2c_sam0_terminate_on_error(dev)) {
		irq_unlock(key);
		return;
	}

	if (error_code < 0) {
		LOG_ERR("DMA write error on %s: %d", DEV_NAME(dev), error_code);
		i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
		irq_unlock(key);

		data->msg.status = error_code;

		k_sem_give(&data->sem);
		return;
	}

	irq_unlock(key);

	/*
	 * DMA has written the whole message now, so just wait for the
	 * final I2C IRQ to indicate that it's finished transmitting.
	 */
	data->msg.size = 0;
	i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_MB;
}

static bool i2c_sam0_dma_write_start(const struct device *dev)
{
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;
	int retval;

	if (cfg->dma_channel == 0xFF) {
		return false;
	}

	if (data->msg.size <= 1) {
		/*
		 * Catch empty writes and skip DMA on single byte transfers.
		 */
		return false;
	}

	struct dma_config dma_cfg = { 0 };
	struct dma_block_config dma_blk = { 0 };

	dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL;
	dma_cfg.source_data_size = 1;
	dma_cfg.dest_data_size = 1;
	dma_cfg.user_data = (void *)dev;
	dma_cfg.dma_callback = i2c_sam0_dma_write_done;
	dma_cfg.block_count = 1;
	dma_cfg.head_block = &dma_blk;
	dma_cfg.dma_slot = cfg->write_dma_request;

	dma_blk.block_size = data->msg.size;
	dma_blk.source_address = (uint32_t)data->msg.buffer;
	dma_blk.dest_address = (uint32_t)(&(i2c->DATA.reg));
	dma_blk.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;

	retval = dma_config(cfg->dma_dev, cfg->dma_channel, &dma_cfg);
	if (retval != 0) {
		LOG_ERR("Write DMA configure on %s failed: %d",
			DEV_NAME(dev), retval);
		return false;
	}

	retval = dma_start(cfg->dma_dev, cfg->dma_channel);
	if (retval != 0) {
		LOG_ERR("Write DMA start on %s failed: %d",
			DEV_NAME(dev), retval);
		return false;
	}

	return true;
}

static void i2c_sam0_dma_read_done(const struct device *dma_dev, void *arg,
				   uint32_t id, int error_code)
{
	const struct device *dev = arg;
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;

	ARG_UNUSED(dma_dev);
	ARG_UNUSED(id);

	int key = irq_lock();

	if (i2c_sam0_terminate_on_error(dev)) {
		irq_unlock(key);
		return;
	}

	if (error_code < 0) {
		LOG_ERR("DMA read error on %s: %d", DEV_NAME(dev), error_code);
		i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
		irq_unlock(key);

		data->msg.status = error_code;

		k_sem_give(&data->sem);
		return;
	}

	irq_unlock(key);

	/*
	 * DMA has read all but the last byte now, so let the ISR handle
	 * that and the terminating NACK.
	 */
	data->msg.buffer += data->msg.size - 1;
	data->msg.size = 1;
	i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_SB;
}

static bool i2c_sam0_dma_read_start(const struct device *dev)
{
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;
	int retval;

	if (cfg->dma_channel == 0xFF) {
		return false;
	}

	if (data->msg.size <= 2) {
		/*
		 * The last byte is always handled by the I2C ISR so
		 * just skip a two length read as well.
		 */
		return false;
	}

	struct dma_config dma_cfg = { 0 };
	struct dma_block_config dma_blk = { 0 };

	dma_cfg.channel_direction = PERIPHERAL_TO_MEMORY;
	dma_cfg.source_data_size = 1;
	dma_cfg.dest_data_size = 1;
	dma_cfg.user_data = (void *)dev;
	dma_cfg.dma_callback = i2c_sam0_dma_read_done;
	dma_cfg.block_count = 1;
	dma_cfg.head_block = &dma_blk;
	dma_cfg.dma_slot = cfg->read_dma_request;

	dma_blk.block_size = data->msg.size - 1;
	dma_blk.dest_address = (uint32_t)data->msg.buffer;
	dma_blk.source_address = (uint32_t)(&(i2c->DATA.reg));
	dma_blk.source_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;

	retval = dma_config(cfg->dma_dev, cfg->dma_channel, &dma_cfg);
	if (retval != 0) {
		LOG_ERR("Read DMA configure on %s failed: %d",
			DEV_NAME(dev), retval);
		return false;
	}

	retval = dma_start(cfg->dma_dev, cfg->dma_channel);
	if (retval != 0) {
		LOG_ERR("Read DMA start on %s failed: %d",
			DEV_NAME(dev), retval);
		return false;
	}

	return true;
}

#endif

static int i2c_sam0_transfer(const struct device *dev, struct i2c_msg *msgs,
			     uint8_t num_msgs, uint16_t addr)
{
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;
	uint32_t addr_reg;

	if (!num_msgs) {
		return 0;
	}
	data->num_msgs = num_msgs;
	data->msgs = msgs;

	for (; data->num_msgs > 0;) {
		if (!data->msgs->len) {
			if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
				return -EINVAL;
			}
		}

		i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;
		i2c->INTFLAG.reg = SERCOM_I2CM_INTFLAG_MASK;

		i2c->STATUS.reg = SERCOM_I2CM_STATUS_ARBLOST |
#ifdef SERCOM_I2CM_STATUS_LENERR
				  SERCOM_I2CM_STATUS_LENERR |
#endif
				  SERCOM_I2CM_STATUS_LOWTOUT |
				  SERCOM_I2CM_STATUS_BUSERR;
		wait_synchronization(i2c);

		data->msg.buffer = data->msgs->buf;
		data->msg.size = data->msgs->len;
		data->msg.status = 0;

		addr_reg = addr << 1U;
		if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
			addr_reg |= 1U;

			/* Set to auto ACK */
			i2c->CTRLB.bit.ACKACT = 0;
			wait_synchronization(i2c);
		}

		if (data->msgs->flags & I2C_MSG_ADDR_10_BITS) {
#ifdef SERCOM_I2CM_ADDR_TENBITEN
			addr_reg |= SERCOM_I2CM_ADDR_TENBITEN;
#else
			return -ENOTSUP;
#endif
		}

		int key = irq_lock();

		/*
		 * Writing the address starts the transaction, issuing
		 * a start/repeated start as required.
		 */
		i2c->ADDR.reg = addr_reg;

		/*
		 * Have to wait here to make sure the address write
		 * clears any pending requests or errors before DMA or
		 * ISR tries to handle it.
		 */
		wait_synchronization(i2c);

#ifdef SERCOM_I2CM_INTENSET_ERROR
		i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_ERROR;
#endif

		if ((data->msgs->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
			/*
			 * Always set MB even when reading, since that's how
			 * some errors are indicated.
			 */
			i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_MB;

#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
			if (!i2c_sam0_dma_read_start(dev))
#endif
			{
				i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_SB;
			}

		} else {
#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
			if (!i2c_sam0_dma_write_start(dev))
#endif
			{
				i2c->INTENSET.reg = SERCOM_I2CM_INTENSET_MB;
			}
		}

		irq_unlock(key);

		/* Now wait for the ISR to handle everything */
		k_sem_take(&data->sem, K_FOREVER);

		if (data->msg.status) {
			/* return the bus to idle */
			i2c->CTRLB.bit.CMD = 3;

			if (data->msg.status & SERCOM_I2CM_STATUS_ARBLOST) {
				LOG_DBG("Arbitration lost on %s",
					DEV_NAME(dev));
				return -EAGAIN;
			}

			LOG_ERR("Transaction error on %s: %08X",
				DEV_NAME(dev), data->msg.status);
			return -EIO;
		}

		/*
		 * Only send a stop if after this message:
		 *   - it is explicitly requested that we send a stop, or
		 *   - we are not conducting a restart, with more messages to follow
		 *
		 * Note: nothing validates the flags, so default to a stop if a stop is
		 * requested... do not let a restart request override it
		 */
		bool send_stop = (data->msgs->flags & I2C_MSG_STOP)
			|| !((data->msgs->flags & I2C_MSG_RESTART) && (data->num_msgs > 1));

		if (send_stop) {
			while (!i2c->STATUS.bit.CLKHOLD) {
			}
			i2c->CTRLB.bit.CMD = 3;
		}

		data->num_msgs--;
		data->msgs++;
	}

	return 0;
}

static int i2c_sam0_set_apply_bitrate(const struct device *dev,
				      uint32_t config)
{
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;
	uint32_t baud;
	uint32_t baud_low;
	uint32_t baud_high;

	uint32_t CTRLA = i2c->CTRLA.reg;

#ifdef SERCOM_I2CM_CTRLA_SPEED_Msk
	CTRLA &= ~SERCOM_I2CM_CTRLA_SPEED_Msk;
#endif
	CTRLA &= ~SERCOM_I2CM_CTRLA_SDAHOLD_Msk;

	switch (I2C_SPEED_GET(config)) {
	case I2C_SPEED_STANDARD:
#ifdef SERCOM_I2CM_CTRLA_SPEED
		CTRLA |= SERCOM_I2CM_CTRLA_SPEED(0);
#endif
		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x0);
		i2c->CTRLA.reg = CTRLA;
		wait_synchronization(i2c);

		/* 5 is the nominal 100ns rise time from the app notes */
		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 100000U - 5U - 10U) / 2U;
		if (baud > 255U || baud < 1U) {
			return -ERANGE;
		}

		LOG_DBG("Setting %s to standard mode with divisor %u",
			DEV_NAME(dev), baud);

		i2c->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(baud);
		break;

	case I2C_SPEED_FAST:
		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x0);
		i2c->CTRLA.reg = CTRLA;
		wait_synchronization(i2c);

		/* 5 is the nominal 100ns rise time from the app notes */
		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 400000U - 5U - 10U) / 2U;
		if (baud > 255U || baud < 1U) {
			return -ERANGE;
		}

		LOG_DBG("Setting %s to fast mode with divisor %u",
			DEV_NAME(dev), baud);

		i2c->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(baud);
		break;

	case I2C_SPEED_FAST_PLUS:
#ifdef SERCOM_I2CM_CTRLA_SPEED
		CTRLA |= SERCOM_I2CM_CTRLA_SPEED(1);
#endif
		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x2);
		i2c->CTRLA.reg = CTRLA;
		wait_synchronization(i2c);

		/* 5 is the nominal 100ns rise time from the app notes */
		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 1000000U - 5U - 10U);

		/* 2:1 low:high ratio */
		baud_high = baud;
		baud_high /= 3U;
		baud_high = CLAMP(baud_high, 1U, 255U);
		baud_low = baud - baud_high;
		if (baud_low < 1U && baud_high > 1U) {
			--baud_high;
			++baud_low;
		}

		if (baud_low < 1U || baud_low > 255U) {
			return -ERANGE;
		}

		LOG_DBG("Setting %s to fast mode plus with divisors %u/%u",
			DEV_NAME(dev), baud_high, baud_low);

		i2c->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(baud_high) |
				SERCOM_I2CM_BAUD_BAUDLOW(baud_low);
		break;

	case I2C_SPEED_HIGH:
#ifdef SERCOM_I2CM_CTRLA_SPEED
		CTRLA |= SERCOM_I2CM_CTRLA_SPEED(2);
#endif
		CTRLA |= SERCOM_I2CM_CTRLA_SDAHOLD(0x2);
		i2c->CTRLA.reg = CTRLA;
		wait_synchronization(i2c);

		baud = (SOC_ATMEL_SAM0_GCLK0_FREQ_HZ / 3400000U) - 2U;

		/* 2:1 low:high ratio */
		baud_high = baud;
		baud_high /= 3U;
		baud_high = CLAMP(baud_high, 1U, 255U);
		baud_low = baud - baud_high;
		if (baud_low < 1U && baud_high > 1U) {
			--baud_high;
			++baud_low;
		}

		if (baud_low < 1U || baud_low > 255U) {
			return -ERANGE;
		}

#ifdef SERCOM_I2CM_BAUD_HSBAUD
		LOG_DBG("Setting %s to high speed with divisors %u/%u",
			DEV_NAME(dev), baud_high, baud_low);

		/*
		 * 48 is just from the app notes, but the datasheet says
		 * it's ignored
		 */
		i2c->BAUD.reg = SERCOM_I2CM_BAUD_HSBAUD(baud_high) |
				SERCOM_I2CM_BAUD_HSBAUDLOW(baud_low) |
				SERCOM_I2CM_BAUD_BAUD(48) |
				SERCOM_I2CM_BAUD_BAUDLOW(48);
#else
		return -ENOTSUP;
#endif
		break;

	default:
		return -ENOTSUP;
	}

	wait_synchronization(i2c);
	return 0;
}

static int i2c_sam0_configure(const struct device *dev, uint32_t config)
{
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;
	int retval;

	if (!(config & I2C_MODE_MASTER)) {
		return -EINVAL;
	}

	if (config & I2C_SPEED_MASK) {
		i2c->CTRLA.bit.ENABLE = 0;
		wait_synchronization(i2c);

		retval = i2c_sam0_set_apply_bitrate(dev, config);

		i2c->CTRLA.bit.ENABLE = 1;
		wait_synchronization(i2c);

		if (retval != 0) {
			return retval;
		}
	}

	return 0;
}

static int i2c_sam0_initialize(const struct device *dev)
{
	struct i2c_sam0_dev_data *data = dev->data;
	const struct i2c_sam0_dev_config *const cfg = dev->config;
	SercomI2cm *i2c = cfg->regs;
	int retval;

#ifdef MCLK
	/* Enable the GCLK */
	GCLK->PCHCTRL[cfg->gclk_core_id].reg = GCLK_PCHCTRL_GEN_GCLK0 |
					       GCLK_PCHCTRL_CHEN;
	/* Enable SERCOM clock in MCLK */
	*cfg->mclk |= cfg->mclk_mask;
#else
	/* Enable the GCLK */
	GCLK->CLKCTRL.reg = cfg->gclk_clkctrl_id | GCLK_CLKCTRL_GEN_GCLK0 |
			    GCLK_CLKCTRL_CLKEN;

	/* Enable SERCOM clock in PM */
	PM->APBCMASK.reg |= cfg->pm_apbcmask;
#endif
	/* Disable all I2C interrupts */
	i2c->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MASK;

	/* I2C mode, enable timeouts */
	i2c->CTRLA.reg = SERCOM_I2CM_CTRLA_MODE_I2C_MASTER |
#ifdef SERCOM_I2CM_CTRLA_LOWTOUTEN
			 SERCOM_I2CM_CTRLA_LOWTOUTEN |
#endif
			 SERCOM_I2CM_CTRLA_INACTOUT(0x3);
	wait_synchronization(i2c);

	/* Enable smart mode (auto ACK) */
	i2c->CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN;
	wait_synchronization(i2c);

	retval = i2c_sam0_set_apply_bitrate(dev,
					    i2c_map_dt_bitrate(cfg->bitrate));
	if (retval != 0) {
		return retval;
	}

	k_sem_init(&data->sem, 0, 1);

	cfg->irq_config_func(dev);

#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
	if (!device_is_ready(cfg->dma_dev)) {
		return -ENODEV;
	}
#endif

	i2c->CTRLA.bit.ENABLE = 1;
	wait_synchronization(i2c);

	/* Force bus idle */
	i2c->STATUS.bit.BUSSTATE = 1;
	wait_synchronization(i2c);

	return 0;
}


static const struct i2c_driver_api i2c_sam0_driver_api = {
	.configure = i2c_sam0_configure,
	.transfer = i2c_sam0_transfer,
};

#ifdef CONFIG_I2C_SAM0_DMA_DRIVEN
#define I2C_SAM0_DMA_CHANNELS(n)					\
	.dma_dev = DEVICE_DT_GET(ATMEL_SAM0_DT_INST_DMA_CTLR(n, tx)),	\
	.write_dma_request = ATMEL_SAM0_DT_INST_DMA_TRIGSRC(n, tx),	\
	.read_dma_request = ATMEL_SAM0_DT_INST_DMA_TRIGSRC(n, rx),	\
	.dma_channel = ATMEL_SAM0_DT_INST_DMA_CHANNEL(n, rx),
#else
#define I2C_SAM0_DMA_CHANNELS(n)
#endif

#define SAM0_I2C_IRQ_CONNECT(n, m)					\
	do {								\
		IRQ_CONNECT(DT_INST_IRQ_BY_IDX(n, m, irq),		\
			    DT_INST_IRQ_BY_IDX(n, m, priority),		\
			    i2c_sam0_isr,				\
			    DEVICE_DT_INST_GET(n), 0);			\
		irq_enable(DT_INST_IRQ_BY_IDX(n, m, irq));		\
	} while (0)

#if DT_INST_IRQ_HAS_IDX(0, 3)
#define I2C_SAM0_IRQ_HANDLER(n)						\
static void i2c_sam0_irq_config_##n(const struct device *dev)			\
{									\
	SAM0_I2C_IRQ_CONNECT(n, 0);					\
	SAM0_I2C_IRQ_CONNECT(n, 1);					\
	SAM0_I2C_IRQ_CONNECT(n, 2);					\
	SAM0_I2C_IRQ_CONNECT(n, 3);					\
}
#else
#define I2C_SAM0_IRQ_HANDLER(n)						\
static void i2c_sam0_irq_config_##n(const struct device *dev)			\
{									\
	SAM0_I2C_IRQ_CONNECT(n, 0);					\
}
#endif

#ifdef MCLK
#define I2C_SAM0_CONFIG(n)						\
static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = {	\
	.regs = (SercomI2cm *)DT_INST_REG_ADDR(n),			\
	.bitrate = DT_INST_PROP(n, clock_frequency),			\
	.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(n),	\
	.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, bit)),	\
	.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, periph_ch),\
	.irq_config_func = &i2c_sam0_irq_config_##n			\
	I2C_SAM0_DMA_CHANNELS(n)					\
}
#else /* !MCLK */
#define I2C_SAM0_CONFIG(n)						\
static const struct i2c_sam0_dev_config i2c_sam0_dev_config_##n = {	\
	.regs = (SercomI2cm *)DT_INST_REG_ADDR(n),			\
	.bitrate = DT_INST_PROP(n, clock_frequency),			\
	.pm_apbcmask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(n, pm, bit)),	\
	.gclk_clkctrl_id = DT_INST_CLOCKS_CELL_BY_NAME(n, gclk, clkctrl_id),\
	.irq_config_func = &i2c_sam0_irq_config_##n,			\
	I2C_SAM0_DMA_CHANNELS(n)					\
}
#endif

#define I2C_SAM0_DEVICE(n)						\
	static void i2c_sam0_irq_config_##n(const struct device *dev);	\
	I2C_SAM0_CONFIG(n);						\
	static struct i2c_sam0_dev_data i2c_sam0_dev_data_##n;		\
	I2C_DEVICE_DT_INST_DEFINE(n,					\
			    i2c_sam0_initialize,			\
			    NULL,					\
			    &i2c_sam0_dev_data_##n,			\
			    &i2c_sam0_dev_config_##n, POST_KERNEL,	\
			    CONFIG_I2C_INIT_PRIORITY,			\
			    &i2c_sam0_driver_api);			\
	I2C_SAM0_IRQ_HANDLER(n)

DT_INST_FOREACH_STATUS_OKAY(I2C_SAM0_DEVICE)
