/*
 * Copyright (c) 2022 Florin Stancu <niflostancu@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ti_cc13xx_cc26xx_watchdog

#include <zephyr/drivers/watchdog.h>
#include <zephyr/irq.h>
#include <soc.h>
#include <errno.h>

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

/* Driverlib includes */
#include <driverlib/watchdog.h>


/*
 * TI CC13xx/CC26xx watchdog is a 32-bit timer that runs on the MCU clock
 * with a fixed 32 divider.
 *
 * For the default MCU frequency of 48MHz:
 * 1ms = (48e6 / 32 / 1000) = 1500 ticks
 * Max. value = 2^32 / 1500 ~= 2863311 ms
 *
 * The watchdog will issue reset only on second in turn time-out (if the timer
 * or the interrupt aren't reset after the first time-out). By default, regular
 * interrupt is generated but platform supports also NMI (can be enabled by
 * setting the `interrupt-nmi` boolean DT property).
 */

#define CPU_FREQ DT_PROP(DT_PATH(cpus, cpu_0), clock_frequency)
#define WATCHDOG_DIV_RATIO	 32
#define WATCHDOG_MS_RATIO	 (CPU_FREQ / WATCHDOG_DIV_RATIO / 1000)
#define WATCHDOG_MAX_RELOAD_MS	 (0xFFFFFFFFu / WATCHDOG_MS_RATIO)
#define WATCHDOG_MS_TO_TICKS(_ms) ((_ms) * WATCHDOG_MS_RATIO)

struct wdt_cc13xx_cc26xx_data {
	uint8_t enabled;
	uint32_t reload;
	wdt_callback_t cb;
	uint8_t flags;
};

struct wdt_cc13xx_cc26xx_cfg {
	uint32_t reg;
	uint8_t irq_nmi;
	void (*irq_cfg_func)(void);
};

static int wdt_cc13xx_cc26xx_install_timeout(const struct device *dev,
				      const struct wdt_timeout_cfg *cfg)
{
	struct wdt_cc13xx_cc26xx_data *data = dev->data;

	/* window watchdog not supported */
	if (cfg->window.min != 0U || cfg->window.max == 0U) {
		return -EINVAL;
	}
	/*
	 * Note: since this SoC doesn't define CONFIG_WDT_MULTISTAGE, we don't need to
	 * specifically check for it and return ENOTSUP
	 */

	if (cfg->window.max > WATCHDOG_MAX_RELOAD_MS) {
		return -EINVAL;
	}
	data->reload = WATCHDOG_MS_TO_TICKS(cfg->window.max);
	data->cb = cfg->callback;
	data->flags = cfg->flags;
	LOG_DBG("raw reload value: %d", data->reload);
	return 0;
}

static int wdt_cc13xx_cc26xx_setup(const struct device *dev, uint8_t options)
{
	const struct wdt_cc13xx_cc26xx_cfg *config = dev->config;
	struct wdt_cc13xx_cc26xx_data *data = dev->data;

	/*
	 * Note: don't check if watchdog is already enabled, an application might
	 * want to dynamically re-configure its options (e.g., decrease the reload
	 * value for critical sections).
	 */

	WatchdogUnlock();

	/* clear any previous interrupt flags */
	WatchdogIntClear();

	/* Stall the WDT counter when halted by debugger */
	if (options & WDT_OPT_PAUSE_HALTED_BY_DBG) {
		WatchdogStallEnable();
	} else {
		WatchdogStallDisable();
	}
	/*
	 * According to TI's datasheets, the WDT is paused in STANDBY mode,
	 * so we simply continue with the setup => don't do this check:
	 * > if (options & WDT_OPT_PAUSE_IN_SLEEP) {
	 * >	return -ENOTSUP;
	 * > }
	 */

	/* raw reload value was computed by `_install_timeout()` */
	WatchdogReloadSet(data->reload);

	/* use the Device Tree-configured interrupt type */
	if (config->irq_nmi) {
		LOG_DBG("NMI enabled");
		WatchdogIntTypeSet(WATCHDOG_INT_TYPE_NMI);
	} else {
		WatchdogIntTypeSet(WATCHDOG_INT_TYPE_INT);
	}

	switch ((data->flags & WDT_FLAG_RESET_MASK)) {
	case WDT_FLAG_RESET_NONE:
		LOG_DBG("reset disabled");
		WatchdogResetDisable();
		break;
	case WDT_FLAG_RESET_SOC:
		LOG_DBG("reset enabled");
		WatchdogResetEnable();
		break;
	default:
		WatchdogLock();
		return -ENOTSUP;
	}

	data->enabled = 1;
	WatchdogEnable();
	WatchdogLock();

	LOG_DBG("done");
	return 0;
}

