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

#include <zephyr/sys/math_extras.h>
#include <nrfx_wdt.h>
#include <zephyr/drivers/watchdog.h>

#define LOG_LEVEL CONFIG_WDT_LOG_LEVEL
#include <zephyr/logging/log.h>
#include <zephyr/irq.h>
LOG_MODULE_REGISTER(wdt_nrfx);

struct wdt_nrfx_data {
	wdt_callback_t m_callbacks[NRF_WDT_CHANNEL_NUMBER];
	uint32_t m_timeout;
	uint8_t m_allocated_channels;
};

struct wdt_nrfx_config {
	nrfx_wdt_t wdt;
};

static int wdt_nrf_setup(const struct device *dev, uint8_t options)
{
	const struct wdt_nrfx_config *config = dev->config;
	const struct wdt_nrfx_data *data = dev->data;
	nrfx_err_t err_code;

	nrfx_wdt_config_t wdt_config = {
		.reload_value = data->m_timeout
	};

#if NRF_WDT_HAS_STOP
	wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_STOP_ENABLE_MASK;
#endif

	if (!(options & WDT_OPT_PAUSE_IN_SLEEP)) {
		wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK;
	}

	if (!(options & WDT_OPT_PAUSE_HALTED_BY_DBG)) {
		wdt_config.behaviour |= NRF_WDT_BEHAVIOUR_RUN_HALT_MASK;
	}

	err_code = nrfx_wdt_reconfigure(&config->wdt, &wdt_config);

	if (err_code != NRFX_SUCCESS) {
		return -EBUSY;
	}

	nrfx_wdt_enable(&config->wdt);

	return 0;
}

static int wdt_nrf_disable(const struct device *dev)
{
#if NRFX_WDT_HAS_STOP
	const struct wdt_nrfx_config *config = dev->config;
	nrfx_err_t err_code;

	err_code = nrfx_wdt_stop(&config->wdt);

	if (err_code != NRFX_SUCCESS) {
		return -ENOTSUP;
	}

	return 0;
#else
	ARG_UNUSED(dev);
	return -EPERM;
#endif
}

static int wdt_nrf_install_timeout(const struct device *dev,
				   const struct wdt_timeout_cfg *cfg)
{
	const struct wdt_nrfx_config *config = dev->config;
	struct wdt_nrfx_data *data = dev->data;
	nrfx_err_t err_code;
	nrfx_wdt_channel_id channel_id;

	if (cfg->flags != WDT_FLAG_RESET_SOC) {
		return -ENOTSUP;
	}

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

	if (data->m_allocated_channels == 0U) {
		/* According to relevant Product Specifications, watchdogs
		 * in all nRF chips can use reload values (determining
		 * the timeout) from range 0xF-0xFFFFFFFF given in 32768 Hz
		 * clock ticks. This makes the allowed range of 0x1-0x07CFFFFF
		 * in milliseconds. Check if the provided value is within
		 * this range. */
		if ((cfg->window.max == 0U) || (cfg->window.max > 0x07CFFFFF)) {
			return -EINVAL;
		}

		/* Save timeout value from first registered watchdog channel. */
		data->m_timeout = cfg->window.max;
	} else if (cfg->window.max != data->m_timeout) {
		return -EINVAL;
	}

	err_code = nrfx_wdt_channel_alloc(&config->wdt,
					  &channel_id);

	if (err_code == NRFX_ERROR_NO_MEM) {
		return -ENOMEM;
	}

	if (cfg->callback != NULL) {
		data->m_callbacks[channel_id] = cfg->callback;
	}

	data->m_allocated_channels++;
	return channel_id;
}

static int wdt_nrf_feed(const struct device *dev, int channel_id)
{
	const struct wdt_nrfx_config *config = dev->config;
	struct wdt_nrfx_data *data = dev->data;

	if (channel_id > data->m_allocated_channels) {
		return -EINVAL;
	}

	nrfx_wdt_channel_feed(&config->wdt,
			      (nrfx_wdt_channel_id)channel_id);

	return 0;
}

static const struct wdt_driver_api wdt_nrfx_driver_api = {
	.setup = wdt_nrf_setup,
	.disable = wdt_nrf_disable,
	.install_timeout = wdt_nrf_install_timeout,
	.feed = wdt_nrf_feed,
};

static void wdt_event_handler(const struct device *dev, uint32_t requests)
{
	struct wdt_nrfx_data *data = dev->data;

	while (requests) {
		uint8_t i = u32_count_trailing_zeros(requests);

		if (data->m_callbacks[i]) {
			data->m_callbacks[i](dev, i);
		}
		requests &= ~BIT(i);
	}
}

#define WDT(idx) DT_NODELABEL(wdt##idx)

#define WDT_NRFX_WDT_DEVICE(idx)					       \
	static void wdt_##idx##_event_handler(uint32_t requests)	       \
	{								       \
		wdt_event_handler(DEVICE_DT_GET(WDT(idx)), requests);	       \
	}								       \
	static int wdt_##idx##_init(const struct device *dev)		       \
	{								       \
		const struct wdt_nrfx_config *config = dev->config;	       \
		nrfx_err_t err_code;					       \
		IRQ_CONNECT(DT_IRQN(WDT(idx)), DT_IRQ(WDT(idx), priority),     \
			    nrfx_isr, nrfx_wdt_##idx##_irq_handler, 0);	       \
		err_code = nrfx_wdt_init(&config->wdt,			       \
					 NULL,				       \
					 wdt_##idx##_event_handler);	       \
		if (err_code != NRFX_SUCCESS) {				       \
			return -EBUSY;					       \
		}							       \
		return 0;						       \
	}								       \
	static struct wdt_nrfx_data wdt_##idx##_data = {		       \
		.m_timeout = 0,						       \
		.m_allocated_channels = 0,				       \
	};								       \
	static const struct wdt_nrfx_config wdt_##idx##z_config = {	       \
		.wdt = NRFX_WDT_INSTANCE(idx),				       \
	};								       \
	DEVICE_DT_DEFINE(WDT(idx),					       \
			    wdt_##idx##_init,				       \
			    NULL,					       \
			    &wdt_##idx##_data,				       \
			    &wdt_##idx##z_config,			       \
			    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,  \
			    &wdt_nrfx_driver_api)

#ifdef CONFIG_HAS_HW_NRF_WDT0
WDT_NRFX_WDT_DEVICE(0);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT1
WDT_NRFX_WDT_DEVICE(1);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT30
WDT_NRFX_WDT_DEVICE(30);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT31
WDT_NRFX_WDT_DEVICE(31);
#endif

#ifdef CONFIG_HAS_HW_NRF_WDT130
WDT_NRFX_WDT_DEVICE(130);
#endif
