[PATCH 1/1] rtc: mediatek: Add mt6685 RTC driver

shunxi zhang ot_shunxi.zhang at mediatek.com
Thu Oct 31 06:58:02 PDT 2024


From: Shunxi Zhang <ot_shunxi.zhang at mediatek.com>

Signed-off-by: Shunxi Zhang <ot_shunxi.zhang at mediatek.com>
---
 drivers/rtc/Kconfig                  |   10 +
 drivers/rtc/Makefile                 |    1 +
 drivers/rtc/rtc-mt6685.c             | 1456 ++++++++++++++++++++++++++
 include/linux/mfd/mt6685-audclk.h    |   11 +
 include/linux/mfd/mt6685/core.h      |   22 +
 include/linux/mfd/mt6685/registers.h |  921 ++++++++++++++++
 include/linux/mfd/mt6685/rtc.h       |  318 ++++++
 7 files changed, 2739 insertions(+)
 create mode 100644 drivers/rtc/rtc-mt6685.c
 create mode 100644 include/linux/mfd/mt6685-audclk.h
 create mode 100644 include/linux/mfd/mt6685/core.h
 create mode 100644 include/linux/mfd/mt6685/registers.h
 create mode 100644 include/linux/mfd/mt6685/rtc.h

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 66eb1122248b..7af04dfac978 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1898,6 +1898,16 @@ config RTC_DRV_MT6397
 
 	  If you want to use MediaTek(R) RTC interface, select Y or M here.
 
+config RTC_DRV_MT6685
+	tristate "Mediatek Real Time Clock driver"
+	depends on MFD_MT6685 || (COMPILE_TEST && IRQ_DOMAIN)
+	help
+	  This selects the Mediatek(R) RTC driver. RTC is part of Mediatek
+	  MT6685. You should enable MT6685 MFD before select
+	  Mediatek(R) RTC driver.
+
+	  If you want to use Mediatek(R) RTC interface, select Y or M here.
+
 config RTC_DRV_MT7622
 	tristate "MediaTek SoC based RTC"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index f62340ecc534..ec982192526d 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -110,6 +110,7 @@ obj-$(CONFIG_RTC_DRV_SSD202D)	+= rtc-ssd202d.o
 obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
 obj-$(CONFIG_RTC_DRV_MT2712)	+= rtc-mt2712.o
 obj-$(CONFIG_RTC_DRV_MT6397)	+= rtc-mt6397.o
+obj-$(CONFIG_RTC_DRV_MT6685)	+= rtc-mt6685.o
 obj-$(CONFIG_RTC_DRV_MT7622)	+= rtc-mt7622.o
 obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
 obj-$(CONFIG_RTC_DRV_MXC)	+= rtc-mxc.o
