/*
 * Copyright (c) 2018 Workaround GmbH
 * Copyright (c) 2018 Allterco Robotics
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Source file for the STM32 RTC driver
 *
 */

#include <time.h>

#include <clock_control/stm32_clock_control.h>
#include <drivers/clock_control.h>
#include <sys/util.h>
#include <kernel.h>
#include <soc.h>
#include <drivers/rtc.h>

#if defined(CONFIG_SOC_SERIES_STM32L4X)
#define EXTI_LINE	LL_EXTI_LINE_18
#elif defined(CONFIG_SOC_SERIES_STM32F4X) \
	|| defined(CONFIG_SOC_SERIES_STM32F3X)	\
	|| defined(CONFIG_SOC_SERIES_STM32F7X)
#define EXTI_LINE	LL_EXTI_LINE_17
#endif

#define EPOCH_OFFSET 946684800

struct rtc_stm32_config {
	struct stm32_pclken pclken;
	LL_RTC_InitTypeDef ll_rtc_config;
};

struct rtc_stm32_data {
	void (*cb_fn)(struct device *dev);
	struct k_sem sem;
};


#define DEV_DATA(dev) ((struct rtc_stm32_data *const)(dev)->driver_data)
#define DEV_SEM(dev) (&DEV_DATA(dev)->sem)
#define DEV_CFG(dev)	\
((const struct rtc_stm32_config * const)(dev)->config->config_info)

static int rtc_stm32_set_alarm(struct device *dev, const u32_t alarm_val);
static void rtc_stm32_irq_config(struct device *dev);

static void rtc_stm32_enable(struct device *dev)
{
	LL_RCC_EnableRTC();
}

static void rtc_stm32_disable(struct device *dev)
{
	LL_RCC_DisableRTC();
}

static u32_t rtc_stm32_read(struct device *dev)
{
	struct tm now = { 0 };
	time_t ts;
	u32_t rtc_date, rtc_time;

	/* Read time and date registers */
	rtc_time = LL_RTC_TIME_Get(RTC);
	rtc_date = LL_RTC_DATE_Get(RTC);

	/* Convert calendar datetime to UNIX timestamp */
	now.tm_year = 100 + __LL_RTC_CONVERT_BCD2BIN(
					__LL_RTC_GET_YEAR(rtc_date));
	/* tm_mon starts from 0 */
	now.tm_mon = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MONTH(rtc_date)) - 1;
	now.tm_mday = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_DAY(rtc_date));

	now.tm_hour = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_HOUR(rtc_time));
	now.tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time));
	now.tm_sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(rtc_time));

	ts = mktime(&now);

	/* Return number of seconds since 2000-01-01 00:00:00 */
	ts -= EPOCH_OFFSET;

	return (u32_t)ts;
}

static int rtc_stm32_set_alarm(struct device *dev, const u32_t alarm_val)
{
	struct tm alarm_tm;
	time_t alarm_ts;
	LL_RTC_AlarmTypeDef rtc_alarm;

	u32_t now = rtc_stm32_read(dev);

	/* The longest period we can match for universally is the
	   duration of the shortest month */
	if ((alarm_val - now) > (RTC_ALARM_DAY * 28)) {
		return -ENOTSUP;
	}

	/* Convert seconds since 2000-01-01 00:00:00 to calendar datetime */
	alarm_ts = alarm_val;
	alarm_ts += EPOCH_OFFSET;
	gmtime_r(&alarm_ts, &alarm_tm);

	/* Apply ALARM_A */
	rtc_alarm.AlarmTime.TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
	rtc_alarm.AlarmTime.Hours = alarm_tm.tm_hour;
	rtc_alarm.AlarmTime.Minutes = alarm_tm.tm_min;
	rtc_alarm.AlarmTime.Seconds = alarm_tm.tm_sec;

	rtc_alarm.AlarmMask = LL_RTC_ALMA_MASK_NONE;
	rtc_alarm.AlarmDateWeekDaySel = LL_RTC_ALMA_DATEWEEKDAYSEL_DATE;
	rtc_alarm.AlarmDateWeekDay = alarm_tm.tm_mday;

	LL_RTC_DisableWriteProtection(RTC);
	LL_RTC_ALMA_Disable(RTC);

	if (LL_RTC_ALMA_Init(RTC, LL_RTC_FORMAT_BIN, &rtc_alarm) != SUCCESS) {
		return -EIO;
	}

	LL_RTC_DisableWriteProtection(RTC);

	LL_RTC_ALMA_Enable(RTC);
	LL_RTC_ClearFlag_ALRA(RTC);
	LL_RTC_EnableIT_ALRA(RTC);

	LL_RTC_EnableWriteProtection(RTC);

	return 0;
}

