/*
 * Copyright (c) 2020-2023 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief Common part of DMA drivers for some NXP SoC.
 */
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <soc.h>
#include <zephyr/drivers/dma.h>
#include <fsl_dma.h>
#include <fsl_inputmux.h>
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
#include <zephyr/sys/barrier.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/util_macro.h>
#include <zephyr/drivers/dma/dma_mcux_lpc.h>

#define DT_DRV_COMPAT nxp_lpc_dma

LOG_MODULE_REGISTER(dma_mcux_lpc, CONFIG_DMA_LOG_LEVEL);

struct dma_mcux_lpc_config {
	DMA_Type *base;
	uint32_t otrig_base_address;
	uint32_t itrig_base_address;
	uint8_t num_of_channels;
	uint8_t num_of_otrigs;
	void (*irq_config_func)(const struct device *dev);
};

struct channel_data {
	SDK_ALIGN(dma_descriptor_t dma_descriptor_table[CONFIG_DMA_MCUX_LPC_NUMBER_OF_DESCRIPTORS],
		  FSL_FEATURE_DMA_LINK_DESCRIPTOR_ALIGN_SIZE);
	dma_handle_t dma_handle;
	const struct device *dev;
	void *user_data;
	dma_callback_t dma_callback;
	enum dma_channel_direction dir;
	uint8_t src_inc;
	uint8_t dst_inc;
	dma_descriptor_t *curr_descriptor;
	uint8_t num_of_descriptors;
	bool descriptors_queued;
	uint32_t width;
	bool busy;
};

struct dma_otrig {
	int8_t source_channel;
	int8_t linked_channel;
};

struct dma_mcux_lpc_dma_data {
	struct channel_data *channel_data;
	struct dma_otrig *otrig_array;
	int8_t *channel_index;
	uint8_t num_channels_used;
};

struct k_spinlock configuring_otrigs;

#define NXP_LPC_DMA_MAX_XFER ((DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK >> \
			      DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT) + 1)

#define DEV_BASE(dev) \
	((DMA_Type *)((const struct dma_mcux_lpc_config *const)(dev)->config)->base)

#define DEV_CHANNEL_DATA(dev, ch)                                              \
	((struct channel_data *)(&(((struct dma_mcux_lpc_dma_data *)dev->data)->channel_data[ch])))

#define DEV_DMA_HANDLE(dev, ch)                                               \
		((dma_handle_t *)(&(DEV_CHANNEL_DATA(dev, ch)->dma_handle)))

#define EMPTY_OTRIG -1

static void nxp_lpc_dma_callback(dma_handle_t *handle, void *param,
			      bool transferDone, uint32_t intmode)
{
	int ret = -EIO;
	struct channel_data *data = (struct channel_data *)param;
	uint32_t channel = handle->channel;

	if (intmode == kDMA_IntError) {
		DMA_AbortTransfer(handle);
	} else if (intmode == kDMA_IntA) {
		ret = DMA_STATUS_BLOCK;
	} else {
		ret = DMA_STATUS_COMPLETE;
	}

	data->busy = DMA_ChannelIsBusy(data->dma_handle.base, channel);

	if (data->dma_callback) {
		data->dma_callback(data->dev, data->user_data, channel, ret);
	}
}

/* Handles DMA interrupts and dispatches to the individual channel */
static void dma_mcux_lpc_irq_handler(const struct device *dev)
{
	DMA_IRQHandle(DEV_BASE(dev));
/*
 * Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store
 * immediate overlapping exception return operation might vector
 * to incorrect interrupt
 */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
	barrier_dsync_fence_full();
#endif
}

