/*
 * Copyright (c) 2018, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <drivers/counter.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>
#include <hal/nrf_rtc.h>
#include <sys/atomic.h>
#ifdef DPPI_PRESENT
#include <nrfx_dppi.h>
#else
#include <nrfx_ppi.h>
#endif

#define LOG_MODULE_NAME counter_rtc
#include <logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_COUNTER_LOG_LEVEL);

#define ERR(...) LOG_INST_ERR( \
	((const struct counter_nrfx_config *)dev->config)->log, __VA_ARGS__)
#define WRN(...) LOG_INST_WRN( \
	((const struct counter_nrfx_config *)dev->config)->log, __VA_ARGS__)
#define INF(...) LOG_INST_INF( \
	((const struct counter_nrfx_config *)dev->config)->log, __VA_ARGS__)
#define DBG(...) LOG_INST_DBG( \
	((const struct counter_nrfx_config *)dev->config)->log, __VA_ARGS__)

#define COUNTER_MAX_TOP_VALUE RTC_COUNTER_COUNTER_Msk

#define COUNTER_GET_TOP_CH(dev) counter_get_num_of_channels(dev)

#define IS_FIXED_TOP(dev) COND_CODE_1(CONFIG_COUNTER_RTC_CUSTOM_TOP_SUPPORT, \
		(((const struct counter_nrfx_config *)dev->config)->fixed_top), (true))

#define IS_PPI_WRAP(dev) COND_CODE_1(CONFIG_COUNTER_RTC_WITH_PPI_WRAP, \
		(((const struct counter_nrfx_config *)dev->config)->use_ppi), (false))

#define CC_ADJUSTED_OFFSET 16
#define CC_ADJ_MASK(chan) (BIT(chan + CC_ADJUSTED_OFFSET))

struct counter_nrfx_data {
	counter_top_callback_t top_cb;
	void *top_user_data;
	uint32_t top;
	uint32_t guard_period;
	/* Store channel interrupt pending and CC adjusted flags. */
	atomic_t ipend_adj;
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	uint8_t ppi_ch;
#endif
};

struct counter_nrfx_ch_data {
	counter_alarm_callback_t callback;
	void *user_data;
};

struct counter_nrfx_config {
	struct counter_config_info info;
	struct counter_nrfx_ch_data *ch_data;
	NRF_RTC_Type *rtc;
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	bool use_ppi;
#endif
#if CONFIG_COUNTER_RTC_CUSTOM_TOP_SUPPORT
	bool fixed_top;
#endif
	LOG_INSTANCE_PTR_DECLARE(log);
};

static int start(const struct device *dev)
{
	const struct counter_nrfx_config *config = dev->config;

	nrf_rtc_task_trigger(config->rtc, NRF_RTC_TASK_START);

	return 0;
}

static int stop(const struct device *dev)
{
	const struct counter_nrfx_config *config = dev->config;

	nrf_rtc_task_trigger(config->rtc, NRF_RTC_TASK_STOP);

	return 0;
}

static uint32_t read(const struct device *dev)
{
	const struct counter_nrfx_config *config = dev->config;

	return nrf_rtc_counter_get(config->rtc);
}

static int get_value(const struct device *dev, uint32_t *ticks)
{
	*ticks = read(dev);
	return 0;
}

/* Return true if value equals 2^n - 1 */
static inline bool is_bit_mask(uint32_t val)
{
	return !(val & (val + 1));
}

/* Function calculates distance between to values assuming that one first
 * argument is in front and that values wrap.
 */
static uint32_t ticks_sub(const struct device *dev, uint32_t val,
			  uint32_t old, uint32_t top)
{
	if (IS_FIXED_TOP(dev)) {
		return (val - old) & COUNTER_MAX_TOP_VALUE;
	} else if (likely(is_bit_mask(top))) {
		return (val - old) & top;
	}

	/* if top is not 2^n-1 */
	return (val >= old) ? (val - old) : val + top + 1 - old;

}

