/*
 * Copyright (c) 2019 Interay Solutions B.V.
 * Copyright (c) 2019 Oane Kingma
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT silabs_gecko_wdog

#include <soc.h>
#include <drivers/watchdog.h>
#include <em_wdog.h>
#include <em_cmu.h>

#include <logging/log.h>
LOG_MODULE_REGISTER(wdt_gecko, CONFIG_WDT_LOG_LEVEL);

/* Defines maximum WDOG_CTRL.PERSEL value which is used by the watchdog module
 * to select its timeout period.
 */
#define WDT_GECKO_MAX_PERIOD_SELECT_VALUE 15

/* Device constant configuration parameters */
struct wdt_gecko_cfg {
	WDOG_TypeDef *base;
	void (*irq_cfg_func)(void);
};

struct wdt_gecko_data {
	wdt_callback_t callback;
	WDOG_Init_TypeDef wdog_config;
	bool timeout_installed;
};

#define DEV_NAME(dev) ((dev)->name)
#define DEV_DATA(dev) \
	((struct wdt_gecko_data *)(dev)->driver_data)
#define DEV_CFG(dev) \
	((struct wdt_gecko_cfg *)(dev)->config_info)

static u32_t wdt_gecko_get_timeout_from_persel(int perSel)
{
	return (8 << perSel) + 1;
}

/* Find the rounded up value of cycles for supplied timeout. When using ULFRCO
 * (default), 1 cycle is 1 ms +/- 12%.
 */
static int wdt_gecko_get_persel_from_timeout(u32_t timeout)
{
	int idx;

	for (idx = 0; idx < WDT_GECKO_MAX_PERIOD_SELECT_VALUE; idx++) {
		if (wdt_gecko_get_timeout_from_persel(idx) >= timeout) {
			break;
		}
	}

	return idx;
}

static int wdt_gecko_convert_window(u32_t window, u32_t period)
{
	int idx = 0;
	u32_t incr_val, comp_val;

	incr_val = period / 8;
	comp_val = 0; /* Initially 0, disable */

	/* Valid window settings range from 12.5% of the calculated
	 * timeout period up to 87.5% (= 7 * 12.5%)
	 */
	while (idx < 7) {
		if (window > comp_val) {
			comp_val += incr_val;
			idx++;
			continue;
		}

		break;
	}

	return idx;
}

static int wdt_gecko_setup(struct device *dev, u8_t options)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	struct wdt_gecko_data *data = DEV_DATA(dev);
	WDOG_TypeDef *wdog = config->base;

	if (!data->timeout_installed) {
		LOG_ERR("No valid timeouts installed");
		return -EINVAL;
	}

	data->wdog_config.em2Run =
		(options & WDT_OPT_PAUSE_IN_SLEEP) == 0U;
	data->wdog_config.em3Run =
		(options & WDT_OPT_PAUSE_IN_SLEEP) == 0U;

	data->wdog_config.debugRun =
		(options & WDT_OPT_PAUSE_HALTED_BY_DBG) == 0U;

	if (data->callback != NULL) {
		/* Interrupt mode for window */
		/* Clear possible lingering interrupts */
		WDOGn_IntClear(wdog, WDOG_IEN_TOUT);
		/* Enable timeout interrupt */
		WDOGn_IntEnable(wdog, WDOG_IEN_TOUT);
	} else {
		/* Disable timeout interrupt */
		WDOGn_IntDisable(wdog, WDOG_IEN_TOUT);
	}

	/* Watchdog is started after initialization */
	WDOGn_Init(wdog, &data->wdog_config);
	LOG_DBG("Setup the watchdog");

	return 0;
}

static int wdt_gecko_disable(struct device *dev)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	struct wdt_gecko_data *data = DEV_DATA(dev);
	WDOG_TypeDef *wdog = config->base;

	WDOGn_Enable(wdog, false);
	data->timeout_installed = false;
	LOG_DBG("Disabled the watchdog");

	return 0;
}