static int dma_mcux_lpc_queue_descriptors(struct channel_data *data,
					   struct dma_block_config *block,
					   uint8_t src_inc,
					   uint8_t dest_inc,
					   bool callback_en)
{
	uint32_t xfer_config = 0U;
	dma_descriptor_t *next_descriptor = NULL;
	uint32_t width = data->width;
	uint32_t max_xfer_bytes = NXP_LPC_DMA_MAX_XFER * width;
	bool setup_extra_descriptor = false;
	/* intA is used to indicate transfer of a block */
	uint8_t enable_a_interrupt;
	/* intB is used to indicate complete transfer of the list of blocks */
	uint8_t enable_b_interrupt;
	uint8_t reload;
	struct dma_block_config local_block;
	bool last_block = false;

	memcpy(&local_block, block, sizeof(struct dma_block_config));

	do {
		/* Descriptors are queued during dma_configure, do not add more
		 * during dma_reload.
		 */
		if (!data->descriptors_queued) {
			/* Increase the number of descriptors queued */
			data->num_of_descriptors++;

			if (data->num_of_descriptors >= CONFIG_DMA_MCUX_LPC_NUMBER_OF_DESCRIPTORS) {
				return -ENOMEM;
			}
			/* Do we need to queue additional DMA descriptors for this block */
			if ((local_block.block_size > max_xfer_bytes) ||
			    (local_block.next_block != NULL)) {
				/* Allocate DMA descriptors */
				next_descriptor =
					&data->dma_descriptor_table[data->num_of_descriptors];
			} else {
				/* Check if this is the last block to transfer */
				if (local_block.next_block == NULL) {
					last_block = true;
					/* Last descriptor, check if we should setup a
					 * circular chain
					 */
					if (!local_block.source_reload_en) {
						/* No more descriptors */
						next_descriptor = NULL;
					} else if (data->num_of_descriptors == 1) {
						/* Allocate one more descriptors for
						 * ping-pong transfer
						 */
						next_descriptor = &data->dma_descriptor_table[
							data->num_of_descriptors];

						setup_extra_descriptor = true;
					} else {
						/* Loop back to the head */
						next_descriptor = data->dma_descriptor_table;
					}
				}
			}
		} else {
			/* Descriptors have already been allocated, reuse them as this
			 * is called from a reload function
			 */
			next_descriptor = data->curr_descriptor->linkToNextDesc;
		}

		/* SPI TX transfers need to queue a DMA descriptor to
		 * indicate an end of transfer. Source or destination
		 * address does not need to be change for these
		 * transactions and the transfer width is 4 bytes
		 */
		if ((local_block.source_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) &&
			(local_block.dest_addr_adj == DMA_ADDR_ADJ_NO_CHANGE)) {
			src_inc = 0;
			dest_inc = 0;
			width = sizeof(uint32_t);
		}

		/* Fire an interrupt after the whole block has been transferred */
		if (local_block.block_size > max_xfer_bytes) {
			enable_a_interrupt = 0;
			enable_b_interrupt = 0;
		} else {
			/* Use intB when this is the end of the block list and transfer */
			if (last_block) {
				enable_a_interrupt = 0;
				enable_b_interrupt = 1;
			} else {
				/* Use intA when we need an interrupt per block
				 * Enable or disable intA based on user configuration
				 */
				enable_a_interrupt = callback_en;
				enable_b_interrupt = 0;
			}
		}

		/* Reload if we have more descriptors */
		if (next_descriptor) {
			reload = 1;
		} else {
			reload = 0;
		}

		/* Enable interrupt and reload for the descriptor */
		xfer_config = DMA_CHANNEL_XFER(reload, 0UL, enable_a_interrupt,
					enable_b_interrupt,
					width,
					src_inc,
					dest_inc,
					MIN(local_block.block_size, max_xfer_bytes));

		DMA_SetupDescriptor(data->curr_descriptor,
				xfer_config,
				(void *)local_block.source_address,
				(void *)local_block.dest_address,
				(void *)next_descriptor);

		data->curr_descriptor = next_descriptor;

		if (local_block.block_size > max_xfer_bytes) {
			local_block.block_size -= max_xfer_bytes;
			if (src_inc) {
				local_block.source_address += max_xfer_bytes;
			}
			if (dest_inc) {
				local_block.dest_address += max_xfer_bytes;
			}
		} else {
			local_block.block_size = 0;
		}
	} while (local_block.block_size > 0);

	/* If an additional descriptor is queued for a certain case, set it up here.
	 */
	if (setup_extra_descriptor) {
		/* Increase the number of descriptors queued */
		data->num_of_descriptors++;

		/* Loop back to the head */
		next_descriptor = data->dma_descriptor_table;

		/* Leave curr pointer unchanged so we start queuing new data from
		 * this descriptor
		 */
		/* Enable or disable interrupt based on user request.
		 * Reload for the descriptor.
		 */
		xfer_config = DMA_CHANNEL_XFER(1UL, 0UL, callback_en, 0U,
					width,
					src_inc,
					dest_inc,
					MIN(local_block.block_size, max_xfer_bytes));
		/* Mark this as invalid */
		xfer_config &= ~DMA_CHANNEL_XFERCFG_CFGVALID_MASK;
		DMA_SetupDescriptor(data->curr_descriptor,
				xfer_config,
				(void *)local_block.source_address,
				(void *)local_block.dest_address,
				(void *)next_descriptor);
	}

	return 0;
}