static uint32_t skip_zero_on_custom_top(uint32_t val, uint32_t top)
{
	/* From Product Specification: If a CC register value is 0 when
	 * a CLEAR task is set, this will not trigger a COMPARE event.
	 */
	if (unlikely(val == 0) && (top != COUNTER_MAX_TOP_VALUE)) {
		val++;
	}

	return val;
}

static uint32_t ticks_add(const struct device *dev, uint32_t val1,
			  uint32_t val2, uint32_t top)
{
	uint32_t sum = val1 + val2;

	if (IS_FIXED_TOP(dev)) {
		ARG_UNUSED(top);
		return sum & COUNTER_MAX_TOP_VALUE;
	}
	if (likely(is_bit_mask(top))) {
		sum = sum & top;
	} else {
		sum = sum > top ? sum - (top + 1) : sum;
	}

	return skip_zero_on_custom_top(sum, top);
}

static void set_cc_int_pending(const struct device *dev, uint8_t chan)
{
	const struct counter_nrfx_config *config = dev->config;
	struct counter_nrfx_data *data = dev->data;

	atomic_or(&data->ipend_adj, BIT(chan));
	NRFX_IRQ_PENDING_SET(NRFX_IRQ_NUMBER_GET(config->rtc));
}

/** @brief Handle case when CC value equals COUNTER+1.
 *
 * RTC will not generate event if CC value equals COUNTER+1. If such CC is
 * about to be set then special algorithm is applied. Since counter must not
 * expire before expected value, CC is set to COUNTER+2. If COUNTER progressed
 * during that time it means that target value is reached and interrupt is
 * manually triggered. If not then interrupt is enabled since it is expected
 * that CC value will generate event.
 *
 * Additionally, an information about CC adjustment is stored. This information
 * is used in the callback to return original CC value which was requested by
 * the user.
 */
static void handle_next_tick_case(const struct device *dev, uint8_t chan,
				  uint32_t now, uint32_t val)
{
	const struct counter_nrfx_config *config = dev->config;
	struct counter_nrfx_data *data = dev->data;

	val = ticks_add(dev, val, 1, data->top);
	nrf_rtc_cc_set(config->rtc, chan, val);
	atomic_or(&data->ipend_adj, CC_ADJ_MASK(chan));
	if (nrf_rtc_counter_get(config->rtc) != now) {
		set_cc_int_pending(dev, chan);
	} else {
		nrf_rtc_int_enable(config->rtc, RTC_CHANNEL_INT_MASK(chan));
	}
}

/*
 * @brief Set COMPARE value with optional too late setting detection.
 *
 * Setting CC algorithm takes into account:
 * - Current COMPARE value written to the register may be close to the current
 *   COUNTER value thus COMPARE event may be generated at any moment
 * - Next COMPARE value may be soon in the future. Taking into account potential
 *   preemption COMPARE value may be set too late.
 * - RTC registers are clocked with LF clock (32kHz) and sampled between two
 *   LF ticks.
 * - Setting COMPARE register to COUNTER+1 does not generate COMPARE event if
 *   done half tick before tick boundary.
 *
 * Algorithm assumes that:
 * - COMPARE interrupt is disabled
 * - absolute value is taking into account guard period. It means that
 *   it won't be further in future than <top> - <guard_period> from now.
 *
 * @param dev	Device.
 * @param chan	COMPARE channel.
 * @param val	Value (absolute or relative).
 * @param flags	Alarm flags.
 *
 * @retval 0 if COMPARE value was set on time and COMPARE interrupt is expected.
 * @retval -ETIME if absolute alarm was set too late and error reporting is
 *		  enabled.
 *
 */
