/*
 * Copyright (c) 2018 blik GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define LOG_LEVEL CONFIG_RTC_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(rtc_mcux);

#include <errno.h>
#include <device.h>
#include <init.h>
#include <kernel.h>
#include <rtc.h>
#include <power.h>
#include <soc.h>
#include <misc/util.h>
#include <fsl_rtc.h>

struct mcux_rtc_config {
	RTC_Type *base;
	void (*irq_config_func)(struct device *dev);
};

struct mcux_rtc_data {
	struct k_sem sync;
	rtc_config_t config;

	/* callback information */
	void (*callback)(void *data);
	void *callback_data;
};

static void mcux_rtc_enable(struct device *dev)
{
	const struct mcux_rtc_config *config = dev->config->config_info;

	RTC_StartTimer(config->base);
	RTC_EnableInterrupts(config->base,
		kRTC_AlarmInterruptEnable |
		kRTC_TimeOverflowInterruptEnable |
		kRTC_TimeInvalidInterruptEnable);
}

static void mcux_rtc_disable(struct device *dev)
{
	const struct mcux_rtc_config *config = dev->config->config_info;

	RTC_DisableInterrupts(config->base,
			      kRTC_AlarmInterruptEnable |
			      kRTC_TimeOverflowInterruptEnable |
			      kRTC_TimeInvalidInterruptEnable);
	RTC_StopTimer(config->base);

	/* clear out any set alarms */
	config->base->TAR = 0;
}

static int mcux_rtc_set_alarm(struct device *dev, const u32_t alarm_val)
{
	const struct mcux_rtc_config *config = dev->config->config_info;

	if (alarm_val < config->base->TSR) {
		LOG_ERR("alarm cannot be earlier than current time");
		return -EINVAL;
	}

	config->base->TAR = alarm_val;
	return 0;
}

static int mcux_rtc_set_config(struct device *dev, struct rtc_config *cfg)
{
	const struct mcux_rtc_config *config = dev->config->config_info;
	struct mcux_rtc_data *data = dev->driver_data;
	int ret = 0;

	/* only allow one modifier at a time */
	k_sem_take(&data->sync, K_FOREVER);

	if (cfg->alarm_enable) {
		/* set up callback information */
		data->callback = (void *) cfg->cb_fn;
		data->callback_data = dev;

		RTC_StopTimer(config->base);
		config->base->TSR = cfg->init_val;
		RTC_StartTimer(config->base);
		ret = mcux_rtc_set_alarm(dev, cfg->alarm_val);
	} else {
		/* clear any existing alarm setting */
		config->base->TAR = 0;

		/* clear callbacks */
		data->callback = NULL;
		data->callback_data = NULL;
	}

	k_sem_give(&data->sync);

	return ret;
}

static u32_t mcux_rtc_read(struct device *dev)
{
	const struct mcux_rtc_config *config = dev->config->config_info;
	u32_t val = config->base->TSR;

	/*
	 * Read TSR seconds twice in case it glitches during an update.
	 * This can happen when a read occurs at the time the register is
	 * incrementing.
	 */
	if (config->base->TSR == val) {
		return val;
	}

	val = config->base->TSR;

	return val;
}

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

	return RTC_GetStatusFlags(config->base) & RTC_SR_TAF_MASK;
}

static const struct rtc_driver_api mcux_rtc_driver_api = {
	.enable = mcux_rtc_enable,
	.disable = mcux_rtc_disable,
	.read = mcux_rtc_read,
	.set_config = mcux_rtc_set_config,
	.set_alarm = mcux_rtc_set_alarm,
	.get_pending_int = mcux_rtc_get_pending_int,
};

static void mcux_rtc_isr(void *arg)
{
	struct device *dev = arg;
	const struct mcux_rtc_config *config = dev->config->config_info;
	struct mcux_rtc_data *data = dev->driver_data;

	/* perform any registered callbacks */
	if (data->callback) {
		data->callback(data->callback_data);
	}

	/*
	 * Clear any conditions to ack the IRQ
	 *
	 * callback may have already reset the alarm flag if a new
	 * alarm value was programmed to the TAR
	 */
	RTC_StopTimer(config->base);
	if (RTC_GetStatusFlags(config->base) & RTC_SR_TAF_MASK) {
		RTC_ClearStatusFlags(config->base, kRTC_AlarmFlag);
	} else if (RTC_GetStatusFlags(config->base) & RTC_SR_TIF_MASK) {
		RTC_ClearStatusFlags(config->base, kRTC_TimeInvalidFlag);
	} else if (RTC_GetStatusFlags(config->base) & RTC_SR_TOF_MASK) {
		RTC_ClearStatusFlags(config->base, kRTC_TimeOverflowFlag);
	}
	RTC_StartTimer(config->base);
}

static int mcux_rtc_init(struct device *dev)
{
	const struct mcux_rtc_config *config = dev->config->config_info;
	struct mcux_rtc_data *data = dev->driver_data;

	k_sem_init(&data->sync, 1, UINT_MAX);

	/* Create default configuration and store it off */
	RTC_GetDefaultConfig(&data->config);
	RTC_Init(config->base, &data->config);

	/* Enable 32kHz oscillator and wait for 1ms to settle */
	config->base->CR |= 0x100;
	k_busy_wait(USEC_PER_MSEC);

	/* connect and enable the IRQ line */
	config->irq_config_func(dev);
	return 0;
}

static struct mcux_rtc_data rtc_mcux_data_0;

static void rtc_mcux_irq_config_0(struct device *dev);

static struct mcux_rtc_config rtc_mcux_config_0 = {
	.base = (RTC_Type *)DT_RTC_MCUX_0_BASE_ADDRESS,
	.irq_config_func = rtc_mcux_irq_config_0,
};

DEVICE_DEFINE(rtc, DT_RTC_MCUX_0_NAME,
	      &mcux_rtc_init, NULL, &rtc_mcux_data_0, &rtc_mcux_config_0,
	      POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
	      &mcux_rtc_driver_api);

static void rtc_mcux_irq_config_0(struct device *dev)
{
	IRQ_CONNECT(DT_RTC_MCUX_0_IRQ, DT_RTC_MCUX_0_IRQ_PRI,
		    mcux_rtc_isr, DEVICE_GET(rtc), 0);
	irq_enable(DT_RTC_MCUX_0_IRQ);
}
