Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003 * Copyright (c) 2014-2015 MediaTek Inc.
0004 * Author: Tianping.Fang <tianping.fang@mediatek.com>
0005 */
0006 
0007 #include <linux/err.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/mfd/mt6397/core.h>
0010 #include <linux/module.h>
0011 #include <linux/mutex.h>
0012 #include <linux/of_device.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/regmap.h>
0015 #include <linux/rtc.h>
0016 #include <linux/mfd/mt6397/rtc.h>
0017 #include <linux/mod_devicetable.h>
0018 
0019 static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
0020 {
0021     int ret;
0022     u32 data;
0023 
0024     ret = regmap_write(rtc->regmap, rtc->addr_base + rtc->data->wrtgr, 1);
0025     if (ret < 0)
0026         return ret;
0027 
0028     ret = regmap_read_poll_timeout(rtc->regmap,
0029                     rtc->addr_base + RTC_BBPU, data,
0030                     !(data & RTC_BBPU_CBUSY),
0031                     MTK_RTC_POLL_DELAY_US,
0032                     MTK_RTC_POLL_TIMEOUT);
0033     if (ret < 0)
0034         dev_err(rtc->rtc_dev->dev.parent,
0035             "failed to write WRTGR: %d\n", ret);
0036 
0037     return ret;
0038 }
0039 
0040 static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
0041 {
0042     struct mt6397_rtc *rtc = data;
0043     u32 irqsta, irqen;
0044     int ret;
0045 
0046     ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_STA, &irqsta);
0047     if ((ret >= 0) && (irqsta & RTC_IRQ_STA_AL)) {
0048         rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
0049         irqen = irqsta & ~RTC_IRQ_EN_AL;
0050         mutex_lock(&rtc->lock);
0051         if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
0052                  irqen) == 0)
0053             mtk_rtc_write_trigger(rtc);
0054         mutex_unlock(&rtc->lock);
0055 
0056         return IRQ_HANDLED;
0057     }
0058 
0059     return IRQ_NONE;
0060 }
0061 
0062 static int __mtk_rtc_read_time(struct mt6397_rtc *rtc,
0063                    struct rtc_time *tm, int *sec)
0064 {
0065     int ret;
0066     u16 data[RTC_OFFSET_COUNT];
0067 
0068     mutex_lock(&rtc->lock);
0069     ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC,
0070                    data, RTC_OFFSET_COUNT);
0071     if (ret < 0)
0072         goto exit;
0073 
0074     tm->tm_sec = data[RTC_OFFSET_SEC];
0075     tm->tm_min = data[RTC_OFFSET_MIN];
0076     tm->tm_hour = data[RTC_OFFSET_HOUR];
0077     tm->tm_mday = data[RTC_OFFSET_DOM];
0078     tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_TC_MTH_MASK;
0079     tm->tm_year = data[RTC_OFFSET_YEAR];
0080 
0081     ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, sec);
0082 exit:
0083     mutex_unlock(&rtc->lock);
0084     return ret;
0085 }
0086 
0087 static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm)
0088 {
0089     time64_t time;
0090     struct mt6397_rtc *rtc = dev_get_drvdata(dev);
0091     int days, sec, ret;
0092 
0093     do {
0094         ret = __mtk_rtc_read_time(rtc, tm, &sec);
0095         if (ret < 0)
0096             goto exit;
0097     } while (sec < tm->tm_sec);
0098 
0099     /* HW register use 7 bits to store year data, minus
0100      * RTC_MIN_YEAR_OFFSET before write year data to register, and plus
0101      * RTC_MIN_YEAR_OFFSET back after read year from register
0102      */
0103     tm->tm_year += RTC_MIN_YEAR_OFFSET;
0104 
0105     /* HW register start mon from one, but tm_mon start from zero. */
0106     tm->tm_mon--;
0107     time = rtc_tm_to_time64(tm);
0108 
0109     /* rtc_tm_to_time64 covert Gregorian date to seconds since
0110      * 01-01-1970 00:00:00, and this date is Thursday.
0111      */
0112     days = div_s64(time, 86400);
0113     tm->tm_wday = (days + 4) % 7;
0114 
0115 exit:
0116     return ret;
0117 }
0118 
0119 static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm)
0120 {
0121     struct mt6397_rtc *rtc = dev_get_drvdata(dev);
0122     int ret;
0123     u16 data[RTC_OFFSET_COUNT];
0124 
0125     tm->tm_year -= RTC_MIN_YEAR_OFFSET;
0126     tm->tm_mon++;
0127 
0128     data[RTC_OFFSET_SEC] = tm->tm_sec;
0129     data[RTC_OFFSET_MIN] = tm->tm_min;
0130     data[RTC_OFFSET_HOUR] = tm->tm_hour;
0131     data[RTC_OFFSET_DOM] = tm->tm_mday;
0132     data[RTC_OFFSET_MTH] = tm->tm_mon;
0133     data[RTC_OFFSET_YEAR] = tm->tm_year;
0134 
0135     mutex_lock(&rtc->lock);
0136     ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_TC_SEC,
0137                 data, RTC_OFFSET_COUNT);
0138     if (ret < 0)
0139         goto exit;
0140 
0141     /* Time register write to hardware after call trigger function */
0142     ret = mtk_rtc_write_trigger(rtc);
0143 
0144 exit:
0145     mutex_unlock(&rtc->lock);
0146     return ret;
0147 }
0148 
0149 static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0150 {
0151     struct rtc_time *tm = &alm->time;
0152     struct mt6397_rtc *rtc = dev_get_drvdata(dev);
0153     u32 irqen, pdn2;
0154     int ret;
0155     u16 data[RTC_OFFSET_COUNT];
0156 
0157     mutex_lock(&rtc->lock);
0158     ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, &irqen);
0159     if (ret < 0)
0160         goto err_exit;
0161     ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_PDN2, &pdn2);
0162     if (ret < 0)
0163         goto err_exit;
0164 
0165     ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
0166                    data, RTC_OFFSET_COUNT);
0167     if (ret < 0)
0168         goto err_exit;
0169 
0170     alm->enabled = !!(irqen & RTC_IRQ_EN_AL);
0171     alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
0172     mutex_unlock(&rtc->lock);
0173 
0174     tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
0175     tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
0176     tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
0177     tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
0178     tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
0179     tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
0180 
0181     tm->tm_year += RTC_MIN_YEAR_OFFSET;
0182     tm->tm_mon--;
0183 
0184     return 0;
0185 err_exit:
0186     mutex_unlock(&rtc->lock);
0187     return ret;
0188 }
0189 
0190 static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0191 {
0192     struct rtc_time *tm = &alm->time;
0193     struct mt6397_rtc *rtc = dev_get_drvdata(dev);
0194     int ret;
0195     u16 data[RTC_OFFSET_COUNT];
0196 
0197     tm->tm_year -= RTC_MIN_YEAR_OFFSET;
0198     tm->tm_mon++;
0199 
0200     mutex_lock(&rtc->lock);
0201     ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
0202                    data, RTC_OFFSET_COUNT);
0203     if (ret < 0)
0204         goto exit;
0205 
0206     data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
0207                 (tm->tm_sec & RTC_AL_SEC_MASK));
0208     data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
0209                 (tm->tm_min & RTC_AL_MIN_MASK));
0210     data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
0211                 (tm->tm_hour & RTC_AL_HOU_MASK));
0212     data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
0213                 (tm->tm_mday & RTC_AL_DOM_MASK));
0214     data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
0215                 (tm->tm_mon & RTC_AL_MTH_MASK));
0216     data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
0217                 (tm->tm_year & RTC_AL_YEA_MASK));
0218 
0219     if (alm->enabled) {
0220         ret = regmap_bulk_write(rtc->regmap,
0221                     rtc->addr_base + RTC_AL_SEC,
0222                     data, RTC_OFFSET_COUNT);
0223         if (ret < 0)
0224             goto exit;
0225         ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_AL_MASK,
0226                    RTC_AL_MASK_DOW);
0227         if (ret < 0)
0228             goto exit;
0229         ret = regmap_update_bits(rtc->regmap,
0230                      rtc->addr_base + RTC_IRQ_EN,
0231                      RTC_IRQ_EN_ONESHOT_AL,
0232                      RTC_IRQ_EN_ONESHOT_AL);
0233         if (ret < 0)
0234             goto exit;
0235     } else {
0236         ret = regmap_update_bits(rtc->regmap,
0237                      rtc->addr_base + RTC_IRQ_EN,
0238                      RTC_IRQ_EN_ONESHOT_AL, 0);
0239         if (ret < 0)
0240             goto exit;
0241     }
0242 
0243     /* All alarm time register write to hardware after calling
0244      * mtk_rtc_write_trigger. This can avoid race condition if alarm
0245      * occur happen during writing alarm time register.
0246      */
0247     ret = mtk_rtc_write_trigger(rtc);
0248 exit:
0249     mutex_unlock(&rtc->lock);
0250     return ret;
0251 }
0252 
0253 static const struct rtc_class_ops mtk_rtc_ops = {
0254     .read_time  = mtk_rtc_read_time,
0255     .set_time   = mtk_rtc_set_time,
0256     .read_alarm = mtk_rtc_read_alarm,
0257     .set_alarm  = mtk_rtc_set_alarm,
0258 };
0259 
0260 static int mtk_rtc_probe(struct platform_device *pdev)
0261 {
0262     struct resource *res;
0263     struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
0264     struct mt6397_rtc *rtc;
0265     int ret;
0266 
0267     rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6397_rtc), GFP_KERNEL);
0268     if (!rtc)
0269         return -ENOMEM;
0270 
0271     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0272     if (!res)
0273         return -EINVAL;
0274     rtc->addr_base = res->start;
0275 
0276     rtc->data = of_device_get_match_data(&pdev->dev);
0277 
0278     rtc->irq = platform_get_irq(pdev, 0);
0279     if (rtc->irq < 0)
0280         return rtc->irq;
0281 
0282     rtc->regmap = mt6397_chip->regmap;
0283     mutex_init(&rtc->lock);
0284 
0285     platform_set_drvdata(pdev, rtc);
0286 
0287     rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev);
0288     if (IS_ERR(rtc->rtc_dev))
0289         return PTR_ERR(rtc->rtc_dev);
0290 
0291     ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
0292                     mtk_rtc_irq_handler_thread,
0293                     IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
0294                     "mt6397-rtc", rtc);
0295 
0296     if (ret) {
0297         dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
0298             rtc->irq, ret);
0299         return ret;
0300     }
0301 
0302     device_init_wakeup(&pdev->dev, 1);
0303 
0304     rtc->rtc_dev->ops = &mtk_rtc_ops;
0305 
0306     return devm_rtc_register_device(rtc->rtc_dev);
0307 }
0308 
0309 #ifdef CONFIG_PM_SLEEP
0310 static int mt6397_rtc_suspend(struct device *dev)
0311 {
0312     struct mt6397_rtc *rtc = dev_get_drvdata(dev);
0313 
0314     if (device_may_wakeup(dev))
0315         enable_irq_wake(rtc->irq);
0316 
0317     return 0;
0318 }
0319 
0320 static int mt6397_rtc_resume(struct device *dev)
0321 {
0322     struct mt6397_rtc *rtc = dev_get_drvdata(dev);
0323 
0324     if (device_may_wakeup(dev))
0325         disable_irq_wake(rtc->irq);
0326 
0327     return 0;
0328 }
0329 #endif
0330 
0331 static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
0332             mt6397_rtc_resume);
0333 
0334 static const struct mtk_rtc_data mt6358_rtc_data = {
0335     .wrtgr = RTC_WRTGR_MT6358,
0336 };
0337 
0338 static const struct mtk_rtc_data mt6397_rtc_data = {
0339     .wrtgr = RTC_WRTGR_MT6397,
0340 };
0341 
0342 static const struct of_device_id mt6397_rtc_of_match[] = {
0343     { .compatible = "mediatek,mt6323-rtc", .data = &mt6397_rtc_data },
0344     { .compatible = "mediatek,mt6358-rtc", .data = &mt6358_rtc_data },
0345     { .compatible = "mediatek,mt6397-rtc", .data = &mt6397_rtc_data },
0346     { }
0347 };
0348 MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);
0349 
0350 static struct platform_driver mtk_rtc_driver = {
0351     .driver = {
0352         .name = "mt6397-rtc",
0353         .of_match_table = mt6397_rtc_of_match,
0354         .pm = &mt6397_pm_ops,
0355     },
0356     .probe  = mtk_rtc_probe,
0357 };
0358 
0359 module_platform_driver(mtk_rtc_driver);
0360 
0361 MODULE_LICENSE("GPL v2");
0362 MODULE_AUTHOR("Tianping Fang <tianping.fang@mediatek.com>");
0363 MODULE_DESCRIPTION("RTC Driver for MediaTek MT6397 PMIC");