/*
 * Copyright (c) 2018-2019 NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#define DT_DRV_COMPAT nxp_imx_epit

#include <drivers/counter.h>
#include <device.h>
#include "clock_freq.h"
#include "epit.h"

#define COUNTER_MAX_RELOAD	0xFFFFFFFF

struct imx_epit_config {
	struct counter_config_info info;
	EPIT_Type *base;
	uint16_t prescaler;
};

struct imx_epit_data {
	volatile counter_top_callback_t callback;
	volatile void *user_data;
};

static inline const struct imx_epit_config *get_epit_config(const struct device *dev)
{
	return CONTAINER_OF(dev->config, struct imx_epit_config,
			    info);
}

static void imx_epit_isr(const struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;
	struct imx_epit_data *driver_data = dev->data;

	EPIT_ClearStatusFlag(base);

	if (driver_data->callback != NULL) {
		driver_data->callback(dev, (void *)driver_data->user_data);
	}
}

static void imx_epit_init(const struct device *dev)
{
	struct imx_epit_config *config = (struct imx_epit_config *)
							   get_epit_config(dev);
	EPIT_Type *base = config->base;
	epit_init_config_t epit_config = {
		.freeRun     = true,
		.waitEnable  = true,
		.stopEnable  = true,
		.dbgEnable   = true,
		.enableMode  = true
	};

	/* Adjust frequency in the counter configuration info */
	config->info.freq = get_epit_clock_freq(base)/(config->prescaler + 1U);

	EPIT_Init(base, &epit_config);
}

static int imx_epit_start(const struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;

	/* Set EPIT clock source */
	EPIT_SetClockSource(base, epitClockSourcePeriph);

	/* Set prescaler */
	EPIT_SetPrescaler(base, get_epit_config(dev)->prescaler);

	/* Start the counter */
	EPIT_Enable(base);

	return 0;
}

static int imx_epit_stop(const struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;

	/* Disable EPIT */
	EPIT_Disable(base);

	return 0;
}

static int imx_epit_get_value(const struct device *dev, uint32_t *ticks)
{
	EPIT_Type *base = get_epit_config(dev)->base;

	*ticks = EPIT_GetCounterLoadValue(base) - EPIT_ReadCounter(base);

	return 0;
}

static int imx_epit_set_top_value(const struct device *dev,
				  const struct counter_top_cfg *cfg)
{
	EPIT_Type *base = get_epit_config(dev)->base;
	struct imx_epit_data *driver_data = dev->data;

	/* Disable EPIT Output Compare interrupt for consistency */
	EPIT_SetIntCmd(base, false);

	driver_data->callback = cfg->callback;
	driver_data->user_data = cfg->user_data;

	/* Set reload value and optionally counter to "ticks" */
	EPIT_SetOverwriteCounter(base,
				!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET));
	EPIT_SetCounterLoadValue(base, cfg->ticks);

	if (cfg->callback != NULL) {
		/* (Re)enable EPIT Output Compare interrupt */
		EPIT_SetIntCmd(base, true);
	}

	return 0;
}

static uint32_t imx_epit_get_pending_int(const struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;

	return EPIT_GetStatusFlag(base) ? 1U : 0U;
}

static uint32_t imx_epit_get_top_value(const struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;

	return EPIT_GetCounterLoadValue(base);
}

static uint32_t imx_epit_get_max_relative_alarm(const struct device *dev)
{
	return COUNTER_MAX_RELOAD;
}

static const struct counter_driver_api imx_epit_driver_api = {
	.start = imx_epit_start,
	.stop = imx_epit_stop,
	.get_value = imx_epit_get_value,
	.set_top_value = imx_epit_set_top_value,
	.get_pending_int = imx_epit_get_pending_int,
	.get_top_value = imx_epit_get_top_value,
	.get_max_relative_alarm = imx_epit_get_max_relative_alarm,
};

#define COUNTER_IMX_EPIT_DEVICE(idx)					       \
static int imx_epit_config_func_##idx(const struct device *dev);	       \
static const struct imx_epit_config imx_epit_##idx##z_config = {	       \
	.info = {							       \
			.max_top_value = COUNTER_MAX_RELOAD,		       \
			.freq = 1U,					       \
			.flags = 0,					       \
			.channels = 0U,					       \
		},							       \
	.base = (EPIT_Type *)DT_INST_REG_ADDR(idx),			       \
	.prescaler = DT_INST_PROP(idx, prescaler),			       \
};									       \
static struct imx_epit_data imx_epit_##idx##_data;			       \
DEVICE_DT_INST_DEFINE(idx,						       \
		    &imx_epit_config_func_##idx,			       \
		    device_pm_control_nop,				       \
		    &imx_epit_##idx##_data, &imx_epit_##idx##z_config.info,    \
		    PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,	       \
		    &imx_epit_driver_api);				       \
static int imx_epit_config_func_##idx(const struct device *dev)		       \
{									       \
	imx_epit_init(dev);						       \
	IRQ_CONNECT(DT_INST_IRQN(idx),					       \
		    DT_INST_IRQ(idx, priority),				       \
		    imx_epit_isr, DEVICE_DT_INST_GET(idx), 0);		       \
	irq_enable(DT_INST_IRQN(idx));					       \
	return 0;							       \
}

DT_INST_FOREACH_STATUS_OKAY(COUNTER_IMX_EPIT_DEVICE)
