/*
 * Copyright (C) 2020, NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_imx_wdog

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

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

#define WDOG_TMOUT_SEC(x)  (((x * 2) / MSEC_PER_SEC) - 1)

struct mcux_wdog_config {
	WDOG_Type *base;
	void (*irq_config_func)(const struct device *dev);
};

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

static int mcux_wdog_setup(const struct device *dev, uint8_t options)
{
	const struct mcux_wdog_config *config = dev->config;
	struct mcux_wdog_data *data = dev->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(const struct device *dev)
{
	const struct mcux_wdog_config *config = dev->config;
	struct mcux_wdog_data *data = dev->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(const struct device *dev,
				     const struct wdt_timeout_cfg *cfg)
{
	struct mcux_wdog_data *data = dev->data;

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

	WDOG_GetDefaultConfig(&data->wdog_config);
	data->wdog_config.interruptTimeValue = 0U;

	if (cfg->window.max < (MSEC_PER_SEC / 2)) {
		LOG_ERR("Invalid window max, shortest window is 500ms");
		return -EINVAL;
	}

	data->wdog_config.timeoutValue =
		  WDOG_TMOUT_SEC(cfg->window.max);

	if (cfg->window.min) {
		LOG_ERR("Invalid window.min, Do not support window model");
		return -EINVAL;
	}
	if (data->wdog_config.timeoutValue > 128) {
		LOG_ERR("Invalid timeoutValue, valid (0.5s - 128.0s)");
		return -EINVAL;
	}

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

	return 0;
}

static int mcux_wdog_feed(const struct device *dev, int channel_id)
{
	const struct mcux_wdog_config *config = dev->config;
	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(const struct device *dev)
{
	const struct mcux_wdog_config *config = dev->config;
	struct mcux_wdog_data *data = dev->data;
	WDOG_Type *base = config->base;
	uint32_t flags;

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

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

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

	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(const struct device *dev);

static const struct mcux_wdog_config mcux_wdog_config = {
	.base = (WDOG_Type *) DT_INST_REG_ADDR(0),
	.irq_config_func = mcux_wdog_config_func,
};

static struct mcux_wdog_data mcux_wdog_data;

DEVICE_DT_INST_DEFINE(0,
		    &mcux_wdog_init,
		    NULL,
		    &mcux_wdog_data, &mcux_wdog_config,
		    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &mcux_wdog_api);

static void mcux_wdog_config_func(const struct device *dev)
{
	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    mcux_wdog_isr, DEVICE_DT_INST_GET(0), 0);

	irq_enable(DT_INST_IRQN(0));
}