static void dma_mcux_lpc_clear_channel_data(struct channel_data *data)
{
	data->dma_callback = NULL;
	data->dir = 0;
	data->src_inc = 0;
	data->dst_inc = 0;
	data->descriptors_queued = false;
	data->num_of_descriptors = 0;
	data->curr_descriptor = NULL;
	data->width = 0;
}

/* Configure a channel */
static int dma_mcux_lpc_configure(const struct device *dev, uint32_t channel,
				  struct dma_config *config)
{
	const struct dma_mcux_lpc_config *dev_config;
	dma_handle_t *p_handle;
	uint32_t xfer_config = 0U;
	struct channel_data *data;
	struct dma_mcux_lpc_dma_data *dma_data;
	struct dma_block_config *block_config;
	uint32_t virtual_channel;
	uint8_t otrig_index;
	uint8_t src_inc = 1, dst_inc = 1;
	bool is_periph = true;
	uint8_t width;
	uint32_t max_xfer_bytes;
	uint8_t reload = 0;
	bool complete_callback;

	if (NULL == dev || NULL == config) {
		return -EINVAL;
	}

	dev_config = dev->config;
	dma_data = dev->data;
	block_config = config->head_block;
	/* The DMA controller deals with just one transfer
	 * size, though the API provides separate sizes
	 * for source and dest. So assert that the source
	 * and dest sizes are the same.
	 */
	assert(config->dest_data_size == config->source_data_size);
	width = config->dest_data_size;

	/* If skip is set on both source and destination
	 * then skip by the same amount on both sides
	 */
	if (block_config->source_gather_en && block_config->dest_scatter_en) {
		assert(block_config->source_gather_interval ==
		       block_config->dest_scatter_interval);
	}

	max_xfer_bytes = NXP_LPC_DMA_MAX_XFER * width;

	/*
	 * Check if circular mode is requested.
	 */
	if (config->head_block->source_reload_en ||
	    config->head_block->dest_reload_en) {
		reload = 1;
	}

	/* Check if have a free slot to store DMA channel data */
	if (dma_data->num_channels_used > dev_config->num_of_channels) {
		LOG_ERR("out of DMA channel %d", channel);
		return -EINVAL;
	}

	/* Check if the dma channel number is valid */
	if (channel >= dev_config->num_of_channels) {
		LOG_ERR("invalid DMA channel number %d", channel);
		return -EINVAL;
	}

	if (config->source_data_size != 4U &&
		config->source_data_size != 2U &&
		config->source_data_size != 1U) {
		LOG_ERR("Source unit size error, %d", config->source_data_size);
		return -EINVAL;
	}

	if (config->dest_data_size != 4U &&
		config->dest_data_size != 2U &&
		config->dest_data_size != 1U) {
		LOG_ERR("Dest unit size error, %d", config->dest_data_size);
		return -EINVAL;
	}