diff --git a/drivers/rtc/rtc-mt6685.c b/drivers/rtc/rtc-mt6685.c
new file mode 100644
index 000000000000..a3aa747a788a
--- /dev/null
+++ b/drivers/rtc/rtc-mt6685.c
@@ -0,0 +1,1456 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ * Author: Amber Lin <Mw.lin at mediatek.com>
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/rtc.h>
+#include <linux/mfd/mt6685/rtc.h>
+#include <linux/mfd/mt6685/core.h>
+#include <linux/mfd/mt6685/registers.h>
+#include <linux/nvmem-provider.h>
+#include <linux/sched/clock.h>
+#include <linux/spmi.h>
+
+#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
+#include <mt-plat/aee.h>
+#endif
+
+#ifdef SUPPORT_PWR_OFF_ALARM
+#include <linux/notifier.h>
+#include <linux/suspend.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/jiffies.h>
+#include <linux/cpumask.h>
+#include <linux/reboot.h>
+#endif
+
+/*debug information*/
+static int rtc_show_time;
+static int rtc_show_alarm;
+
+module_param(rtc_show_time, int, 0644);
+module_param(rtc_show_alarm, int, 0644);
+
+static int mtk_rtc_write_trigger(struct mt6685_rtc *rtc);
+
+static int counter;
+
+static void power_on_mclk(struct mt6685_rtc *rtc)
+{
+	mutex_lock(&rtc->clk_lock);
+	/*Power on RTC MCLK and 32k clk before write RTC register*/
+	regmap_write(rtc->regmap, RG_RTC_32K_CK_PDN_CLR, RG_RTC_32K_CK_PDN_MASK);
+	regmap_write(rtc->regmap, RG_RTC_MCLK_PDN_CLR, RG_RTC_MCLK_PDN_MASK);
+	counter++;
+	mdelay(1);
+	mutex_unlock(&rtc->clk_lock);
+}
+
+static void power_down_mclk(struct mt6685_rtc *rtc)
+{
+	mutex_lock(&rtc->clk_lock);
+	counter--;
+	if (counter < 0) {
+		//dump_stack();
+		pr_info("mclk_counter[%d]\n", counter);
+	}
+	if (counter == 0) {
+		/*Power down RTC MCLK and 32k clk after write RTC register*/
+		regmap_write(rtc->regmap, RG_RTC_32K_CK_PDN_SET, RG_RTC_32K_CK_PDN_MASK);
+		regmap_write(rtc->regmap, RG_RTC_MCLK_PDN_SET, RG_RTC_MCLK_PDN_MASK);
+		mdelay(1);
+	}
+	mutex_unlock(&rtc->clk_lock);
+}
+
+static int rtc_bulk_read(struct mt6685_rtc *rtc, unsigned int reg,
+			 void *val, size_t val_count)
+{
+	int ret;
+
+	if (rtc->data->single_read_write_is_supported) {
+		ret = regmap_bulk_read(rtc->regmap, reg, val, val_count);
+	} else {
+		int i;
+
+		for (i = 0; i < val_count; i += 2)
+			ret = regmap_bulk_read(rtc->regmap, reg + i, val + i, 2);
+	}
+
+	return ret;
+}
+
+static int rtc_read(struct mt6685_rtc *rtc, unsigned int reg,
+		    unsigned int *val)
+{
+	rtc_bulk_read(rtc, reg, val, 2);
+	return 0;
+}
+
+static int rtc_bulk_write(struct mt6685_rtc *rtc, unsigned int reg,
+			  const void *val, size_t val_count)
+{
+	int ret;
+
+	if (rtc->data->single_read_write_is_supported) {
+		ret = regmap_bulk_write(rtc->regmap, reg, val, val_count);
+	} else {
+		int i;
+
+		for (i = 0; i < val_count; i += 2)
+			ret = regmap_bulk_write(rtc->regmap, reg + i, val + i, 2);
+	}
+
+	return ret;
+}
+
+static int rtc_write(struct mt6685_rtc *rtc, unsigned int reg,
+		     unsigned int val)
+{
+	rtc_bulk_write(rtc, reg, &val, 2);
+	return 0;
+}
+
+static int rtc_update_bits(struct mt6685_rtc *rtc, unsigned int reg,
+			   unsigned int mask, unsigned int val)
+{
+	int ret;
+	unsigned int tmp, orig = 0;
+
+	ret = rtc_read(rtc, reg, &orig);
+	if (ret != 0)
+		return ret;
+	tmp = orig & ~mask;
+	tmp |= val & mask;
+	ret = rtc_write(rtc, reg, tmp);
+	return ret;
+}
+
+static const struct reg_field mt6685_spare_reg_fields[SPARE_RG_MAX] = {
+	[SPARE_FG2] = REG_FIELD(RTC_RG_FG2, 0, 7),
+	[SPARE_FG3] = REG_FIELD(RTC_RG_FG3, 0, 7),
+	[SPARE_SPAR0]  = REG_FIELD(RTC_SPAR0, 0, 7),
+#ifdef SUPPORT_PWR_OFF_ALARM
+	[SPARE_KPOC]   = REG_FIELD(RTC_PDN1_H, 6, 6),
+#endif
+};
+
+static int rtc_field_read(struct mt6685_rtc *rtc,
+			  const struct reg_field *field, unsigned int *val)
+{
+	int ret;
+	unsigned int orig, mask;
+
+	ret = rtc_read(rtc, rtc->addr_base + field->reg, &orig);
+	if (ret != 0)
+		return ret;
+
+	mask = GENMASK(field->msb, field->lsb);
+	orig &= mask;
+	orig >>= field->lsb;
+	*val = orig;
+
+	dev_notice(rtc->rtc_dev->dev.parent, "%s: rg:0x%x, val:0x%x\n",
+		   __func__, field->reg, *val);
+
+	return 0;
+}
+
+static int rtc_unlock_fg_rg(struct mt6685_rtc *rtc, const struct reg_field *field)
+{
+	int ret = 0;
+
+	if (field->reg == RTC_RG_FG2) {
+		ret = rtc_write(rtc, rtc->addr_base + RTC_RG_FG2, 0xaf);
+		ret |= rtc_write(rtc, rtc->addr_base + RTC_RG_FG2, 0xaf);
+		ret |= rtc_write(rtc, rtc->addr_base + RTC_RG_FG2, 0x5e);
+	} else if (field->reg == RTC_RG_FG3) {
+		ret = rtc_write(rtc, rtc->addr_base + RTC_RG_FG3, 0x66);
+		ret |= rtc_write(rtc, rtc->addr_base + RTC_RG_FG3, 0x66);
+		ret |= rtc_write(rtc, rtc->addr_base + RTC_RG_FG3, 0xf1);
+	}
+
+	if (ret != 0) {
+		dev_notice(rtc->rtc_dev->dev.parent, "%s failed\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rtc_field_write(struct mt6685_rtc *rtc,
+			   const struct reg_field *field, unsigned int val)
+{
+	int ret;
+	unsigned int tmp, orig = 0, latest;
+	unsigned int mask;
+
+	ret = rtc_read(rtc, rtc->addr_base + field->reg, &orig);
+	if (ret != 0)
+		return ret;
+
+	if (rtc->data->chip_version == MT6685_SERIES) {
+		ret = rtc_unlock_fg_rg(rtc, field);
+		if (ret != 0)
+			return ret;
+	}
+
+	mask = GENMASK(field->msb, field->lsb);
+	tmp = orig & ~mask;
+	tmp |= (val << field->lsb) & mask;
+
+	ret = rtc_write(rtc, rtc->addr_base + field->reg, tmp);
+	if (ret != 0)
+		return ret;
+
+	mtk_rtc_write_trigger(rtc);
+
+	rtc_read(rtc, rtc->addr_base + field->reg, &latest);
+	latest &= mask;
+	latest >>= field->lsb;
+
+	if (latest != val)
+		pr_info("%s: reg:0x%x, val:0x%x, latest:0x%x",
+			__func__, field->reg, val, latest);
+
+	return 0;
+}
+
+static u16 rtc_pwron_reg[RTC_OFFSET_COUNT][3] = {
+	{RTC_PWRON_SEC, RTC_PWRON_SEC_MASK, RTC_PWRON_SEC_SHIFT},
+	{RTC_PWRON_MIN, RTC_PWRON_MIN_MASK, RTC_PWRON_MIN_SHIFT},
+	{RTC_PWRON_HOU, RTC_PWRON_HOU_MASK, RTC_PWRON_HOU_SHIFT},
+	{RTC_PWRON_DOM, RTC_PWRON_DOM_MASK, RTC_PWRON_DOM_SHIFT},
+	{0, 0, 0},
+	{RTC_PWRON_MTH, RTC_PWRON_MTH_MASK, RTC_PWRON_MTH_SHIFT},
+	{RTC_PWRON_YEA, RTC_PWRON_YEA_MASK, RTC_PWRON_YEA_SHIFT},
+};
+
+static const struct reg_field mt6685_cali_reg_fields[CALI_FILED_MAX] = {
+	[EOSC_CALI_TD]		= REG_FIELD(EOSC_CALI_TD_MT6685, 0, 2),
+};
+
+static int rtc_eosc_cali_td;
+module_param(rtc_eosc_cali_td, int, 0644);
+
+static void mtk_rtc_enable_k_eosc(struct device *dev)
+{
+	struct mt6685_rtc *rtc = dev_get_drvdata(dev);
+	u32 td;
+
+	power_on_mclk(rtc);
+
+	if (!rtc->cali_is_supported) {
+		power_down_mclk(rtc);
+		return;
+	}
+
+	if (rtc_eosc_cali_td) {
+		dev_notice(dev, "%s: rtc_eosc_cali_td = %d\n",
+			   __func__, rtc_eosc_cali_td);
+		switch (rtc_eosc_cali_td) {
+		case 1:
+			td = EOSC_CALI_TD_01_SEC;
+			break;
+		case 2:
+			td = EOSC_CALI_TD_02_SEC;
+			break;
+		case 4:
+			td = EOSC_CALI_TD_04_SEC;
+			break;
+		case 16:
+			td = EOSC_CALI_TD_16_SEC;
+			break;
+		default:
+			td = EOSC_CALI_TD_08_SEC;
+			break;
+		}
+
+		rtc_field_write(rtc, &rtc->data->cali_reg_fields[EOSC_CALI_TD], td);
+	}
+	power_down_mclk(rtc);
+}
+
+#ifdef SUPPORT_PWR_OFF_ALARM
+
+static u32 bootmode = NORMAL_BOOT;
+static struct wakeup_source *mt6685_rtc_suspend_lock;
+#if IS_ENABLED(CONFIG_PM)
+static bool rtc_pm_notifier_registered;
+static unsigned long rtc_pm_status;
+#endif
+static bool kpoc_alarm;
+
+#if IS_ENABLED(CONFIG_PM)
+
+#define PM_DUMMY 0xFFFF
+
+static int rtc_pm_event(struct notifier_block *notifier, unsigned long pm_event,
+			void *unused)
+{
+	struct mt6685_rtc *rtc = container_of(notifier,
+		struct mt6685_rtc, pm_nb);
+
+	switch (pm_event) {
+	case PM_SUSPEND_PREPARE:
+		rtc_pm_status = PM_SUSPEND_PREPARE;
+		return NOTIFY_DONE;
+	case PM_POST_SUSPEND:
+		rtc_pm_status = PM_POST_SUSPEND;
+		break;
+	default:
+		rtc_pm_status = PM_DUMMY;
+		break;
+	}
+
+	if (kpoc_alarm) {
+		dev_notice(rtc->rtc_dev->dev.parent,
+			   "%s trigger reboot\n", __func__);
+		complete(&rtc->comp);
+		kpoc_alarm = false;
+	}
+	return NOTIFY_DONE;
+}
+#endif /* CONFIG_PM */
+
+static void rtc_mark_kpoc(struct mt6685_rtc *rtc)
+{
+	power_on_mclk(rtc);
+	mutex_lock(&rtc->lock);
+	rtc_field_write(rtc, &rtc->data->spare_reg_fields[SPARE_KPOC], 1);
+	mutex_unlock(&rtc->lock);
+	power_down_mclk(rtc);
+}
+
+static void mtk_rtc_work_queue(struct work_struct *work)
+{
+	struct mt6685_rtc *rtc = container_of(work, struct mt6685_rtc, work);
+	unsigned long ret;
+	unsigned int msecs;
+
+	ret = wait_for_completion_timeout(&rtc->comp, msecs_to_jiffies(30000));
+	if (!ret) {
+		dev_notice(rtc->rtc_dev->dev.parent, "%s timeout\n", __func__);
+		WARN_ON(1);
+	} else {
+		msecs = jiffies_to_msecs(ret);
+		dev_notice(rtc->rtc_dev->dev.parent,
+			   "%s timeleft= %d\n", __func__, msecs);
+		rtc_mark_kpoc(rtc);
+		kernel_restart("kpoc");
+	}
+}
+
+static void mtk_rtc_reboot(struct mt6685_rtc *rtc)
+{
+	__pm_stay_awake(mt6685_rtc_suspend_lock);
+
+	init_completion(&rtc->comp);
+	schedule_work_on(cpumask_first(cpu_online_mask), &rtc->work);
+
+#if IS_ENABLED(CONFIG_PM)
+	if (!rtc_pm_notifier_registered)
+		goto reboot;
+
+	if (rtc_pm_status != PM_SUSPEND_PREPARE)
+		goto reboot;
+#endif
+
+	kpoc_alarm = true;
+
+	dev_notice(rtc->rtc_dev->dev.parent, "%s:wait\n", __func__);
+	return;
+
+#if IS_ENABLED(CONFIG_PM)
+reboot:
+	dev_notice(rtc->rtc_dev->dev.parent, "%s:trigger\n", __func__);
+	complete(&rtc->comp);
+#endif
+}
+
+static void mtk_rtc_update_pwron_alarm_flag(struct mt6685_rtc *rtc)
+{
+	int ret;
+
+	power_on_mclk(rtc);
+
+	ret = rtc_update_bits(rtc,
+			      rtc->addr_base + RTC_PDN1,
+			      RTC_PDN1_PWRON_TIME, 0);
+	if (ret < 0)
+		goto exit;
+
+	ret =  rtc_update_bits(rtc,
+			       rtc->addr_base + RTC_PDN2,
+			       RTC_PDN2_PWRON_ALARM, RTC_PDN2_PWRON_ALARM);
+	if (ret < 0)
+		goto exit;
+
+	mtk_rtc_write_trigger(rtc);
+	power_down_mclk(rtc);
+	dev_notice(rtc->rtc_dev->dev.parent, "%s info\n", __func__);
+	return;
+
+exit:
+	power_down_mclk(rtc);
+	dev_err(rtc->rtc_dev->dev.parent, "%s error\n", __func__);
+}
+
+static int mtk_rtc_restore_alarm(struct mt6685_rtc *rtc, struct rtc_time *tm)
+{
+	int ret;
+	u16 data[RTC_OFFSET_COUNT] = { 0 };
+
+	power_on_mclk(rtc);
+
+	ret = rtc_bulk_read(rtc, rtc->addr_base + RTC_AL_SEC,
+			    data, RTC_OFFSET_COUNT * 2);
+	if (ret < 0)
+		goto exit;
+
+	data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
+				(tm->tm_sec & RTC_AL_SEC_MASK));
+	data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
+				(tm->tm_min & RTC_AL_MIN_MASK));
+	data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
+				(tm->tm_hour & RTC_AL_HOU_MASK));
+	data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
+				(tm->tm_mday & RTC_AL_DOM_MASK));
+	data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
+				(tm->tm_mon & RTC_AL_MTH_MASK));
+	data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
+				(tm->tm_year & RTC_AL_YEA_MASK));
+
+	dev_notice(rtc->rtc_dev->dev.parent,
+		   "restore al time = %04d/%02d/%02d %02d:%02d:%02d\n",
+		   tm->tm_year + RTC_MIN_YEAR, tm->tm_mon, tm->tm_mday,
+		   tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	ret = rtc_bulk_write(rtc, rtc->addr_base + RTC_AL_SEC,
+			     data, RTC_OFFSET_COUNT * 2);
+	if (ret < 0)
+		goto exit;
+
+	ret = rtc_write(rtc, rtc->addr_base + RTC_AL_MASK,
+			RTC_AL_MASK_DOW);
+	if (ret < 0)
+		goto exit;
+
+	ret =  rtc_update_bits(rtc,
+			       rtc->addr_base + RTC_IRQ_EN,
+			       RTC_IRQ_EN_AL, RTC_IRQ_EN_AL);
+	if (ret < 0)
+		goto exit;
+
+	mtk_rtc_write_trigger(rtc);
+	power_down_mclk(rtc);
+	return ret;
+
+exit:
+	power_down_mclk(rtc);
+	dev_err(rtc->rtc_dev->dev.parent, "%s error\n", __func__);
+	return ret;
+}
+
+static bool mtk_rtc_is_pwron_alarm(struct mt6685_rtc *rtc,
+				   struct rtc_time *nowtm, struct rtc_time *tm)
+{
+	u32 pdn1 = 0, spar1 = 0, pdn2 = 0, spar0 = 0;
+	int ret, sec = 0;
+	u16 data[RTC_OFFSET_COUNT] = { 0 };
+
+	ret = rtc_read(rtc, rtc->addr_base + RTC_PDN1, &pdn1);
+	if (ret < 0)
+		goto exit;
+
+	dev_notice(rtc->rtc_dev->dev.parent, "pdn1 = 0x%x\n", pdn1);
+
+	if (pdn1 & RTC_PDN1_PWRON_TIME) {/* power-on time is available */
+
+		/*get current rtc time*/
+		do {
+			ret = rtc_bulk_read(rtc,
+					    rtc->addr_base + RTC_TC_SEC,
+					    data, RTC_OFFSET_COUNT * 2);
+			if (ret < 0)
+				goto exit;
+			nowtm->tm_sec = data[RTC_OFFSET_SEC] & RTC_TC_SEC_MASK;
+			nowtm->tm_min = data[RTC_OFFSET_MIN] & RTC_TC_MIN_MASK;
+			nowtm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_TC_HOU_MASK;
+			nowtm->tm_mday = data[RTC_OFFSET_DOM] & RTC_TC_DOM_MASK;
+			nowtm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK;
+			nowtm->tm_year = data[RTC_OFFSET_YEAR] & RTC_TC_YEA_MASK;
+
+			ret = rtc_read(rtc,
+				       rtc->addr_base + RTC_TC_SEC, &sec);
+			if (ret < 0)
+				goto exit;
+			sec &= RTC_TC_SEC_MASK;
+
+		} while (sec < nowtm->tm_sec);
+
+		dev_notice(rtc->rtc_dev->dev.parent,
+			   "get now time = %04d/%02d/%02d %02d:%02d:%02d\n",
+			   nowtm->tm_year + RTC_MIN_YEAR, nowtm->tm_mon,
+			   nowtm->tm_mday, nowtm->tm_hour,
+			   nowtm->tm_min, nowtm->tm_sec);
+
+		/*get power on time from SPARE */
+		ret = rtc_read(rtc,
+			       rtc->addr_base + RTC_SPAR0, &spar0);
+		if (ret < 0)
+			goto exit;
+
+		ret = rtc_read(rtc,
+			       rtc->addr_base + RTC_SPAR1, &spar1);
+		if (ret < 0)
+			goto exit;
+
+		ret = rtc_read(rtc,
+			       rtc->addr_base + RTC_PDN2, &pdn2);
+		if (ret < 0)
+			goto exit;
+		dev_notice(rtc->rtc_dev->dev.parent,
+			   "spar0=0x%x, spar1=0x%x, pdn2=0x%x\n",
+			   spar0, spar1, pdn2);
+
+		tm->tm_sec =
+			(spar0 & RTC_PWRON_SEC_MASK) >> RTC_PWRON_SEC_SHIFT;
+		tm->tm_min =
+			(spar1 & RTC_PWRON_MIN_MASK) >> RTC_PWRON_MIN_SHIFT;
+		tm->tm_hour =
+			(spar1 & RTC_PWRON_HOU_MASK) >> RTC_PWRON_HOU_SHIFT;
+		tm->tm_mday =
+			(spar1 & RTC_PWRON_DOM_MASK) >> RTC_PWRON_DOM_SHIFT;
+		tm->tm_mon =
+			(pdn2 & RTC_PWRON_MTH_MASK) >> RTC_PWRON_MTH_SHIFT;
+		tm->tm_year =
+			(pdn2 & RTC_PWRON_YEA_MASK) >> RTC_PWRON_YEA_SHIFT;
+
+		dev_notice(rtc->rtc_dev->dev.parent,
+			   "get pwron time = %04d/%02d/%02d %02d:%02d:%02d\n",
+			   tm->tm_year + RTC_MIN_YEAR, tm->tm_mon, tm->tm_mday,
+			   tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+		return true;
+	}
+	return false;
+exit:
+	dev_err(rtc->rtc_dev->dev.parent, "%s error\n", __func__);
+	return false;
+}
+#endif
+
+static int mtk_rtc_write_trigger(struct mt6685_rtc *rtc)
+{
+	unsigned long timeout = jiffies + HZ;
+	int ret;
+	u32 data = 0;
+
+	ret = rtc_write(rtc,
+			rtc->addr_base + rtc->data->wrtgr, 1);
+	if (ret < 0)
+		return ret;
+
+	while (1) {
+		ret = rtc_read(rtc, rtc->addr_base + RTC_BBPU,
+			       &data);
+		if (ret < 0)
+			break;
+		if (!(data & RTC_BBPU_CBUSY))
+			break;
+		if (time_after(jiffies, timeout)) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+		cpu_relax();
+	}
+	return ret;
+}
+
+static void mtk_rtc_reset_bbpu_alarm_status(struct mt6685_rtc *rtc)
+{
+	u32 bbpu;
+	int ret;
+
+	power_on_mclk(rtc);
+
+	bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN | RTC_BBPU_RESET_AL;
+	ret = rtc_write(rtc, rtc->addr_base + RTC_BBPU, bbpu);
+	if (ret < 0)
+		goto exit;
+
+	mtk_rtc_write_trigger(rtc);
+	power_down_mclk(rtc);
+	return;
+exit:
+	power_down_mclk(rtc);
+	dev_err(rtc->rtc_dev->dev.parent, "%s error\n", __func__);
+}
+
+static int mtk_rtc_is_alarm_irq(struct mt6685_rtc *rtc)
+{
+	u32 irqsta = 0, bbpu = 0, sck = 0, sck_check = 0, irqsta_check = 0;
+	int ret;
+
+	power_on_mclk(rtc);
+
+	ret = rtc_read(rtc, rtc->addr_base + RTC_IRQ_STA, &irqsta);/* read clear */
+
+	/*clear SCK_TOP rtc interrupt*/
+	rtc_read(rtc, SCK_TOP_INT_STATUS0, &sck);
+	rtc_write(rtc, SCK_TOP_INT_STATUS0, sck);
+
+	rtc_read(rtc, SCK_TOP_INT_STATUS0, &sck_check);
+	if (sck_check) {
+		udelay(70);
+		rtc_write(rtc, SCK_TOP_INT_STATUS0, 1);
+
+		rtc_read(rtc, SCK_TOP_INT_STATUS0, &sck_check);
+		if (sck_check) {
+			dev_notice(rtc->rtc_dev->dev.parent,
+				   "%s: TOP INT STA 0x%x\n", __func__, sck_check);
+
+			rtc_read(rtc, rtc->addr_base + RTC_IRQ_STA, &irqsta_check);
+			dev_notice(rtc->rtc_dev->dev.parent,
+				   "%s: IRQ STA 0x%x\n", __func__, irqsta_check);
+		}
+	}
+
+	if (ret == 0 && (irqsta & RTC_IRQ_STA_AL)) {
+		bbpu = RTC_BBPU_KEY | RTC_BBPU_PWREN;
+		ret = rtc_write(rtc,
+				rtc->addr_base + RTC_BBPU, bbpu);
+		if (ret < 0)
+			dev_err(rtc->rtc_dev->dev.parent,
+				"%s: %d error\n", __func__, __LINE__);
+
+		ret =  rtc_update_bits(rtc,
+				       rtc->addr_base + RTC_IRQ_EN,
+				       RTC_IRQ_EN_AL, 0);
+		if (ret < 0)
+			dev_err(rtc->rtc_dev->dev.parent,
+				"%s: %d error\n", __func__, __LINE__);
+		mtk_rtc_write_trigger(rtc);
+		power_down_mclk(rtc);
+		return RTC_ALSTA;
+	}
+	power_down_mclk(rtc);
+	return RTC_NONE;
+}
+
+static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
+{
+	struct mt6685_rtc *rtc = data;
+	bool pwron_alm = false;
+	int status = RTC_NONE;
+#ifdef SUPPORT_PWR_OFF_ALARM
+	bool pwron_alarm = false;
+	struct rtc_time nowtm, tm;
+#endif
+
+	mutex_lock(&rtc->lock);
+
+	status = mtk_rtc_is_alarm_irq(rtc);
+
+	if (!rtc->rtc_dev) {
+		mutex_unlock(&rtc->lock);
+		return IRQ_NONE;
+	}
+
+	dev_notice(rtc->rtc_dev->dev.parent, "%s:%d\n", __func__, status);
+
+	if (status == RTC_NONE) {
+		mutex_unlock(&rtc->lock);
+		return IRQ_NONE;
+	}
+
+	mtk_rtc_reset_bbpu_alarm_status(rtc);
+
+#ifdef SUPPORT_PWR_OFF_ALARM
+	pwron_alarm = mtk_rtc_is_pwron_alarm(rtc, &nowtm, &tm);
+	nowtm.tm_year += RTC_MIN_YEAR;
+	tm.tm_year += RTC_MIN_YEAR;
+	if (pwron_alarm) {
+		time64_t now_time, time;
+
+		now_time =
+		    mktime64(nowtm.tm_year, nowtm.tm_mon, nowtm.tm_mday,
+			     nowtm.tm_hour, nowtm.tm_min, nowtm.tm_sec);
+
+		if (now_time == -1) {
+			mutex_unlock(&rtc->lock);
+			goto out;
+		}
+
+		time =
+		    mktime64(tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
+			     tm.tm_min, tm.tm_sec);
+
+		if (time == -1) {
+			mutex_unlock(&rtc->lock);
+			goto out;
+		}
+
+		/* power on */
+		if (now_time >= time - 1 && now_time <= time + 4) {
+			if (bootmode == KERNEL_POWER_OFF_CHARGING_BOOT ||
+			    bootmode == LOW_POWER_OFF_CHARGING_BOOT) {
+				mtk_rtc_reboot(rtc);
+				mutex_unlock(&rtc->lock);
+				disable_irq_nosync(rtc->irq);
+				goto out;
+			} else {
+				mtk_rtc_update_pwron_alarm_flag(rtc);
+				pwron_alm = true;
+			}
+		} else if (now_time < time) {	/* set power-on alarm */
+			time -= 1;
+			rtc_time64_to_tm(time, &tm);
+			tm.tm_year -= RTC_MIN_YEAR_OFFSET;
+			tm.tm_mon += 1;
+			mtk_rtc_restore_alarm(rtc, &tm);
+		}
+	}
+#endif
+	mutex_unlock(&rtc->lock);
+
+out:
+	if (rtc->rtc_dev)
+		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
+
+	if (rtc_show_alarm)
+		dev_notice(rtc->rtc_dev->dev.parent, "%s time is up\n",
+			   pwron_alm ? "power-on" : "alarm");
+
+	return IRQ_HANDLED;
+}
+
+static int __mtk_rtc_read_time(struct mt6685_rtc *rtc,
+			       struct rtc_time *tm, int *sec)
+{
+	int ret;
+	unsigned int reload = 0;
+	u16 data[RTC_OFFSET_COUNT] = { 0 };
+
+	power_on_mclk(rtc);
+
+	rtc_read(rtc, rtc->addr_base + RTC_BBPU, &reload);
+	reload = reload | RTC_BBPU_KEY | RTC_BBPU_RELOAD;
+	rtc_write(rtc, rtc->addr_base + RTC_BBPU, reload);
+	mtk_rtc_write_trigger(rtc);
+	power_down_mclk(rtc);
+
+	mutex_lock(&rtc->lock);
+	ret = rtc_bulk_read(rtc, rtc->addr_base + RTC_TC_SEC,
+			    data, RTC_OFFSET_COUNT * 2);
+	if (ret < 0)
+		goto exit;
+
+	tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_TC_SEC_MASK;
+	tm->tm_min = data[RTC_OFFSET_MIN] & RTC_TC_MIN_MASK;
+	tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_TC_HOU_MASK;
+	tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_TC_DOM_MASK;
+	tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK;
+	tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_TC_YEA_MASK;
+
+	ret = rtc_read(rtc, rtc->addr_base + RTC_TC_SEC, sec);
+	*sec &= RTC_TC_SEC_MASK;
+exit:
+	mutex_unlock(&rtc->lock);
+	return ret;
+}
+
+static void mtk_rtc_set_pwron_time(struct mt6685_rtc *rtc, struct rtc_time *tm)
+{
+	u32 data[RTC_OFFSET_COUNT];
+	int ret, i;
+
+	data[RTC_OFFSET_SEC] =
+		((tm->tm_sec << RTC_PWRON_SEC_SHIFT) & RTC_PWRON_SEC_MASK);
+	data[RTC_OFFSET_MIN] =
+		((tm->tm_min << RTC_PWRON_MIN_SHIFT) & RTC_PWRON_MIN_MASK);
+	data[RTC_OFFSET_HOUR] =
+		((tm->tm_hour << RTC_PWRON_HOU_SHIFT) & RTC_PWRON_HOU_MASK);
+	data[RTC_OFFSET_DOM] =
+		((tm->tm_mday << RTC_PWRON_DOM_SHIFT) & RTC_PWRON_DOM_MASK);
+	data[RTC_OFFSET_MTH] =
+		((tm->tm_mon << RTC_PWRON_MTH_SHIFT) & RTC_PWRON_MTH_MASK);
+	data[RTC_OFFSET_YEAR] =
+		((tm->tm_year << RTC_PWRON_YEA_SHIFT) & RTC_PWRON_YEA_MASK);
+
+	for (i = RTC_OFFSET_SEC; i < RTC_OFFSET_COUNT; i++) {
+		if (i == RTC_OFFSET_DOW)
+			continue;
+		ret =  rtc_update_bits(rtc,
+				       rtc->addr_base + rtc_pwron_reg[i][RTC_REG],
+				       rtc_pwron_reg[i][RTC_MASK], data[i]);
+		if (ret < 0)
+			goto exit;
+		mtk_rtc_write_trigger(rtc);
+	}
+	return;
+exit:
+	dev_err(rtc->rtc_dev->dev.parent, "%s error\n", __func__);
+}
+
+static void mtk_rtc_save_pwron_time(struct mt6685_rtc *rtc,
+				    bool enable, struct rtc_time *tm)
+{
+	u32 pdn1 = 0;
+	int ret;
+
+	/* set power on time */
+	mtk_rtc_set_pwron_time(rtc, tm);
+
+	/* update power on alarm related flags */
+	if (enable)
+		pdn1 = RTC_PDN1_PWRON_TIME;
+	ret =  rtc_update_bits(rtc,
+			       rtc->addr_base + RTC_PDN1,
+			       RTC_PDN1_PWRON_TIME, pdn1);
+	if (ret < 0)
+		dev_err(rtc->rtc_dev->dev.parent, "%s error\n", __func__);
+
+	mtk_rtc_write_trigger(rtc);
+}
+
+static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	time64_t time;
+	struct mt6685_rtc *rtc = dev_get_drvdata(dev);
+	int days, sec, ret;
+	unsigned long long timeout = sched_clock() + 500000000;
+
+	do {
+		ret = __mtk_rtc_read_time(rtc, tm, &sec);
+		if (ret < 0)
+			goto exit;
+		if (sched_clock() > timeout) {
+			pr_notice("%s, time out\n", __func__);
+			break;
+		}
+	} while (sec < tm->tm_sec);
+
+	/* HW register use 7 bits to store year data, minus
+	 * RTC_MIN_YEAR_OFFSET before write year data to register, and plus
+	 * RTC_MIN_YEAR_OFFSET back after read year from register
+	 */
+	tm->tm_year += RTC_MIN_YEAR_OFFSET;//+110
+
+	/* HW register start mon from one, but tm_mon start from zero. */
+	tm->tm_mon--;
+	time = rtc_tm_to_time64(tm);
+
+	/* rtc_tm_to_time64 covert Gregorian date to seconds since
+	 * 01-01-1970 00:00:00, and this date is Thursday.
+	 */
+	days = div_s64(time, 86400);
+	tm->tm_wday = (days + 4) % 7;
+
+	if (rtc_show_time) {
+		dev_notice(rtc->rtc_dev->dev.parent,
+			   "read tc time = %04d/%02d/%02d (%d) %02d:%02d:%02d\n",
+			   tm->tm_year + RTC_BASE_YEAR, tm->tm_mon + 1,
+			   tm->tm_mday, tm->tm_wday, tm->tm_hour,
+			   tm->tm_min, tm->tm_sec);
+	}
+exit:
+	return ret;
+}
+
+static bool mtk_rtc_check_set_time(struct mt6685_rtc *rtc, struct rtc_time *tm,
+				   int retry_time, int rtc_time_reg)
+{
+	int ret, i, j, write_fail = 0, prot_key = 0xDEAD, hwid = 0, mclk = 0;
+	u16 data[RTC_OFFSET_COUNT], latest[RTC_OFFSET_COUNT];
+
+	data[RTC_OFFSET_SEC] = tm->tm_sec;
+	data[RTC_OFFSET_MIN] = tm->tm_min;
+	data[RTC_OFFSET_HOUR] = tm->tm_hour;
+	data[RTC_OFFSET_DOM] = tm->tm_mday;
+	data[RTC_OFFSET_MTH] = tm->tm_mon;
+	data[RTC_OFFSET_YEAR] = tm->tm_year;
+
+	for (j = 1; j <= retry_time; j++) {
+		write_fail = 0;
+
+		ret = rtc_bulk_read(rtc, rtc->addr_base + rtc_time_reg,
+				    latest, RTC_OFFSET_COUNT * 2);
+		if (ret < 0)
+			return ret;
+
+		for (i = 0; i < RTC_OFFSET_COUNT; i++) {
+			if (i == RTC_OFFSET_DOW)
+				continue;
+
+			latest[i] = latest[i] & rtc_time_mask[i];
+			if (latest[i] != data[i])
+				write_fail++;
+
+			if (j == retry_time) {
+				ret = rtc_read(rtc, rtc->data->hwid, &hwid);
+				if (ret < 0)
+					return ret;
+
+				ret = rtc_read(rtc, RG_RTC_MCLK_PDN, &mclk);
+				if (ret < 0)
+					return ret;
+				mclk = mclk >> RG_RTC_MCLK_PDN_STA_SHIFT & RG_RTC_MCLK_PDN_STA_MASK;
+
+				if (rtc->data->chip_version == MT6685_SERIES) {
+					ret = rtc_read(rtc,
+						       rtc->addr_base + RTC_SPAR_MACRO, &prot_key);
+
+					if (ret < 0)
+						return ret;
+
+					prot_key =
+						prot_key >> SPAR_PROT_STAT_SHIFT
+						& SPAR_PROT_STAT_MASK;
+				}
+
+				dev_info(rtc->rtc_dev->dev.parent,
+					 "[HWID 0x%x, MCLK 0x%x, prot key 0x%x] %s write %d, latest %d\n",
+					 hwid, mclk, prot_key, rtc_time_reg_name[i],
+					 data[i], latest[i]);
+			}
+		}
+
+		if (write_fail > 0)
+			mdelay(2);
+		else
+			break;
+	}
+
+	if (write_fail > 0)
+		return false;
+
+	return true;
+}
+
+static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct mt6685_rtc *rtc = dev_get_drvdata(dev);
+	int ret, result = 0;
+	u16 data[RTC_OFFSET_COUNT];
+
+	power_on_mclk(rtc);
+
+	dev_notice(rtc->rtc_dev->dev.parent,
+		   "set tc time = %04d/%02d/%02d %02d:%02d:%02d\n",
+		   tm->tm_year + RTC_BASE_YEAR, tm->tm_mon + 1, tm->tm_mday,
+		   tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	tm->tm_year -= RTC_MIN_YEAR_OFFSET;
+	tm->tm_mon++;
+
+	data[RTC_OFFSET_SEC] = tm->tm_sec;
+	data[RTC_OFFSET_MIN] = tm->tm_min;
+	data[RTC_OFFSET_HOUR] = tm->tm_hour;
+	data[RTC_OFFSET_DOM] = tm->tm_mday;
+	data[RTC_OFFSET_MTH] = tm->tm_mon;
+	data[RTC_OFFSET_YEAR] = tm->tm_year;
+
+	mutex_lock(&rtc->lock);
+	ret = rtc_bulk_write(rtc, rtc->addr_base + RTC_TC_SEC,
+			     data, RTC_OFFSET_COUNT * 2);
+	if (ret < 0)
+		goto exit;
+
+	/* Time register write to hardware after call trigger function */
+	ret = mtk_rtc_write_trigger(rtc);
+	if (ret < 0)
+		goto exit;
+
+	result = mtk_rtc_check_set_time(rtc, tm, 2, RTC_TC_SEC);
+
+	if (!result) {
+		dev_info(rtc->rtc_dev->dev.parent, "check rtc set time\n");
+#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
+		aee_kernel_warning("mt6685-rtc", "mt6685-rtc: set tick time failed\n");
+#endif
+	}
+
+exit:
+	mutex_unlock(&rtc->lock);
+	power_down_mclk(rtc);
+	return ret;
+}
+
+static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rtc_time *tm = &alm->time;
+	struct mt6685_rtc *rtc = dev_get_drvdata(dev);
+	u32 irqen = 0, pdn2 = 0;
+	int ret;
+	u16 data[RTC_OFFSET_COUNT] = { 0 };
+
+	mutex_lock(&rtc->lock);
+	ret = rtc_read(rtc, rtc->addr_base + RTC_IRQ_EN, &irqen);
+	if (ret < 0)
+		goto err_exit;
+	ret = rtc_read(rtc, rtc->addr_base + RTC_PDN2, &pdn2);
+	if (ret < 0)
+		goto err_exit;
+
+	ret = rtc_bulk_read(rtc, rtc->addr_base + RTC_AL_SEC,
+			    data, RTC_OFFSET_COUNT * 2);
+	if (ret < 0)
+		goto err_exit;
+
+	alm->enabled = !!(irqen & RTC_IRQ_EN_AL);
+	alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
+	mutex_unlock(&rtc->lock);
+
+	tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
+	tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
+	tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
+	tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
+	tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
+	tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
+
+	tm->tm_year += RTC_MIN_YEAR_OFFSET;
+	tm->tm_mon--;
+
+	dev_notice(rtc->rtc_dev->dev.parent,
+		   "read al time = %04d/%02d/%02d %02d:%02d:%02d (%d)\n",
+		   tm->tm_year + RTC_BASE_YEAR, tm->tm_mon + 1, tm->tm_mday,
+		   tm->tm_hour, tm->tm_min, tm->tm_sec, alm->enabled);
+
+	return 0;
+err_exit:
+	mutex_unlock(&rtc->lock);
+	return ret;
+}
+
+static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct rtc_time *tm = &alm->time;
+	struct mt6685_rtc *rtc = dev_get_drvdata(dev);
+	int ret, result = 0;
+	u16 data[RTC_OFFSET_COUNT];
+	ktime_t target;
+
+	power_on_mclk(rtc);
+
+	if (alm->enabled == 1) {
+		/* Add one more second to postpone wake time. */
+		target = rtc_tm_to_ktime(*tm);
+		target = ktime_add_ns(target, NSEC_PER_SEC);
+		*tm = rtc_ktime_to_tm(target);
+	}
+
+	tm->tm_year -= RTC_MIN_YEAR_OFFSET;
+	tm->tm_mon++;
+
+	dev_notice(rtc->rtc_dev->dev.parent,
+		   "set al time = %04d/%02d/%02d %02d:%02d:%02d (%d)\n",
+		   tm->tm_year + RTC_MIN_YEAR, tm->tm_mon, tm->tm_mday,
+		   tm->tm_hour, tm->tm_min, tm->tm_sec, alm->enabled);
+
+	mutex_lock(&rtc->lock);
+
+	switch (alm->enabled) {
+	case 3:
+		/* enable power-on alarm with logo */
+		mtk_rtc_save_pwron_time(rtc, true, tm);
+		break;
+	case 4:
+		/* disable power-on alarm */
+		mtk_rtc_save_pwron_time(rtc, false, tm);
+		break;
+	default:
+		break;
+	}
+
+	ret = rtc_update_bits(rtc,
+			      rtc->addr_base + RTC_PDN2,
+			      RTC_PDN2_PWRON_ALARM, 0);
+	if (ret < 0)
+		goto exit;
+	mtk_rtc_write_trigger(rtc);
+
+	ret = rtc_bulk_read(rtc, rtc->addr_base + RTC_AL_SEC,
+			    data, RTC_OFFSET_COUNT * 2);
+	if (ret < 0)
+		goto exit;
+
+	data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
+				(tm->tm_sec & RTC_AL_SEC_MASK));
+	data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
+				(tm->tm_min & RTC_AL_MIN_MASK));
+	data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
+				(tm->tm_hour & RTC_AL_HOU_MASK));
+	data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
+				(tm->tm_mday & RTC_AL_DOM_MASK));
+	data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
+				(tm->tm_mon & RTC_AL_MTH_MASK));
+	data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
+				(tm->tm_year & RTC_AL_YEA_MASK));
+
+	if (alm->enabled) {
+		ret = rtc_bulk_write(rtc,
+				     rtc->addr_base + RTC_AL_SEC,
+				     data, RTC_OFFSET_COUNT * 2);
+		if (ret < 0)
+			goto exit;
+		ret = rtc_write(rtc, rtc->addr_base + RTC_AL_MASK,
+				RTC_AL_MASK_DOW);
+		if (ret < 0)
+			goto exit;
+
+		ret =  rtc_update_bits(rtc,
+				       rtc->addr_base + RTC_IRQ_EN,
+				       RTC_IRQ_EN_AL, RTC_IRQ_EN_AL);
+		if (ret < 0)
+			goto exit;
+		} else {
+			ret =  rtc_update_bits(rtc,
+					       rtc->addr_base + RTC_IRQ_EN,
+					       RTC_IRQ_EN_AL, 0);
+			if (ret < 0)
+				goto exit;
+		}
+
+	/* All alarm time register write to hardware after calling
+	 * mtk_rtc_write_trigger. This can avoid race condition if alarm
+	 * occur happen during writing alarm time register.
+	 */
+	ret = mtk_rtc_write_trigger(rtc);
+	if (ret < 0)
+		goto exit;
+
+	result = mtk_rtc_check_set_time(rtc, tm, 2, RTC_AL_SEC);
+
+	if (!result) {
+		dev_info(rtc->rtc_dev->dev.parent, "check rtc set alarm\n");
+#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
+		aee_kernel_warning("mt6685-rtc", "mt6685-rtc: set alarm time failed\n");
+#endif
+	}
+exit:
+	mutex_unlock(&rtc->lock);
+	power_down_mclk(rtc);
+	return ret;
+}
+
+static int rtc_alarm_set_power_on(struct device *dev, struct rtc_wkalrm *alm)
+{
+	int err = 0;
+	struct rtc_time tm;
+	time64_t now, scheduled;
+
+	err = rtc_valid_tm(&alm->time);
+	if (err != 0)
+		return err;
+	scheduled = rtc_tm_to_time64(&alm->time);
+
+	err = mtk_rtc_read_time(dev, &tm);
+	if (err != 0)
+		return err;
+	now = rtc_tm_to_time64(&tm);
+
+	if (scheduled <= now)
+		alm->enabled = 4;
+	else
+		alm->enabled = 3;
+
+	mtk_rtc_set_alarm(dev, alm);
+
+	return err;
+}
+
+static int mtk_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+	void __user *uarg = (void __user *)arg;
+	int err = 0;
+	struct rtc_wkalrm alm;
+
+	switch (cmd) {
+	case RTC_POFF_ALM_SET:
+		if (copy_from_user(&alm.time, uarg, sizeof(alm.time)))
+			return -EFAULT;
+		err = rtc_alarm_set_power_on(dev, &alm);
+		break;
+	default:
+		err = -EINVAL;
+		break;
+	}
+
+	return err;
+}
+
+static const struct rtc_class_ops mtk_rtc_ops = {
+	.ioctl      = mtk_rtc_ioctl,
+	.read_time  = mtk_rtc_read_time,
+	.set_time   = mtk_rtc_set_time,
+	.read_alarm = mtk_rtc_read_alarm,
+	.set_alarm  = mtk_rtc_set_alarm,
+};
+
+static int rtc_nvram_read(void *priv, unsigned int offset, void *val,
+			  size_t bytes)
+{
+	struct mt6685_rtc *rtc = dev_get_drvdata(priv);
+	unsigned int ival;
+	int ret;
+	u8 *buf = val;
+
+	mutex_lock(&rtc->lock);
+
+	for (; bytes; bytes--) {
+		ret = rtc_field_read(rtc,
+				     &rtc->data->spare_reg_fields[offset++],
+				     &ival);
+
+		if (ret)
+			goto out;
+
+		*buf++ = (u8)ival;
+	}
+
+out:
+	mutex_unlock(&rtc->lock);
+	return ret;
+}
+
+static int rtc_nvram_write(void *priv, unsigned int offset, void *val,
+			   size_t bytes)
+{
+	struct mt6685_rtc *rtc = dev_get_drvdata(priv);
+	unsigned int ival;
+	int ret;
+	u8 *buf = val;
+
+	power_on_mclk(rtc);
+
+	mutex_lock(&rtc->lock);
+
+	for (; bytes; bytes--) {
+		ival = *buf++;
+		ret = rtc_field_write(rtc,
+				      &rtc->data->spare_reg_fields[offset++],
+				      ival);
+
+		if (ret)
+			goto out;
+	}
+
+out:
+	mutex_unlock(&rtc->lock);
+	power_down_mclk(rtc);
+	return ret;
+}
+
+static int mtk_rtc_set_spare(struct device *dev)
+{
+	struct mt6685_rtc *rtc = dev_get_drvdata(dev);
+	int ret;
+	struct nvmem_config nvmem_cfg = {
+		.name = "mtk_rtc_nvmem",
+		.word_size = SPARE_REG_WIDTH,
+		.stride = 1,
+		.size = SPARE_RG_MAX * SPARE_REG_WIDTH,
+		.reg_read = rtc_nvram_read,
+		.reg_write = rtc_nvram_write,
+		.priv = dev,
+	};
+
+	ret = devm_rtc_nvmem_register(rtc->rtc_dev, &nvmem_cfg);
+	if (ret)
+		dev_err(rtc->rtc_dev->dev.parent, "nvmem register failed\n");
+
+	return ret;
+}
+
+static int mtk_rtc_probe(struct platform_device *pdev)
+{
+	struct mt6685_rtc *rtc;
+	struct device_node *np = pdev->dev.of_node;
+	int ret;
+#ifdef SUPPORT_PWR_OFF_ALARM
+	struct device_node *of_chosen = NULL;
+	struct tag_bootmode *tag = NULL;
+#endif
+	if (!of_device_is_available(np)) {
+		dev_err(&pdev->dev, "rtc disabled\n");
+		return -1;
+	}
+
+	rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6685_rtc), GFP_KERNEL);
+	if (!rtc) {
+		//dev_err(&pdev->dev, "devm_kzalloc failed\n");
+		return -ENOMEM;
+	}
+
+	rtc->data = of_device_get_match_data(&pdev->dev);
+	if (!rtc->data) {
+		dev_err(&pdev->dev, "of_device_get_match_data failed\n");
+		return -ENODEV;
+	}
+
+	if (of_property_read_u32(pdev->dev.of_node, "base", &rtc->addr_base))
+		rtc->addr_base = RTC_DSN_ID;
+
+	pr_notice("%s: rtc->addr_base =0x%x\n", __func__, rtc->addr_base);
+
+	mutex_init(&rtc->lock);
+	mutex_init(&rtc->clk_lock);
+
+	platform_set_drvdata(pdev, rtc);
+
+	rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
+	if (IS_ERR(rtc->rtc_dev)) {
+		dev_err(&pdev->dev, "Failed devm_rtc_allocate_device: %p\n", rtc->rtc_dev);
+		return PTR_ERR(rtc->rtc_dev);
+	}
+
+	rtc->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!rtc->regmap) {
+		pr_err("%s: get regmap failed\n", __func__);
+		return -ENODEV;
+	}
+
+#ifdef SUPPORT_PWR_OFF_ALARM
+	mt6685_rtc_suspend_lock =
+		wakeup_source_register(NULL, "mt6685-rtc suspend wakelock");
+
+	of_chosen = of_find_node_by_path("/chosen");
+	if (!of_chosen)
+		of_chosen = of_find_node_by_path("/chosen at 0");
+
+	if (of_chosen) {
+		tag = (struct tag_bootmode *)of_get_property
+		       (of_chosen, "atag,boot", NULL);
+		if (!tag) {
+			dev_err(&pdev->dev,
+				"%s: failed to get atag,boot\n", __func__);
+		} else {
+			dev_notice(&pdev->dev,
+				   "%s, bootmode:%d\n", __func__, tag->bootmode);
+			bootmode = tag->bootmode;
+		}
+	} else {
+		dev_err(&pdev->dev,
+			"%s: failed to get /chosen and /chosen at 0\n", __func__);
+	}
+
+#if IS_ENABLED(CONFIG_PM)
+	rtc->pm_nb.notifier_call = rtc_pm_event;
+	rtc->pm_nb.priority = 0;
+	if (register_pm_notifier(&rtc->pm_nb))
+		dev_err(&pdev->dev, "rtc pm faile\n");
+	else
+		rtc_pm_notifier_registered = true;
+#endif /* CONFIG_PM */
+
+	INIT_WORK(&rtc->work, mtk_rtc_work_queue);
+#endif
+
+	/* Obtain interrupt ID from DTS or MFD */
+	rtc->irq = platform_get_irq(pdev, 0);
+	if (rtc->irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq(%d)\n", rtc->irq);
+#if IS_ENABLED(CONFIG_PM)
+		rtc_pm_notifier_registered = false;
+		unregister_pm_notifier(&rtc->pm_nb);
+#endif
+		return rtc->irq;
+	}
+
+	ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
+					mtk_rtc_irq_handler_thread,
+					IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+					"mt6685-rtc", rtc);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
+			rtc->irq, ret);
+#if IS_ENABLED(CONFIG_PM)
+		rtc_pm_notifier_registered = false;
+		unregister_pm_notifier(&rtc->pm_nb);
+#endif
+		return ret;
+	}
+
+	/*Enable SCK_TOP rtc interrupt*/
+	rtc_update_bits(rtc, SCK_TOP_INT_CON0, EN_RTC_INTERRUPT, 1);
+
+	device_init_wakeup(&pdev->dev, 1);
+
+	rtc->rtc_dev->ops = &mtk_rtc_ops;
+
+	if (rtc->data->spare_reg_fields)
+		if (mtk_rtc_set_spare(&pdev->dev))
+			dev_info(&pdev->dev, "spare is not supported\n");
+
+	ret = devm_rtc_register_device(rtc->rtc_dev);
+	if (ret) {
+		dev_err(&pdev->dev, "register rtc device failed\n");
+	};
+
+	enable_irq_wake(rtc->irq);
+
+	if (rtc->data->cali_reg_fields)
+		rtc->cali_is_supported = true;
+
+	power_on_mclk(rtc);
+	power_down_mclk(rtc);
+	return 0;
+}
+
+static void mtk_rtc_shutdown(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct mt6685_rtc *rtc = dev_get_drvdata(&pdev->dev);
+
+	if (rtc->data->chip_version == MT6685_SERIES) {
+		/*Normal sequence power off when PON falling*/
+		ret = rtc_update_bits(rtc, TOP2_ELR1, TOP2_ELR1_MASK, 1);
+		if (ret < 0)
+			dev_info(&pdev->dev, "check mt6685 TOP2_ELR1\n");
+	}
+
+	if (rtc->cali_is_supported)
+		mtk_rtc_enable_k_eosc(&pdev->dev);
+}
+
+static const struct mtk_rtc_data mt6685_rtc_data = {
+	.wrtgr = RTC_WRTGR,
+	.hwid = HWID_MT6685,
+	.chip_version = MT6685_SERIES,
+	.spare_reg_fields = mt6685_spare_reg_fields,
+	.cali_reg_fields = mt6685_cali_reg_fields,
+	.single_read_write_is_supported = true,
+};
+
+static const struct of_device_id mt6685_rtc_of_match[] = {
+	{ .compatible = "mediatek,mt6685-rtc", .data = &mt6685_rtc_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mt6685_rtc_of_match);
+
+static struct platform_driver mtk_rtc_driver = {
+	.driver = {
+		.name = "mt6685-rtc",
+		.of_match_table = mt6685_rtc_of_match,
+	},
+	.probe	= mtk_rtc_probe,
+	.shutdown = mtk_rtc_shutdown,
+};
+
+module_platform_driver(mtk_rtc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mw Lin <Mw.Lin at mediatek.com>");
+MODULE_DESCRIPTION("RTC Driver for MediaTek MT6685 Clock IC");
diff --git a/include/linux/mfd/mt6685-audclk.h b/include/linux/mfd/mt6685-audclk.h
new file mode 100644
index 000000000000..fd99effd0a6c
--- /dev/null
+++ b/include/linux/mfd/mt6685-audclk.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ */
+#ifndef _AUDIO_DCXO_H_
+#define _AUDIO_DCXO_H_
+
+/* just be called by audio module for dcxo */
+void mt6685_set_dcxo_mode(unsigned int mode);
+void mt6685_set_dcxo(bool enable);
+#endif
diff --git a/include/linux/mfd/mt6685/core.h b/include/linux/mfd/mt6685/core.h
new file mode 100644
index 000000000000..dcaf800e8212
--- /dev/null
+++ b/include/linux/mfd/mt6685/core.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MFD_MT6685_CORE_H__
+#define __MFD_MT6685_CORE_H__
+
+struct mt6685_chip {
+	struct device *dev;
+	struct regmap *regmap;
+	int irq;
+	struct irq_domain *irq_domain;
+	struct mutex irqlock; /* Mid-end lock for synchronous operation */
+	u16 wake_mask[2];
+	u16 irq_masks_cur[2];
+	u16 irq_masks_cache[2];
+	u16 int_con[2];
+	u16 int_status[2];
+};
+
+#endif /* __MFD_MT6685_CORE_H__ */
diff --git a/include/linux/mfd/mt6685/registers.h b/include/linux/mfd/mt6685/registers.h
new file mode 100644
index 000000000000..3072a59545b6
--- /dev/null
+++ b/include/linux/mfd/mt6685/registers.h
@@ -0,0 +1,921 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc
+ */
+
+#ifndef _MT6685_HW_H_
+#define _MT6685_HW_H_
+
+#define MT6685_REG_BASE                  ((unsigned int)(0x0))
+#define MT6685_HWCID_L                   (MT6685_REG_BASE + 0x8)
+#define MT6685_TOP_CON                   (MT6685_REG_BASE + 0x18)
+#define MT6685_TOP_CKPDN_CON0            (MT6685_REG_BASE + 0x10b)
+#define MT6685_TOP_CKPDN_CON0_SET        (MT6685_REG_BASE + 0x10c)
+#define MT6685_TOP_CKPDN_CON0_CLR        (MT6685_REG_BASE + 0x10d)
+#define MT6685_TOP_CKSEL_CON0            (MT6685_REG_BASE + 0x111)
+#define MT6685_TOP_CKSEL_CON0_SET        (MT6685_REG_BASE + 0x112)
+#define MT6685_TOP_CKSEL_CON0_CLR        (MT6685_REG_BASE + 0x113)
+#define MT6685_TOP2_ELR1                 (MT6685_REG_BASE + 0x12f)
+#define MT6685_TOP_DIG_WPK               (MT6685_REG_BASE + 0x3a8)
+#define MT6685_TOP_DIG_WPK_H             (MT6685_REG_BASE + 0x3a9)
+#define MT6685_SCK_TOP_INT_STATUS0       (MT6685_REG_BASE + 0x534)
+#define MT6685_SCK_TOP_INT_RAW_STATUS0   (MT6685_REG_BASE + 0x536)
+#define MT6685_SCK_TOP_CON0_L            (MT6685_REG_BASE + 0x50c)
+#define MT6685_SCK_TOP_CON0_H            (MT6685_REG_BASE + 0x50d)
+#define MT6685_SCK_TOP_CKPDN_CON0_L      (MT6685_REG_BASE + 0x514)
+#define MT6685_SCK_TOP_CKPDN_CON0_L_SET  (MT6685_REG_BASE + 0x515)
+#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR  (MT6685_REG_BASE + 0x516)
+#define MT6685_SCK_TOP_RST_CON0          (MT6685_REG_BASE + 0x522)
+#define MT6685_SCK_TOP_INT_CON0          (MT6685_REG_BASE + 0x528)
+#define MT6685_SCK_TOP_INT_CON0_SET      (MT6685_REG_BASE + 0x52a)
+#define MT6685_SCK_TOP_INT_CON0_CLR      (MT6685_REG_BASE + 0x52c)
+#define MT6685_FQMTR_CON0_L              (MT6685_REG_BASE + 0x546)
+#define MT6685_FQMTR_CON0_H              (MT6685_REG_BASE + 0x547)
+#define MT6685_FQMTR_CON1_L              (MT6685_REG_BASE + 0x548)
+#define MT6685_FQMTR_CON2_L              (MT6685_REG_BASE + 0x54a)
+#define MT6685_SCK_TOP_CKSEL_CON         (MT6685_REG_BASE + 0x568)
+#define MT6685_RTC_SPAR_RELOAD           (MT6685_REG_BASE + 0x56a)
+#define MT6685_RTC_ANA_ID                (MT6685_REG_BASE + 0x580)
+#define MT6685_RTC_DIG_ID                (MT6685_REG_BASE + 0x581)
+#define MT6685_RTC_ANA_REV               (MT6685_REG_BASE + 0x582)
+#define MT6685_RTC_DIG_REV               (MT6685_REG_BASE + 0x583)
+#define MT6685_RTC_DBI                   (MT6685_REG_BASE + 0x584)
+#define MT6685_RTC_ESP                   (MT6685_REG_BASE + 0x585)
+#define MT6685_RTC_FPI                   (MT6685_REG_BASE + 0x586)
+#define MT6685_RTC_DXI                   (MT6685_REG_BASE + 0x587)
+#define MT6685_RTC_BBPU_L                (MT6685_REG_BASE + 0x588)
+#define MT6685_RTC_BBPU_H                (MT6685_REG_BASE + 0x589)
+#define MT6685_RTC_IRQ_STA               (MT6685_REG_BASE + 0x58a)
+#define MT6685_RTC_IRQ_EN                (MT6685_REG_BASE + 0x58c)
+#define MT6685_RTC_CII_EN_L              (MT6685_REG_BASE + 0x58e)
+#define MT6685_RTC_CII_EN_H              (MT6685_REG_BASE + 0x58f)
+#define MT6685_RTC_AL_MASK               (MT6685_REG_BASE + 0x590)
+#define MT6685_RTC_TC_SEC                (MT6685_REG_BASE + 0x592)
+#define MT6685_RTC_TC_MIN                (MT6685_REG_BASE + 0x594)
+#define MT6685_RTC_TC_HOU                (MT6685_REG_BASE + 0x596)
+#define MT6685_RTC_TC_DOM                (MT6685_REG_BASE + 0x598)
+#define MT6685_RTC_TC_DOW                (MT6685_REG_BASE + 0x59a)
+#define MT6685_RTC_TC_MTH_L              (MT6685_REG_BASE + 0x59c)
+#define MT6685_RTC_TC_MTH_H              (MT6685_REG_BASE + 0x59d)
+#define MT6685_RTC_TC_YEA                (MT6685_REG_BASE + 0x59e)
+#define MT6685_RTC_AL_SEC_L              (MT6685_REG_BASE + 0x5a0)
+#define MT6685_RTC_AL_SEC_H              (MT6685_REG_BASE + 0x5a1)
+#define MT6685_RTC_AL_MIN                (MT6685_REG_BASE + 0x5a2)
+#define MT6685_RTC_AL_HOU_L              (MT6685_REG_BASE + 0x5a4)
+#define MT6685_RTC_AL_HOU_H              (MT6685_REG_BASE + 0x5a5)
+#define MT6685_RTC_AL_DOM_L              (MT6685_REG_BASE + 0x5a6)
+#define MT6685_RTC_AL_DOM_H              (MT6685_REG_BASE + 0x5a7)
+#define MT6685_RTC_AL_DOW_L              (MT6685_REG_BASE + 0x5a8)
+#define MT6685_RTC_AL_DOW_H              (MT6685_REG_BASE + 0x5a9)
+#define MT6685_RTC_AL_MTH_L              (MT6685_REG_BASE + 0x5aa)
+#define MT6685_RTC_AL_MTH_H              (MT6685_REG_BASE + 0x5ab)
+#define MT6685_RTC_AL_YEA_L              (MT6685_REG_BASE + 0x5ac)
+#define MT6685_RTC_AL_YEA_H              (MT6685_REG_BASE + 0x5ad)
+#define MT6685_RTC_OSC32CON_L            (MT6685_REG_BASE + 0x5ae)
+#define MT6685_RTC_OSC32CON_H            (MT6685_REG_BASE + 0x5af)
+#define MT6685_RTC_POWERKEY1_L           (MT6685_REG_BASE + 0x5b0)
+#define MT6685_RTC_POWERKEY1_H           (MT6685_REG_BASE + 0x5b1)
+#define MT6685_RTC_POWERKEY2_L           (MT6685_REG_BASE + 0x5b2)
+#define MT6685_RTC_POWERKEY2_H           (MT6685_REG_BASE + 0x5b3)
+#define MT6685_RTC_PDN1_L                (MT6685_REG_BASE + 0x5b4)
+#define MT6685_RTC_PDN1_H                (MT6685_REG_BASE + 0x5b5)
+#define MT6685_RTC_PDN2_L                (MT6685_REG_BASE + 0x5b6)
+#define MT6685_RTC_PDN2_H                (MT6685_REG_BASE + 0x5b7)
+#define MT6685_RTC_SPAR0_L               (MT6685_REG_BASE + 0x5b8)
+#define MT6685_RTC_SPAR0_H               (MT6685_REG_BASE + 0x5b9)
+#define MT6685_RTC_SPAR1_L               (MT6685_REG_BASE + 0x5ba)
+#define MT6685_RTC_SPAR1_H               (MT6685_REG_BASE + 0x5bb)
+#define MT6685_RTC_PROT_L                (MT6685_REG_BASE + 0x5bc)
+#define MT6685_RTC_PROT_H                (MT6685_REG_BASE + 0x5bd)
+#define MT6685_RTC_DIFF_L                (MT6685_REG_BASE + 0x5be)
+#define MT6685_RTC_DIFF_H                (MT6685_REG_BASE + 0x5bf)
+#define MT6685_RTC_CALI_L                (MT6685_REG_BASE + 0x5c0)
+#define MT6685_RTC_CALI_H                (MT6685_REG_BASE + 0x5c1)
+#define MT6685_RTC_WRTGR                 (MT6685_REG_BASE + 0x5c2)
+#define MT6685_RTC_CON_L                 (MT6685_REG_BASE + 0x5c4)
+#define MT6685_RTC_CON_H                 (MT6685_REG_BASE + 0x5c5)
+#define MT6685_RTC_SEC_CTRL              (MT6685_REG_BASE + 0x5c6)
+#define MT6685_RTC_INT_CNT_L             (MT6685_REG_BASE + 0x5c8)
+#define MT6685_RTC_INT_CNT_H             (MT6685_REG_BASE + 0x5c9)
+#define MT6685_RTC_SEC_DAT0_L            (MT6685_REG_BASE + 0x5ca)
+#define MT6685_RTC_SEC_DAT0_H            (MT6685_REG_BASE + 0x5cb)
+#define MT6685_RTC_SEC_DAT1_L            (MT6685_REG_BASE + 0x5cc)
+#define MT6685_RTC_SEC_DAT1_H            (MT6685_REG_BASE + 0x5cd)
+#define MT6685_RTC_SEC_DAT2_L            (MT6685_REG_BASE + 0x5ce)
+#define MT6685_RTC_SEC_DAT2_H            (MT6685_REG_BASE + 0x5cf)
+#define MT6685_RTC_RG_FG0                (MT6685_REG_BASE + 0x5d0)
+#define MT6685_RTC_RG_FG1                (MT6685_REG_BASE + 0x5d2)
+#define MT6685_RTC_RG_FG2                (MT6685_REG_BASE + 0x5d4)
+#define MT6685_RTC_RG_FG3                (MT6685_REG_BASE + 0x5d6)
+#define MT6685_RTC_SPAR_MACRO            (MT6685_REG_BASE + 0x5d8)
+#define MT6685_RTC_SPAR_CORE             (MT6685_REG_BASE + 0x5e0)
+#define MT6685_RTC_EOSC_CALI             (MT6685_REG_BASE + 0x5e2)
+#define MT6685_RTC_SEC_ANA_ID            (MT6685_REG_BASE + 0x600)
+#define MT6685_RTC_SEC_DIG_ID            (MT6685_REG_BASE + 0x601)
+#define MT6685_RTC_SEC_ANA_REV           (MT6685_REG_BASE + 0x602)
+#define MT6685_RTC_SEC_DIG_REV           (MT6685_REG_BASE + 0x603)
+#define MT6685_RTC_SEC_DBI               (MT6685_REG_BASE + 0x604)
+#define MT6685_RTC_SEC_ESP               (MT6685_REG_BASE + 0x605)
+#define MT6685_RTC_SEC_FPI               (MT6685_REG_BASE + 0x606)
+#define MT6685_RTC_SEC_DXI               (MT6685_REG_BASE + 0x607)
+#define MT6685_RTC_TC_SEC_SEC            (MT6685_REG_BASE + 0x608)
+#define MT6685_RTC_TC_MIN_SEC            (MT6685_REG_BASE + 0x60a)
+#define MT6685_RTC_TC_HOU_SEC            (MT6685_REG_BASE + 0x60c)
+#define MT6685_RTC_TC_DOM_SEC            (MT6685_REG_BASE + 0x60e)
+#define MT6685_RTC_TC_DOW_SEC            (MT6685_REG_BASE + 0x610)
+#define MT6685_RTC_TC_MTH_SEC            (MT6685_REG_BASE + 0x612)
+#define MT6685_RTC_TC_YEA_SEC            (MT6685_REG_BASE + 0x614)
+#define MT6685_RTC_SEC_CK_PDN            (MT6685_REG_BASE + 0x616)
+#define MT6685_RTC_SEC_WRTGR             (MT6685_REG_BASE + 0x618)
+#define MT6685_DCXO_DIG_MODE_CW0         (MT6685_REG_BASE + 0x789)
+/* mask is HEX;	shift is Integer */
+#define MT6685_RG_SRCLKEN_IN0_HW_MODE_ADDR                  \
+	MT6685_TOP_CON
+#define MT6685_RG_SRCLKEN_IN0_HW_MODE_MASK                  0x1
+#define MT6685_RG_SRCLKEN_IN0_HW_MODE_SHIFT                 1
+#define MT6685_RG_SRCLKEN_IN1_HW_MODE_ADDR                  \
+	MT6685_TOP_CON
+#define MT6685_RG_SRCLKEN_IN1_HW_MODE_MASK                  0x1
+#define MT6685_RG_FQMTR_32K_CK_PDN_ADDR                     \
+	MT6685_TOP_CKPDN_CON0
+#define MT6685_RG_FQMTR_32K_CK_PDN_MASK                     0x1
+#define MT6685_RG_FQMTR_32K_CK_PDN_SHIFT                    4
+	#define MT6685_RG_SRCLKEN_IN1_HW_MODE_SHIFT             2
+#define MT6685_RG_FQMTR_CK_PDN_ADDR                         \
+	MT6685_TOP_CKPDN_CON0
+#define MT6685_RG_FQMTR_CK_PDN_MASK                         0x1
+#define MT6685_RG_FQMTR_CK_PDN_SHIFT                        5
+#define MT6685_RG_INTRP_CK_PDN_ADDR                         \
+	MT6685_TOP_CKPDN_CON0
+#define MT6685_RG_INTRP_CK_PDN_MASK                         0x1
+#define MT6685_RG_INTRP_CK_PDN_SHIFT                        6
+#define MT6685_TOP_CKPDN_CON0_SET_ADDR                      \
+	MT6685_TOP_CKPDN_CON0_SET
+#define MT6685_TOP_CKPDN_CON0_SET_MASK                      0xFF
+#define MT6685_TOP_CKPDN_CON0_SET_SHIFT                     0
+#define MT6685_TOP_CKPDN_CON0_CLR_ADDR                      \
+	MT6685_TOP_CKPDN_CON0_CLR
+#define MT6685_TOP_CKPDN_CON0_CLR_MASK                      0xFF
+#define MT6685_TOP_CKPDN_CON0_CLR_SHIFT                     0
+#define MT6685_RG_FQMTR_CK_CKSEL_ADDR                       \
+	MT6685_TOP_CKSEL_CON0
+#define MT6685_RG_FQMTR_CK_CKSEL_MASK                       0x7
+#define MT6685_RG_FQMTR_CK_CKSEL_SHIFT                      0
+#define MT6685_RG_PMU32K_CK_CKSEL_ADDR                      \
+	MT6685_TOP_CKSEL_CON0
+#define MT6685_RG_PMU32K_CK_CKSEL_MASK                      0x1
+#define MT6685_RG_PMU32K_CK_CKSEL_SHIFT                     3
+#define MT6685_TOP_CKSEL_CON0_SET_ADDR                      \
+	MT6685_TOP_CKSEL_CON0_SET
+#define MT6685_TOP_CKSEL_CON0_SET_MASK                      0xFF
+#define MT6685_TOP_CKSEL_CON0_SET_SHIFT                     0
+#define MT6685_TOP_CKSEL_CON0_CLR_ADDR                      \
+	MT6685_TOP_CKSEL_CON0_CLR
+#define MT6685_TOP_CKSEL_CON0_CLR_MASK                      0xFF
+#define MT6685_TOP_CKSEL_CON0_CLR_SHIFT                     0
+#define MT6685_DIG_WPK_KEY_ADDR                             \
+	MT6685_TOP_DIG_WPK
+#define MT6685_DIG_WPK_KEY_MASK                             0xFF
+#define MT6685_DIG_WPK_KEY_SHIFT                            0
+#define MT6685_DIG_WPK_KEY_H_ADDR                           \
+	MT6685_TOP_DIG_WPK_H
+#define MT6685_DIG_WPK_KEY_H_MASK                           0xFF
+#define MT6685_DIG_WPK_KEY_H_SHIFT                          0
+#define MT6685_SCK_TOP_XTAL_SEL_ADDR                        \
+	MT6685_SCK_TOP_CON0_L
+#define MT6685_SCK_TOP_XTAL_SEL_MASK                        0x1
+#define MT6685_SCK_TOP_XTAL_SEL_SHIFT                       0
+#define MT6685_RG_RTC_SEC_MCLK_PDN_ADDR                     \
+	MT6685_SCK_TOP_CKPDN_CON0_L
+#define MT6685_RG_RTC_SEC_MCLK_PDN_MASK                     0x1
+#define MT6685_RG_RTC_SEC_MCLK_PDN_SHIFT                    0
+#define MT6685_RG_RTC_EOSC32_CK_PDN_ADDR                    \
+	MT6685_SCK_TOP_CKPDN_CON0_L
+#define MT6685_RG_RTC_EOSC32_CK_PDN_MASK                    0x1
+#define MT6685_RG_RTC_EOSC32_CK_PDN_SHIFT                   2
+#define MT6685_RG_RTC_SEC_32K_CK_PDN_ADDR                   \
+	MT6685_SCK_TOP_CKPDN_CON0_L
+#define MT6685_RG_RTC_SEC_32K_CK_PDN_MASK                   0x1
+#define MT6685_RG_RTC_SEC_32K_CK_PDN_SHIFT                  3
+#define MT6685_RG_RTC_MCLK_PDN_ADDR                         \
+	MT6685_SCK_TOP_CKPDN_CON0_L
+#define MT6685_RG_RTC_MCLK_PDN_MASK                         0x1
+#define MT6685_RG_RTC_MCLK_PDN_SHIFT                        4
+#define MT6685_RG_RTC_32K_CK_PDN_ADDR                       \
+	MT6685_SCK_TOP_CKPDN_CON0_L
+#define MT6685_RG_RTC_32K_CK_PDN_MASK                       0x1
+#define MT6685_RG_RTC_32K_CK_PDN_SHIFT                      5
+#define MT6685_SCK_TOP_CKPDN_CON0_L_SET_ADDR                \
+	MT6685_SCK_TOP_CKPDN_CON0_L_SET
+#define MT6685_SCK_TOP_CKPDN_CON0_L_SET_MASK                0xFF
+#define MT6685_SCK_TOP_CKPDN_CON0_L_SET_SHIFT               0
+#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR_ADDR                \
+	MT6685_SCK_TOP_CKPDN_CON0_L_CLR
+#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR_MASK                0xFF
+#define MT6685_SCK_TOP_CKPDN_CON0_L_CLR_SHIFT               0
+#define MT6685_RG_BANK_FQMTR_RST_ADDR                       \
+	MT6685_SCK_TOP_RST_CON0
+#define MT6685_RG_BANK_FQMTR_RST_MASK                       0x1
+#define MT6685_RG_BANK_FQMTR_RST_SHIFT                      6
+#define MT6685_RG_RTC_DIG_TEST_MODE_ADDR                    \
+	MT6685_RTC_DIG_CON0_H
+#define MT6685_RG_RTC_DIG_TEST_MODE_MASK                    0x1
+#define MT6685_RG_RTC_DIG_TEST_MODE_SHIFT                   7
+#define MT6685_FQMTR_TCKSEL_ADDR                            \
+	MT6685_FQMTR_CON0_L
+#define MT6685_FQMTR_TCKSEL_MASK                            0x7
+#define MT6685_FQMTR_TCKSEL_SHIFT                           0
+#define MT6685_FQMTR_BUSY_ADDR                              \
+	MT6685_FQMTR_CON0_L
+#define MT6685_FQMTR_BUSY_MASK                              0x1
+#define MT6685_FQMTR_BUSY_SHIFT                             3
+#define MT6685_FQMTR_DCXO26M_EN_ADDR                        \
+	MT6685_FQMTR_CON0_L
+#define MT6685_FQMTR_DCXO26M_EN_MASK                        0x1
+#define MT6685_FQMTR_DCXO26M_EN_SHIFT                       4
+#define MT6685_FQMTR_EN_ADDR                                \
+	MT6685_FQMTR_CON0_H
+#define MT6685_FQMTR_EN_MASK                                0x1
+#define MT6685_FQMTR_EN_SHIFT                               7
+#define MT6685_FQMTR_WINSET_L_ADDR                          \
+	MT6685_FQMTR_CON1_L
+#define MT6685_FQMTR_WINSET_L_MASK                          0xFF
+#define MT6685_FQMTR_WINSET_L_SHIFT                         0
+#define MT6685_FQMTR_WINSET_H_ADDR                          \
+	MT6685_FQMTR_CON1_H
+#define MT6685_FQMTR_WINSET_H_MASK                          0xFF
+#define MT6685_FQMTR_WINSET_H_SHIFT                         0
+#define MT6685_FQMTR_DATA_L_ADDR                            \
+	MT6685_FQMTR_CON2_L
+#define MT6685_FQMTR_DATA_L_MASK                            0xFF
+#define MT6685_FQMTR_DATA_L_SHIFT                           0
+#define MT6685_RG_RTC_32K1V8_0_SEL_ADDR                     \
+	MT6685_SCK_TOP_CKSEL_CON
+#define MT6685_RG_RTC_32K1V8_0_SEL_MASK                     0x3
+#define MT6685_RG_RTC_32K1V8_0_SEL_SHIFT                    0
+#define MT6685_SPAR_SW_RELOAD_ADDR                          \
+	MT6685_RTC_SPAR_RELOAD
+#define MT6685_SPAR_SW_RELOAD_MASK                          0x1
+#define MT6685_SPAR_SW_RELOAD_SHIFT                         0
+#define MT6685_RTC_ANA_ID_ADDR                              \
+	MT6685_RTC_ANA_ID
+#define MT6685_RTC_ANA_ID_MASK                              0xFF
+#define MT6685_RTC_ANA_ID_SHIFT                             0
+#define MT6685_RTC_DIG_ID_ADDR                              \
+	MT6685_RTC_DIG_ID
+#define MT6685_RTC_DIG_ID_MASK                              0xFF
+#define MT6685_RTC_DIG_ID_SHIFT                             0
+#define MT6685_RTC_ANA_MINOR_REV_ADDR                       \
+	MT6685_RTC_ANA_REV
+#define MT6685_RTC_ANA_MINOR_REV_MASK                       0xF
+#define MT6685_RTC_ANA_MINOR_REV_SHIFT                      0
+#define MT6685_RTC_ANA_MAJOR_REV_ADDR                       \
+	MT6685_RTC_ANA_REV
+#define MT6685_RTC_ANA_MAJOR_REV_MASK                       0xF
+#define MT6685_RTC_ANA_MAJOR_REV_SHIFT                      4
+#define MT6685_RTC_DIG_MINOR_REV_ADDR                       \
+	MT6685_RTC_DIG_REV
+#define MT6685_RTC_DIG_MINOR_REV_MASK                       0xF
+#define MT6685_RTC_DIG_MINOR_REV_SHIFT                      0
+#define MT6685_RTC_DIG_MAJOR_REV_ADDR                       \
+	MT6685_RTC_DIG_REV
+#define MT6685_RTC_DIG_MAJOR_REV_MASK                       0xF
+#define MT6685_RTC_DIG_MAJOR_REV_SHIFT                      4
+#define MT6685_RTC_CBS_ADDR                                 \
+	MT6685_RTC_DBI
+#define MT6685_RTC_CBS_MASK                                 0x3
+#define MT6685_RTC_CBS_SHIFT                                0
+#define MT6685_RTC_BIX_ADDR                                 \
+	MT6685_RTC_DBI
+#define MT6685_RTC_BIX_MASK                                 0x3
+#define MT6685_RTC_BIX_SHIFT                                2
+#define MT6685_RTC_ESP_ADDR                                 \
+	MT6685_RTC_ESP
+#define MT6685_RTC_ESP_MASK                                 0xFF
+#define MT6685_RTC_ESP_SHIFT                                0
+#define MT6685_RTC_FPI_ADDR                                 \
+	MT6685_RTC_FPI
+#define MT6685_RTC_FPI_MASK                                 0xFF
+#define MT6685_RTC_FPI_SHIFT                                0
+#define MT6685_RTC_DXI_ADDR                                 \
+	MT6685_RTC_DXI
+#define MT6685_RTC_DXI_MASK                                 0xFF
+#define MT6685_RTC_DXI_SHIFT                                0
+#define MT6685_BBPU_ADDR                                    \
+	MT6685_RTC_BBPU_L
+#define MT6685_BBPU_MASK                                    0xF
+#define MT6685_BBPU_SHIFT                                   0
+#define MT6685_CLRPKY_ADDR                                  \
+	MT6685_RTC_BBPU_L
+#define MT6685_CLRPKY_MASK                                  0x1
+#define MT6685_CLRPKY_SHIFT                                 4
+#define MT6685_RELOAD_ADDR                                  \
+	MT6685_RTC_BBPU_L
+#define MT6685_RELOAD_MASK                                  0x1
+#define MT6685_RELOAD_SHIFT                                 5
+#define MT6685_CBUSY_ADDR                                   \
+	MT6685_RTC_BBPU_L
+#define MT6685_CBUSY_MASK                                   0x1
+#define MT6685_CBUSY_SHIFT                                  6
+#define MT6685_ALARM_STATUS_ADDR                            \
+	MT6685_RTC_BBPU_L
+#define MT6685_ALARM_STATUS_MASK                            0x1
+#define MT6685_ALARM_STATUS_SHIFT                           7
+#define MT6685_KEY_BBPU_ADDR                                \
+	MT6685_RTC_BBPU_H
+#define MT6685_KEY_BBPU_MASK                                0xFF
+#define MT6685_KEY_BBPU_SHIFT                               0
+#define MT6685_ALSTA_ADDR                                   \
+	MT6685_RTC_IRQ_STA
+#define MT6685_ALSTA_MASK                                   0x1
+#define MT6685_ALSTA_SHIFT                                  0
+#define MT6685_TCSTA_ADDR                                   \
+	MT6685_RTC_IRQ_STA
+#define MT6685_TCSTA_MASK                                   0x1
+#define MT6685_TCSTA_SHIFT                                  1
+#define MT6685_LPSTA_ADDR                                   \
+	MT6685_RTC_IRQ_STA
+#define MT6685_LPSTA_MASK                                   0x1
+#define MT6685_LPSTA_SHIFT                                  3
+#define MT6685_AL_EN_ADDR                                   \
+	MT6685_RTC_IRQ_EN
+#define MT6685_AL_EN_MASK                                   0x1
+#define MT6685_AL_EN_SHIFT                                  0
+#define MT6685_TC_EN_ADDR                                   \
+	MT6685_RTC_IRQ_EN
+#define MT6685_TC_EN_MASK                                   0x1
+#define MT6685_TC_EN_SHIFT                                  1
+#define MT6685_ONESHOT_ADDR                                 \
+	MT6685_RTC_IRQ_EN
+#define MT6685_ONESHOT_MASK                                 0x1
+#define MT6685_ONESHOT_SHIFT                                2
+#define MT6685_LP_EN_ADDR                                   \
+	MT6685_RTC_IRQ_EN
+#define MT6685_LP_EN_MASK                                   0x1
+#define MT6685_LP_EN_SHIFT                                  3
+#define MT6685_SECCII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_SECCII_MASK                                  0x1
+#define MT6685_SECCII_SHIFT                                 0
+#define MT6685_MINCII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_MINCII_MASK                                  0x1
+#define MT6685_MINCII_SHIFT                                 1
+#define MT6685_HOUCII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_HOUCII_MASK                                  0x1
+#define MT6685_HOUCII_SHIFT                                 2
+#define MT6685_DOMCII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_DOMCII_MASK                                  0x1
+#define MT6685_DOMCII_SHIFT                                 3
+#define MT6685_DOWCII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_DOWCII_MASK                                  0x1
+#define MT6685_DOWCII_SHIFT                                 4
+#define MT6685_MTHCII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_MTHCII_MASK                                  0x1
+#define MT6685_MTHCII_SHIFT                                 5
+#define MT6685_YEACII_ADDR                                  \
+	MT6685_RTC_CII_EN_L
+#define MT6685_YEACII_MASK                                  0x1
+#define MT6685_YEACII_SHIFT                                 6
+#define MT6685_SECCII_1_2_ADDR                              \
+	MT6685_RTC_CII_EN_L
+#define MT6685_SECCII_1_2_MASK                              0x1
+#define MT6685_SECCII_1_2_SHIFT                             7
+#define MT6685_SECCII_1_4_ADDR                              \
+	MT6685_RTC_CII_EN_H
+#define MT6685_SECCII_1_4_MASK                              0x1
+#define MT6685_SECCII_1_4_SHIFT                             0
+#define MT6685_SECCII_1_8_ADDR                              \
+	MT6685_RTC_CII_EN_H
+#define MT6685_SECCII_1_8_MASK                              0x1
+#define MT6685_SECCII_1_8_SHIFT                             1
+#define MT6685_SEC_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_SEC_MSK_MASK                                 0x1
+#define MT6685_SEC_MSK_SHIFT                                0
+#define MT6685_MIN_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_MIN_MSK_MASK                                 0x1
+#define MT6685_MIN_MSK_SHIFT                                1
+#define MT6685_HOU_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_HOU_MSK_MASK                                 0x1
+#define MT6685_HOU_MSK_SHIFT                                2
+#define MT6685_DOM_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_DOM_MSK_MASK                                 0x1
+#define MT6685_DOM_MSK_SHIFT                                3
+#define MT6685_DOW_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_DOW_MSK_MASK                                 0x1
+#define MT6685_DOW_MSK_SHIFT                                4
+#define MT6685_MTH_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_MTH_MSK_MASK                                 0x1
+#define MT6685_MTH_MSK_SHIFT                                5
+#define MT6685_YEA_MSK_ADDR                                 \
+	MT6685_RTC_AL_MASK
+#define MT6685_YEA_MSK_MASK                                 0x1
+#define MT6685_YEA_MSK_SHIFT                                6
+#define MT6685_TC_SECOND_ADDR                               \
+	MT6685_RTC_TC_SEC
+#define MT6685_TC_SECOND_MASK                               0x3F
+#define MT6685_TC_SECOND_SHIFT                              0
+#define MT6685_TC_MINUTE_ADDR                               \
+	MT6685_RTC_TC_MIN
+#define MT6685_TC_MINUTE_MASK                               0x3F
+#define MT6685_TC_MINUTE_SHIFT                              0
+#define MT6685_TC_HOUR_ADDR                                 \
+	MT6685_RTC_TC_HOU
+#define MT6685_TC_HOUR_MASK                                 0x1F
+#define MT6685_TC_HOUR_SHIFT                                0
+#define MT6685_TC_DOM_ADDR                                  \
+	MT6685_RTC_TC_DOM
+#define MT6685_TC_DOM_MASK                                  0x1F
+#define MT6685_TC_DOM_SHIFT                                 0
+#define MT6685_TC_DOW_ADDR                                  \
+	MT6685_RTC_TC_DOW
+#define MT6685_TC_DOW_MASK                                  0x7
+#define MT6685_TC_DOW_SHIFT                                 0
+#define MT6685_TC_MONTH_ADDR                                \
+	MT6685_RTC_TC_MTH_L
+#define MT6685_TC_MONTH_MASK                                0xF
+#define MT6685_TC_MONTH_SHIFT                               0
+#define MT6685_RTC_MACRO_ID_L_ADDR                          \
+	MT6685_RTC_TC_MTH_L
+#define MT6685_RTC_MACRO_ID_L_MASK                          0xF
+#define MT6685_RTC_MACRO_ID_L_SHIFT                         4
+#define MT6685_RTC_MACRO_ID_H_ADDR                          \
+	MT6685_RTC_TC_MTH_H
+#define MT6685_RTC_MACRO_ID_H_MASK                          0xFF
+#define MT6685_RTC_MACRO_ID_H_SHIFT                         0
+#define MT6685_TC_YEAR_ADDR                                 \
+	MT6685_RTC_TC_YEA
+#define MT6685_TC_YEAR_MASK                                 0x7F
+#define MT6685_TC_YEAR_SHIFT                                0
+#define MT6685_AL_SECOND_ADDR                               \
+	MT6685_RTC_AL_SEC_L
+#define MT6685_AL_SECOND_MASK                               0x3F
+#define MT6685_AL_SECOND_SHIFT                              0
+#define MT6685_BBPU_AUTO_PDN_SEL_ADDR                       \
+	MT6685_RTC_AL_SEC_L
+#define MT6685_BBPU_AUTO_PDN_SEL_MASK                       0x1
+#define MT6685_BBPU_AUTO_PDN_SEL_SHIFT                      6
+#define MT6685_BBPU_2SEC_CK_SEL_ADDR                        \
+	MT6685_RTC_AL_SEC_L
+#define MT6685_BBPU_2SEC_CK_SEL_MASK                        0x1
+#define MT6685_BBPU_2SEC_CK_SEL_SHIFT                       7
+#define MT6685_BBPU_2SEC_EN_ADDR                            \
+	MT6685_RTC_AL_SEC_H
+#define MT6685_BBPU_2SEC_EN_MASK                            0x1
+#define MT6685_BBPU_2SEC_EN_SHIFT                           0
+#define MT6685_BBPU_2SEC_MODE_ADDR                          \
+	MT6685_RTC_AL_SEC_H
+#define MT6685_BBPU_2SEC_MODE_MASK                          0x3
+#define MT6685_BBPU_2SEC_MODE_SHIFT                         1
+#define MT6685_BBPU_2SEC_STAT_CLEAR_ADDR                    \
+	MT6685_RTC_AL_SEC_H
+#define MT6685_BBPU_2SEC_STAT_CLEAR_MASK                    0x1
+#define MT6685_BBPU_2SEC_STAT_CLEAR_SHIFT                   3
+#define MT6685_BBPU_2SEC_STAT_STA_ADDR                      \
+	MT6685_RTC_AL_SEC_H
+#define MT6685_BBPU_2SEC_STAT_STA_MASK                      0x1
+#define MT6685_BBPU_2SEC_STAT_STA_SHIFT                     4
+#define MT6685_RTC_LPD_OPT_ADDR                             \
+	MT6685_RTC_AL_SEC_H
+#define MT6685_RTC_LPD_OPT_MASK                             0x3
+#define MT6685_RTC_LPD_OPT_SHIFT                            5
+#define MT6685_K_EOSC32_VTCXO_ON_SEL_ADDR                   \
+	MT6685_RTC_AL_SEC_H
+#define MT6685_K_EOSC32_VTCXO_ON_SEL_MASK                   0x1
+#define MT6685_K_EOSC32_VTCXO_ON_SEL_SHIFT                  7
+#define MT6685_AL_MINUTE_ADDR                               \
+	MT6685_RTC_AL_MIN
+#define MT6685_AL_MINUTE_MASK                               0x3F
+#define MT6685_AL_MINUTE_SHIFT                              0
+#define MT6685_AL_HOUR_ADDR                                 \
+	MT6685_RTC_AL_HOU_L
+#define MT6685_AL_HOUR_MASK                                 0x1F
+#define MT6685_AL_HOUR_SHIFT                                0
+#define MT6685_NEW_SPARE0_ADDR                              \
+	MT6685_RTC_AL_HOU_H
+#define MT6685_NEW_SPARE0_MASK                              0xFF
+#define MT6685_NEW_SPARE0_SHIFT                             0
+#define MT6685_AL_DOM_ADDR                                  \
+	MT6685_RTC_AL_DOM_L
+#define MT6685_AL_DOM_MASK                                  0x1F
+#define MT6685_AL_DOM_SHIFT                                 0
+#define MT6685_NEW_SPARE1_ADDR                              \
+	MT6685_RTC_AL_DOM_H
+#define MT6685_NEW_SPARE1_MASK                              0xFF
+#define MT6685_NEW_SPARE1_SHIFT                             0
+#define MT6685_AL_DOW_ADDR                                  \
+	MT6685_RTC_AL_DOW_L
+#define MT6685_AL_DOW_MASK                                  0x7
+#define MT6685_AL_DOW_SHIFT                                 0
+#define MT6685_RG_EOSC_CALI_TD_ADDR                         \
+	MT6685_RTC_AL_DOW_L
+#define MT6685_RG_EOSC_CALI_TD_MASK                         0x7
+#define MT6685_RG_EOSC_CALI_TD_SHIFT                        5
+#define MT6685_NEW_SPARE2_ADDR                              \
+	MT6685_RTC_AL_DOW_H
+#define MT6685_NEW_SPARE2_MASK                              0xFF
+#define MT6685_NEW_SPARE2_SHIFT                             0
+#define MT6685_AL_MONTH_ADDR                                \
+	MT6685_RTC_AL_MTH_L
+#define MT6685_AL_MONTH_MASK                                0xF
+#define MT6685_AL_MONTH_SHIFT                               0
+#define MT6685_NEW_SPARE3_ADDR                              \
+	MT6685_RTC_AL_MTH_H
+#define MT6685_NEW_SPARE3_MASK                              0xFF
+#define MT6685_NEW_SPARE3_SHIFT                             0
+#define MT6685_AL_YEAR_ADDR                                 \
+	MT6685_RTC_AL_YEA_L
+#define MT6685_AL_YEAR_MASK                                 0x7F
+#define MT6685_AL_YEAR_SHIFT                                0
+#define MT6685_RTC_K_EOSC_RSV_ADDR                          \
+	MT6685_RTC_AL_YEA_H
+#define MT6685_RTC_K_EOSC_RSV_MASK                          0xFF
+#define MT6685_RTC_K_EOSC_RSV_SHIFT                         0
+#define MT6685_XOSCCALI_ADDR                                \
+	MT6685_RTC_OSC32CON_L
+#define MT6685_XOSCCALI_MASK                                0x1F
+#define MT6685_XOSCCALI_SHIFT                               0
+#define MT6685_RTC_XOSC32_ENB_ADDR                          \
+	MT6685_RTC_OSC32CON_L
+#define MT6685_RTC_XOSC32_ENB_MASK                          0x1
+#define MT6685_RTC_XOSC32_ENB_SHIFT                         5
+#define MT6685_RTC_EMBCK_SEL_MODE_ADDR                      \
+	MT6685_RTC_OSC32CON_L
+#define MT6685_RTC_EMBCK_SEL_MODE_MASK                      0x3
+#define MT6685_RTC_EMBCK_SEL_MODE_SHIFT                     6
+#define MT6685_RTC_EMBCK_SRC_SEL_ADDR                       \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_EMBCK_SRC_SEL_MASK                       0x1
+#define MT6685_RTC_EMBCK_SRC_SEL_SHIFT                      0
+#define MT6685_RTC_EMBCK_SEL_OPTION_ADDR                    \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_EMBCK_SEL_OPTION_MASK                    0x1
+#define MT6685_RTC_EMBCK_SEL_OPTION_SHIFT                   1
+#define MT6685_RTC_GPS_CKOUT_EN_ADDR                        \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_GPS_CKOUT_EN_MASK                        0x1
+#define MT6685_RTC_GPS_CKOUT_EN_SHIFT                       2
+#define MT6685_RTC_EOSC32_VCT_EN_ADDR                       \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_EOSC32_VCT_EN_MASK                       0x1
+#define MT6685_RTC_EOSC32_VCT_EN_SHIFT                      3
+#define MT6685_RTC_EOSC32_CHOP_EN_ADDR                      \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_EOSC32_CHOP_EN_MASK                      0x1
+#define MT6685_RTC_EOSC32_CHOP_EN_SHIFT                     4
+#define MT6685_RTC_GP_OSC32_CON_ADDR                        \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_GP_OSC32_CON_MASK                        0x3
+#define MT6685_RTC_GP_OSC32_CON_SHIFT                       5
+#define MT6685_RTC_REG_XOSC32_ENB_ADDR                      \
+	MT6685_RTC_OSC32CON_H
+#define MT6685_RTC_REG_XOSC32_ENB_MASK                      0x1
+#define MT6685_RTC_REG_XOSC32_ENB_SHIFT                     7
+#define MT6685_RTC_POWERKEY1_L_ADDR                         \
+	MT6685_RTC_POWERKEY1_L
+#define MT6685_RTC_POWERKEY1_L_MASK                         0xFF
+#define MT6685_RTC_POWERKEY1_L_SHIFT                        0
+#define MT6685_RTC_POWERKEY1_H_ADDR                         \
+	MT6685_RTC_POWERKEY1_H
+#define MT6685_RTC_POWERKEY1_H_MASK                         0xFF
+#define MT6685_RTC_POWERKEY1_H_SHIFT                        0
+#define MT6685_RTC_POWERKEY2_L_ADDR                         \
+	MT6685_RTC_POWERKEY2_L
+#define MT6685_RTC_POWERKEY2_L_MASK                         0xFF
+#define MT6685_RTC_POWERKEY2_L_SHIFT                        0
+#define MT6685_RTC_POWERKEY2_H_ADDR                         \
+	MT6685_RTC_POWERKEY2_H
+#define MT6685_RTC_POWERKEY2_H_MASK                         0xFF
+#define MT6685_RTC_POWERKEY2_H_SHIFT                        0
+#define MT6685_RTC_PDN1_L_ADDR                              \
+	MT6685_RTC_PDN1_L
+#define MT6685_RTC_PDN1_L_MASK                              0xFF
+#define MT6685_RTC_PDN1_L_SHIFT                             0
+#define MT6685_RTC_PDN1_H_ADDR                              \
+	MT6685_RTC_PDN1_H
+#define MT6685_RTC_PDN1_H_MASK                              0xFF
+#define MT6685_RTC_PDN1_H_SHIFT                             0
+#define MT6685_RTC_PDN2_L_ADDR                              \
+	MT6685_RTC_PDN2_L
+#define MT6685_RTC_PDN2_L_MASK                              0xFF
+#define MT6685_RTC_PDN2_L_SHIFT                             0
+#define MT6685_RTC_PDN2_H_ADDR                              \
+	MT6685_RTC_PDN2_H
+#define MT6685_RTC_PDN2_H_MASK                              0xFF
+#define MT6685_RTC_PDN2_H_SHIFT                             0
+#define MT6685_RTC_SPAR0_L_ADDR                             \
+	MT6685_RTC_SPAR0_L
+#define MT6685_RTC_SPAR0_L_MASK                             0xFF
+#define MT6685_RTC_SPAR0_L_SHIFT                            0
+#define MT6685_RTC_SPAR0_H_ADDR                             \
+	MT6685_RTC_SPAR0_H
+#define MT6685_RTC_SPAR0_H_MASK                             0xFF
+#define MT6685_RTC_SPAR0_H_SHIFT                            0
+#define MT6685_RTC_SPAR1_L_ADDR                             \
+	MT6685_RTC_SPAR1_L
+#define MT6685_RTC_SPAR1_L_MASK                             0xFF
+#define MT6685_RTC_SPAR1_L_SHIFT                            0
+#define MT6685_RTC_SPAR1_H_ADDR                             \
+	MT6685_RTC_SPAR1_H
+#define MT6685_RTC_SPAR1_H_MASK                             0xFF
+#define MT6685_RTC_SPAR1_H_SHIFT                            0
+#define MT6685_RTC_PROT_L_ADDR                              \
+	MT6685_RTC_PROT_L
+#define MT6685_RTC_PROT_L_MASK                              0xFF
+#define MT6685_RTC_PROT_L_SHIFT                             0
+#define MT6685_RTC_PROT_H_ADDR                              \
+	MT6685_RTC_PROT_H
+#define MT6685_RTC_PROT_H_MASK                              0xFF
+#define MT6685_RTC_PROT_H_SHIFT                             0
+#define MT6685_RTC_DIFF_L_ADDR                              \
+	MT6685_RTC_DIFF_L
+#define MT6685_RTC_DIFF_L_MASK                              0xFF
+#define MT6685_RTC_DIFF_L_SHIFT                             0
+#define MT6685_RTC_DIFF_H_ADDR                              \
+	MT6685_RTC_DIFF_H
+#define MT6685_RTC_DIFF_H_MASK                              0xF
+#define MT6685_RTC_DIFF_H_SHIFT                             0
+#define MT6685_POWER_DETECTED_ADDR                          \
+	MT6685_RTC_DIFF_H
+#define MT6685_POWER_DETECTED_MASK                          0x1
+#define MT6685_POWER_DETECTED_SHIFT                         4
+#define MT6685_K_EOSC32_RSV_ADDR                            \
+	MT6685_RTC_DIFF_H
+#define MT6685_K_EOSC32_RSV_MASK                            0x1
+#define MT6685_K_EOSC32_RSV_SHIFT                           6
+#define MT6685_CALI_RD_SEL_ADDR                             \
+	MT6685_RTC_DIFF_H
+#define MT6685_CALI_RD_SEL_MASK                             0x1
+#define MT6685_CALI_RD_SEL_SHIFT                            7
+#define MT6685_RTC_CALI_L_ADDR                              \
+	MT6685_RTC_CALI_L
+#define MT6685_RTC_CALI_L_MASK                              0xFF
+#define MT6685_RTC_CALI_L_SHIFT                             0
+#define MT6685_RTC_CALI_H_ADDR                              \
+	MT6685_RTC_CALI_H
+#define MT6685_RTC_CALI_H_MASK                              0x3F
+#define MT6685_RTC_CALI_H_SHIFT                             0
+#define MT6685_CALI_WR_SEL_ADDR                             \
+	MT6685_RTC_CALI_H
+#define MT6685_CALI_WR_SEL_MASK                             0x1
+#define MT6685_CALI_WR_SEL_SHIFT                            6
+#define MT6685_K_EOSC32_OVERFLOW_ADDR                       \
+	MT6685_RTC_CALI_H
+#define MT6685_K_EOSC32_OVERFLOW_MASK                       0x1
+#define MT6685_K_EOSC32_OVERFLOW_SHIFT                      7
+#define MT6685_WRTGR_ADDR                                   \
+	MT6685_RTC_WRTGR
+#define MT6685_WRTGR_MASK                                   0x1
+#define MT6685_WRTGR_SHIFT                                  0
+#define MT6685_VBAT_LPSTA_RAW_ADDR                          \
+	MT6685_RTC_CON_L
+#define MT6685_VBAT_LPSTA_RAW_MASK                          0x1
+#define MT6685_VBAT_LPSTA_RAW_SHIFT                         0
+#define MT6685_EOSC32_LPEN_ADDR                             \
+	MT6685_RTC_CON_L
+#define MT6685_EOSC32_LPEN_MASK                             0x1
+#define MT6685_EOSC32_LPEN_SHIFT                            1
+#define MT6685_XOSC32_LPEN_ADDR                             \
+	MT6685_RTC_CON_L
+#define MT6685_XOSC32_LPEN_MASK                             0x1
+#define MT6685_XOSC32_LPEN_SHIFT                            2
+#define MT6685_LPRST_ADDR                                   \
+	MT6685_RTC_CON_L
+#define MT6685_LPRST_MASK                                   0x1
+#define MT6685_LPRST_SHIFT                                  3
+#define MT6685_CDBO_ADDR                                    \
+	MT6685_RTC_CON_L
+#define MT6685_CDBO_MASK                                    0x1
+#define MT6685_CDBO_SHIFT                                   4
+#define MT6685_F32KOB_ADDR                                  \
+	MT6685_RTC_CON_L
+#define MT6685_F32KOB_MASK                                  0x1
+#define MT6685_F32KOB_SHIFT                                 5
+#define MT6685_GPO_ADDR                                     \
+	MT6685_RTC_CON_L
+#define MT6685_GPO_MASK                                     0x1
+#define MT6685_GPO_SHIFT                                    6
+#define MT6685_GOE_ADDR                                     \
+	MT6685_RTC_CON_L
+#define MT6685_GOE_MASK                                     0x1
+#define MT6685_GOE_SHIFT                                    7
+#define MT6685_GSR_ADDR                                     \
+	MT6685_RTC_CON_H
+#define MT6685_GSR_MASK                                     0x1
+#define MT6685_GSR_SHIFT                                    0
+#define MT6685_GSMT_ADDR                                    \
+	MT6685_RTC_CON_H
+#define MT6685_GSMT_MASK                                    0x1
+#define MT6685_GSMT_SHIFT                                   1
+#define MT6685_GPEN_ADDR                                    \
+	MT6685_RTC_CON_H
+#define MT6685_GPEN_MASK                                    0x1
+#define MT6685_GPEN_SHIFT                                   2
+#define MT6685_GPU_ADDR                                     \
+	MT6685_RTC_CON_H
+#define MT6685_GPU_MASK                                     0x1
+#define MT6685_GPU_SHIFT                                    3
+#define MT6685_GE4_ADDR                                     \
+	MT6685_RTC_CON_H
+#define MT6685_GE4_MASK                                     0x1
+#define MT6685_GE4_SHIFT                                    4
+#define MT6685_GE8_ADDR                                     \
+	MT6685_RTC_CON_H
+#define MT6685_GE8_MASK                                     0x1
+#define MT6685_GE8_SHIFT                                    5
+#define MT6685_GPI_ADDR                                     \
+	MT6685_RTC_CON_H
+#define MT6685_GPI_MASK                                     0x1
+#define MT6685_GPI_SHIFT                                    6
+#define MT6685_LPSTA_RAW_ADDR                               \
+	MT6685_RTC_CON_H
+#define MT6685_LPSTA_RAW_MASK                               0x1
+#define MT6685_LPSTA_RAW_SHIFT                              7
+#define MT6685_DAT0_LOCK_ADDR                               \
+	MT6685_RTC_SEC_CTRL
+#define MT6685_DAT0_LOCK_MASK                               0x1
+#define MT6685_DAT0_LOCK_SHIFT                              0
+#define MT6685_DAT1_LOCK_ADDR                               \
+	MT6685_RTC_SEC_CTRL
+#define MT6685_DAT1_LOCK_MASK                               0x1
+#define MT6685_DAT1_LOCK_SHIFT                              1
+#define MT6685_DAT2_LOCK_ADDR                               \
+	MT6685_RTC_SEC_CTRL
+#define MT6685_DAT2_LOCK_MASK                               0x1
+#define MT6685_DAT2_LOCK_SHIFT                              2
+#define MT6685_RTC_INT_CNT_L_ADDR                           \
+	MT6685_RTC_INT_CNT_L
+#define MT6685_RTC_INT_CNT_L_MASK                           0xFF
+#define MT6685_RTC_INT_CNT_L_SHIFT                          0
+#define MT6685_RTC_INT_CNT_H_ADDR                           \
+	MT6685_RTC_INT_CNT_H
+#define MT6685_RTC_INT_CNT_H_MASK                           0x7F
+#define MT6685_RTC_INT_CNT_H_SHIFT                          0
+#define MT6685_RTC_SEC_DAT0_L_ADDR                          \
+	MT6685_RTC_SEC_DAT0_L
+#define MT6685_RTC_SEC_DAT0_L_MASK                          0xFF
+#define MT6685_RTC_SEC_DAT0_L_SHIFT                         0
+#define MT6685_RTC_SEC_DAT0_H_ADDR                          \
+	MT6685_RTC_SEC_DAT0_H
+#define MT6685_RTC_SEC_DAT0_H_MASK                          0xFF
+#define MT6685_RTC_SEC_DAT0_H_SHIFT                         0
+#define MT6685_RTC_SEC_DAT1_L_ADDR                          \
+	MT6685_RTC_SEC_DAT1_L
+#define MT6685_RTC_SEC_DAT1_L_MASK                          0xFF
+#define MT6685_RTC_SEC_DAT1_L_SHIFT                         0
+#define MT6685_RTC_SEC_DAT1_H_ADDR                          \
+	MT6685_RTC_SEC_DAT1_H
+#define MT6685_RTC_SEC_DAT1_H_MASK                          0xFF
+#define MT6685_RTC_SEC_DAT1_H_SHIFT                         0
+#define MT6685_RTC_SEC_DAT2_L_ADDR                          \
+	MT6685_RTC_SEC_DAT2_L
+#define MT6685_RTC_SEC_DAT2_L_MASK                          0xFF
+#define MT6685_RTC_SEC_DAT2_L_SHIFT                         0
+#define MT6685_RTC_SEC_DAT2_H_ADDR                          \
+	MT6685_RTC_SEC_DAT2_H
+#define MT6685_RTC_SEC_DAT2_H_MASK                          0xFF
+#define MT6685_RTC_SEC_DAT2_H_SHIFT                         0
+#define MT6685_RTC_RG_FG0_ADDR                              \
+	MT6685_RTC_RG_FG0
+#define MT6685_RTC_RG_FG0_MASK                              0xFF
+#define MT6685_RTC_RG_FG0_SHIFT                             0
+#define MT6685_RTC_RG_FG1_ADDR                              \
+	MT6685_RTC_RG_FG1
+#define MT6685_RTC_RG_FG1_MASK                              0xFF
+#define MT6685_RTC_RG_FG1_SHIFT                             0
+#define MT6685_RTC_RG_FG2_ADDR                              \
+	MT6685_RTC_RG_FG2
+#define MT6685_RTC_RG_FG2_MASK                              0xFF
+#define MT6685_RTC_RG_FG2_SHIFT                             0
+#define MT6685_RTC_RG_FG3_ADDR                              \
+	MT6685_RTC_RG_FG3
+#define MT6685_RTC_RG_FG3_MASK                              0xFF
+#define MT6685_RTC_RG_FG3_SHIFT                             0
+#define MT6685_RTC_UVLO_WAIT_ADDR                           \
+	MT6685_RTC_SPAR_MACRO
+#define MT6685_RTC_UVLO_WAIT_MASK                           0x3
+#define MT6685_RTC_UVLO_WAIT_SHIFT                          0
+#define MT6685_RTC_SPAR_THRE_SEL_ADDR                       \
+	MT6685_RTC_SPAR_MACRO
+#define MT6685_RTC_SPAR_THRE_SEL_MASK                       0x1
+#define MT6685_RTC_SPAR_THRE_SEL_SHIFT                      2
+#define MT6685_RTC_SPAR_PWRKEY_MATCH_LPD_ADDR               \
+	MT6685_RTC_SPAR_MACRO
+#define MT6685_RTC_SPAR_PWRKEY_MATCH_LPD_MASK               0x1
+#define MT6685_RTC_SPAR_PWRKEY_MATCH_LPD_SHIFT              4
+#define MT6685_RTC_SPAR_PWRKEY_MATCH_ADDR                   \
+	MT6685_RTC_SPAR_MACRO
+#define MT6685_RTC_SPAR_PWRKEY_MATCH_MASK                   0x1
+#define MT6685_RTC_SPAR_PWRKEY_MATCH_SHIFT                  5
+#define MT6685_SPAR_PROT_STAT_ADDR                          \
+	MT6685_RTC_SPAR_MACRO
+#define MT6685_RTC_SPAR_PROT_STAT_MASK                      0x3
+#define MT6685_RTC_SPAR_PROT_STAT_SHIFT                     6
+#define MT6685_RTC_SPAR_CORE_ADDR                           \
+	MT6685_RTC_SPAR_CORE
+#define MT6685_RTC_SPAR_CORE_MASK                           0xFF
+#define MT6685_RTC_SPAR_CORE_SHIFT                          0
+#define MT6685_RTC_RG_EOSC_CALI_ADDR                        \
+	MT6685_RTC_EOSC_CALI
+#define MT6685_RTC_RG_EOSC_CALI_MASK                        0x1F
+#define MT6685_RTC_RG_EOSC_CALI_SHIFT                       0
+#define MT6685_RTC_SEC_ANA_ID_ADDR                          \
+	MT6685_RTC_SEC_ANA_ID
+#define MT6685_RTC_SEC_ANA_ID_MASK                          0xFF
+#define MT6685_RTC_SEC_ANA_ID_SHIFT                         0
+#define MT6685_RTC_SEC_DIG_ID_ADDR                          \
+	MT6685_RTC_SEC_DIG_ID
+#define MT6685_RTC_SEC_DIG_ID_MASK                          0xFF
+#define MT6685_RTC_SEC_DIG_ID_SHIFT                         0
+#define MT6685_RTC_SEC_ANA_MINOR_REV_ADDR                   \
+	MT6685_RTC_SEC_ANA_REV
+#define MT6685_RTC_SEC_ANA_MINOR_REV_MASK                   0xF
+#define MT6685_RTC_SEC_ANA_MINOR_REV_SHIFT                  0
+#define MT6685_RTC_SEC_ANA_MAJOR_REV_ADDR                   \
+	MT6685_RTC_SEC_ANA_REV
+#define MT6685_RTC_SEC_ANA_MAJOR_REV_MASK                   0xF
+#define MT6685_RTC_SEC_ANA_MAJOR_REV_SHIFT                  4
+#define MT6685_RTC_SEC_DIG_MINOR_REV_ADDR                   \
+	MT6685_RTC_SEC_DIG_REV
+#define MT6685_RTC_SEC_DIG_MINOR_REV_MASK                   0xF
+#define MT6685_RTC_SEC_DIG_MINOR_REV_SHIFT                  0
+#define MT6685_RTC_SEC_DIG_MAJOR_REV_ADDR                   \
+	MT6685_RTC_SEC_DIG_REV
+#define MT6685_RTC_SEC_DIG_MAJOR_REV_MASK                   0xF
+#define MT6685_RTC_SEC_DIG_MAJOR_REV_SHIFT                  4
+#define MT6685_RTC_SEC_CBS_ADDR                             \
+	MT6685_RTC_SEC_DBI
+#define MT6685_RTC_SEC_CBS_MASK                             0x3
+#define MT6685_RTC_SEC_CBS_SHIFT                            0
+#define MT6685_RTC_SEC_BIX_ADDR                             \
+	MT6685_RTC_SEC_DBI
+#define MT6685_RTC_SEC_BIX_MASK                             0x3
+#define MT6685_RTC_SEC_BIX_SHIFT                            2
+#define MT6685_RTC_SEC_ESP_ADDR                             \
+	MT6685_RTC_SEC_ESP
+#define MT6685_RTC_SEC_ESP_MASK                             0xFF
+#define MT6685_RTC_SEC_ESP_SHIFT                            0
+#define MT6685_RTC_SEC_FPI_ADDR                             \
+	MT6685_RTC_SEC_FPI
+#define MT6685_RTC_SEC_FPI_MASK                             0xFF
+#define MT6685_RTC_SEC_FPI_SHIFT                            0
+#define MT6685_RTC_SEC_DXI_ADDR                             \
+	MT6685_RTC_SEC_DXI
+#define MT6685_RTC_SEC_DXI_MASK                             0xFF
+#define MT6685_RTC_SEC_DXI_SHIFT                            0
+#define MT6685_TC_SECOND_SEC_ADDR                           \
+	MT6685_RTC_TC_SEC_SEC
+#define MT6685_TC_SECOND_SEC_MASK                           0x3F
+#define MT6685_TC_SECOND_SEC_SHIFT                          0
+#define MT6685_TC_MINUTE_SEC_ADDR                           \
+	MT6685_RTC_TC_MIN_SEC
+#define MT6685_TC_MINUTE_SEC_MASK                           0x3F
+#define MT6685_TC_MINUTE_SEC_SHIFT                          0
+#define MT6685_TC_HOUR_SEC_ADDR                             \
+	MT6685_RTC_TC_HOU_SEC
+#define MT6685_TC_HOUR_SEC_MASK                             0x1F
+#define MT6685_TC_HOUR_SEC_SHIFT                            0
+#define MT6685_TC_DOM_SEC_ADDR                              \
+	MT6685_RTC_TC_DOM_SEC
+#define MT6685_TC_DOM_SEC_MASK                              0x1F
+#define MT6685_TC_DOM_SEC_SHIFT                             0
+#define MT6685_TC_DOW_SEC_ADDR                              \
+	MT6685_RTC_TC_DOW_SEC
+#define MT6685_TC_DOW_SEC_MASK                              0x7
+#define MT6685_TC_DOW_SEC_SHIFT                             0
+#define MT6685_TC_MONTH_SEC_ADDR                            \
+	MT6685_RTC_TC_MTH_SEC
+#define MT6685_TC_MONTH_SEC_MASK                            0xF
+#define MT6685_TC_MONTH_SEC_SHIFT                           0
+#define MT6685_TC_YEAR_SEC_ADDR                             \
+	MT6685_RTC_TC_YEA_SEC
+#define MT6685_TC_YEAR_SEC_MASK                             0x7F
+#define MT6685_TC_YEAR_SEC_SHIFT                            0
+#define MT6685_RTC_SEC_CK_PDN_ADDR                          \
+	MT6685_RTC_SEC_CK_PDN
+#define MT6685_RTC_SEC_CK_PDN_MASK                          0x1
+#define MT6685_RTC_SEC_CK_PDN_SHIFT                         0
+#define MT6685_RTC_SEC_WRTGR_ADDR                           \
+	MT6685_RTC_SEC_WRTGR
+#define MT6685_RTC_SEC_WRTGR_MASK                           0x1
+#define MT6685_RTC_SEC_WRTGR_SHIFT                          0
+#define MT6685_XO_EN32K_MAN_ADDR                            \
+	MT6685_DCXO_DIG_MODE_CW0
+#define MT6685_XO_EN32K_MAN_MASK                            0x1
+#define MT6685_XO_EN32K_MAN_SHIFT                           1
+#define MT6685_RG_INT_EN_RTC_ADDR                           \
+	MT6685_SCK_TOP_INT_CON0
+#define MT6685_RG_INT_EN_RTC_MASK                           0x1
+#define MT6685_RG_INT_EN_RTC_SHIFT                          0
+
+#endif		/* _MT6685_HW_H_ */
diff --git a/include/linux/mfd/mt6685/rtc.h b/include/linux/mfd/mt6685/rtc.h
new file mode 100644
index 000000000000..cb5b62a717d5
--- /dev/null
+++ b/include/linux/mfd/mt6685/rtc.h
@@ -0,0 +1,318 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MT6685_RTC_H__
+#define __MT6685_RTC_H__
+
+#include <linux/mfd/mt6685/registers.h>
+
+/*features*/
+#define SUPPORT_PWR_OFF_ALARM
+
+#define HWID                    MT6685_HWCID_L
+
+/* we map HW YEA 0 (2000) to 1968 not 1970 because 2000 is the leap year */
+#define RTC_MIN_YEAR            1968
+#define RTC_BASE_YEAR           1900
+#define RTC_NUM_YEARS           128
+#define RTC_MIN_YEAR_OFFSET     (RTC_MIN_YEAR - RTC_BASE_YEAR)
+
+#define RTC_TC_SEC                      0x12
+#define RTC_TC_MIN                      0x14
+#define RTC_TC_HOU                      0x16
+#define RTC_TC_DOM                      0x18
+#define RTC_TC_DOW                      0x1A
+#define RTC_TC_MTH                      0x1C
+#define RTC_TC_YEA                      0x1E
+/* Min, Hour, Dom... register offset to RTC_TC_SEC */
+#define RTC_OFFSET_SEC                  0
+#define RTC_OFFSET_MIN                  1
+#define RTC_OFFSET_HOUR                 2
+#define RTC_OFFSET_DOM                  3
+#define RTC_OFFSET_DOW                  4
+#define RTC_OFFSET_MTH                  5
+#define RTC_OFFSET_YEAR                 6
+#define RTC_OFFSET_COUNT                7
+
+#define RTC_DSN_ID                      0x580
+
+#define DCXO_ANA_ID                     0x200
+
+#define RTC_BBPU                        0x8
+#define RTC_WRTGR_MT6685                0x42
+#define RTC_IRQ_STA                     0xa
+#define RTC_IRQ_EN                      0xc
+#define RTC_AL_MASK                     0x10
+
+#define RTC_AL_SEC                      0x20
+#define RTC_AL_MIN                      0x22
+#define RTC_AL_HOU                      0x24
+#define RTC_AL_HOU_H                    0x25
+#define RTC_AL_DOM                      0x26
+#define RTC_AL_DOW                      0x28
+#define RTC_AL_DOW_H                    0x29
+#define RTC_AL_MTH                      0x2a
+#define RTC_AL_MTH_H                    0x2b
+#define RTC_AL_YEA                      0x2c
+#define RTC_AL_YEA_H                    0x2d
+#define RTC_OSC32CON                    0x2e
+#define RTC_POWERKEY1                   0x30
+#define RTC_POWERKEY2                   0x32
+#define RTC_PDN1                        0x34
+#define RTC_PDN1_H                      0x35
+#define RTC_PDN2                        0x36
+#define RTC_SPAR0                       0x38
+#define RTC_SPAR1                       0x3a
+#define RTC_PROT                        0x3c
+#define RTC_WRTGR                       0x42
+#define RTC_CON                         0x44
+#define RTC_INT_CNT_L                   0x48
+#define RTC_SPAR_MACRO                  0x58
+
+#define RTC_TC_SEC_MASK                 0x3f
+#define RTC_TC_MIN_MASK                 0x3f
+#define RTC_TC_HOU_MASK                 0x1f
+#define RTC_TC_DOM_MASK                 0x1f
+#define RTC_TC_DOW_MASK                 0x7
+#define RTC_TC_MTH_MASK                 0xf
+#define RTC_TC_YEA_MASK                 0x7f
+
+#define RTC_AL_SEC_MASK                 0x3f
+#define RTC_AL_MIN_MASK                 0x3f
+#define RTC_AL_HOU_MASK                 0x1f
+#define RTC_AL_DOM_MASK                 0x1f
+#define RTC_AL_DOW_MASK                 0x7
+#define RTC_AL_MTH_MASK                 0xf
+#define RTC_AL_YEA_MASK                 0x7f
+
+#define RTC_PWRON_YEA                   RTC_PDN2
+#define RTC_PWRON_MTH                   RTC_PDN2
+#define RTC_PWRON_SEC                   RTC_SPAR0
+#define RTC_PWRON_MIN                   RTC_SPAR1
+#define RTC_PWRON_HOU                   RTC_SPAR1
+#define RTC_PWRON_DOM                   RTC_SPAR1
+
+#define RTC_PWRON_SEC_SHIFT             0x0
+#define RTC_PWRON_MIN_SHIFT             0x0
+#define RTC_PWRON_HOU_SHIFT             0x6
+#define RTC_PWRON_DOM_SHIFT             0xb
+#define RTC_PWRON_MTH_SHIFT             0x0
+#define RTC_PWRON_YEA_SHIFT             0x8
+
+#define RTC_PWRON_SEC_MASK              (RTC_AL_SEC_MASK << RTC_PWRON_SEC_SHIFT)
+#define RTC_PWRON_MIN_MASK              (RTC_AL_MIN_MASK << RTC_PWRON_MIN_SHIFT)
+#define RTC_PWRON_HOU_MASK              (RTC_AL_HOU_MASK << RTC_PWRON_HOU_SHIFT)
+#define RTC_PWRON_DOM_MASK              (RTC_AL_DOM_MASK << RTC_PWRON_DOM_SHIFT)
+#define RTC_PWRON_MTH_MASK              (RTC_AL_MTH_MASK << RTC_PWRON_MTH_SHIFT)
+#define RTC_PWRON_YEA_MASK              (RTC_AL_YEA_MASK << RTC_PWRON_YEA_SHIFT)
+
+#define RTC_BBPU_KEY                    0x4300
+#define RTC_BBPU_CBUSY                  BIT(6)
+#define RTC_BBPU_RELOAD                 BIT(5)
+#define RTC_BBPU_AUTO                   BIT(3)
+#define RTC_BBPU_CLR                    BIT(1)
+#define RTC_BBPU_PWREN                  BIT(0)
+#define RTC_BBPU_AL_STA                 BIT(7)
+#define RTC_BBPU_RESET_AL               BIT(3)
+#define RTC_BBPU_RESET_SPAR             BIT(2)
+
+#define RTC_AL_MASK_DOW                 BIT(4)
+
+#define RTC_IRQ_EN_LP                   BIT(3)
+#define RTC_IRQ_EN_ONESHOT              BIT(2)
+#define RTC_IRQ_EN_AL                   BIT(0)
+#define RTC_IRQ_EN_ONESHOT_AL           (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
+
+#define RTC_IRQ_STA_LP                  BIT(3)
+#define RTC_IRQ_STA_AL                  BIT(0)
+
+#define RTC_PDN1_PWRON_TIME             BIT(7)
+#define RTC_PDN2_PWRON_LOGO             BIT(15)
+#define RTC_PDN2_PWRON_ALARM            BIT(4)
+
+#define RTC_RG_FG2                      0x54
+#define RTC_RG_FG3                      0x56
+
+#define EOSC_CALI_TD_MT6685				0x29
+#define EOSC_CALI_TD_MASK               0x3
+
+#define HWID_MT6685				        0x8
+
+#define TOP_RTC_EOSC32_CK_PDN           MT6685_SCK_TOP_CKPDN_CON0_L
+#define TOP_RTC_EOSC32_CK_PDN_MASK      (MT6685_RG_RTC_EOSC32_CK_PDN_MASK \
+						<< MT6685_RG_RTC_EOSC32_CK_PDN_SHIFT)
+
+#define TOP_DIG_WPK                     MT6685_TOP_DIG_WPK
+#define DIG_WPK_KEY_MASK        (MT6685_DIG_WPK_KEY_MASK << MT6685_DIG_WPK_KEY_SHIFT)
+
+#define TOP_DIG_WPK_H                   MT6685_TOP_DIG_WPK_H
+#define DIG_WPK_KEY_H_MASK      (MT6685_DIG_WPK_KEY_H_MASK << MT6685_DIG_WPK_KEY_H_SHIFT)
+
+#define RG_RTC_MCLK_PDN                 MT6685_SCK_TOP_CKPDN_CON0_L
+#define RG_RTC_MCLK_PDN_STA_MASK        MT6685_RG_RTC_MCLK_PDN_MASK
+#define RG_RTC_MCLK_PDN_STA_SHIFT       MT6685_RG_RTC_MCLK_PDN_SHIFT
+
+#define RG_RTC_MCLK_PDN_SET             MT6685_SCK_TOP_CKPDN_CON0_L_SET
+#define RG_RTC_MCLK_PDN_CLR             MT6685_SCK_TOP_CKPDN_CON0_L_CLR
+#define RG_RTC_MCLK_PDN_MASK    (MT6685_RG_RTC_MCLK_PDN_MASK << MT6685_RG_RTC_MCLK_PDN_SHIFT)
+
+#define RG_RTC_32K_CK_PDN_SET             MT6685_SCK_TOP_CKPDN_CON0_L_SET
+#define RG_RTC_32K_CK_PDN_CLR             MT6685_SCK_TOP_CKPDN_CON0_L_CLR
+#define RG_RTC_32K_CK_PDN_MASK   (MT6685_RG_RTC_32K_CK_PDN_MASK << MT6685_RG_RTC_32K_CK_PDN_SHIFT)
+
+#define SPAR_PROT_STAT_MASK             MT6685_RTC_SPAR_PROT_STAT_MASK
+#define SPAR_PROT_STAT_SHIFT            MT6685_RTC_SPAR_PROT_STAT_SHIFT
+
+/*SCK_TOP rtc interrupt*/
+#define SCK_TOP_INT_CON0                MT6685_SCK_TOP_INT_CON0
+#define EN_RTC_INTERRUPT                MT6685_RG_INT_EN_RTC_MASK
+#define SCK_TOP_INT_STATUS0             MT6685_SCK_TOP_INT_STATUS0
+
+#define TOP2_ELR1                       MT6685_TOP2_ELR1
+#define TOP2_ELR1_MASK                  BIT(0)
+
+#define MTK_RTC_POLL_DELAY_US            10
+#define MTK_RTC_POLL_TIMEOUT             (jiffies_to_usecs(HZ))
+
+#define RTC_POFF_ALM_SET                 _IOW('p', 0x15, struct rtc_time) /* Set alarm time  */
+
+#define SPARE_REG_WIDTH                  1
+
+enum mtk_rtc_spare_enum {
+	SPARE_FG2,
+	SPARE_FG3,
+	SPARE_SPAR0,
+#ifdef SUPPORT_PWR_OFF_ALARM
+	SPARE_KPOC,
+#endif
+	SPARE_RG_MAX,
+};
+
+enum rtc_irq_sta {
+	RTC_NONE,
+	RTC_ALSTA,
+	RTC_TCSTA,
+	RTC_LPSTA,
+};
+
+enum rtc_reg_set {
+	RTC_REG,
+	RTC_MASK,
+	RTC_SHIFT
+};
+
+enum chip_version {
+	NULL_SERIES,
+	MT6685_SERIES,
+};
+
+#define EOSC_SOL_1      0x5
+#define EOSC_SOL_2      0x7
+
+enum rtc_eosc_cali_td {
+	EOSC_CALI_TD_01_SEC = 0x3,
+	EOSC_CALI_TD_02_SEC,
+	EOSC_CALI_TD_04_SEC,
+	EOSC_CALI_TD_08_SEC,
+	EOSC_CALI_TD_16_SEC,
+};
+
+enum cali_field_enum {
+	EOSC_CALI_TD,
+	CALI_FILED_MAX,
+};
+
+#ifdef SUPPORT_PWR_OFF_ALARM
+struct tag_bootmode {
+	u32 size;
+	u32 tag;
+	u32 bootmode;
+	u32 boottype;
+};
+
+enum boot_mode_t {
+	NORMAL_BOOT = 0,
+	META_BOOT = 1,
+	RECOVERY_BOOT = 2,
+	SW_REBOOT = 3,
+	FACTORY_BOOT = 4,
+	ADVMETA_BOOT = 5,
+	ATE_FACTORY_BOOT = 6,
+	ALARM_BOOT = 7,
+	KERNEL_POWER_OFF_CHARGING_BOOT = 8,
+	LOW_POWER_OFF_CHARGING_BOOT = 9,
+	DONGLE_BOOT = 10,
+	UNKNOWN_BOOT
+};
+#endif
+
+struct mtk_rtc_data {
+	u32         wrtgr;
+	u32         hwid;
+	u32			chip_version;
+	bool        single_read_write_is_supported;
+	const struct reg_field *spare_reg_fields;
+	const struct reg_field *cali_reg_fields;
+};
+
+static const char *rtc_time_reg_name[RTC_OFFSET_COUNT] = {
+	[0] = "SEC",
+	[1] = "MIN",
+	[2] = "HOUR",
+	[3] = "DOM",
+	[4] = "DOW",
+	[5] = "MTH",
+	[6] = "YEAR",
+};
+
+enum rtc_time_mask {
+	SEC_MASK,
+	MIN_MASK,
+	HOU_MASK,
+	DOM_MASK,
+	DOW_MASK,
+	MTH_MASK,
+	YEA_MASK,
+	MASK_COUNT
+
+};
+
+static char rtc_time_mask[MASK_COUNT] = {
+	[SEC_MASK] = 0x3f,
+	[MIN_MASK] = 0x3f,
+	[HOU_MASK] = 0x1f,
+	[DOM_MASK] = 0x1f,
+	[DOW_MASK] = 0x7,
+	[MTH_MASK] = 0xf,
+	[YEA_MASK] = 0x7f
+};
+
+struct mt6685_rtc {
+	struct rtc_device       *rtc_dev;
+
+	/* Protect register access from multiple tasks */
+	struct mutex            lock;
+	/**
+	 * struct mutex - Mutex for controlling access to the clock
+	 *
+	 * This mutex is used to synchronize access to the clock in the RTC driver.
+	 */
+	struct mutex            clk_lock;
+	struct regmap           *regmap;
+	struct regmap           *regmap_spar;
+	int                     irq;
+	u32                     addr_base;
+	const struct mtk_rtc_data *data;
+	bool                    cali_is_supported;
+#ifdef SUPPORT_PWR_OFF_ALARM
+	struct work_struct work;
+	struct completion comp;
+#if IS_ENABLED(CONFIG_PM)
+struct notifier_block pm_nb;
+#endif
+#endif
+};
+
+#endif /* __MT6685_RTC_H__ */
-- 
2.46.0




More information about the Linux-mediatek mailing list