/*
 * Copyright (c) 2020, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <zephyr/drivers/counter.h>
#include <soc.h>
#include <hw_counter.h>

#define DT_COUNTER_LABEL counter0
#define DRIVER_CONFIG_INFO_FLAGS (COUNTER_CONFIG_INFO_COUNT_UP)
#define DRIVER_CONFIG_INFO_CHANNELS 1
#define COUNTER_NATIVE_POSIX_IRQ_FLAGS (0)
#define COUNTER_NATIVE_POSIX_IRQ_PRIORITY (2)

#define COUNTER_PERIOD (USEC_PER_SEC / CONFIG_COUNTER_NATIVE_POSIX_FREQUENCY)
#define TOP_VALUE (UINT_MAX)

static struct counter_alarm_cfg pending_alarm;
static bool is_alarm_pending;
static const struct device *device;

static void counter_isr(const void *arg)
{
	ARG_UNUSED(arg);
	uint32_t current_value = hw_counter_get_value();

	if (is_alarm_pending) {
		is_alarm_pending = false;
		pending_alarm.callback(device, 0, current_value,
				       pending_alarm.user_data);
	}
}

static int ctr_init(const struct device *dev)
{
	device = dev;
	is_alarm_pending = false;

	IRQ_CONNECT(COUNTER_EVENT_IRQ, COUNTER_NATIVE_POSIX_IRQ_PRIORITY,
		    counter_isr, NULL, COUNTER_NATIVE_POSIX_IRQ_FLAGS);
	hw_counter_set_period(COUNTER_PERIOD);
	hw_counter_set_target(TOP_VALUE);

	return 0;
}

static int ctr_start(const struct device *dev)
{
	ARG_UNUSED(dev);

	hw_counter_start();
	return 0;
}

static int ctr_stop(const struct device *dev)
{
	ARG_UNUSED(dev);

	hw_counter_stop();
	return 0;
}

static int ctr_get_value(const struct device *dev, uint32_t *ticks)
{
	ARG_UNUSED(dev);

	*ticks = hw_counter_get_value();
	return 0;
}

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

static int ctr_set_top_value(const struct device *dev,
			     const struct counter_top_cfg *cfg)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(cfg);

	posix_print_warning("%s not supported\n", __func__);
	return -ENOTSUP;
}

static uint32_t ctr_get_top_value(const struct device *dev)
{
	return TOP_VALUE;
}

static int ctr_set_alarm(const struct device *dev, uint8_t chan_id,
			 const struct counter_alarm_cfg *alarm_cfg)
{
	ARG_UNUSED(dev);

	if (chan_id >= DRIVER_CONFIG_INFO_CHANNELS) {
		posix_print_warning("channel %u is not supported\n", chan_id);
		return -ENOTSUP;
	}

	pending_alarm = *alarm_cfg;
	is_alarm_pending = true;

	if (!(alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE)) {
		pending_alarm.ticks =
			hw_counter_get_value() + pending_alarm.ticks;
	}

	hw_counter_set_target(pending_alarm.ticks);
	irq_enable(COUNTER_EVENT_IRQ);

	return 0;
}

static int ctr_cancel_alarm(const struct device *dev, uint8_t chan_id)
{
	ARG_UNUSED(dev);

	if (chan_id >= DRIVER_CONFIG_INFO_CHANNELS) {
		posix_print_warning("channel %u is not supported\n", chan_id);
		return -ENOTSUP;
	}

	is_alarm_pending = false;

	return 0;
}

static const struct counter_driver_api ctr_api = {
	.start = ctr_start,
	.stop = ctr_stop,
	.get_value = ctr_get_value,
	.set_alarm = ctr_set_alarm,
	.cancel_alarm = ctr_cancel_alarm,
	.set_top_value = ctr_set_top_value,
	.get_pending_int = ctr_get_pending_int,
	.get_top_value = ctr_get_top_value,
};

static const struct counter_config_info ctr_config = {
	.max_top_value = UINT_MAX,
	.freq = CONFIG_COUNTER_NATIVE_POSIX_FREQUENCY,
	.channels = DRIVER_CONFIG_INFO_CHANNELS,
	.flags = DRIVER_CONFIG_INFO_FLAGS
};

DEVICE_DT_DEFINE(DT_NODELABEL(DT_COUNTER_LABEL), ctr_init,
		    NULL, NULL, &ctr_config, PRE_KERNEL_1,
		    CONFIG_COUNTER_INIT_PRIORITY, &ctr_api);