static int set_cc(const struct device *dev, uint8_t chan, uint32_t val,
		  uint32_t flags)
{
	const struct counter_nrfx_config *config = dev->config;
	struct counter_nrfx_data *data = dev->data;

	__ASSERT_NO_MSG(data->guard_period < data->top);
	NRF_RTC_Type  *rtc = config->rtc;
	nrf_rtc_event_t evt;
	uint32_t prev_val;
	uint32_t top;
	uint32_t now;
	uint32_t diff;
	uint32_t int_mask = RTC_CHANNEL_INT_MASK(chan);
	int err = 0;
	uint32_t max_rel_val;
	bool absolute = flags & COUNTER_ALARM_CFG_ABSOLUTE;
	bool irq_on_late;

	__ASSERT(nrf_rtc_int_enable_check(rtc, int_mask) == 0,
			"Expected that CC interrupt is disabled.");

	evt = RTC_CHANNEL_EVENT_ADDR(chan);
	top =  data->top;
	now = nrf_rtc_counter_get(rtc);

	/* First take care of a risk of an event coming from CC being set to
	 * next tick. Reconfigure CC to future (now tick is the furtherest
	 * future). If CC was set to next tick we need to wait for up to 15us
	 * (half of 32k tick) and clean potential event. After that time there
	 * is no risk of unwanted event.
	 */
	prev_val = nrf_rtc_cc_get(rtc, chan);
	nrf_rtc_event_clear(rtc, evt);
	nrf_rtc_cc_set(rtc, chan, now);
	nrf_rtc_event_enable(rtc, int_mask);

	if (ticks_sub(dev, prev_val, now, top) == 1) {
		NRFX_DELAY_US(15);
		nrf_rtc_event_clear(rtc, evt);
	}

	now = nrf_rtc_counter_get(rtc);

	if (absolute) {
		val = skip_zero_on_custom_top(val, top);
		irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
		max_rel_val = top - data->guard_period;
	} else {
		/* If relative value is smaller than half of the counter range
		 * it is assumed that there is a risk of setting value too late
		 * and late detection algorithm must be applied. When late
		 * setting is detected, interrupt shall be triggered for
		 * immediate expiration of the timer. Detection is performed
		 * by limiting relative distance between CC and counter.
		 *
		 * Note that half of counter range is an arbitrary value.
		 */
		irq_on_late = val < (top / 2);
		/* limit max to detect short relative being set too late. */
		max_rel_val = irq_on_late ? top / 2 : top;
		val = ticks_add(dev, now, val, top);
	}

	diff = ticks_sub(dev, val, now, top);
	if (diff == 1) {
		/* CC cannot be set to COUNTER+1 because that will not
		 * generate an event. In that case, special handling is
		 * performed (attempt to set CC to COUNTER+2).
		 */
		handle_next_tick_case(dev, chan, now, val);
	} else {
		nrf_rtc_cc_set(rtc, chan, val);
		now = nrf_rtc_counter_get(rtc);

		/* decrement value to detect also case when val == read(dev).
		 * Otherwise, condition would need to include comparing diff
		 * against 0.
		 */
		diff = ticks_sub(dev, val - 1, now, top);
		if (diff > max_rel_val) {
			if (absolute) {
				err = -ETIME;
			}

			/* Interrupt is triggered always for relative alarm and
			 * for absolute depending on the flag.
			 */
			if (irq_on_late) {
				set_cc_int_pending(dev, chan);
			} else {
				config->ch_data[chan].callback = NULL;
			}
		} else if (diff == 0) {
			/* It is possible that setting CC was interrupted and
			 * CC might be set to COUNTER+1 value which will not
			 * generate an event. In that case, special handling
			 * is performed (attempt to set CC to COUNTER+2).
			 */
			handle_next_tick_case(dev, chan, now, val);
		} else {
			nrf_rtc_int_enable(rtc, int_mask);
		}
	}

	return err;
}

static int set_channel_alarm(const struct device *dev, uint8_t chan,
			     const struct counter_alarm_cfg *alarm_cfg)
{
	const struct counter_nrfx_config *nrfx_config = dev->config;
	struct counter_nrfx_data *data = dev->data;
	struct counter_nrfx_ch_data *chdata = &nrfx_config->ch_data[chan];

	if (alarm_cfg->ticks > data->top) {
		return -EINVAL;
	}

	if (chdata->callback) {
		return -EBUSY;
	}

	chdata->callback = alarm_cfg->callback;
	chdata->user_data = alarm_cfg->user_data;
	atomic_and(&data->ipend_adj, ~CC_ADJ_MASK(chan));

	return set_cc(dev, chan, alarm_cfg->ticks, alarm_cfg->flags);
}

