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

#include <zephyr/drivers/watchdog.h>
#include <zephyr/drivers/counter.h>
#include <zephyr/logging/log_ctrl.h>

#define WDT_CHANNEL_COUNT DT_PROP(DT_WDT_COUNTER, num_channels)
#define DT_WDT_COUNTER DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_counter_watchdog)

#define WDT_SUPPORTED_CFG_FLAGS (WDT_FLAG_RESET_NONE | WDT_FLAG_RESET_SOC)

extern void sys_arch_reboot(int type);

struct wdt_counter_data {
	wdt_callback_t callback[CONFIG_WDT_COUNTER_CH_COUNT];
	uint32_t timeout[CONFIG_WDT_COUNTER_CH_COUNT];
	uint8_t flags[CONFIG_WDT_COUNTER_CH_COUNT];
	uint8_t alloc_cnt;
};

static struct wdt_counter_data wdt_data;

struct wdt_counter_config {
	const struct device *counter;
};

static int wdt_counter_setup(const struct device *dev, uint8_t options)
{
	const struct wdt_counter_config *config = dev->config;
	const struct device *counter = config->counter;

	if ((options & WDT_OPT_PAUSE_IN_SLEEP) || (options & WDT_OPT_PAUSE_HALTED_BY_DBG)) {
		return -ENOTSUP;
	}

	return counter_start(counter);
}

static int wdt_counter_disable(const struct device *dev)
{
	const struct wdt_counter_config *config = dev->config;
	const struct device *counter = config->counter;

	return counter_stop(counter);
}

static void counter_alarm_callback(const struct device *dev,
				   uint8_t chan_id, uint32_t ticks,
				   void *user_data)
{
	const struct device *wdt_dev = user_data;
	struct wdt_counter_data *data = wdt_dev->data;

	counter_stop(dev);
	if (data->callback[chan_id]) {
		data->callback[chan_id](wdt_dev, chan_id);
	}

	if (data->flags[chan_id] & WDT_FLAG_RESET_SOC) {
		LOG_PANIC();
		sys_arch_reboot(0);
	}
}

static int timeout_set(const struct device *dev, int chan_id, bool cancel)
{
	const struct wdt_counter_config *config = dev->config;
	struct wdt_counter_data *data = dev->data;
	const struct device *counter = config->counter;
	struct counter_alarm_cfg alarm_cfg = {
		.callback = counter_alarm_callback,
		.ticks = data->timeout[chan_id],
		.user_data = (void *)dev,
		.flags = 0
	};

	if (cancel) {
		int err = counter_cancel_channel_alarm(counter, chan_id);

		if (err < 0) {
			return err;
		}
	}

	return counter_set_channel_alarm(counter, chan_id, &alarm_cfg);
}

static int wdt_counter_install_timeout(const struct device *dev,
				   const struct wdt_timeout_cfg *cfg)
{
	struct wdt_counter_data *data = dev->data;
	const struct wdt_counter_config *config = dev->config;
	const struct device *counter = config->counter;
	int chan_id;

	if (!device_is_ready(counter)) {
		return -EIO;
	}

	uint32_t max_timeout = counter_get_top_value(counter) -
				counter_get_guard_period(counter,
				COUNTER_GUARD_PERIOD_LATE_TO_SET);
	uint32_t timeout_ticks = counter_us_to_ticks(counter, cfg->window.max * 1000);

	if (cfg->flags & ~WDT_SUPPORTED_CFG_FLAGS) {
		return -ENOTSUP;
	}

	if (cfg->window.min != 0U) {
		return -EINVAL;
	}

	if (timeout_ticks > max_timeout || timeout_ticks == 0) {
		return -EINVAL;
	}

	if (data->alloc_cnt == 0) {
		return -ENOMEM;
	}

	data->alloc_cnt--;
	chan_id = data->alloc_cnt;
	data->timeout[chan_id] = timeout_ticks;
	data->callback[chan_id] = cfg->callback;
	data->flags[chan_id] = cfg->flags;

	int err = timeout_set(dev, chan_id, false);

	if (err < 0) {
		return err;
	}

	return chan_id;
}

static int wdt_counter_feed(const struct device *dev, int chan_id)
{
	const struct wdt_counter_config *config = dev->config;

	if (chan_id > counter_get_num_of_channels(config->counter)) {
		return -EINVAL;
	}

	/* Move alarm further in time. */
	return timeout_set(dev, chan_id, true);
}

static const struct wdt_driver_api wdt_counter_driver_api = {
	.setup = wdt_counter_setup,
	.disable = wdt_counter_disable,
	.install_timeout = wdt_counter_install_timeout,
	.feed = wdt_counter_feed,
};

static const struct wdt_counter_config wdt_counter_config = {
	.counter = DEVICE_DT_GET(DT_PHANDLE(DT_WDT_COUNTER, counter)),
};


static int wdt_counter_init(const struct device *dev)
{
	const struct wdt_counter_config *config = dev->config;
	struct wdt_counter_data *data = dev->data;
	uint8_t ch_cnt = counter_get_num_of_channels(config->counter);

	data->alloc_cnt = MIN(ch_cnt, CONFIG_WDT_COUNTER_CH_COUNT);

	return 0;
}

DEVICE_DT_DEFINE(DT_WDT_COUNTER, wdt_counter_init, NULL,
		 &wdt_data, &wdt_counter_config,
		 POST_KERNEL,
		 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		 &wdt_counter_driver_api);
