/*
 * Copyright 2022 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/irq.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/drivers/interrupt_controller/intc_eirq_nxp_s32.h>

#include <Siul2_Icu_Ip_Irq.h>

#define NXP_S32_NUM_CHANNELS		SIUL2_ICU_IP_NUM_OF_CHANNELS
/*
 * The macros from low level driver contains a bracket so
 * it cannot be used for some Zephyr macros (e.g LISTIFY).
 * This just does remove the bracket to be used for such macro.
 */
#define NXP_S32_NUM_CHANNELS_DEBRACKET	__DEBRACKET SIUL2_ICU_IP_NUM_OF_CHANNELS

struct eirq_nxp_s32_config {
	uint8_t instance;
	mem_addr_t disr0;
	mem_addr_t direr0;

	const Siul2_Icu_Ip_ConfigType *icu_cfg;
	const struct pinctrl_dev_config *pincfg;
};

/* Wrapper callback for each EIRQ line, from low level driver callback to GPIO callback */
struct eirq_nxp_s32_cb {
	eirq_nxp_s32_callback_t cb;
	uint8_t pin;
	void *data;
};

struct eirq_nxp_s32_data {
	struct eirq_nxp_s32_cb *cb;
};

int eirq_nxp_s32_set_callback(const struct device *dev, uint8_t line,
				eirq_nxp_s32_callback_t cb, uint8_t pin, void *arg)
{
	struct eirq_nxp_s32_data *data = dev->data;

	__ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range");

	if (data->cb[line].cb) {
		return -EBUSY;
	}

	data->cb[line].cb   = cb;
	data->cb[line].pin  = pin;
	data->cb[line].data = arg;

	return 0;
}

void eirq_nxp_s32_unset_callback(const struct device *dev, uint8_t line)
{
	struct eirq_nxp_s32_data *data = dev->data;

	__ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range");

	data->cb[line].cb    = NULL;
	data->cb[line].pin   = 0;
	data->cb[line].data  = NULL;
}

void eirq_nxp_s32_enable_interrupt(const struct device *dev, uint8_t line,
					Siul2_Icu_Ip_EdgeType edge_type)
{
	const struct eirq_nxp_s32_config *config = dev->config;

	__ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range");

	Siul2_Icu_Ip_SetActivationCondition(config->instance, line, edge_type);
	Siul2_Icu_Ip_EnableNotification(config->instance, line);
	Siul2_Icu_Ip_EnableInterrupt(config->instance, line);
}

void eirq_nxp_s32_disable_interrupt(const struct device *dev, uint8_t line)
{
	const struct eirq_nxp_s32_config *config = dev->config;

	__ASSERT(line < NXP_S32_NUM_CHANNELS, "Interrupt line is out of range");

	Siul2_Icu_Ip_DisableInterrupt(config->instance, line);
	Siul2_Icu_Ip_DisableNotification(config->instance, line);
	Siul2_Icu_Ip_SetActivationCondition(config->instance, line, SIUL2_ICU_DISABLE);
}

uint32_t eirq_nxp_s32_get_pending(const struct device *dev)
{
	const struct eirq_nxp_s32_config *config = dev->config;

	return sys_read32(config->disr0) & sys_read32(config->direr0);
}

static void eirq_nxp_s32_callback(const struct device *dev, uint8 line)
{
	const struct eirq_nxp_s32_data *data = dev->data;

	if (data->cb[line].cb != NULL) {
		data->cb[line].cb(data->cb[line].pin, data->cb[line].data);
	}
}

static int eirq_nxp_s32_init(const struct device *dev)
{
	const struct eirq_nxp_s32_config *config = dev->config;
	int err;

	err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT);
	if (err) {
		return err;
	}

	if (Siul2_Icu_Ip_Init(config->instance, config->icu_cfg)) {
		return -EINVAL;
	}

	return 0;
}

#define EIRQ_NXP_S32_NODE(n)	DT_NODELABEL(eirq##n)

#define EIRQ_NXP_S32_CALLBACK(line, n)								\
	void nxp_s32_icu_##n##_eirq_line_##line##_callback(void)				\
	{											\
		const struct device *dev = DEVICE_DT_GET(EIRQ_NXP_S32_NODE(n));			\
												\
		eirq_nxp_s32_callback(dev, line);						\
	}

