/*
 * 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(get_nrfx_config(dev)->log, __VA_ARGS__)
#define WRN(...) LOG_INST_WRN(get_nrfx_config(dev)->log, __VA_ARGS__)
#define INF(...) LOG_INST_INF(get_nrfx_config(dev)->log, __VA_ARGS__)
#define DBG(...) LOG_INST_DBG(get_nrfx_config(dev)->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, \
		(get_nrfx_config(dev)->fixed_top), (true))

#define IS_PPI_WRAP(dev) COND_CODE_1(CONFIG_COUNTER_RTC_WITH_PPI_WRAP, \
		(get_nrfx_config(dev)->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;
	u32_t top;
	u32_t guard_period;
	/* Store channel interrupt pending and CC adjusted flags. */
	atomic_t ipend_adj;
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	u8_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 inline struct counter_nrfx_data *get_dev_data(struct device *dev)
{
	return dev->driver_data;
}

static inline const struct counter_nrfx_config *get_nrfx_config(
							struct device *dev)
{
	return CONTAINER_OF(dev->config_info,
				struct counter_nrfx_config, info);
}

static int start(struct device *dev)
{
	nrf_rtc_task_trigger(get_nrfx_config(dev)->rtc, NRF_RTC_TASK_START);

	return 0;
}

static int stop(struct device *dev)
{
	nrf_rtc_task_trigger(get_nrfx_config(dev)->rtc, NRF_RTC_TASK_STOP);

	return 0;
}

static u32_t read(struct device *dev)
{
	return nrf_rtc_counter_get(get_nrfx_config(dev)->rtc);
}

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