static int wdt_cc13xx_cc26xx_disable(const struct device *dev)
{
	struct wdt_cc13xx_cc26xx_data *data = dev->data;

	if (!WatchdogRunning()) {
		return -EFAULT;
	}

	/*
	 * Node: once started, the watchdog timer cannot be stopped!
	 * All we can do is disable the timeout reset, but the interrupt
	 * will be triggered if it was enabled (though it won't trigger the
	 * user callback due to `enabled` being unsed)!
	 */
	data->enabled = 0;
	WatchdogUnlock();
	WatchdogResetDisable();
	WatchdogLock();

	return 0;
}

static int wdt_cc13xx_cc26xx_feed(const struct device *dev, int channel_id)
{
	struct wdt_cc13xx_cc26xx_data *data = dev->data;

	WatchdogUnlock();
	WatchdogIntClear();
	WatchdogReloadSet(data->reload);
	WatchdogLock();
	LOG_DBG("feed %i", data->reload);
	return 0;
}

static void wdt_cc13xx_cc26xx_isr(const struct device *dev)
{
	struct wdt_cc13xx_cc26xx_data *data = dev->data;

	/* Simulate the watchdog being disabled: don't call the handler. */
	if (!data->enabled) {
		return;
	}

	/*
	 * Note: don't clear the interrupt here, leave it for the callback
	 * to decide (by calling `_feed()`)
	 */

	LOG_DBG("ISR");
	if (data->cb) {
		data->cb(dev, 0);
	}
}

static int wdt_cc13xx_cc26xx_init(const struct device *dev)
{
	const struct wdt_cc13xx_cc26xx_cfg *config = dev->config;
	uint8_t options = 0;

	LOG_DBG("init");
	config->irq_cfg_func();

	if (IS_ENABLED(CONFIG_WDT_DISABLE_AT_BOOT)) {
		return 0;
	}

#ifdef CONFIG_DEBUG
	/* when CONFIG_DEBUG is enabled, pause the WDT during debugging */
	options = WDT_OPT_PAUSE_HALTED_BY_DBG;
#endif /* CONFIG_DEBUG */

	return wdt_cc13xx_cc26xx_setup(dev, options);
}

static const struct wdt_driver_api wdt_cc13xx_cc26xx_api = {
	.setup = wdt_cc13xx_cc26xx_setup,
	.disable = wdt_cc13xx_cc26xx_disable,
	.install_timeout = wdt_cc13xx_cc26xx_install_timeout,
	.feed = wdt_cc13xx_cc26xx_feed,
};

#define CC13XX_CC26XX_WDT_INIT(index)						 \
	static void wdt_cc13xx_cc26xx_irq_cfg_##index(void)			 \
	{									 \
		if (DT_INST_PROP(index, interrupt_nmi)) {			 \
			return; /* NMI interrupt is used */			 \
		}								 \
		IRQ_CONNECT(DT_INST_IRQN(index),				 \
			DT_INST_IRQ(index, priority),				 \
			wdt_cc13xx_cc26xx_isr, DEVICE_DT_INST_GET(index), 0);	 \
		irq_enable(DT_INST_IRQN(index));				 \
	}									 \
	static struct wdt_cc13xx_cc26xx_data wdt_cc13xx_cc26xx_data_##index = {	 \
		.reload = WATCHDOG_MS_TO_TICKS(					 \
			CONFIG_WDT_CC13XX_CC26XX_INITIAL_TIMEOUT),		 \
		.cb = NULL,							 \
		.flags = 0,							 \
	};									 \
	static struct wdt_cc13xx_cc26xx_cfg wdt_cc13xx_cc26xx_cfg_##index = {	 \
		.reg = DT_INST_REG_ADDR(index),					 \
		.irq_nmi = DT_INST_PROP(index, interrupt_nmi),			 \
		.irq_cfg_func = wdt_cc13xx_cc26xx_irq_cfg_##index,		 \
	};									 \
	DEVICE_DT_INST_DEFINE(index,						 \
		wdt_cc13xx_cc26xx_init, NULL,					 \
		&wdt_cc13xx_cc26xx_data_##index,				 \
		&wdt_cc13xx_cc26xx_cfg_##index,					 \
		POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,		 \
		&wdt_cc13xx_cc26xx_api);

DT_INST_FOREACH_STATUS_OKAY(CC13XX_CC26XX_WDT_INIT)
