/*
 * Copyright (c) 2019, Linaro Limited.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <counter.h>
#include <fsl_gpt.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(mcux_gpt, CONFIG_COUNTER_LOG_LEVEL);

struct mcux_gpt_config {
	/* info must be first element */
	struct counter_config_info info;
	GPT_Type *base;
	clock_name_t clock_source;
};

struct mcux_gpt_data {
	counter_alarm_callback_t alarm_callback;
	counter_top_callback_t top_callback;
	void *alarm_user_data;
	void *top_user_data;
};

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

	GPT_StartTimer(config->base);

	return 0;
}

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

	GPT_StopTimer(config->base);

	return 0;
}

static u32_t mcux_gpt_read(struct device *dev)
{
	const struct mcux_gpt_config *config = dev->config->config_info;

	return GPT_GetCurrentTimerCount(config->base);
}

static int mcux_gpt_set_alarm(struct device *dev, u8_t chan_id,
			      const struct counter_alarm_cfg *alarm_cfg)
{
	const struct mcux_gpt_config *config = dev->config->config_info;
	struct mcux_gpt_data *data = dev->driver_data;

	u32_t current = mcux_gpt_read(dev);
	u32_t ticks = alarm_cfg->ticks;

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

	if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
		ticks += current;
	}

	if (data->alarm_callback) {
		return -EBUSY;
	}

	data->alarm_callback = alarm_cfg->callback;
	data->alarm_user_data = alarm_cfg->user_data;

	GPT_SetOutputCompareValue(config->base, kGPT_OutputCompare_Channel1,
				  ticks);
	GPT_EnableInterrupts(config->base, kGPT_OutputCompare1InterruptEnable);

	return 0;
}

static int mcux_gpt_cancel_alarm(struct device *dev, u8_t chan_id)
{
	const struct mcux_gpt_config *config = dev->config->config_info;
	struct mcux_gpt_data *data = dev->driver_data;

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

	GPT_DisableInterrupts(config->base, kGPT_OutputCompare1InterruptEnable);
	data->alarm_callback = NULL;

	return 0;
}

void mcux_gpt_isr(void *p)
{
	struct device *dev = p;
	const struct mcux_gpt_config *config = dev->config->config_info;
	struct mcux_gpt_data *data = dev->driver_data;
	u32_t current = mcux_gpt_read(dev);
	u32_t status;

	status =  GPT_GetStatusFlags(config->base, kGPT_OutputCompare1Flag |
				     kGPT_RollOverFlag);
	GPT_ClearStatusFlags(config->base, status);
	__DSB();

	if ((status & kGPT_OutputCompare1Flag) && data->alarm_callback) {
		GPT_DisableInterrupts(config->base,
				      kGPT_OutputCompare1InterruptEnable);
		counter_alarm_callback_t alarm_cb = data->alarm_callback;
		data->alarm_callback = NULL;
		alarm_cb(dev, 0, current, data->alarm_user_data);
	}

	if ((status & kGPT_RollOverFlag) && data->top_callback) {
		data->top_callback(dev, data->top_user_data);
	}
}

static u32_t mcux_gpt_get_pending_int(struct device *dev)
{
	const struct mcux_gpt_config *config = dev->config->config_info;

	return GPT_GetStatusFlags(config->base, kGPT_OutputCompare1Flag);
}

static int mcux_gpt_set_top_value(struct device *dev,
				  const struct counter_top_cfg *cfg)
{
	const struct mcux_gpt_config *config = dev->config->config_info;
	struct mcux_gpt_data *data = dev->driver_data;

	if (cfg->ticks != config->info.max_top_value) {
		LOG_ERR("Wrap can only be set to 0x%x",
			config->info.max_top_value);
		return -ENOTSUP;
	}

	data->top_callback = cfg->callback;
	data->top_user_data = cfg->user_data;

	GPT_EnableInterrupts(config->base, kGPT_RollOverFlagInterruptEnable);

	return 0;
}

static u32_t mcux_gpt_get_top_value(struct device *dev)
{
	const struct mcux_gpt_config *config = dev->config->config_info;

	return config->info.max_top_value;
}

static u32_t mcux_gpt_get_max_relative_alarm(struct device *dev)
{
	const struct mcux_gpt_config *config = dev->config->config_info;

	return config->info.max_top_value;
}

static int mcux_gpt_init(struct device *dev)
{
	const struct mcux_gpt_config *config = dev->config->config_info;
	gpt_config_t gptConfig;
	u32_t clock_freq;

	/* Adjust divider to match expected freq */
	clock_freq = CLOCK_GetFreq(config->clock_source);
	if (clock_freq % config->info.freq) {
		LOG_ERR("Cannot Adjust GPT freq to %u\n", config->info.freq);
		return -EINVAL;
	}

	GPT_GetDefaultConfig(&gptConfig);
	gptConfig.enableFreeRun = true; /* Do not reset on compare */
	gptConfig.clockSource = kGPT_ClockSource_Periph;
	gptConfig.divider = clock_freq / config->info.freq;
	GPT_Init(config->base, &gptConfig);

	return 0;
}

static const struct counter_driver_api mcux_gpt_driver_api = {
	.start = mcux_gpt_start,
	.stop = mcux_gpt_stop,
	.read = mcux_gpt_read,
	.set_alarm = mcux_gpt_set_alarm,
	.cancel_alarm = mcux_gpt_cancel_alarm,
	.set_top_value = mcux_gpt_set_top_value,
	.get_pending_int = mcux_gpt_get_pending_int,
	.get_top_value = mcux_gpt_get_top_value,
	.get_max_relative_alarm = mcux_gpt_get_max_relative_alarm,
};

#define GPT_DEVICE_INIT_MCUX(n)			  \
	static struct mcux_gpt_data mcux_gpt_data_ ## n;			\
										\
	static const struct mcux_gpt_config mcux_gpt_config_ ## n = {    	\
		.base = (void *)DT_COUNTER_MCUX_GPT_ ## n ## _BASE_ADDRESS,	\
		.clock_source = kCLOCK_PerClk,					\
		.info = {							\
			.max_top_value = UINT32_MAX,				\
			.freq = 25000000,					\
			.channels = 1,						\
		},								\
	};									\
										\
	static int mcux_gpt_## n ##_init(struct device *dev);			\
	DEVICE_AND_API_INIT(mcux_gpt ## n,					\
			    DT_COUNTER_MCUX_GPT_ ## n ## _NAME,			\
			    mcux_gpt_## n ##_init,				\
			    &mcux_gpt_data_ ## n,				\
			    &mcux_gpt_config_ ## n,				\
			    POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,	\
			    &mcux_gpt_driver_api);				\
										\
	static int mcux_gpt_## n ##_init(struct device *dev)			\
	{	 								\
		IRQ_CONNECT(DT_COUNTER_MCUX_GPT_## n ##_IRQ,			\
			    DT_COUNTER_MCUX_GPT_## n ##_IRQ_PRI,		\
			    mcux_gpt_isr, DEVICE_GET(mcux_gpt ## n), 0);	\
		irq_enable(DT_COUNTER_MCUX_GPT_## n ##_IRQ);			\
		return mcux_gpt_init(dev);					\
	}									\

#ifdef CONFIG_COUNTER_MCUX_GPT1
GPT_DEVICE_INIT_MCUX(1)
#endif

#ifdef CONFIG_COUNTER_MCUX_GPT2
GPT_DEVICE_INIT_MCUX(2)
#endif