/* Return true if value equals 2^n - 1 */
static inline bool is_bit_mask(u32_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 u32_t ticks_sub(struct device *dev, u32_t val, u32_t old, u32_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 u32_t skip_zero_on_custom_top(u32_t val, u32_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 u32_t ticks_add(struct device *dev, u32_t val1, u32_t val2, u32_t top)
{
	u32_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(struct device *dev, u8_t chan)
{
	atomic_or(&get_dev_data(dev)->ipend_adj, BIT(chan));
	NRFX_IRQ_PENDING_SET(NRFX_IRQ_NUMBER_GET(get_nrfx_config(dev)->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(struct device *dev, u8_t chan,
				  u32_t now, u32_t val)
{
	val = ticks_add(dev, val, 1, get_dev_data(dev)->top);
	nrf_rtc_cc_set(get_nrfx_config(dev)->rtc, chan, val);
	atomic_or(&get_dev_data(dev)->ipend_adj, CC_ADJ_MASK(chan));
	if (nrf_rtc_counter_get(get_nrfx_config(dev)->rtc) != now) {
		set_cc_int_pending(dev, chan);
	} else {
		nrf_rtc_int_enable(get_nrfx_config(dev)->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(struct device *dev, u8_t chan, u32_t val, u32_t flags)
{
	__ASSERT_NO_MSG(get_dev_data(dev)->guard_period <
			get_dev_data(dev)->top);
	NRF_RTC_Type  *rtc = get_nrfx_config(dev)->rtc;
	nrf_rtc_event_t evt;
	u32_t prev_val;
	u32_t top;
	u32_t now;
	u32_t diff;
	u32_t int_mask = RTC_CHANNEL_INT_MASK(chan);
	int err = 0;
	u32_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 =  get_dev_data(dev)->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 - get_dev_data(dev)->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 {
				get_nrfx_config(dev)->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(struct device *dev, u8_t chan,
			     const struct counter_alarm_cfg *alarm_cfg)
{
	const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev);
	struct counter_nrfx_ch_data *chdata = &nrfx_config->ch_data[chan];

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

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

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

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

static void disable(struct device *dev, u8_t chan)
{
	const struct counter_nrfx_config *config = get_nrfx_config(dev);
	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(struct device *dev, u8_t chan_id)
{
	disable(dev, chan_id);

	return 0;
}

static int ppi_setup(struct device *dev, u8_t chan)
{
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev);
	struct counter_nrfx_data *data = get_dev_data(dev);
	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 */
	u32_t evt_addr;
	u32_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(struct device *dev, u8_t chan)
{
#if CONFIG_COUNTER_RTC_WITH_PPI_WRAP
	const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev);
	u8_t ppi_ch = get_dev_data(dev)->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(struct device *dev)
{
	return (get_dev_data(dev)->top != COUNTER_MAX_TOP_VALUE)
			&& !IS_PPI_WRAP(dev);
}

static int set_fixed_top_value(struct device *dev,
				const struct counter_top_cfg *cfg)
{
	NRF_RTC_Type *rtc = get_nrfx_config(dev)->rtc;

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

	nrf_rtc_int_disable(rtc, NRF_RTC_INT_OVERFLOW_MASK);
	get_dev_data(dev)->top_cb = cfg->callback;
	get_dev_data(dev)->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(struct device *dev, const struct counter_top_cfg *cfg)
{
	const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev);
	NRF_RTC_Type *rtc = nrfx_config->rtc;
	struct counter_nrfx_data *dev_data = get_dev_data(dev);
	u32_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 u32_t get_pending_int(struct device *dev)
{
	return 0;
}

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

	clock = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_clock)));
	if (!clock) {
		return -ENODEV;
	}

	clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_LF);

	nrf_rtc_prescaler_set(rtc, prescaler);

	NRFX_IRQ_ENABLE(NRFX_IRQ_NUMBER_GET(rtc));

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

	return err;
}

static u32_t get_top_value(struct device *dev)
{
	return get_dev_data(dev)->top;
}

static u32_t get_max_relative_alarm(struct device *dev)
{
	return get_dev_data(dev)->top;
}

static u32_t get_guard_period(struct device *dev, u32_t flags)
{
	return get_dev_data(dev)->guard_period;
}

static int set_guard_period(struct device *dev, u32_t guard, u32_t flags)
{
	get_dev_data(dev)->guard_period = guard;
	return 0;
}

static void top_irq_handle(struct device *dev)
{
	NRF_RTC_Type *rtc = get_nrfx_config(dev)->rtc;
	counter_top_callback_t cb = get_dev_data(dev)->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, get_dev_data(dev)->top_user_data);
		}
	}
}

static void alarm_irq_handle(struct device *dev, u32_t chan)
{
	NRF_RTC_Type *rtc = get_nrfx_config(dev)->rtc;
	nrf_rtc_event_t evt = RTC_CHANNEL_EVENT_ADDR(chan);
	u32_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 = get_dev_data(dev)->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(&get_dev_data(dev)->ipend_adj, ~BIT(chan));
		nrf_rtc_int_disable(rtc, int_mask);

		chdata = &get_nrfx_config(dev)->ch_data[chan];
		cb = chdata->callback;
		chdata->callback = NULL;

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

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

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

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

	for (u32_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_max_relative_alarm = get_max_relative_alarm,
	.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 COUNTER_NRF_RTC_DEVICE(idx)					       \
	BUILD_ASSERT((RTC_PROP(idx, prescaler) - 1) <=			       \
		     RTC_PRESCALER_PRESCALER_Msk,			       \
		     "RTC prescaler out of range");			       \
	DEVICE_DECLARE(rtc_##idx);					       \
	static int counter_##idx##_init(struct device *dev)		       \
	{								       \
		IRQ_CONNECT(DT_IRQN(RTC(idx)), DT_IRQ(RTC(idx), priority),     \
			    irq_handler, DEVICE_GET(rtc_##idx), 0);	       \
		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_AND_API_INIT(rtc_##idx,					       \
			    DT_LABEL(RTC(idx)),				       \
			    counter_##idx##_init,			       \
			    &counter_##idx##_data,			       \
			    &nrfx_counter_##idx##_config.info,		       \
			    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,  \
			    &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