static int rtc_stm32_set_config(struct device *dev, struct rtc_config *cfg)
{
	int result = 0;
	time_t init_ts = 0;
	struct tm init_tm = { 0 };

	LL_RTC_DateTypeDef rtc_date = { 0 };
	LL_RTC_TimeTypeDef rtc_time = { 0 };

	/* Convert seconds since 2000-01-01 00:00:00 to calendar datetime */
	init_ts = cfg->init_val;
	init_ts += EPOCH_OFFSET;

	gmtime_r(&init_ts, &init_tm);

	rtc_date.Year = init_tm.tm_year % 100;
	/* tm_mon starts from 0 */
	rtc_date.Month = init_tm.tm_mon + 1;
	rtc_date.Day = init_tm.tm_mday;
	rtc_date.WeekDay = init_tm.tm_wday + 1;

	rtc_time.TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
	rtc_time.Hours = init_tm.tm_hour;
	rtc_time.Minutes = init_tm.tm_min;
	rtc_time.Seconds = init_tm.tm_sec;

	k_sem_take(DEV_SEM(dev), K_FOREVER);

	if (cfg->cb_fn != NULL) {
		DEV_DATA(dev)->cb_fn = cfg->cb_fn;
	}

	if (LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BIN, &rtc_date) != SUCCESS) {
		result = -EIO;
		goto fin;
	}

	if (LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BIN, &rtc_time) != SUCCESS) {
		result = -EIO;
		goto fin;
	}

	if (cfg->alarm_enable) {
		rtc_stm32_set_alarm(dev, cfg->alarm_val);
	}

fin:
	k_sem_give(DEV_SEM(dev));

	return result;
}

static u32_t rtc_stm32_get_pending_int(struct device *dev)
{
	return LL_RTC_IsActiveFlag_ALRA(RTC) != 0;
}

void rtc_stm32_isr(void *arg)
{
	struct device *const dev = (struct device *)arg;

	if (LL_RTC_IsActiveFlag_ALRA(RTC) != 0) {

		if (DEV_DATA(dev)->cb_fn != NULL) {
			DEV_DATA(dev)->cb_fn(dev);
		}

		LL_RTC_ClearFlag_ALRA(RTC);
		LL_RTC_DisableIT_ALRA(RTC);
	}

	LL_EXTI_ClearFlag_0_31(EXTI_LINE);
}

static int rtc_stm32_init(struct device *dev)
{
	struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
	const struct rtc_stm32_config *cfg = DEV_CFG(dev);

	__ASSERT_NO_MSG(clk);

	k_sem_init(DEV_SEM(dev), 1, UINT_MAX);
	DEV_DATA(dev)->cb_fn = NULL;

	if (clock_control_on(clk,
		(clock_control_subsys_t *) &cfg->pclken) != 0) {
		return -EIO;
	}

	LL_PWR_EnableBkUpAccess();
	LL_RCC_ForceBackupDomainReset();
	LL_RCC_ReleaseBackupDomainReset();

#if defined(CONFIG_RTC_STM32_CLOCK_LSI)

	LL_RCC_LSI_Enable();
	while (LL_RCC_LSI_IsReady() != 1) {
	}

	LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);

#else /* CONFIG_RTC_STM32_CLOCK_LSE */

	LL_RCC_LSE_SetDriveCapability(CONFIG_RTC_STM32_LSE_DRIVE_STRENGTH);
	LL_RCC_LSE_Enable();

	/* Wait until LSE is ready */
	while (LL_RCC_LSE_IsReady() != 1) {
	}

	LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);

#endif

	LL_RCC_EnableRTC();

	if (LL_RTC_DeInit(RTC) != SUCCESS) {
		return -EIO;
	}

	if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)
			      &cfg->ll_rtc_config)) != SUCCESS) {
		return -EIO;
	}

	LL_RTC_EnableShadowRegBypass(RTC);

	LL_EXTI_EnableIT_0_31(EXTI_LINE);
	LL_EXTI_EnableRisingTrig_0_31(EXTI_LINE);

	rtc_stm32_irq_config(dev);

	return 0;
}

static struct rtc_stm32_data rtc_data;

static const struct rtc_stm32_config rtc_config = {
	.pclken = {
		.enr = LL_APB1_GRP1_PERIPH_PWR,
		.bus = STM32_CLOCK_BUS_APB1,
	},
	.ll_rtc_config = {
		.HourFormat = LL_RTC_HOURFORMAT_24HOUR,

#if defined(CONFIG_RTC_STM32_CLOCK_LSI)

		/* prescaler values for LSI @ 32 KHz */
		.AsynchPrescaler = 0x7F,
		.SynchPrescaler = 0x00F9,

#else /* CONFIG_RTC_STM32_CLOCK_LSE */

		/* prescaler values for LSE @ 32768 Hz */
		.AsynchPrescaler = 0x7F,
		.SynchPrescaler = 0x00FF,
#endif

	},
};

static const struct rtc_driver_api rtc_api = {
		.enable = rtc_stm32_enable,
		.disable = rtc_stm32_disable,
		.read = rtc_stm32_read,
		.set_config = rtc_stm32_set_config,
		.set_alarm = rtc_stm32_set_alarm,
		.get_pending_int = rtc_stm32_get_pending_int,
};

DEVICE_AND_API_INIT(rtc_stm32, CONFIG_RTC_0_NAME, &rtc_stm32_init,
		    &rtc_data, &rtc_config, PRE_KERNEL_1,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &rtc_api);

static void rtc_stm32_irq_config(struct device *dev)
{
	IRQ_CONNECT(DT_RTC_0_IRQ, DT_RTC_0_IRQ_PRI,
		    rtc_stm32_isr, DEVICE_GET(rtc_stm32), 0);
	irq_enable(DT_RTC_0_IRQ);
}