	switch (config->channel_direction) {
	case MEMORY_TO_MEMORY:
		is_periph = false;
		if (block_config->source_gather_en) {
			src_inc = block_config->source_gather_interval / width;
			/* The current controller only supports incrementing the
			 * source and destination up to 4 time transfer width
			 */
			if ((src_inc > 4) || (src_inc == 3)) {
				return -EINVAL;
			}
		}

		if (block_config->dest_scatter_en) {
			dst_inc = block_config->dest_scatter_interval / width;
			/* The current controller only supports incrementing the
			 * source and destination up to 4 time transfer width
			 */
			if ((dst_inc > 4) || (dst_inc == 3)) {
				return -EINVAL;
			}
		}
		break;
	case MEMORY_TO_PERIPHERAL:
		/* Set the source increment value */
		if (block_config->source_gather_en) {
			src_inc = block_config->source_gather_interval / width;
			/* The current controller only supports incrementing the
			 * source and destination up to 4 time transfer width
			 */
			if ((src_inc > 4) || (src_inc == 3)) {
				return -EINVAL;
			}
		}

		dst_inc = 0;
		break;
	case PERIPHERAL_TO_MEMORY:
		src_inc = 0;

		/* Set the destination increment value */
		if (block_config->dest_scatter_en) {
			dst_inc = block_config->dest_scatter_interval / width;
			/* The current controller only supports incrementing the
			 * source and destination up to 4 time transfer width
			 */
			if ((dst_inc > 4) || (dst_inc == 3)) {
				return -EINVAL;
			}
		}
		break;
	default:
		LOG_ERR("not support transfer direction");
		return -EINVAL;
	}

	/* Check if user does not want to increment address */
	if (block_config->source_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) {
		src_inc = 0;
	}

	if (block_config->dest_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) {
		dst_inc = 0;
	}

	/* If needed, allocate a slot to store dma channel data */
	if (dma_data->channel_index[channel] == -1) {
		dma_data->channel_index[channel] = dma_data->num_channels_used;
		dma_data->num_channels_used++;
		/* Get the slot number that has the dma channel data */
		virtual_channel = dma_data->channel_index[channel];
		/* dma channel data */
		p_handle = DEV_DMA_HANDLE(dev, virtual_channel);
		data = DEV_CHANNEL_DATA(dev, virtual_channel);

		DMA_CreateHandle(p_handle, DEV_BASE(dev), channel);
		DMA_SetCallback(p_handle, nxp_lpc_dma_callback, (void *)data);
	} else {
		/* Get the slot number that has the dma channel data */
		virtual_channel = dma_data->channel_index[channel];
		/* dma channel data */
		p_handle = DEV_DMA_HANDLE(dev, virtual_channel);
		data = DEV_CHANNEL_DATA(dev, virtual_channel);
	}

	dma_mcux_lpc_clear_channel_data(data);

	data->dir = config->channel_direction;
	/* Save the increment values for the reload function */
	data->src_inc = src_inc;
	data->dst_inc = dst_inc;

	if (data->busy) {
		DMA_AbortTransfer(p_handle);
	}

	LOG_DBG("channel is %d", p_handle->channel);

	k_spinlock_key_t otrigs_key = k_spin_lock(&configuring_otrigs);

	data->width = width;

