/*
 * 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;
	u16_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(struct device *dev)
{
	return CONTAINER_OF(dev->config_info, struct imx_epit_config,
			    info);
}

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

	EPIT_ClearStatusFlag(base);

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

static void imx_epit_init(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(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(struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;

	/* Disable EPIT */
	EPIT_Disable(base);

	return 0;
}

static int imx_epit_get_value(struct device *dev, u32_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(struct device *dev,
				  const struct counter_top_cfg *cfg)
{
	EPIT_Type *base = get_epit_config(dev)->base;
	struct imx_epit_data *driver_data = dev->driver_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 u32_t imx_epit_get_pending_int(struct device *dev)
{
	EPIT_Type *base = get_epit_config(dev)->base;

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

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

	return EPIT_GetCounterLoadValue(base);
}

static u32_t imx_epit_get_max_relative_alarm(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(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_AND_API_INIT(epit_##idx, DT_INST_LABEL(idx),			       \
		    &imx_epit_config_func_##idx,			       \
		    &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(struct device *dev)		       \
{									       \
	imx_epit_init(dev);						       \
	IRQ_CONNECT(DT_INST_IRQN(idx),					       \
		    DT_INST_IRQ(idx, priority),				       \
		    imx_epit_isr, DEVICE_GET(epit_##idx), 0);		       \
	irq_enable(DT_INST_IRQN(idx));					       \
	return 0;							       \
}

DT_INST_FOREACH_STATUS_OKAY(COUNTER_IMX_EPIT_DEVICE)