static void disable(const struct device *dev, uint8_t chan)
{
	const struct counter_nrfx_config *config = dev->config;
	NRF_RTC_Type *rtc = config->rtc;
	nrf_rtc_event_t evt = RTC_CHANNEL_EVENT_ADDR(chan);

	nrf_rtc_int_disable(rtc, RTC_CHANNEL_INT_MASK(chan));
	nrf_rtc_event_disable(rtc, RTC_CHANNEL_INT_MASK(chan));
	nrf_rtc_event_clear(rtc, evt);
	config->ch_data[chan].callback = NULL;
}

static int cancel_alarm(const struct device *dev, uint8_t chan_id)
{
	disable(dev, chan_id);

	return 0;
}

static int ppi_setup(const struct device *dev, uint8_t chan)
{
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	const struct counter_nrfx_config *nrfx_config = dev->config;
	struct counter_nrfx_data *data = dev->data;
	NRF_RTC_Type *rtc = nrfx_config->rtc;
	nrf_rtc_event_t evt = RTC_CHANNEL_EVENT_ADDR(chan);
	nrfx_err_t result;

	if (!nrfx_config->use_ppi) {
		return 0;
	}

	nrf_rtc_event_enable(rtc, RTC_CHANNEL_INT_MASK(chan));
#ifdef DPPI_PRESENT
	result = nrfx_dppi_channel_alloc(&data->ppi_ch);
	if (result != NRFX_SUCCESS) {
		ERR("Failed to allocate PPI channel.");
		return -ENODEV;
	}

	nrf_rtc_subscribe_set(rtc, NRF_RTC_TASK_CLEAR, data->ppi_ch);
	nrf_rtc_publish_set(rtc->p_reg, evt, data->ppi_ch);
	(void)nrfx_dppi_channel_enable(data->ppi_ch);
#else /* DPPI_PRESENT */
	uint32_t evt_addr;
	uint32_t task_addr;

	evt_addr = nrf_rtc_event_address_get(rtc, evt);
	task_addr = nrf_rtc_task_address_get(rtc, NRF_RTC_TASK_CLEAR);

	result = nrfx_ppi_channel_alloc(&data->ppi_ch);
	if (result != NRFX_SUCCESS) {
		ERR("Failed to allocate PPI channel.");
		return -ENODEV;
	}
	(void)nrfx_ppi_channel_assign(data->ppi_ch, evt_addr, task_addr);
	(void)nrfx_ppi_channel_enable(data->ppi_ch);
#endif
#endif /* CONFIG_COUNTER_RTC_WITH_PPI_WRAP */
	return 0;
}

static void ppi_free(const struct device *dev, uint8_t chan)
{
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	const struct counter_nrfx_config *nrfx_config = dev->config;
	struct counter_nrfx_data *data = dev->data;
	uint8_t ppi_ch = data->ppi_ch;
	NRF_RTC_Type *rtc = nrfx_config->rtc;

	if (!nrfx_config->use_ppi) {
		return;
	}
	nrf_rtc_event_disable(rtc, RTC_CHANNEL_INT_MASK(chan));
#ifdef DPPI_PRESENT
	NRF_RTC_Type *rtc = nrfx_config->rtc;
	nrf_rtc_event_t evt = RTC_CHANNEL_EVENT_ADDR(chan);

	(void)nrfx_dppi_channel_disable(ppi_ch);
	nrf_rtc_subscribe_clear(rtc, NRF_RTC_TASK_CLEAR);
	nrf_rtc_publish_clear(rtc, evt);
	(void)nrfx_dppi_channel_free(ppi_ch);
#else /* DPPI_PRESENT */
	(void)nrfx_ppi_channel_disable(ppi_ch);
	(void)nrfx_ppi_channel_free(ppi_ch);
#endif
#endif
}

