0001
0002
0003
0004
0005
0006
0007 #include <linux/delay.h>
0008 #include <linux/init.h>
0009 #include <linux/io.h>
0010 #include <linux/irqdomain.h>
0011 #include <linux/module.h>
0012 #include <linux/of_address.h>
0013 #include <linux/of_irq.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/rtc.h>
0016
0017 #define MT2712_BBPU 0x0000
0018 #define MT2712_BBPU_CLRPKY BIT(4)
0019 #define MT2712_BBPU_RELOAD BIT(5)
0020 #define MT2712_BBPU_CBUSY BIT(6)
0021 #define MT2712_BBPU_KEY (0x43 << 8)
0022
0023 #define MT2712_IRQ_STA 0x0004
0024 #define MT2712_IRQ_STA_AL BIT(0)
0025 #define MT2712_IRQ_STA_TC BIT(1)
0026
0027 #define MT2712_IRQ_EN 0x0008
0028 #define MT2712_IRQ_EN_AL BIT(0)
0029 #define MT2712_IRQ_EN_TC BIT(1)
0030 #define MT2712_IRQ_EN_ONESHOT BIT(2)
0031
0032 #define MT2712_CII_EN 0x000c
0033
0034 #define MT2712_AL_MASK 0x0010
0035 #define MT2712_AL_MASK_DOW BIT(4)
0036
0037 #define MT2712_TC_SEC 0x0014
0038 #define MT2712_TC_MIN 0x0018
0039 #define MT2712_TC_HOU 0x001c
0040 #define MT2712_TC_DOM 0x0020
0041 #define MT2712_TC_DOW 0x0024
0042 #define MT2712_TC_MTH 0x0028
0043 #define MT2712_TC_YEA 0x002c
0044
0045 #define MT2712_AL_SEC 0x0030
0046 #define MT2712_AL_MIN 0x0034
0047 #define MT2712_AL_HOU 0x0038
0048 #define MT2712_AL_DOM 0x003c
0049 #define MT2712_AL_DOW 0x0040
0050 #define MT2712_AL_MTH 0x0044
0051 #define MT2712_AL_YEA 0x0048
0052
0053 #define MT2712_SEC_MASK 0x003f
0054 #define MT2712_MIN_MASK 0x003f
0055 #define MT2712_HOU_MASK 0x001f
0056 #define MT2712_DOM_MASK 0x001f
0057 #define MT2712_DOW_MASK 0x0007
0058 #define MT2712_MTH_MASK 0x000f
0059 #define MT2712_YEA_MASK 0x007f
0060
0061 #define MT2712_POWERKEY1 0x004c
0062 #define MT2712_POWERKEY2 0x0050
0063 #define MT2712_POWERKEY1_KEY 0xa357
0064 #define MT2712_POWERKEY2_KEY 0x67d2
0065
0066 #define MT2712_CON0 0x005c
0067 #define MT2712_CON1 0x0060
0068
0069 #define MT2712_PROT 0x0070
0070 #define MT2712_PROT_UNLOCK1 0x9136
0071 #define MT2712_PROT_UNLOCK2 0x586a
0072
0073 #define MT2712_WRTGR 0x0078
0074
0075 #define MT2712_RTC_TIMESTAMP_END_2127 4985971199LL
0076
0077 struct mt2712_rtc {
0078 struct rtc_device *rtc;
0079 void __iomem *base;
0080 int irq;
0081 u8 irq_wake_enabled;
0082 u8 powerlost;
0083 };
0084
0085 static inline u32 mt2712_readl(struct mt2712_rtc *mt2712_rtc, u32 reg)
0086 {
0087 return readl(mt2712_rtc->base + reg);
0088 }
0089
0090 static inline void mt2712_writel(struct mt2712_rtc *mt2712_rtc,
0091 u32 reg, u32 val)
0092 {
0093 writel(val, mt2712_rtc->base + reg);
0094 }
0095
0096 static void mt2712_rtc_write_trigger(struct mt2712_rtc *mt2712_rtc)
0097 {
0098 unsigned long timeout = jiffies + HZ / 10;
0099
0100 mt2712_writel(mt2712_rtc, MT2712_WRTGR, 1);
0101 while (1) {
0102 if (!(mt2712_readl(mt2712_rtc, MT2712_BBPU)
0103 & MT2712_BBPU_CBUSY))
0104 break;
0105
0106 if (time_after(jiffies, timeout)) {
0107 dev_err(&mt2712_rtc->rtc->dev,
0108 "%s time out!\n", __func__);
0109 break;
0110 }
0111 cpu_relax();
0112 }
0113 }
0114
0115 static void mt2712_rtc_writeif_unlock(struct mt2712_rtc *mt2712_rtc)
0116 {
0117 mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK1);
0118 mt2712_rtc_write_trigger(mt2712_rtc);
0119 mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK2);
0120 mt2712_rtc_write_trigger(mt2712_rtc);
0121 }
0122
0123 static irqreturn_t rtc_irq_handler_thread(int irq, void *data)
0124 {
0125 struct mt2712_rtc *mt2712_rtc = data;
0126 u16 irqsta;
0127
0128
0129 irqsta = mt2712_readl(mt2712_rtc, MT2712_IRQ_STA);
0130 if (irqsta & MT2712_IRQ_STA_AL) {
0131 rtc_update_irq(mt2712_rtc->rtc, 1, RTC_IRQF | RTC_AF);
0132 return IRQ_HANDLED;
0133 }
0134
0135 return IRQ_NONE;
0136 }
0137
0138 static void __mt2712_rtc_read_time(struct mt2712_rtc *mt2712_rtc,
0139 struct rtc_time *tm, int *sec)
0140 {
0141 tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC)
0142 & MT2712_SEC_MASK;
0143 tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_TC_MIN)
0144 & MT2712_MIN_MASK;
0145 tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_TC_HOU)
0146 & MT2712_HOU_MASK;
0147 tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_TC_DOM)
0148 & MT2712_DOM_MASK;
0149 tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_TC_MTH) - 1)
0150 & MT2712_MTH_MASK;
0151 tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_TC_YEA) + 100)
0152 & MT2712_YEA_MASK;
0153
0154 *sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC) & MT2712_SEC_MASK;
0155 }
0156
0157 static int mt2712_rtc_read_time(struct device *dev, struct rtc_time *tm)
0158 {
0159 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0160 int sec;
0161
0162 if (mt2712_rtc->powerlost)
0163 return -EINVAL;
0164
0165 do {
0166 __mt2712_rtc_read_time(mt2712_rtc, tm, &sec);
0167 } while (sec < tm->tm_sec);
0168
0169 return 0;
0170 }
0171
0172 static int mt2712_rtc_set_time(struct device *dev, struct rtc_time *tm)
0173 {
0174 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0175
0176 mt2712_writel(mt2712_rtc, MT2712_TC_SEC, tm->tm_sec & MT2712_SEC_MASK);
0177 mt2712_writel(mt2712_rtc, MT2712_TC_MIN, tm->tm_min & MT2712_MIN_MASK);
0178 mt2712_writel(mt2712_rtc, MT2712_TC_HOU, tm->tm_hour & MT2712_HOU_MASK);
0179 mt2712_writel(mt2712_rtc, MT2712_TC_DOM, tm->tm_mday & MT2712_DOM_MASK);
0180 mt2712_writel(mt2712_rtc, MT2712_TC_MTH,
0181 (tm->tm_mon + 1) & MT2712_MTH_MASK);
0182 mt2712_writel(mt2712_rtc, MT2712_TC_YEA,
0183 (tm->tm_year - 100) & MT2712_YEA_MASK);
0184
0185 mt2712_rtc_write_trigger(mt2712_rtc);
0186
0187 if (mt2712_rtc->powerlost)
0188 mt2712_rtc->powerlost = false;
0189
0190 return 0;
0191 }
0192
0193 static int mt2712_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0194 {
0195 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0196 struct rtc_time *tm = &alm->time;
0197 u16 irqen;
0198
0199 irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
0200 alm->enabled = !!(irqen & MT2712_IRQ_EN_AL);
0201
0202 tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_AL_SEC) & MT2712_SEC_MASK;
0203 tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_AL_MIN) & MT2712_MIN_MASK;
0204 tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_AL_HOU) & MT2712_HOU_MASK;
0205 tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_AL_DOM) & MT2712_DOM_MASK;
0206 tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_AL_MTH) - 1)
0207 & MT2712_MTH_MASK;
0208 tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_AL_YEA) + 100)
0209 & MT2712_YEA_MASK;
0210
0211 return 0;
0212 }
0213
0214 static int mt2712_rtc_alarm_irq_enable(struct device *dev,
0215 unsigned int enabled)
0216 {
0217 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0218 u16 irqen;
0219
0220 irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN);
0221 if (enabled)
0222 irqen |= MT2712_IRQ_EN_AL;
0223 else
0224 irqen &= ~MT2712_IRQ_EN_AL;
0225 mt2712_writel(mt2712_rtc, MT2712_IRQ_EN, irqen);
0226 mt2712_rtc_write_trigger(mt2712_rtc);
0227
0228 return 0;
0229 }
0230
0231 static int mt2712_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0232 {
0233 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0234 struct rtc_time *tm = &alm->time;
0235
0236 dev_dbg(&mt2712_rtc->rtc->dev, "set al time: %ptR, alm en: %d\n",
0237 tm, alm->enabled);
0238
0239 mt2712_writel(mt2712_rtc, MT2712_AL_SEC,
0240 (mt2712_readl(mt2712_rtc, MT2712_AL_SEC)
0241 & ~(MT2712_SEC_MASK)) | (tm->tm_sec & MT2712_SEC_MASK));
0242 mt2712_writel(mt2712_rtc, MT2712_AL_MIN,
0243 (mt2712_readl(mt2712_rtc, MT2712_AL_MIN)
0244 & ~(MT2712_MIN_MASK)) | (tm->tm_min & MT2712_MIN_MASK));
0245 mt2712_writel(mt2712_rtc, MT2712_AL_HOU,
0246 (mt2712_readl(mt2712_rtc, MT2712_AL_HOU)
0247 & ~(MT2712_HOU_MASK)) | (tm->tm_hour & MT2712_HOU_MASK));
0248 mt2712_writel(mt2712_rtc, MT2712_AL_DOM,
0249 (mt2712_readl(mt2712_rtc, MT2712_AL_DOM)
0250 & ~(MT2712_DOM_MASK)) | (tm->tm_mday & MT2712_DOM_MASK));
0251 mt2712_writel(mt2712_rtc, MT2712_AL_MTH,
0252 (mt2712_readl(mt2712_rtc, MT2712_AL_MTH)
0253 & ~(MT2712_MTH_MASK))
0254 | ((tm->tm_mon + 1) & MT2712_MTH_MASK));
0255 mt2712_writel(mt2712_rtc, MT2712_AL_YEA,
0256 (mt2712_readl(mt2712_rtc, MT2712_AL_YEA)
0257 & ~(MT2712_YEA_MASK))
0258 | ((tm->tm_year - 100) & MT2712_YEA_MASK));
0259
0260
0261 mt2712_writel(mt2712_rtc, MT2712_AL_MASK, MT2712_AL_MASK_DOW);
0262 mt2712_rtc_write_trigger(mt2712_rtc);
0263
0264 mt2712_rtc_alarm_irq_enable(dev, alm->enabled);
0265
0266 return 0;
0267 }
0268
0269
0270 static void mt2712_rtc_hw_init(struct mt2712_rtc *mt2712_rtc)
0271 {
0272 u32 p1, p2;
0273
0274 mt2712_writel(mt2712_rtc, MT2712_BBPU,
0275 MT2712_BBPU_KEY | MT2712_BBPU_RELOAD);
0276
0277 mt2712_writel(mt2712_rtc, MT2712_CII_EN, 0);
0278 mt2712_writel(mt2712_rtc, MT2712_AL_MASK, 0);
0279
0280 mt2712_writel(mt2712_rtc, MT2712_CON0, 0x4848);
0281 mt2712_writel(mt2712_rtc, MT2712_CON1, 0x0048);
0282
0283 mt2712_rtc_write_trigger(mt2712_rtc);
0284
0285 p1 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY1);
0286 p2 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY2);
0287 if (p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY) {
0288 mt2712_rtc->powerlost = true;
0289 dev_dbg(&mt2712_rtc->rtc->dev,
0290 "powerkey not set (lost power)\n");
0291 } else {
0292 mt2712_rtc->powerlost = false;
0293 }
0294
0295
0296 mt2712_writel(mt2712_rtc, MT2712_POWERKEY1, MT2712_POWERKEY1_KEY);
0297 mt2712_writel(mt2712_rtc, MT2712_POWERKEY2, MT2712_POWERKEY2_KEY);
0298 mt2712_rtc_write_trigger(mt2712_rtc);
0299
0300 mt2712_rtc_writeif_unlock(mt2712_rtc);
0301 }
0302
0303 static const struct rtc_class_ops mt2712_rtc_ops = {
0304 .read_time = mt2712_rtc_read_time,
0305 .set_time = mt2712_rtc_set_time,
0306 .read_alarm = mt2712_rtc_read_alarm,
0307 .set_alarm = mt2712_rtc_set_alarm,
0308 .alarm_irq_enable = mt2712_rtc_alarm_irq_enable,
0309 };
0310
0311 static int mt2712_rtc_probe(struct platform_device *pdev)
0312 {
0313 struct mt2712_rtc *mt2712_rtc;
0314 int ret;
0315
0316 mt2712_rtc = devm_kzalloc(&pdev->dev,
0317 sizeof(struct mt2712_rtc), GFP_KERNEL);
0318 if (!mt2712_rtc)
0319 return -ENOMEM;
0320
0321 mt2712_rtc->base = devm_platform_ioremap_resource(pdev, 0);
0322 if (IS_ERR(mt2712_rtc->base))
0323 return PTR_ERR(mt2712_rtc->base);
0324
0325
0326 mt2712_rtc_hw_init(mt2712_rtc);
0327
0328 mt2712_rtc->irq = platform_get_irq(pdev, 0);
0329 if (mt2712_rtc->irq < 0)
0330 return mt2712_rtc->irq;
0331
0332 platform_set_drvdata(pdev, mt2712_rtc);
0333
0334 mt2712_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
0335 if (IS_ERR(mt2712_rtc->rtc))
0336 return PTR_ERR(mt2712_rtc->rtc);
0337
0338 ret = devm_request_threaded_irq(&pdev->dev, mt2712_rtc->irq, NULL,
0339 rtc_irq_handler_thread,
0340 IRQF_ONESHOT | IRQF_TRIGGER_LOW,
0341 dev_name(&mt2712_rtc->rtc->dev),
0342 mt2712_rtc);
0343 if (ret) {
0344 dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
0345 mt2712_rtc->irq, ret);
0346 return ret;
0347 }
0348
0349 device_init_wakeup(&pdev->dev, true);
0350
0351 mt2712_rtc->rtc->ops = &mt2712_rtc_ops;
0352 mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0353 mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127;
0354
0355 return devm_rtc_register_device(mt2712_rtc->rtc);
0356 }
0357
0358 #ifdef CONFIG_PM_SLEEP
0359 static int mt2712_rtc_suspend(struct device *dev)
0360 {
0361 int wake_status = 0;
0362 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0363
0364 if (device_may_wakeup(dev)) {
0365 wake_status = enable_irq_wake(mt2712_rtc->irq);
0366 if (!wake_status)
0367 mt2712_rtc->irq_wake_enabled = true;
0368 }
0369
0370 return 0;
0371 }
0372
0373 static int mt2712_rtc_resume(struct device *dev)
0374 {
0375 int wake_status = 0;
0376 struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev);
0377
0378 if (device_may_wakeup(dev) && mt2712_rtc->irq_wake_enabled) {
0379 wake_status = disable_irq_wake(mt2712_rtc->irq);
0380 if (!wake_status)
0381 mt2712_rtc->irq_wake_enabled = false;
0382 }
0383
0384 return 0;
0385 }
0386
0387 static SIMPLE_DEV_PM_OPS(mt2712_pm_ops, mt2712_rtc_suspend,
0388 mt2712_rtc_resume);
0389 #endif
0390
0391 static const struct of_device_id mt2712_rtc_of_match[] = {
0392 { .compatible = "mediatek,mt2712-rtc", },
0393 { },
0394 };
0395
0396 MODULE_DEVICE_TABLE(of, mt2712_rtc_of_match);
0397
0398 static struct platform_driver mt2712_rtc_driver = {
0399 .driver = {
0400 .name = "mt2712-rtc",
0401 .of_match_table = mt2712_rtc_of_match,
0402 #ifdef CONFIG_PM_SLEEP
0403 .pm = &mt2712_pm_ops,
0404 #endif
0405 },
0406 .probe = mt2712_rtc_probe,
0407 };
0408
0409 module_platform_driver(mt2712_rtc_driver);
0410
0411 MODULE_DESCRIPTION("MediaTek MT2712 SoC based RTC Driver");
0412 MODULE_AUTHOR("Ran Bi <ran.bi@mediatek.com>");
0413 MODULE_LICENSE("GPL");