	if (config->source_chaining_en || config->dest_chaining_en) {
		/* Chaining is enabled */
		if (!dev_config->otrig_base_address || !dev_config->itrig_base_address) {
			LOG_ERR("Calling function tried to setup up channel"
			" chaining but the current platform is missing"
			" the correct trigger base addresses.");
			k_spin_unlock(&configuring_otrigs, otrigs_key);
			return -ENXIO;
		}

		LOG_DBG("link dma 0 channel %d with channel %d",
			channel, config->linked_channel);
		uint8_t is_otrig_available = 0;

		for (otrig_index = 0; otrig_index < dev_config->num_of_otrigs;
			++otrig_index) {
			if (dma_data->otrig_array[otrig_index].linked_channel == EMPTY_OTRIG ||
			    dma_data->otrig_array[otrig_index].source_channel == channel) {
				if (dma_data->otrig_array[otrig_index].source_channel == channel) {
					int ChannelToDisable =
						dma_data->otrig_array[otrig_index].linked_channel;
					DMA_DisableChannel(DEV_BASE(dev), ChannelToDisable);
					DEV_BASE(dev)->CHANNEL[ChannelToDisable].CFG &=
						~DMA_CHANNEL_CFG_HWTRIGEN_MASK;
				}
				is_otrig_available = 1;
				break;
			}
		}
		if (!is_otrig_available) {
			LOG_ERR("Calling function tried to setup up multiple"
			" channels to be configured but the dma driver has"
			" run out of OTrig Muxes");
			k_spin_unlock(&configuring_otrigs, otrigs_key);
			return -EINVAL;
		}

		/* Since INPUTMUX handles the dma signals and
		 * must be hardware triggered via the INPUTMUX
		 * hardware.
		 */
		DEV_BASE(dev)->CHANNEL[config->linked_channel].CFG |=
			DMA_CHANNEL_CFG_HWTRIGEN_MASK;

		DMA_EnableChannel(DEV_BASE(dev), config->linked_channel);

		/* Link OTrig Muxes with passed-in channels */
		INPUTMUX_AttachSignal(INPUTMUX, otrig_index,
			dev_config->otrig_base_address + channel);
		INPUTMUX_AttachSignal(INPUTMUX, config->linked_channel,
				dev_config->itrig_base_address + otrig_index);

		/* Otrig is now connected with linked channel */
		dma_data->otrig_array[otrig_index].source_channel = channel;
		dma_data->otrig_array[otrig_index].linked_channel = config->linked_channel;
	} else {
		/* Chaining is _NOT_ enabled, Freeing connected OTrig */
		for (otrig_index = 0; otrig_index < dev_config->num_of_otrigs; otrig_index++) {
			if (dma_data->otrig_array[otrig_index].linked_channel != EMPTY_OTRIG &&
			   (channel == dma_data->otrig_array[otrig_index].source_channel)) {
				int ChannelToDisable =
					dma_data->otrig_array[otrig_index].linked_channel;
				DMA_DisableChannel(DEV_BASE(dev), ChannelToDisable);
				DEV_BASE(dev)->CHANNEL[ChannelToDisable].CFG &=
					~DMA_CHANNEL_CFG_HWTRIGEN_MASK;
				dma_data->otrig_array[otrig_index].linked_channel = EMPTY_OTRIG;
				dma_data->otrig_array[otrig_index].source_channel = EMPTY_OTRIG;
				break;
			}
		}
	}

	k_spin_unlock(&configuring_otrigs, otrigs_key);

	complete_callback = config->complete_callback_en;

	/* Check if we need to queue DMA descriptors */
	if ((block_config->block_size > max_xfer_bytes) ||
		(block_config->next_block != NULL)) {
		/* Allocate a DMA descriptor */
		data->curr_descriptor = data->dma_descriptor_table;

		if (block_config->block_size > max_xfer_bytes) {
			/* Disable interrupt as this is not the entire data.
			 * Reload for the descriptor
			 */
			xfer_config = DMA_CHANNEL_XFER(1UL, 0UL, 0UL, 0UL,
					width,
					src_inc,
					dst_inc,
					max_xfer_bytes);
		} else {
			/* Enable INTA interrupt if user requested DMA for each block.
			 * Reload for the descriptor.
			 */
			xfer_config = DMA_CHANNEL_XFER(1UL, 0UL, complete_callback, 0UL,
					width,
					src_inc,
					dst_inc,
					block_config->block_size);
		}
	} else {
		/* Enable interrupt for the descriptor */
		xfer_config = DMA_CHANNEL_XFER(0UL, 0UL, 1UL, 0UL,
				width,
				src_inc,
				dst_inc,
				block_config->block_size);
	}
	/* DMA controller requires that the address be aligned to transfer size */
	assert(block_config->source_address == ROUND_UP(block_config->source_address, width));
	assert(block_config->dest_address == ROUND_UP(block_config->dest_address, width));

	DMA_SubmitChannelTransferParameter(p_handle,
					xfer_config,
					(void *)block_config->source_address,
					(void *)block_config->dest_address,
					(void *)data->curr_descriptor);