/* Return true if counter must be cleared by the CPU. It is cleared
 * automatically in case of max top value or PPI usage.
 */
static bool sw_wrap_required(const struct device *dev)
{
	struct counter_nrfx_data *data = dev->data;

	return (data->top != COUNTER_MAX_TOP_VALUE) && !IS_PPI_WRAP(dev);
}

static int set_fixed_top_value(const struct device *dev,
				const struct counter_top_cfg *cfg)
{
	const struct counter_nrfx_config *config = dev->config;
	struct counter_nrfx_data *data = dev->data;

	NRF_RTC_Type *rtc = config->rtc;

	if (cfg->ticks != COUNTER_MAX_TOP_VALUE) {
		return -EINVAL;
	}

	nrf_rtc_int_disable(rtc, NRF_RTC_INT_OVERFLOW_MASK);
	data->top_cb = cfg->callback;
	data->top_user_data = cfg->user_data;

	if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
		nrf_rtc_task_trigger(rtc, NRF_RTC_TASK_CLEAR);
	}

	if (cfg->callback) {
		nrf_rtc_int_enable(rtc, NRF_RTC_INT_OVERFLOW_MASK);
	}

	return 0;
}

static int set_top_value(const struct device *dev,
			 const struct counter_top_cfg *cfg)
{
	const struct counter_nrfx_config *nrfx_config = dev->config;
	NRF_RTC_Type *rtc = nrfx_config->rtc;
	struct counter_nrfx_data *dev_data = dev->data;
	uint32_t top_ch = COUNTER_GET_TOP_CH(dev);
	int err = 0;

	if (IS_FIXED_TOP(dev)) {
		return set_fixed_top_value(dev, cfg);
	}

	for (int i = 0; i < counter_get_num_of_channels(dev); i++) {
		/* Overflow can be changed only when all alarms are
		 * disables.
		 */
		if (nrfx_config->ch_data[i].callback) {
			return -EBUSY;
		}
	}

	nrf_rtc_int_disable(rtc, RTC_CHANNEL_INT_MASK(top_ch));

	if (IS_PPI_WRAP(dev)) {
		if ((dev_data->top == COUNTER_MAX_TOP_VALUE) &&
				cfg->ticks != COUNTER_MAX_TOP_VALUE) {
			err = ppi_setup(dev, top_ch);
		} else if (((dev_data->top != COUNTER_MAX_TOP_VALUE) &&
				cfg->ticks == COUNTER_MAX_TOP_VALUE)) {
			ppi_free(dev, top_ch);
		}
	}

	dev_data->top_cb = cfg->callback;
	dev_data->top_user_data = cfg->user_data;
	dev_data->top = cfg->ticks;
	nrf_rtc_cc_set(rtc, top_ch, cfg->ticks);

	if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
		nrf_rtc_task_trigger(rtc, NRF_RTC_TASK_CLEAR);
	} else if (read(dev) >= cfg->ticks) {
		err = -ETIME;
		if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) {
			nrf_rtc_task_trigger(rtc, NRF_RTC_TASK_CLEAR);
		}
	}

	if (cfg->callback || sw_wrap_required(dev)) {
		nrf_rtc_int_enable(rtc, RTC_CHANNEL_INT_MASK(top_ch));
	}

	return err;
}

static uint32_t get_pending_int(const struct device *dev)
{
	return 0;
}

static int init_rtc(const struct device *dev, uint32_t prescaler)
{
	const struct counter_nrfx_config *nrfx_config = dev->config;
	struct counter_nrfx_data *data = dev->data;
	struct counter_top_cfg top_cfg = {
		.ticks = COUNTER_MAX_TOP_VALUE
	};
	NRF_RTC_Type *rtc = nrfx_config->rtc;
	int err;

	z_nrf_clock_control_lf_on(CLOCK_CONTROL_NRF_LF_START_NOWAIT);

	nrf_rtc_prescaler_set(rtc, prescaler);

	NRFX_IRQ_ENABLE(NRFX_IRQ_NUMBER_GET(rtc));

	data->top = COUNTER_MAX_TOP_VALUE;
	err = set_top_value(dev, &top_cfg);
	DBG("Initialized");

	return err;
}