static int wdt_gecko_install_timeout(struct device *dev,
				     const struct wdt_timeout_cfg *cfg)
{
	struct wdt_gecko_data *data = DEV_DATA(dev);
	data->wdog_config = (WDOG_Init_TypeDef)WDOG_INIT_DEFAULT;
	u32_t installed_timeout;

	if (data->timeout_installed) {
		LOG_ERR("No more timeouts can be installed");
		return -ENOMEM;
	}

	if ((cfg->window.max < wdt_gecko_get_timeout_from_persel(0)) ||
		(cfg->window.max > wdt_gecko_get_timeout_from_persel(
			WDT_GECKO_MAX_PERIOD_SELECT_VALUE))) {
		LOG_ERR("Upper limit timeout out of range");
		return -EINVAL;
	}

#if defined(_WDOG_CTRL_CLKSEL_MASK)
	data->wdog_config.clkSel = wdogClkSelULFRCO;
#endif

	data->wdog_config.perSel = (WDOG_PeriodSel_TypeDef)
		wdt_gecko_get_persel_from_timeout(cfg->window.max);

	installed_timeout = wdt_gecko_get_timeout_from_persel(
		data->wdog_config.perSel);
	LOG_INF("Installed timeout value: %u", installed_timeout);

	if (cfg->window.min > 0) {
		/* Window mode. Use rounded up timeout value to
		 * calculate minimum window setting.
		 */
		data->wdog_config.winSel = (WDOG_WinSel_TypeDef)
			wdt_gecko_convert_window(cfg->window.min,
						installed_timeout);

		LOG_INF("Installed window value: %u",
			(installed_timeout / 8) * data->wdog_config.winSel);
	} else {
		/* Normal mode */
		data->wdog_config.winSel = wdogIllegalWindowDisable;
	}

	/* Set mode of watchdog and callback */
	switch (cfg->flags) {
	case WDT_FLAG_RESET_SOC:
	case WDT_FLAG_RESET_CPU_CORE:
		if (cfg->callback != NULL) {
			LOG_ERR("Reset mode with callback not supported\n");
			return -ENOTSUP;
		}
		data->wdog_config.resetDisable = false;
		LOG_DBG("Configuring reset CPU/SoC mode\n");
		break;

	case WDT_FLAG_RESET_NONE:
		data->wdog_config.resetDisable = true;
		data->callback = cfg->callback;
		LOG_DBG("Configuring non-reset mode\n");
		break;

	default:
		LOG_ERR("Unsupported watchdog config flag");
		return -EINVAL;
	}

	data->timeout_installed = true;

	return 0;
}

static int wdt_gecko_feed(struct device *dev, int channel_id)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	WDOG_TypeDef *wdog = config->base;

	if (channel_id != 0) {
		LOG_ERR("Invalid channel id");
		return -EINVAL;
	}

	WDOGn_Feed(wdog);
	LOG_DBG("Fed the watchdog");

	return 0;
}

static void wdt_gecko_isr(void *arg)
{
	struct device *dev = (struct device *)arg;
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);
	struct wdt_gecko_data *data = DEV_DATA(dev);
	WDOG_TypeDef *wdog = config->base;
	u32_t flags;

	/* Clear IRQ flags */
	flags = WDOGn_IntGet(wdog);
	WDOGn_IntClear(wdog, flags);

	if (data->callback != NULL) {
		data->callback(dev, 0);
	}
}

static int wdt_gecko_init(struct device *dev)
{
	const struct wdt_gecko_cfg *config = DEV_CFG(dev);

#ifdef CONFIG_WDT_DISABLE_AT_BOOT
	/* Ignore any errors */
	wdt_gecko_disable(dev);
#endif

	/* Enable ULFRCO (1KHz) oscillator */
	CMU_OscillatorEnable(cmuOsc_ULFRCO, true, false);

	/* Ensure LE modules are clocked */
	CMU_ClockEnable(cmuClock_CORELE, true);

	/* Enable IRQs */
	config->irq_cfg_func();

	LOG_INF("Device %s initialized", DEV_NAME(dev));

	return 0;
}

static const struct wdt_driver_api wdt_gecko_driver_api = {
	.setup = wdt_gecko_setup,
	.disable = wdt_gecko_disable,
	.install_timeout = wdt_gecko_install_timeout,
	.feed = wdt_gecko_feed,
};

#define GECKO_WDT_INIT(index)						\
									\
	static void wdt_gecko_cfg_func_##index(void);			\
									\
	static const struct wdt_gecko_cfg wdt_gecko_cfg_##index = {	\
		.base = (WDOG_TypeDef *)				\
			DT_INST_REG_ADDR(index),\
		.irq_cfg_func = wdt_gecko_cfg_func_##index,		\
	};								\
	static struct wdt_gecko_data wdt_gecko_data_##index;		\
									\
	DEVICE_AND_API_INIT(wdt_##index,				\
				DT_INST_LABEL(index),\
				&wdt_gecko_init, &wdt_gecko_data_##index,\
				&wdt_gecko_cfg_##index, POST_KERNEL,	\
				CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,	\
				&wdt_gecko_driver_api);			\
									\
	static void wdt_gecko_cfg_func_##index(void)			\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(index),	\
			DT_INST_IRQ(index, priority),\
			wdt_gecko_isr, DEVICE_GET(wdt_##index), 0);	\
		irq_enable(DT_INST_IRQN(index));	\
	}

DT_INST_FOREACH_STATUS_OKAY(GECKO_WDT_INIT)
