Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Real-time clock driver for MPC5121
0004  *
0005  * Copyright 2007, Domen Puncer <domen.puncer@telargo.com>
0006  * Copyright 2008, Freescale Semiconductor, Inc. All rights reserved.
0007  * Copyright 2011, Dmitry Eremin-Solenikov
0008  */
0009 
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/rtc.h>
0013 #include <linux/of.h>
0014 #include <linux/of_address.h>
0015 #include <linux/of_device.h>
0016 #include <linux/of_irq.h>
0017 #include <linux/of_platform.h>
0018 #include <linux/io.h>
0019 #include <linux/slab.h>
0020 
0021 struct mpc5121_rtc_regs {
0022     u8 set_time;        /* RTC + 0x00 */
0023     u8 hour_set;        /* RTC + 0x01 */
0024     u8 minute_set;      /* RTC + 0x02 */
0025     u8 second_set;      /* RTC + 0x03 */
0026 
0027     u8 set_date;        /* RTC + 0x04 */
0028     u8 month_set;       /* RTC + 0x05 */
0029     u8 weekday_set;     /* RTC + 0x06 */
0030     u8 date_set;        /* RTC + 0x07 */
0031 
0032     u8 write_sw;        /* RTC + 0x08 */
0033     u8 sw_set;      /* RTC + 0x09 */
0034     u16 year_set;       /* RTC + 0x0a */
0035 
0036     u8 alm_enable;      /* RTC + 0x0c */
0037     u8 alm_hour_set;    /* RTC + 0x0d */
0038     u8 alm_min_set;     /* RTC + 0x0e */
0039     u8 int_enable;      /* RTC + 0x0f */
0040 
0041     u8 reserved1;
0042     u8 hour;        /* RTC + 0x11 */
0043     u8 minute;      /* RTC + 0x12 */
0044     u8 second;      /* RTC + 0x13 */
0045 
0046     u8 month;       /* RTC + 0x14 */
0047     u8 wday_mday;       /* RTC + 0x15 */
0048     u16 year;       /* RTC + 0x16 */
0049 
0050     u8 int_alm;     /* RTC + 0x18 */
0051     u8 int_sw;      /* RTC + 0x19 */
0052     u8 alm_status;      /* RTC + 0x1a */
0053     u8 sw_minute;       /* RTC + 0x1b */
0054 
0055     u8 bus_error_1;     /* RTC + 0x1c */
0056     u8 int_day;     /* RTC + 0x1d */
0057     u8 int_min;     /* RTC + 0x1e */
0058     u8 int_sec;     /* RTC + 0x1f */
0059 
0060     /*
0061      * target_time:
0062      *  intended to be used for hibernation but hibernation
0063      *  does not work on silicon rev 1.5 so use it for non-volatile
0064      *  storage of offset between the actual_time register and linux
0065      *  time
0066      */
0067     u32 target_time;    /* RTC + 0x20 */
0068     /*
0069      * actual_time:
0070      *  readonly time since VBAT_RTC was last connected
0071      */
0072     u32 actual_time;    /* RTC + 0x24 */
0073     u32 keep_alive;     /* RTC + 0x28 */
0074 };
0075 
0076 struct mpc5121_rtc_data {
0077     unsigned irq;
0078     unsigned irq_periodic;
0079     struct mpc5121_rtc_regs __iomem *regs;
0080     struct rtc_device *rtc;
0081     struct rtc_wkalrm wkalarm;
0082 };
0083 
0084 /*
0085  * Update second/minute/hour registers.
0086  *
0087  * This is just so alarm will work.
0088  */
0089 static void mpc5121_rtc_update_smh(struct mpc5121_rtc_regs __iomem *regs,
0090                    struct rtc_time *tm)
0091 {
0092     out_8(&regs->second_set, tm->tm_sec);
0093     out_8(&regs->minute_set, tm->tm_min);
0094     out_8(&regs->hour_set, tm->tm_hour);
0095 
0096     /* set time sequence */
0097     out_8(&regs->set_time, 0x1);
0098     out_8(&regs->set_time, 0x3);
0099     out_8(&regs->set_time, 0x1);
0100     out_8(&regs->set_time, 0x0);
0101 }
0102 
0103 static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm)
0104 {
0105     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0106     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0107     unsigned long now;
0108 
0109     /*
0110      * linux time is actual_time plus the offset saved in target_time
0111      */
0112     now = in_be32(&regs->actual_time) + in_be32(&regs->target_time);
0113 
0114     rtc_time64_to_tm(now, tm);
0115 
0116     /*
0117      * update second minute hour registers
0118      * so alarms will work
0119      */
0120     mpc5121_rtc_update_smh(regs, tm);
0121 
0122     return 0;
0123 }
0124 
0125 static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm)
0126 {
0127     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0128     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0129     unsigned long now;
0130 
0131     /*
0132      * The actual_time register is read only so we write the offset
0133      * between it and linux time to the target_time register.
0134      */
0135     now = rtc_tm_to_time64(tm);
0136     out_be32(&regs->target_time, now - in_be32(&regs->actual_time));
0137 
0138     /*
0139      * update second minute hour registers
0140      * so alarms will work
0141      */
0142     mpc5121_rtc_update_smh(regs, tm);
0143 
0144     return 0;
0145 }
0146 
0147 static int mpc5200_rtc_read_time(struct device *dev, struct rtc_time *tm)
0148 {
0149     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0150     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0151     int tmp;
0152 
0153     tm->tm_sec = in_8(&regs->second);
0154     tm->tm_min = in_8(&regs->minute);
0155 
0156     /* 12 hour format? */
0157     if (in_8(&regs->hour) & 0x20)
0158         tm->tm_hour = (in_8(&regs->hour) >> 1) +
0159             (in_8(&regs->hour) & 1 ? 12 : 0);
0160     else
0161         tm->tm_hour = in_8(&regs->hour);
0162 
0163     tmp = in_8(&regs->wday_mday);
0164     tm->tm_mday = tmp & 0x1f;
0165     tm->tm_mon = in_8(&regs->month) - 1;
0166     tm->tm_year = in_be16(&regs->year) - 1900;
0167     tm->tm_wday = (tmp >> 5) % 7;
0168     tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
0169     tm->tm_isdst = 0;
0170 
0171     return 0;
0172 }
0173 
0174 static int mpc5200_rtc_set_time(struct device *dev, struct rtc_time *tm)
0175 {
0176     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0177     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0178 
0179     mpc5121_rtc_update_smh(regs, tm);
0180 
0181     /* date */
0182     out_8(&regs->month_set, tm->tm_mon + 1);
0183     out_8(&regs->weekday_set, tm->tm_wday ? tm->tm_wday : 7);
0184     out_8(&regs->date_set, tm->tm_mday);
0185     out_be16(&regs->year_set, tm->tm_year + 1900);
0186 
0187     /* set date sequence */
0188     out_8(&regs->set_date, 0x1);
0189     out_8(&regs->set_date, 0x3);
0190     out_8(&regs->set_date, 0x1);
0191     out_8(&regs->set_date, 0x0);
0192 
0193     return 0;
0194 }
0195 
0196 static int mpc5121_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0197 {
0198     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0199     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0200 
0201     *alarm = rtc->wkalarm;
0202 
0203     alarm->pending = in_8(&regs->alm_status);
0204 
0205     return 0;
0206 }
0207 
0208 static int mpc5121_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
0209 {
0210     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0211     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0212 
0213     alarm->time.tm_mday = -1;
0214     alarm->time.tm_mon = -1;
0215     alarm->time.tm_year = -1;
0216 
0217     out_8(&regs->alm_min_set, alarm->time.tm_min);
0218     out_8(&regs->alm_hour_set, alarm->time.tm_hour);
0219 
0220     out_8(&regs->alm_enable, alarm->enabled);
0221 
0222     rtc->wkalarm = *alarm;
0223     return 0;
0224 }
0225 
0226 static irqreturn_t mpc5121_rtc_handler(int irq, void *dev)
0227 {
0228     struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
0229     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0230 
0231     if (in_8(&regs->int_alm)) {
0232         /* acknowledge and clear status */
0233         out_8(&regs->int_alm, 1);
0234         out_8(&regs->alm_status, 1);
0235 
0236         rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
0237         return IRQ_HANDLED;
0238     }
0239 
0240     return IRQ_NONE;
0241 }
0242 
0243 static irqreturn_t mpc5121_rtc_handler_upd(int irq, void *dev)
0244 {
0245     struct mpc5121_rtc_data *rtc = dev_get_drvdata((struct device *)dev);
0246     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0247 
0248     if (in_8(&regs->int_sec) && (in_8(&regs->int_enable) & 0x1)) {
0249         /* acknowledge */
0250         out_8(&regs->int_sec, 1);
0251 
0252         rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_UF);
0253         return IRQ_HANDLED;
0254     }
0255 
0256     return IRQ_NONE;
0257 }
0258 
0259 static int mpc5121_rtc_alarm_irq_enable(struct device *dev,
0260                     unsigned int enabled)
0261 {
0262     struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev);
0263     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0264     int val;
0265 
0266     if (enabled)
0267         val = 1;
0268     else
0269         val = 0;
0270 
0271     out_8(&regs->alm_enable, val);
0272     rtc->wkalarm.enabled = val;
0273 
0274     return 0;
0275 }
0276 
0277 static const struct rtc_class_ops mpc5121_rtc_ops = {
0278     .read_time = mpc5121_rtc_read_time,
0279     .set_time = mpc5121_rtc_set_time,
0280     .read_alarm = mpc5121_rtc_read_alarm,
0281     .set_alarm = mpc5121_rtc_set_alarm,
0282     .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable,
0283 };
0284 
0285 static const struct rtc_class_ops mpc5200_rtc_ops = {
0286     .read_time = mpc5200_rtc_read_time,
0287     .set_time = mpc5200_rtc_set_time,
0288     .read_alarm = mpc5121_rtc_read_alarm,
0289     .set_alarm = mpc5121_rtc_set_alarm,
0290     .alarm_irq_enable = mpc5121_rtc_alarm_irq_enable,
0291 };
0292 
0293 static int mpc5121_rtc_probe(struct platform_device *op)
0294 {
0295     struct mpc5121_rtc_data *rtc;
0296     int err = 0;
0297 
0298     rtc = devm_kzalloc(&op->dev, sizeof(*rtc), GFP_KERNEL);
0299     if (!rtc)
0300         return -ENOMEM;
0301 
0302     rtc->regs = devm_platform_ioremap_resource(op, 0);
0303     if (IS_ERR(rtc->regs)) {
0304         dev_err(&op->dev, "%s: couldn't map io space\n", __func__);
0305         return PTR_ERR(rtc->regs);
0306     }
0307 
0308     device_init_wakeup(&op->dev, 1);
0309 
0310     platform_set_drvdata(op, rtc);
0311 
0312     rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1);
0313     err = devm_request_irq(&op->dev, rtc->irq, mpc5121_rtc_handler, 0,
0314                    "mpc5121-rtc", &op->dev);
0315     if (err) {
0316         dev_err(&op->dev, "%s: could not request irq: %i\n",
0317                             __func__, rtc->irq);
0318         goto out_dispose;
0319     }
0320 
0321     rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0);
0322     err = devm_request_irq(&op->dev, rtc->irq_periodic,
0323                    mpc5121_rtc_handler_upd, 0, "mpc5121-rtc_upd",
0324                    &op->dev);
0325     if (err) {
0326         dev_err(&op->dev, "%s: could not request irq: %i\n",
0327                         __func__, rtc->irq_periodic);
0328         goto out_dispose2;
0329     }
0330 
0331     rtc->rtc = devm_rtc_allocate_device(&op->dev);
0332     if (IS_ERR(rtc->rtc)) {
0333         err = PTR_ERR(rtc->rtc);
0334         goto out_dispose2;
0335     }
0336 
0337     rtc->rtc->ops = &mpc5200_rtc_ops;
0338     set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtc->features);
0339     clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtc->features);
0340     rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000;
0341     rtc->rtc->range_max = 65733206399ULL; /* 4052-12-31 23:59:59 */
0342 
0343     if (of_device_is_compatible(op->dev.of_node, "fsl,mpc5121-rtc")) {
0344         u32 ka;
0345         ka = in_be32(&rtc->regs->keep_alive);
0346         if (ka & 0x02) {
0347             dev_warn(&op->dev,
0348                 "mpc5121-rtc: Battery or oscillator failure!\n");
0349             out_be32(&rtc->regs->keep_alive, ka);
0350         }
0351         rtc->rtc->ops = &mpc5121_rtc_ops;
0352         /*
0353          * This is a limitation of the driver that abuses the target
0354          * time register, the actual maximum year for the mpc5121 is
0355          * also 4052.
0356          */
0357         rtc->rtc->range_min = 0;
0358         rtc->rtc->range_max = U32_MAX;
0359     }
0360 
0361     err = devm_rtc_register_device(rtc->rtc);
0362     if (err)
0363         goto out_dispose2;
0364 
0365     return 0;
0366 
0367 out_dispose2:
0368     irq_dispose_mapping(rtc->irq_periodic);
0369 out_dispose:
0370     irq_dispose_mapping(rtc->irq);
0371 
0372     return err;
0373 }
0374 
0375 static int mpc5121_rtc_remove(struct platform_device *op)
0376 {
0377     struct mpc5121_rtc_data *rtc = platform_get_drvdata(op);
0378     struct mpc5121_rtc_regs __iomem *regs = rtc->regs;
0379 
0380     /* disable interrupt, so there are no nasty surprises */
0381     out_8(&regs->alm_enable, 0);
0382     out_8(&regs->int_enable, in_8(&regs->int_enable) & ~0x1);
0383 
0384     irq_dispose_mapping(rtc->irq);
0385     irq_dispose_mapping(rtc->irq_periodic);
0386 
0387     return 0;
0388 }
0389 
0390 #ifdef CONFIG_OF
0391 static const struct of_device_id mpc5121_rtc_match[] = {
0392     { .compatible = "fsl,mpc5121-rtc", },
0393     { .compatible = "fsl,mpc5200-rtc", },
0394     {},
0395 };
0396 MODULE_DEVICE_TABLE(of, mpc5121_rtc_match);
0397 #endif
0398 
0399 static struct platform_driver mpc5121_rtc_driver = {
0400     .driver = {
0401         .name = "mpc5121-rtc",
0402         .of_match_table = of_match_ptr(mpc5121_rtc_match),
0403     },
0404     .probe = mpc5121_rtc_probe,
0405     .remove = mpc5121_rtc_remove,
0406 };
0407 
0408 module_platform_driver(mpc5121_rtc_driver);
0409 
0410 MODULE_LICENSE("GPL");
0411 MODULE_AUTHOR("John Rigby <jcrigby@gmail.com>");