	/* Start queuing DMA descriptors */
	if (data->curr_descriptor) {
		if (block_config->block_size > max_xfer_bytes) {
			/* Queue additional DMA descriptors because the amount of data to
			 * be transferred is greater that the DMA descriptors max XFERCOUNT.
			 */
			struct dma_block_config local_block = { 0 };

			if (src_inc) {
				local_block.source_address = block_config->source_address
							     + max_xfer_bytes;
			} else {
				local_block.source_address = block_config->source_address;
			}
			if (dst_inc) {
				local_block.dest_address = block_config->dest_address
							     + max_xfer_bytes;
			} else {
				local_block.dest_address = block_config->dest_address;
			}
			local_block.block_size = block_config->block_size - max_xfer_bytes;
			local_block.next_block = block_config->next_block;
			local_block.source_reload_en = reload;

			if (block_config->next_block == NULL) {
				/* This is the last block, enable callback. */
				complete_callback = true;
			}

			if (dma_mcux_lpc_queue_descriptors(data, &local_block,
					src_inc, dst_inc, complete_callback)) {
				return -ENOMEM;
			}
		}
		/* Get the next block to transfer */
		block_config = block_config->next_block;

		while (block_config != NULL) {
			block_config->source_reload_en = reload;

			/* DMA controller requires that the address be aligned to transfer size */
			assert(block_config->source_address ==
			       ROUND_UP(block_config->source_address, width));
			assert(block_config->dest_address ==
			       ROUND_UP(block_config->dest_address, width));

			if (block_config->next_block == NULL) {
				/* This is the last block. Enable callback if not enabled. */
				complete_callback = true;
			}
			if (dma_mcux_lpc_queue_descriptors(data, block_config,
				src_inc, dst_inc, complete_callback)) {
				return -ENOMEM;
			}

			/* Get the next block and start queuing descriptors */
			block_config = block_config->next_block;
		}
		/* We have finished queuing DMA descriptors */
		data->descriptors_queued = true;
	}

	if (config->dma_slot) {
		uint32_t cfg_reg = 0;

		/* User supplied manual trigger configuration */
		if (config->dma_slot & LPC_DMA_PERIPH_REQ_EN) {
			cfg_reg |= DMA_CHANNEL_CFG_PERIPHREQEN_MASK;
		}
		if (config->dma_slot & LPC_DMA_HWTRIG_EN) {
			/* Setup hardware trigger */
			cfg_reg |= DMA_CHANNEL_CFG_HWTRIGEN_MASK;
			if (config->dma_slot & LPC_DMA_TRIGTYPE_LEVEL) {
				cfg_reg |= DMA_CHANNEL_CFG_TRIGTYPE_MASK;
			}
			if (config->dma_slot & LPC_DMA_TRIGPOL_HIGH_RISING) {
				cfg_reg |= DMA_CHANNEL_CFG_TRIGPOL_MASK;
			}
			if (config->dma_slot & LPC_DMA_TRIGBURST) {
				cfg_reg |= DMA_CHANNEL_CFG_TRIGBURST_MASK;
				cfg_reg |= DMA_CHANNEL_CFG_BURSTPOWER(
					LPC_DMA_GET_BURSTPOWER(config->dma_slot));
			}
		}
		p_handle->base->CHANNEL[p_handle->channel].CFG = cfg_reg;
	} else if (is_periph) {
		DMA_EnableChannelPeriphRq(p_handle->base, p_handle->channel);
	} else {
		DMA_DisableChannelPeriphRq(p_handle->base, p_handle->channel);
	}
	DMA_SetChannelPriority(p_handle->base, p_handle->channel, config->channel_priority);

	data->busy = false;
	if (config->dma_callback) {
		LOG_DBG("INSTALL call back on channel %d", channel);
		data->user_data = config->user_data;
		data->dma_callback = config->dma_callback;
		data->dev = dev;
	}

	return 0;
}