static uint32_t get_top_value(const struct device *dev)
{
	struct counter_nrfx_data *data = dev->data;

	return data->top;
}

static uint32_t get_guard_period(const struct device *dev, uint32_t flags)
{
	struct counter_nrfx_data *data = dev->data;

	return data->guard_period;
}

static int set_guard_period(const struct device *dev, uint32_t guard,
			    uint32_t flags)
{
	struct counter_nrfx_data *data = dev->data;

	data->guard_period = guard;
	return 0;
}

static void top_irq_handle(const struct device *dev)
{
	const struct counter_nrfx_config *config = dev->config;
	struct counter_nrfx_data *data = dev->data;

	NRF_RTC_Type *rtc = config->rtc;
	counter_top_callback_t cb = data->top_cb;
	nrf_rtc_event_t top_evt;

	top_evt = IS_FIXED_TOP(dev) ?
		  NRF_RTC_EVENT_OVERFLOW :
		  RTC_CHANNEL_EVENT_ADDR(counter_get_num_of_channels(dev));

	if (nrf_rtc_event_check(rtc, top_evt)) {
		nrf_rtc_event_clear(rtc, top_evt);

		/* Perform manual clear if custom top value is used and PPI
		 * clearing is not used.
		 */
		if (!IS_FIXED_TOP(dev) && !IS_PPI_WRAP(dev)) {
			nrf_rtc_task_trigger(rtc, NRF_RTC_TASK_CLEAR);
		}

		if (cb) {
			cb(dev, data->top_user_data);
		}
	}
}

static void alarm_irq_handle(const struct device *dev, uint32_t chan)
{
	const struct counter_nrfx_config *config = dev->config;
	struct counter_nrfx_data *data = dev->data;

	NRF_RTC_Type *rtc = config->rtc;
	nrf_rtc_event_t evt = RTC_CHANNEL_EVENT_ADDR(chan);
	uint32_t int_mask = RTC_CHANNEL_INT_MASK(chan);
	bool hw_irq_pending = nrf_rtc_event_check(rtc, evt) &&
			      nrf_rtc_int_enable_check(rtc, int_mask);
	bool sw_irq_pending = data->ipend_adj & BIT(chan);

	if (hw_irq_pending || sw_irq_pending) {
		struct counter_nrfx_ch_data *chdata;
		counter_alarm_callback_t cb;

		nrf_rtc_event_clear(rtc, evt);
		atomic_and(&data->ipend_adj, ~BIT(chan));
		nrf_rtc_int_disable(rtc, int_mask);

		chdata = &config->ch_data[chan];
		cb = chdata->callback;
		chdata->callback = NULL;

		if (cb) {
			uint32_t cc = nrf_rtc_cc_get(rtc, chan);

			if (data->ipend_adj & CC_ADJ_MASK(chan)) {
				cc = ticks_sub(dev, cc, 1, data->top);
			}

			cb(dev, chan, cc, chdata->user_data);
		}
	}
}

static void irq_handler(const struct device *dev)
{
	top_irq_handle(dev);

	for (uint32_t i = 0; i < counter_get_num_of_channels(dev); i++) {
		alarm_irq_handle(dev, i);
	}
}

static const struct counter_driver_api counter_nrfx_driver_api = {
	.start = start,
	.stop = stop,
	.get_value = get_value,
	.set_alarm = set_channel_alarm,
	.cancel_alarm = cancel_alarm,
	.set_top_value = set_top_value,
	.get_pending_int = get_pending_int,
	.get_top_value = get_top_value,
	.get_guard_period = get_guard_period,
	.set_guard_period = set_guard_period,
};

