/*
 *
 * Copyright (c) 2018, NXP

 * SPDX-License-Identifier: Apache-2.0
 */

#include <drivers/watchdog.h>
#include <drivers/clock_control.h>
#include <fsl_wdog.h>

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

#define MIN_TIMEOUT 4

struct mcux_wdog_config {
	WDOG_Type *base;
	char *clock_name;
	clock_control_subsys_t clock_subsys;
	void (*irq_config_func)(struct device *dev);
};

struct mcux_wdog_data {
	wdt_callback_t callback;
	wdog_config_t wdog_config;
	bool timeout_valid;
};

static int mcux_wdog_setup(struct device *dev, u8_t options)
{
	const struct mcux_wdog_config *config = dev->config->config_info;
	struct mcux_wdog_data *data = dev->driver_data;
	WDOG_Type *base = config->base;

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

	data->wdog_config.workMode.enableStop =
		(options & WDT_OPT_PAUSE_IN_SLEEP) == 0U;

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

	WDOG_Init(base, &data->wdog_config);
	LOG_DBG("Setup the watchdog");

	return 0;
}

static int mcux_wdog_disable(struct device *dev)
{
	const struct mcux_wdog_config *config = dev->config->config_info;
	struct mcux_wdog_data *data = dev->driver_data;
	WDOG_Type *base = config->base;

	WDOG_Deinit(base);
	data->timeout_valid = false;
	LOG_DBG("Disabled the watchdog");

	return 0;
}

static int mcux_wdog_install_timeout(struct device *dev,
				     const struct wdt_timeout_cfg *cfg)
{
	const struct mcux_wdog_config *config = dev->config->config_info;
	struct mcux_wdog_data *data = dev->driver_data;
	struct device *clock_dev;
	u32_t clock_freq;

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

	clock_dev = device_get_binding(config->clock_name);
	if (clock_dev == NULL) {
		return -EINVAL;
	}

	if (clock_control_get_rate(clock_dev, config->clock_subsys,
				   &clock_freq)) {
		return -EINVAL;
	}

	WDOG_GetDefaultConfig(&data->wdog_config);

	data->wdog_config.timeoutValue = clock_freq * cfg->window.max / 1000U;

	if (cfg->window.min) {
		data->wdog_config.enableWindowMode = true;
		data->wdog_config.windowValue =
			clock_freq * cfg->window.min / 1000U;
	} else {
		data->wdog_config.enableWindowMode = false;
		data->wdog_config.windowValue = 0;
	}

	if ((data->wdog_config.timeoutValue < MIN_TIMEOUT) ||
	    (data->wdog_config.timeoutValue < data->wdog_config.windowValue)) {
		LOG_ERR("Invalid timeout");
		return -EINVAL;
	}

	data->wdog_config.clockSource = kWDOG_LpoClockSource;
	data->wdog_config.enableInterrupt = cfg->callback != NULL;
	data->callback = cfg->callback;
	data->timeout_valid = true;

	return 0;
}

static int mcux_wdog_feed(struct device *dev, int channel_id)
{
	const struct mcux_wdog_config *config = dev->config->config_info;
	WDOG_Type *base = config->base;

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

	WDOG_Refresh(base);
	LOG_DBG("Fed the watchdog");

	return 0;
}

static void mcux_wdog_isr(void *arg)
{
	struct device *dev = (struct device *)arg;
	const struct mcux_wdog_config *config = dev->config->config_info;
	struct mcux_wdog_data *data = dev->driver_data;
	WDOG_Type *base = config->base;
	u32_t flags;

	flags = WDOG_GetStatusFlags(base);
	WDOG_ClearStatusFlags(base, flags);

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

static int mcux_wdog_init(struct device *dev)
{
	const struct mcux_wdog_config *config = dev->config->config_info;

	config->irq_config_func(dev);

	return 0;
}

static const struct wdt_driver_api mcux_wdog_api = {
	.setup = mcux_wdog_setup,
	.disable = mcux_wdog_disable,
	.install_timeout = mcux_wdog_install_timeout,
	.feed = mcux_wdog_feed,
};

static void mcux_wdog_config_func_0(struct device *dev);

static const struct mcux_wdog_config mcux_wdog_config_0 = {
	.base = (WDOG_Type *) DT_WDT_0_BASE_ADDRESS,
	.clock_name = DT_WDT_0_CLOCK_NAME,
	.clock_subsys = (clock_control_subsys_t) DT_WDT_0_CLOCK_SUBSYS,
	.irq_config_func = mcux_wdog_config_func_0,
};

static struct mcux_wdog_data mcux_wdog_data_0;

DEVICE_AND_API_INIT(mcux_wdog_0, DT_INST_0_NXP_KINETIS_WDOG_LABEL,
		    &mcux_wdog_init,
		    &mcux_wdog_data_0, &mcux_wdog_config_0,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &mcux_wdog_api);

static void mcux_wdog_config_func_0(struct device *dev)
{
	IRQ_CONNECT(DT_WDT_0_IRQ, DT_WDT_0_IRQ_PRI,
		    mcux_wdog_isr, DEVICE_GET(mcux_wdog_0), 0);

	irq_enable(DT_WDT_0_IRQ);
}