static int dma_mcux_lpc_start(const struct device *dev, uint32_t channel)
{
	struct dma_mcux_lpc_dma_data *dev_data = dev->data;
	int8_t virtual_channel = dev_data->channel_index[channel];
	struct channel_data *data = DEV_CHANNEL_DATA(dev, virtual_channel);

	LOG_DBG("START TRANSFER");
	LOG_DBG("DMA CTRL 0x%x", DEV_BASE(dev)->CTRL);
	data->busy = true;
	DMA_StartTransfer(DEV_DMA_HANDLE(dev, virtual_channel));
	return 0;
}

static int dma_mcux_lpc_stop(const struct device *dev, uint32_t channel)
{
	struct dma_mcux_lpc_dma_data *dev_data = dev->data;
	int8_t virtual_channel = dev_data->channel_index[channel];
	struct channel_data *data = DEV_CHANNEL_DATA(dev, virtual_channel);

	if (!data->busy) {
		return 0;
	}
	DMA_AbortTransfer(DEV_DMA_HANDLE(dev, virtual_channel));
	DMA_DisableChannel(DEV_BASE(dev), channel);

	data->busy = false;
	return 0;
}

static int dma_mcux_lpc_reload(const struct device *dev, uint32_t channel,
			       uint32_t src, uint32_t dst, size_t size)
{
	struct dma_mcux_lpc_dma_data *dev_data = dev->data;
	int8_t virtual_channel = dev_data->channel_index[channel];
	struct channel_data *data = DEV_CHANNEL_DATA(dev, virtual_channel);
	uint32_t xfer_config = 0U;

	/* DMA controller requires that the address be aligned to transfer size */
	assert(src == ROUND_UP(src, data->width));
	assert(dst == ROUND_UP(dst, data->width));

	if (!data->descriptors_queued) {
		dma_handle_t *p_handle;

		p_handle = DEV_DMA_HANDLE(dev, virtual_channel);

		/* Only one buffer, enable interrupt */
		xfer_config = DMA_CHANNEL_XFER(0UL, 0UL, 1UL, 0UL,
					data->width,
					data->src_inc,
					data->dst_inc,
					size);
		DMA_SubmitChannelTransferParameter(p_handle,
						xfer_config,
						(void *)src,
						(void *)dst,
						NULL);
	} else {
		struct dma_block_config local_block = { 0 };

		local_block.source_address = src;
		local_block.dest_address = dst;
		local_block.block_size = size;
		local_block.source_reload_en = 1;
		dma_mcux_lpc_queue_descriptors(data, &local_block,
					       data->src_inc, data->dst_inc, true);
	}

	return 0;
}

static int dma_mcux_lpc_get_status(const struct device *dev, uint32_t channel,
				   struct dma_status *status)
{
	const struct dma_mcux_lpc_config *config = dev->config;
	struct dma_mcux_lpc_dma_data *dev_data = dev->data;
	int8_t virtual_channel = dev_data->channel_index[channel];
	struct channel_data *data = DEV_CHANNEL_DATA(dev, virtual_channel);

	if (channel > config->num_of_channels) {
		return -EINVAL;
	}

	/* If channel is actually busy or the virtual channel is just not set up */
	if (data->busy && (virtual_channel != -1)) {
		status->busy = true;
		status->pending_length = DMA_GetRemainingBytes(DEV_BASE(dev), channel);
	} else {
		status->busy = false;
		status->pending_length = 0;
	}
	status->dir = data->dir;
	LOG_DBG("DMA CR 0x%x", DEV_BASE(dev)->CTRL);
	LOG_DBG("DMA INT 0x%x", DEV_BASE(dev)->INTSTAT);

	return 0;
}

static int dma_mcux_lpc_init(const struct device *dev)
{
	const struct dma_mcux_lpc_config *config = dev->config;
	struct dma_mcux_lpc_dma_data *data = dev->data;

	/* Indicate that the Otrig Muxes are not connected */
	for (int i = 0; i < config->num_of_otrigs; i++) {
		data->otrig_array[i].source_channel = EMPTY_OTRIG;
		data->otrig_array[i].linked_channel = EMPTY_OTRIG;
	}

	/*
	 * Initialize to -1 to indicate dma channel does not have a slot
	 * assigned to store dma channel data
	 */
	for (int i = 0; i < config->num_of_channels; i++) {
		data->channel_index[i] = -1;
	}

	data->num_channels_used = 0;

	DMA_Init(DEV_BASE(dev));
	INPUTMUX_Init(INPUTMUX);

	return 0;
}

