162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci* Copyright (c) 2014-2015 MediaTek Inc. 462306a36Sopenharmony_ci* Author: Tianping.Fang <tianping.fang@mediatek.com> 562306a36Sopenharmony_ci*/ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/err.h> 862306a36Sopenharmony_ci#include <linux/interrupt.h> 962306a36Sopenharmony_ci#include <linux/mfd/mt6397/core.h> 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/mutex.h> 1262306a36Sopenharmony_ci#include <linux/of.h> 1362306a36Sopenharmony_ci#include <linux/platform_device.h> 1462306a36Sopenharmony_ci#include <linux/regmap.h> 1562306a36Sopenharmony_ci#include <linux/rtc.h> 1662306a36Sopenharmony_ci#include <linux/mfd/mt6397/rtc.h> 1762306a36Sopenharmony_ci#include <linux/mod_devicetable.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci int ret; 2262306a36Sopenharmony_ci u32 data; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci ret = regmap_write(rtc->regmap, rtc->addr_base + rtc->data->wrtgr, 1); 2562306a36Sopenharmony_ci if (ret < 0) 2662306a36Sopenharmony_ci return ret; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci ret = regmap_read_poll_timeout(rtc->regmap, 2962306a36Sopenharmony_ci rtc->addr_base + RTC_BBPU, data, 3062306a36Sopenharmony_ci !(data & RTC_BBPU_CBUSY), 3162306a36Sopenharmony_ci MTK_RTC_POLL_DELAY_US, 3262306a36Sopenharmony_ci MTK_RTC_POLL_TIMEOUT); 3362306a36Sopenharmony_ci if (ret < 0) 3462306a36Sopenharmony_ci dev_err(rtc->rtc_dev->dev.parent, 3562306a36Sopenharmony_ci "failed to write WRTGR: %d\n", ret); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci return ret; 3862306a36Sopenharmony_ci} 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_cistatic irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct mt6397_rtc *rtc = data; 4362306a36Sopenharmony_ci u32 irqsta, irqen; 4462306a36Sopenharmony_ci int ret; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_STA, &irqsta); 4762306a36Sopenharmony_ci if ((ret >= 0) && (irqsta & RTC_IRQ_STA_AL)) { 4862306a36Sopenharmony_ci rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); 4962306a36Sopenharmony_ci irqen = irqsta & ~RTC_IRQ_EN_AL; 5062306a36Sopenharmony_ci mutex_lock(&rtc->lock); 5162306a36Sopenharmony_ci if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, 5262306a36Sopenharmony_ci irqen) == 0) 5362306a36Sopenharmony_ci mtk_rtc_write_trigger(rtc); 5462306a36Sopenharmony_ci mutex_unlock(&rtc->lock); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci return IRQ_HANDLED; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci return IRQ_NONE; 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic int __mtk_rtc_read_time(struct mt6397_rtc *rtc, 6362306a36Sopenharmony_ci struct rtc_time *tm, int *sec) 6462306a36Sopenharmony_ci{ 6562306a36Sopenharmony_ci int ret; 6662306a36Sopenharmony_ci u16 data[RTC_OFFSET_COUNT]; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci mutex_lock(&rtc->lock); 6962306a36Sopenharmony_ci ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, 7062306a36Sopenharmony_ci data, RTC_OFFSET_COUNT); 7162306a36Sopenharmony_ci if (ret < 0) 7262306a36Sopenharmony_ci goto exit; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci tm->tm_sec = data[RTC_OFFSET_SEC]; 7562306a36Sopenharmony_ci tm->tm_min = data[RTC_OFFSET_MIN]; 7662306a36Sopenharmony_ci tm->tm_hour = data[RTC_OFFSET_HOUR]; 7762306a36Sopenharmony_ci tm->tm_mday = data[RTC_OFFSET_DOM]; 7862306a36Sopenharmony_ci tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK; 7962306a36Sopenharmony_ci tm->tm_year = data[RTC_OFFSET_YEAR]; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, sec); 8262306a36Sopenharmony_ciexit: 8362306a36Sopenharmony_ci mutex_unlock(&rtc->lock); 8462306a36Sopenharmony_ci return ret; 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci time64_t time; 9062306a36Sopenharmony_ci struct mt6397_rtc *rtc = dev_get_drvdata(dev); 9162306a36Sopenharmony_ci int days, sec, ret; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci do { 9462306a36Sopenharmony_ci ret = __mtk_rtc_read_time(rtc, tm, &sec); 9562306a36Sopenharmony_ci if (ret < 0) 9662306a36Sopenharmony_ci goto exit; 9762306a36Sopenharmony_ci } while (sec < tm->tm_sec); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci /* HW register use 7 bits to store year data, minus 10062306a36Sopenharmony_ci * RTC_MIN_YEAR_OFFSET before write year data to register, and plus 10162306a36Sopenharmony_ci * RTC_MIN_YEAR_OFFSET back after read year from register 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci tm->tm_year += RTC_MIN_YEAR_OFFSET; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci /* HW register start mon from one, but tm_mon start from zero. */ 10662306a36Sopenharmony_ci tm->tm_mon--; 10762306a36Sopenharmony_ci time = rtc_tm_to_time64(tm); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* rtc_tm_to_time64 covert Gregorian date to seconds since 11062306a36Sopenharmony_ci * 01-01-1970 00:00:00, and this date is Thursday. 11162306a36Sopenharmony_ci */ 11262306a36Sopenharmony_ci days = div_s64(time, 86400); 11362306a36Sopenharmony_ci tm->tm_wday = (days + 4) % 7; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ciexit: 11662306a36Sopenharmony_ci return ret; 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_cistatic int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci struct mt6397_rtc *rtc = dev_get_drvdata(dev); 12262306a36Sopenharmony_ci int ret; 12362306a36Sopenharmony_ci u16 data[RTC_OFFSET_COUNT]; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci tm->tm_year -= RTC_MIN_YEAR_OFFSET; 12662306a36Sopenharmony_ci tm->tm_mon++; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci data[RTC_OFFSET_SEC] = tm->tm_sec; 12962306a36Sopenharmony_ci data[RTC_OFFSET_MIN] = tm->tm_min; 13062306a36Sopenharmony_ci data[RTC_OFFSET_HOUR] = tm->tm_hour; 13162306a36Sopenharmony_ci data[RTC_OFFSET_DOM] = tm->tm_mday; 13262306a36Sopenharmony_ci data[RTC_OFFSET_MTH] = tm->tm_mon; 13362306a36Sopenharmony_ci data[RTC_OFFSET_YEAR] = tm->tm_year; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci mutex_lock(&rtc->lock); 13662306a36Sopenharmony_ci ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_TC_SEC, 13762306a36Sopenharmony_ci data, RTC_OFFSET_COUNT); 13862306a36Sopenharmony_ci if (ret < 0) 13962306a36Sopenharmony_ci goto exit; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci /* Time register write to hardware after call trigger function */ 14262306a36Sopenharmony_ci ret = mtk_rtc_write_trigger(rtc); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ciexit: 14562306a36Sopenharmony_ci mutex_unlock(&rtc->lock); 14662306a36Sopenharmony_ci return ret; 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci struct rtc_time *tm = &alm->time; 15262306a36Sopenharmony_ci struct mt6397_rtc *rtc = dev_get_drvdata(dev); 15362306a36Sopenharmony_ci u32 irqen, pdn2; 15462306a36Sopenharmony_ci int ret; 15562306a36Sopenharmony_ci u16 data[RTC_OFFSET_COUNT]; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci mutex_lock(&rtc->lock); 15862306a36Sopenharmony_ci ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, &irqen); 15962306a36Sopenharmony_ci if (ret < 0) 16062306a36Sopenharmony_ci goto err_exit; 16162306a36Sopenharmony_ci ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_PDN2, &pdn2); 16262306a36Sopenharmony_ci if (ret < 0) 16362306a36Sopenharmony_ci goto err_exit; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, 16662306a36Sopenharmony_ci data, RTC_OFFSET_COUNT); 16762306a36Sopenharmony_ci if (ret < 0) 16862306a36Sopenharmony_ci goto err_exit; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci alm->enabled = !!(irqen & RTC_IRQ_EN_AL); 17162306a36Sopenharmony_ci alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); 17262306a36Sopenharmony_ci mutex_unlock(&rtc->lock); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK; 17562306a36Sopenharmony_ci tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK; 17662306a36Sopenharmony_ci tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK; 17762306a36Sopenharmony_ci tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK; 17862306a36Sopenharmony_ci tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK; 17962306a36Sopenharmony_ci tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci tm->tm_year += RTC_MIN_YEAR_OFFSET; 18262306a36Sopenharmony_ci tm->tm_mon--; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci return 0; 18562306a36Sopenharmony_cierr_exit: 18662306a36Sopenharmony_ci mutex_unlock(&rtc->lock); 18762306a36Sopenharmony_ci return ret; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistatic int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci struct rtc_time *tm = &alm->time; 19362306a36Sopenharmony_ci struct mt6397_rtc *rtc = dev_get_drvdata(dev); 19462306a36Sopenharmony_ci int ret; 19562306a36Sopenharmony_ci u16 data[RTC_OFFSET_COUNT]; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci tm->tm_year -= RTC_MIN_YEAR_OFFSET; 19862306a36Sopenharmony_ci tm->tm_mon++; 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_ci mutex_lock(&rtc->lock); 20162306a36Sopenharmony_ci ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, 20262306a36Sopenharmony_ci data, RTC_OFFSET_COUNT); 20362306a36Sopenharmony_ci if (ret < 0) 20462306a36Sopenharmony_ci goto exit; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) | 20762306a36Sopenharmony_ci (tm->tm_sec & RTC_AL_SEC_MASK)); 20862306a36Sopenharmony_ci data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) | 20962306a36Sopenharmony_ci (tm->tm_min & RTC_AL_MIN_MASK)); 21062306a36Sopenharmony_ci data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) | 21162306a36Sopenharmony_ci (tm->tm_hour & RTC_AL_HOU_MASK)); 21262306a36Sopenharmony_ci data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) | 21362306a36Sopenharmony_ci (tm->tm_mday & RTC_AL_DOM_MASK)); 21462306a36Sopenharmony_ci data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) | 21562306a36Sopenharmony_ci (tm->tm_mon & RTC_AL_MTH_MASK)); 21662306a36Sopenharmony_ci data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) | 21762306a36Sopenharmony_ci (tm->tm_year & RTC_AL_YEA_MASK)); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if (alm->enabled) { 22062306a36Sopenharmony_ci ret = regmap_bulk_write(rtc->regmap, 22162306a36Sopenharmony_ci rtc->addr_base + RTC_AL_SEC, 22262306a36Sopenharmony_ci data, RTC_OFFSET_COUNT); 22362306a36Sopenharmony_ci if (ret < 0) 22462306a36Sopenharmony_ci goto exit; 22562306a36Sopenharmony_ci ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_AL_MASK, 22662306a36Sopenharmony_ci RTC_AL_MASK_DOW); 22762306a36Sopenharmony_ci if (ret < 0) 22862306a36Sopenharmony_ci goto exit; 22962306a36Sopenharmony_ci ret = regmap_update_bits(rtc->regmap, 23062306a36Sopenharmony_ci rtc->addr_base + RTC_IRQ_EN, 23162306a36Sopenharmony_ci RTC_IRQ_EN_ONESHOT_AL, 23262306a36Sopenharmony_ci RTC_IRQ_EN_ONESHOT_AL); 23362306a36Sopenharmony_ci if (ret < 0) 23462306a36Sopenharmony_ci goto exit; 23562306a36Sopenharmony_ci } else { 23662306a36Sopenharmony_ci ret = regmap_update_bits(rtc->regmap, 23762306a36Sopenharmony_ci rtc->addr_base + RTC_IRQ_EN, 23862306a36Sopenharmony_ci RTC_IRQ_EN_ONESHOT_AL, 0); 23962306a36Sopenharmony_ci if (ret < 0) 24062306a36Sopenharmony_ci goto exit; 24162306a36Sopenharmony_ci } 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci /* All alarm time register write to hardware after calling 24462306a36Sopenharmony_ci * mtk_rtc_write_trigger. This can avoid race condition if alarm 24562306a36Sopenharmony_ci * occur happen during writing alarm time register. 24662306a36Sopenharmony_ci */ 24762306a36Sopenharmony_ci ret = mtk_rtc_write_trigger(rtc); 24862306a36Sopenharmony_ciexit: 24962306a36Sopenharmony_ci mutex_unlock(&rtc->lock); 25062306a36Sopenharmony_ci return ret; 25162306a36Sopenharmony_ci} 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic const struct rtc_class_ops mtk_rtc_ops = { 25462306a36Sopenharmony_ci .read_time = mtk_rtc_read_time, 25562306a36Sopenharmony_ci .set_time = mtk_rtc_set_time, 25662306a36Sopenharmony_ci .read_alarm = mtk_rtc_read_alarm, 25762306a36Sopenharmony_ci .set_alarm = mtk_rtc_set_alarm, 25862306a36Sopenharmony_ci}; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic int mtk_rtc_probe(struct platform_device *pdev) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci struct resource *res; 26362306a36Sopenharmony_ci struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); 26462306a36Sopenharmony_ci struct mt6397_rtc *rtc; 26562306a36Sopenharmony_ci int ret; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6397_rtc), GFP_KERNEL); 26862306a36Sopenharmony_ci if (!rtc) 26962306a36Sopenharmony_ci return -ENOMEM; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 27262306a36Sopenharmony_ci if (!res) 27362306a36Sopenharmony_ci return -EINVAL; 27462306a36Sopenharmony_ci rtc->addr_base = res->start; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci rtc->data = of_device_get_match_data(&pdev->dev); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci rtc->irq = platform_get_irq(pdev, 0); 27962306a36Sopenharmony_ci if (rtc->irq < 0) 28062306a36Sopenharmony_ci return rtc->irq; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci rtc->regmap = mt6397_chip->regmap; 28362306a36Sopenharmony_ci mutex_init(&rtc->lock); 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci platform_set_drvdata(pdev, rtc); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); 28862306a36Sopenharmony_ci if (IS_ERR(rtc->rtc_dev)) 28962306a36Sopenharmony_ci return PTR_ERR(rtc->rtc_dev); 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL, 29262306a36Sopenharmony_ci mtk_rtc_irq_handler_thread, 29362306a36Sopenharmony_ci IRQF_ONESHOT | IRQF_TRIGGER_HIGH, 29462306a36Sopenharmony_ci "mt6397-rtc", rtc); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci if (ret) { 29762306a36Sopenharmony_ci dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", 29862306a36Sopenharmony_ci rtc->irq, ret); 29962306a36Sopenharmony_ci return ret; 30062306a36Sopenharmony_ci } 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci device_init_wakeup(&pdev->dev, 1); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci rtc->rtc_dev->ops = &mtk_rtc_ops; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci return devm_rtc_register_device(rtc->rtc_dev); 30762306a36Sopenharmony_ci} 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci#ifdef CONFIG_PM_SLEEP 31062306a36Sopenharmony_cistatic int mt6397_rtc_suspend(struct device *dev) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci struct mt6397_rtc *rtc = dev_get_drvdata(dev); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (device_may_wakeup(dev)) 31562306a36Sopenharmony_ci enable_irq_wake(rtc->irq); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci return 0; 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic int mt6397_rtc_resume(struct device *dev) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci struct mt6397_rtc *rtc = dev_get_drvdata(dev); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci if (device_may_wakeup(dev)) 32562306a36Sopenharmony_ci disable_irq_wake(rtc->irq); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci return 0; 32862306a36Sopenharmony_ci} 32962306a36Sopenharmony_ci#endif 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend, 33262306a36Sopenharmony_ci mt6397_rtc_resume); 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic const struct mtk_rtc_data mt6358_rtc_data = { 33562306a36Sopenharmony_ci .wrtgr = RTC_WRTGR_MT6358, 33662306a36Sopenharmony_ci}; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistatic const struct mtk_rtc_data mt6397_rtc_data = { 33962306a36Sopenharmony_ci .wrtgr = RTC_WRTGR_MT6397, 34062306a36Sopenharmony_ci}; 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_cistatic const struct of_device_id mt6397_rtc_of_match[] = { 34362306a36Sopenharmony_ci { .compatible = "mediatek,mt6323-rtc", .data = &mt6397_rtc_data }, 34462306a36Sopenharmony_ci { .compatible = "mediatek,mt6358-rtc", .data = &mt6358_rtc_data }, 34562306a36Sopenharmony_ci { .compatible = "mediatek,mt6397-rtc", .data = &mt6397_rtc_data }, 34662306a36Sopenharmony_ci { } 34762306a36Sopenharmony_ci}; 34862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, mt6397_rtc_of_match); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cistatic struct platform_driver mtk_rtc_driver = { 35162306a36Sopenharmony_ci .driver = { 35262306a36Sopenharmony_ci .name = "mt6397-rtc", 35362306a36Sopenharmony_ci .of_match_table = mt6397_rtc_of_match, 35462306a36Sopenharmony_ci .pm = &mt6397_pm_ops, 35562306a36Sopenharmony_ci }, 35662306a36Sopenharmony_ci .probe = mtk_rtc_probe, 35762306a36Sopenharmony_ci}; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_cimodule_platform_driver(mtk_rtc_driver); 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 36262306a36Sopenharmony_ciMODULE_AUTHOR("Tianping Fang <tianping.fang@mediatek.com>"); 36362306a36Sopenharmony_ciMODULE_DESCRIPTION("RTC Driver for MediaTek MT6397 PMIC"); 364