/*
 * Devicetree access is done with node labels due to HAL API
 * requirements. In particular, RTCx_CC_NUM values from HALs
 * are indexed by peripheral number, so DT_INST APIs won't work.
 */

#define RTC(idx)		DT_NODELABEL(rtc##idx)
#define RTC_PROP(idx, prop)	DT_PROP(RTC(idx), prop)

#define RTC_IRQ_CONNECT(idx)						       \
	COND_CODE_1(CONFIG_COUNTER_RTC##idx##_ZLI,			       \
		(IRQ_DIRECT_CONNECT(DT_IRQN(RTC(idx)),			       \
				    DT_IRQ(RTC(idx), priority),		       \
				    counter_rtc##idx##_isr_wrapper,	       \
				    IRQ_ZERO_LATENCY)),			       \
		(IRQ_CONNECT(DT_IRQN(RTC(idx)), DT_IRQ(RTC(idx), priority),    \
			    irq_handler, DEVICE_DT_GET(RTC(idx)), 0))	       \
	)

#define COUNTER_NRF_RTC_DEVICE(idx)					       \
	BUILD_ASSERT((RTC_PROP(idx, prescaler) - 1) <=			       \
		     RTC_PRESCALER_PRESCALER_Msk,			       \
		     "RTC prescaler out of range");			       \
	COND_CODE_1(CONFIG_COUNTER_RTC##idx##_ZLI, (			       \
		ISR_DIRECT_DECLARE(counter_rtc##idx##_isr_wrapper)	       \
		{							       \
			irq_handler(DEVICE_DT_GET(RTC(idx)));		       \
			/* No rescheduling, it shall not access zephyr primitives. */ \
			return 0;					       \
		}), ())							       \
	static int counter_##idx##_init(const struct device *dev)	       \
	{								       \
		RTC_IRQ_CONNECT(idx);					       \
		return init_rtc(dev, RTC_PROP(idx, prescaler) - 1);	       \
	}								       \
	static struct counter_nrfx_data counter_##idx##_data;		       \
	static struct counter_nrfx_ch_data				       \
		counter##idx##_ch_data[RTC##idx##_CC_NUM];		       \
	LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, CONFIG_COUNTER_LOG_LEVEL); \
	static const struct counter_nrfx_config nrfx_counter_##idx##_config = {\
		.info = {						       \
			.max_top_value = COUNTER_MAX_TOP_VALUE,		       \
			.freq = RTC_PROP(idx, clock_frequency) /	       \
				RTC_PROP(idx, prescaler),		       \
			.flags = COUNTER_CONFIG_INFO_COUNT_UP,		       \
			.channels = RTC_PROP(idx, fixed_top) ?		       \
				RTC##idx##_CC_NUM : RTC##idx##_CC_NUM - 1      \
		},							       \
		.ch_data = counter##idx##_ch_data,			       \
		.rtc = (NRF_RTC_Type *)DT_REG_ADDR(RTC(idx)),		       \
		IF_ENABLED(CONFIG_COUNTER_RTC_WITH_PPI_WRAP,		       \
			   (.use_ppi = RTC_PROP(idx, ppi_wrap),))	       \
		IF_ENABLED(CONFIG_COUNTER_RTC_CUSTOM_TOP_SUPPORT,	       \
			   (.fixed_top = RTC_PROP(idx, fixed_top),))	       \
		LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx)	       \
	};								       \
	DEVICE_DT_DEFINE(RTC(idx),					       \
			    counter_##idx##_init,			       \
			    NULL,					       \
			    &counter_##idx##_data,			       \
			    &nrfx_counter_##idx##_config.info,		       \
			    PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY,	       \
			    &counter_nrfx_driver_api)

#ifdef CONFIG_COUNTER_RTC0
COUNTER_NRF_RTC_DEVICE(0);
#endif

#ifdef CONFIG_COUNTER_RTC1
COUNTER_NRF_RTC_DEVICE(1);
#endif

#ifdef CONFIG_COUNTER_RTC2
COUNTER_NRF_RTC_DEVICE(2);
#endif