static const struct dma_driver_api dma_mcux_lpc_api = {
	.config = dma_mcux_lpc_configure,
	.start = dma_mcux_lpc_start,
	.stop = dma_mcux_lpc_stop,
	.reload = dma_mcux_lpc_reload,
	.get_status = dma_mcux_lpc_get_status,
};

#define DMA_MCUX_LPC_CONFIG_FUNC(n)					\
	static void dma_mcux_lpc_config_func_##n(const struct device *dev)	\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(n),				\
			    DT_INST_IRQ(n, priority),			\
			    dma_mcux_lpc_irq_handler, DEVICE_DT_INST_GET(n), 0);\
									\
		irq_enable(DT_INST_IRQN(n));				\
	}
#define DMA_MCUX_LPC_IRQ_CFG_FUNC_INIT(n)				\
	.irq_config_func = dma_mcux_lpc_config_func_##n
#define DMA_MCUX_LPC_INIT_CFG(n)					\
	DMA_MCUX_LPC_DECLARE_CFG(n,					\
				 DMA_MCUX_LPC_IRQ_CFG_FUNC_INIT(n))

#define DMA_MCUX_LPC_NUM_USED_CHANNELS(n)				\
	COND_CODE_0(CONFIG_DMA_MCUX_LPC_NUMBER_OF_CHANNELS_ALLOCATED,	\
		    (DT_INST_PROP(n, dma_channels)),			\
		    (MIN(CONFIG_DMA_MCUX_LPC_NUMBER_OF_CHANNELS_ALLOCATED,	\
			DT_INST_PROP(n, dma_channels))))

#define DMA_MCUX_LPC_DECLARE_CFG(n, IRQ_FUNC_INIT)			\
static const struct dma_mcux_lpc_config dma_##n##_config = {		\
	.base = (DMA_Type *)DT_INST_REG_ADDR(n),			\
	.num_of_channels = DT_INST_PROP(n, dma_channels),		\
	.num_of_otrigs = DT_INST_PROP_OR(n, nxp_dma_num_of_otrigs, 0),			\
	.otrig_base_address = DT_INST_PROP_OR(n, nxp_dma_otrig_base_address, 0x0),	\
	.itrig_base_address = DT_INST_PROP_OR(n, nxp_dma_itrig_base_address, 0x0),	\
	IRQ_FUNC_INIT							\
}

#define DMA_INIT(n) \
									\
	static const struct dma_mcux_lpc_config dma_##n##_config;	\
									\
	static struct channel_data dma_##n##_channel_data_arr		\
			[DMA_MCUX_LPC_NUM_USED_CHANNELS(n)] = {0};	\
									\
	static struct dma_otrig dma_##n##_otrig_arr			\
			[DT_INST_PROP_OR(n, nxp_dma_num_of_otrigs, 0)]; \
									\
	static int8_t							\
		dma_##n##_channel_index_arr				\
				[DT_INST_PROP(n, dma_channels)] = {0};	\
									\
	static struct dma_mcux_lpc_dma_data dma_data_##n = {		\
		.channel_data = dma_##n##_channel_data_arr,		\
		.channel_index = dma_##n##_channel_index_arr,		\
		.otrig_array = dma_##n##_otrig_arr,			\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n,					\
			    &dma_mcux_lpc_init,				\
			    NULL,					\
			    &dma_data_##n, &dma_##n##_config,		\
			    PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY,	\
			    &dma_mcux_lpc_api);				\
									\
	DMA_MCUX_LPC_CONFIG_FUNC(n)					\
	DMA_MCUX_LPC_INIT_CFG(n);

DT_INST_FOREACH_STATUS_OKAY(DMA_INIT)