#define EIRQ_NXP_S32_CHANNEL_CONFIG(idx, n)							\
	{											\
		.hwChannel = idx,								\
		.digFilterEn = DT_PROP_OR(DT_CHILD(EIRQ_NXP_S32_NODE(n), line_##idx),		\
						filter_enable, 0),				\
		.maxFilterCnt = DT_PROP_OR(DT_CHILD(EIRQ_NXP_S32_NODE(n), line_##idx),		\
						filter_counter, 0),				\
		.intSel = SIUL2_ICU_IRQ,							\
		.intEdgeSel = SIUL2_ICU_DISABLE,						\
		.callback = NULL,								\
		.Siul2ChannelNotification = nxp_s32_icu_##n##_eirq_line_##idx##_callback,	\
		.callbackParam = 0U								\
	}

#define EIRQ_NXP_S32_CHANNELS_CONFIG(n)								\
	static const Siul2_Icu_Ip_ChannelConfigType eirq_##n##_channel_nxp_s32_cfg[] = {	\
		LISTIFY(NXP_S32_NUM_CHANNELS_DEBRACKET,	EIRQ_NXP_S32_CHANNEL_CONFIG, (,), n)	\
	}

#define EIRQ_NXP_S32_INSTANCE_CONFIG(n)								\
	static const Siul2_Icu_Ip_InstanceConfigType eirq_##n##_instance_nxp_s32_cfg = {	\
		.intFilterClk = DT_PROP_OR(EIRQ_NXP_S32_NODE(n),				\
						filter_prescaler, (0)),				\
		.altIntFilterClk = 0U,								\
	}

#define EIRQ_NXP_S32_COMBINE_CONFIG(n)								\
	static const Siul2_Icu_Ip_ConfigType eirq_##n##_nxp_s32_cfg = {				\
		.numChannels	 = NXP_S32_NUM_CHANNELS,					\
		.pInstanceConfig = &eirq_##n##_instance_nxp_s32_cfg,				\
		.pChannelsConfig = &eirq_##n##_channel_nxp_s32_cfg,				\
	}

#define EIRQ_NXP_S32_CONFIG(n)									\
	LISTIFY(NXP_S32_NUM_CHANNELS_DEBRACKET, EIRQ_NXP_S32_CALLBACK, (), n)			\
	EIRQ_NXP_S32_CHANNELS_CONFIG(n);							\
	EIRQ_NXP_S32_INSTANCE_CONFIG(n);							\
	EIRQ_NXP_S32_COMBINE_CONFIG(n);

#define EIRQ_NXP_S32_INIT_DEVICE(n)								\
	EIRQ_NXP_S32_CONFIG(n)									\
	PINCTRL_DT_DEFINE(EIRQ_NXP_S32_NODE(n));						\
	static const struct eirq_nxp_s32_config eirq_nxp_s32_conf_##n = {			\
		.instance = n,									\
		.disr0    = (mem_addr_t)DT_REG_ADDR_BY_NAME(EIRQ_NXP_S32_NODE(n), disr0),	\
		.direr0   = (mem_addr_t)DT_REG_ADDR_BY_NAME(EIRQ_NXP_S32_NODE(n), direr0),	\
		.icu_cfg  = (Siul2_Icu_Ip_ConfigType *)&eirq_##n##_nxp_s32_cfg,			\
		.pincfg   = PINCTRL_DT_DEV_CONFIG_GET(EIRQ_NXP_S32_NODE(n))			\
	};											\
	static struct eirq_nxp_s32_cb eirq_nxp_s32_cb_##n[NXP_S32_NUM_CHANNELS];		\
	static struct eirq_nxp_s32_data eirq_nxp_s32_data_##n = {				\
		.cb = eirq_nxp_s32_cb_##n,							\
	};											\
	static int eirq_nxp_s32_init##n(const struct device *dev);				\
	DEVICE_DT_DEFINE(EIRQ_NXP_S32_NODE(n),							\
		eirq_nxp_s32_init##n,								\
		NULL,										\
		&eirq_nxp_s32_data_##n,								\
		&eirq_nxp_s32_conf_##n,								\
		PRE_KERNEL_1,									\
		CONFIG_INTC_INIT_PRIORITY,							\
		NULL);										\
	static int eirq_nxp_s32_init##n(const struct device *dev)				\
	{											\
		int err;									\
												\
		err = eirq_nxp_s32_init(dev);							\
		if (err) {									\
			return err;								\
		}										\
												\
		IRQ_CONNECT(DT_IRQN(EIRQ_NXP_S32_NODE(n)),					\
			DT_IRQ(EIRQ_NXP_S32_NODE(n), priority),					\
			SIUL2_##n##_ICU_EIRQ_SINGLE_INT_HANDLER,				\
			DEVICE_DT_GET(EIRQ_NXP_S32_NODE(n)),					\
			DT_IRQ(EIRQ_NXP_S32_NODE(n), flags));					\
												\
		irq_enable(DT_IRQN(EIRQ_NXP_S32_NODE(n)));					\
												\
		return 0;									\
	}

#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(0), okay)
EIRQ_NXP_S32_INIT_DEVICE(0)
#endif

#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(1), okay)
EIRQ_NXP_S32_INIT_DEVICE(1)
#endif

#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(4), okay)
EIRQ_NXP_S32_INIT_DEVICE(4)
#endif

#if DT_NODE_HAS_STATUS(EIRQ_NXP_S32_NODE(5), okay)
EIRQ_NXP_S32_INIT_DEVICE(5)
#endif
