0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/bcd.h>
0010 #include <linux/clk.h>
0011 #include <linux/delay.h>
0012 #include <linux/init.h>
0013 #include <linux/io.h>
0014 #include <linux/irq.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/rtc.h>
0019 #include <linux/slab.h>
0020 #include <linux/spinlock.h>
0021
0022
0023 #define TIME_REG 0x00
0024 #define DATE_REG 0x04
0025 #define ALARM_TIME_REG 0x08
0026 #define ALARM_DATE_REG 0x0C
0027 #define CTRL_REG 0x10
0028 #define STATUS_REG 0x14
0029
0030
0031 #define SECONDS_UNITS (0xf<<0)
0032 #define SECONDS_TENS (0x7<<4)
0033 #define MINUTES_UNITS (0xf<<8)
0034 #define MINUTES_TENS (0x7<<12)
0035 #define HOURS_UNITS (0xf<<16)
0036 #define HOURS_TENS (0x3<<20)
0037
0038
0039 #define DAYS_UNITS (0xf<<0)
0040 #define DAYS_TENS (0x3<<4)
0041 #define MONTHS_UNITS (0xf<<8)
0042 #define MONTHS_TENS (0x1<<12)
0043 #define YEARS_UNITS (0xf<<16)
0044 #define YEARS_TENS (0xf<<20)
0045 #define YEARS_HUNDREDS (0xf<<24)
0046 #define YEARS_MILLENIUMS (0xf<<28)
0047
0048
0049 #define SECOND_SHIFT 0x00
0050 #define MINUTE_SHIFT 0x08
0051 #define HOUR_SHIFT 0x10
0052 #define MDAY_SHIFT 0x00
0053 #define MONTH_SHIFT 0x08
0054 #define YEAR_SHIFT 0x10
0055
0056 #define SECOND_MASK 0x7F
0057 #define MIN_MASK 0x7F
0058 #define HOUR_MASK 0x3F
0059 #define DAY_MASK 0x3F
0060 #define MONTH_MASK 0x7F
0061 #define YEAR_MASK 0xFFFF
0062
0063
0064 #define TIME_BYP (1<<9)
0065 #define INT_ENABLE (1<<31)
0066
0067
0068 #define CLK_UNCONNECTED (1<<0)
0069 #define PEND_WR_TIME (1<<2)
0070 #define PEND_WR_DATE (1<<3)
0071 #define LOST_WR_TIME (1<<4)
0072 #define LOST_WR_DATE (1<<5)
0073 #define RTC_INT_MASK (1<<31)
0074 #define STATUS_BUSY (PEND_WR_TIME | PEND_WR_DATE)
0075 #define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE)
0076
0077 struct spear_rtc_config {
0078 struct rtc_device *rtc;
0079 struct clk *clk;
0080 spinlock_t lock;
0081 void __iomem *ioaddr;
0082 unsigned int irq_wake;
0083 };
0084
0085 static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config)
0086 {
0087 unsigned int val;
0088 unsigned long flags;
0089
0090 spin_lock_irqsave(&config->lock, flags);
0091 val = readl(config->ioaddr + STATUS_REG);
0092 val |= RTC_INT_MASK;
0093 writel(val, config->ioaddr + STATUS_REG);
0094 spin_unlock_irqrestore(&config->lock, flags);
0095 }
0096
0097 static inline void spear_rtc_enable_interrupt(struct spear_rtc_config *config)
0098 {
0099 unsigned int val;
0100
0101 val = readl(config->ioaddr + CTRL_REG);
0102 if (!(val & INT_ENABLE)) {
0103 spear_rtc_clear_interrupt(config);
0104 val |= INT_ENABLE;
0105 writel(val, config->ioaddr + CTRL_REG);
0106 }
0107 }
0108
0109 static inline void spear_rtc_disable_interrupt(struct spear_rtc_config *config)
0110 {
0111 unsigned int val;
0112
0113 val = readl(config->ioaddr + CTRL_REG);
0114 if (val & INT_ENABLE) {
0115 val &= ~INT_ENABLE;
0116 writel(val, config->ioaddr + CTRL_REG);
0117 }
0118 }
0119
0120 static inline int is_write_complete(struct spear_rtc_config *config)
0121 {
0122 int ret = 0;
0123 unsigned long flags;
0124
0125 spin_lock_irqsave(&config->lock, flags);
0126 if ((readl(config->ioaddr + STATUS_REG)) & STATUS_FAIL)
0127 ret = -EIO;
0128 spin_unlock_irqrestore(&config->lock, flags);
0129
0130 return ret;
0131 }
0132
0133 static void rtc_wait_not_busy(struct spear_rtc_config *config)
0134 {
0135 int status, count = 0;
0136 unsigned long flags;
0137
0138
0139 for (count = 0; count < 80; count++) {
0140 spin_lock_irqsave(&config->lock, flags);
0141 status = readl(config->ioaddr + STATUS_REG);
0142 spin_unlock_irqrestore(&config->lock, flags);
0143 if ((status & STATUS_BUSY) == 0)
0144 break;
0145
0146 msleep(1);
0147 }
0148 }
0149
0150 static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
0151 {
0152 struct spear_rtc_config *config = dev_id;
0153 unsigned long events = 0;
0154 unsigned int irq_data;
0155
0156 spin_lock(&config->lock);
0157 irq_data = readl(config->ioaddr + STATUS_REG);
0158 spin_unlock(&config->lock);
0159
0160 if ((irq_data & RTC_INT_MASK)) {
0161 spear_rtc_clear_interrupt(config);
0162 events = RTC_IRQF | RTC_AF;
0163 rtc_update_irq(config->rtc, 1, events);
0164 return IRQ_HANDLED;
0165 } else
0166 return IRQ_NONE;
0167
0168 }
0169
0170 static void tm2bcd(struct rtc_time *tm)
0171 {
0172 tm->tm_sec = bin2bcd(tm->tm_sec);
0173 tm->tm_min = bin2bcd(tm->tm_min);
0174 tm->tm_hour = bin2bcd(tm->tm_hour);
0175 tm->tm_mday = bin2bcd(tm->tm_mday);
0176 tm->tm_mon = bin2bcd(tm->tm_mon + 1);
0177 tm->tm_year = bin2bcd(tm->tm_year);
0178 }
0179
0180 static void bcd2tm(struct rtc_time *tm)
0181 {
0182 tm->tm_sec = bcd2bin(tm->tm_sec);
0183 tm->tm_min = bcd2bin(tm->tm_min);
0184 tm->tm_hour = bcd2bin(tm->tm_hour);
0185 tm->tm_mday = bcd2bin(tm->tm_mday);
0186 tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
0187
0188 tm->tm_year = bcd2bin(tm->tm_year);
0189 }
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
0200 {
0201 struct spear_rtc_config *config = dev_get_drvdata(dev);
0202 unsigned int time, date;
0203
0204
0205 rtc_wait_not_busy(config);
0206
0207 do {
0208 time = readl(config->ioaddr + TIME_REG);
0209 date = readl(config->ioaddr + DATE_REG);
0210 } while (time == readl(config->ioaddr + TIME_REG));
0211 tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
0212 tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
0213 tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
0214 tm->tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
0215 tm->tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
0216 tm->tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
0217
0218 bcd2tm(tm);
0219 return 0;
0220 }
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
0231 {
0232 struct spear_rtc_config *config = dev_get_drvdata(dev);
0233 unsigned int time, date;
0234
0235 tm2bcd(tm);
0236
0237 rtc_wait_not_busy(config);
0238 time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) |
0239 (tm->tm_hour << HOUR_SHIFT);
0240 date = (tm->tm_mday << MDAY_SHIFT) | (tm->tm_mon << MONTH_SHIFT) |
0241 (tm->tm_year << YEAR_SHIFT);
0242 writel(time, config->ioaddr + TIME_REG);
0243 writel(date, config->ioaddr + DATE_REG);
0244
0245 return is_write_complete(config);
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0257 {
0258 struct spear_rtc_config *config = dev_get_drvdata(dev);
0259 unsigned int time, date;
0260
0261 rtc_wait_not_busy(config);
0262
0263 time = readl(config->ioaddr + ALARM_TIME_REG);
0264 date = readl(config->ioaddr + ALARM_DATE_REG);
0265 alm->time.tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
0266 alm->time.tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
0267 alm->time.tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
0268 alm->time.tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
0269 alm->time.tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
0270 alm->time.tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
0271
0272 bcd2tm(&alm->time);
0273 alm->enabled = readl(config->ioaddr + CTRL_REG) & INT_ENABLE;
0274
0275 return 0;
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286 static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0287 {
0288 struct spear_rtc_config *config = dev_get_drvdata(dev);
0289 unsigned int time, date;
0290 int err;
0291
0292 tm2bcd(&alm->time);
0293
0294 rtc_wait_not_busy(config);
0295
0296 time = (alm->time.tm_sec << SECOND_SHIFT) | (alm->time.tm_min <<
0297 MINUTE_SHIFT) | (alm->time.tm_hour << HOUR_SHIFT);
0298 date = (alm->time.tm_mday << MDAY_SHIFT) | (alm->time.tm_mon <<
0299 MONTH_SHIFT) | (alm->time.tm_year << YEAR_SHIFT);
0300
0301 writel(time, config->ioaddr + ALARM_TIME_REG);
0302 writel(date, config->ioaddr + ALARM_DATE_REG);
0303 err = is_write_complete(config);
0304 if (err < 0)
0305 return err;
0306
0307 if (alm->enabled)
0308 spear_rtc_enable_interrupt(config);
0309 else
0310 spear_rtc_disable_interrupt(config);
0311
0312 return 0;
0313 }
0314
0315 static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled)
0316 {
0317 struct spear_rtc_config *config = dev_get_drvdata(dev);
0318 int ret = 0;
0319
0320 spear_rtc_clear_interrupt(config);
0321
0322 switch (enabled) {
0323 case 0:
0324
0325 spear_rtc_disable_interrupt(config);
0326 break;
0327 case 1:
0328
0329 spear_rtc_enable_interrupt(config);
0330 break;
0331 default:
0332 ret = -EINVAL;
0333 break;
0334 }
0335
0336 return ret;
0337 }
0338
0339 static const struct rtc_class_ops spear_rtc_ops = {
0340 .read_time = spear_rtc_read_time,
0341 .set_time = spear_rtc_set_time,
0342 .read_alarm = spear_rtc_read_alarm,
0343 .set_alarm = spear_rtc_set_alarm,
0344 .alarm_irq_enable = spear_alarm_irq_enable,
0345 };
0346
0347 static int spear_rtc_probe(struct platform_device *pdev)
0348 {
0349 struct spear_rtc_config *config;
0350 int status = 0;
0351 int irq;
0352
0353 config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
0354 if (!config)
0355 return -ENOMEM;
0356
0357 config->rtc = devm_rtc_allocate_device(&pdev->dev);
0358 if (IS_ERR(config->rtc))
0359 return PTR_ERR(config->rtc);
0360
0361
0362 irq = platform_get_irq(pdev, 0);
0363 if (irq < 0)
0364 return irq;
0365
0366 status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name,
0367 config);
0368 if (status) {
0369 dev_err(&pdev->dev, "Alarm interrupt IRQ%d already claimed\n",
0370 irq);
0371 return status;
0372 }
0373
0374 config->ioaddr = devm_platform_ioremap_resource(pdev, 0);
0375 if (IS_ERR(config->ioaddr))
0376 return PTR_ERR(config->ioaddr);
0377
0378 config->clk = devm_clk_get(&pdev->dev, NULL);
0379 if (IS_ERR(config->clk))
0380 return PTR_ERR(config->clk);
0381
0382 status = clk_prepare_enable(config->clk);
0383 if (status < 0)
0384 return status;
0385
0386 spin_lock_init(&config->lock);
0387 platform_set_drvdata(pdev, config);
0388
0389 config->rtc->ops = &spear_rtc_ops;
0390 config->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000;
0391 config->rtc->range_max = RTC_TIMESTAMP_END_9999;
0392
0393 status = devm_rtc_register_device(config->rtc);
0394 if (status)
0395 goto err_disable_clock;
0396
0397 if (!device_can_wakeup(&pdev->dev))
0398 device_init_wakeup(&pdev->dev, 1);
0399
0400 return 0;
0401
0402 err_disable_clock:
0403 clk_disable_unprepare(config->clk);
0404
0405 return status;
0406 }
0407
0408 static int spear_rtc_remove(struct platform_device *pdev)
0409 {
0410 struct spear_rtc_config *config = platform_get_drvdata(pdev);
0411
0412 spear_rtc_disable_interrupt(config);
0413 clk_disable_unprepare(config->clk);
0414 device_init_wakeup(&pdev->dev, 0);
0415
0416 return 0;
0417 }
0418
0419 #ifdef CONFIG_PM_SLEEP
0420 static int spear_rtc_suspend(struct device *dev)
0421 {
0422 struct platform_device *pdev = to_platform_device(dev);
0423 struct spear_rtc_config *config = platform_get_drvdata(pdev);
0424 int irq;
0425
0426 irq = platform_get_irq(pdev, 0);
0427 if (device_may_wakeup(&pdev->dev)) {
0428 if (!enable_irq_wake(irq))
0429 config->irq_wake = 1;
0430 } else {
0431 spear_rtc_disable_interrupt(config);
0432 clk_disable(config->clk);
0433 }
0434
0435 return 0;
0436 }
0437
0438 static int spear_rtc_resume(struct device *dev)
0439 {
0440 struct platform_device *pdev = to_platform_device(dev);
0441 struct spear_rtc_config *config = platform_get_drvdata(pdev);
0442 int irq;
0443
0444 irq = platform_get_irq(pdev, 0);
0445
0446 if (device_may_wakeup(&pdev->dev)) {
0447 if (config->irq_wake) {
0448 disable_irq_wake(irq);
0449 config->irq_wake = 0;
0450 }
0451 } else {
0452 clk_enable(config->clk);
0453 spear_rtc_enable_interrupt(config);
0454 }
0455
0456 return 0;
0457 }
0458 #endif
0459
0460 static SIMPLE_DEV_PM_OPS(spear_rtc_pm_ops, spear_rtc_suspend, spear_rtc_resume);
0461
0462 static void spear_rtc_shutdown(struct platform_device *pdev)
0463 {
0464 struct spear_rtc_config *config = platform_get_drvdata(pdev);
0465
0466 spear_rtc_disable_interrupt(config);
0467 clk_disable(config->clk);
0468 }
0469
0470 #ifdef CONFIG_OF
0471 static const struct of_device_id spear_rtc_id_table[] = {
0472 { .compatible = "st,spear600-rtc" },
0473 {}
0474 };
0475 MODULE_DEVICE_TABLE(of, spear_rtc_id_table);
0476 #endif
0477
0478 static struct platform_driver spear_rtc_driver = {
0479 .probe = spear_rtc_probe,
0480 .remove = spear_rtc_remove,
0481 .shutdown = spear_rtc_shutdown,
0482 .driver = {
0483 .name = "rtc-spear",
0484 .pm = &spear_rtc_pm_ops,
0485 .of_match_table = of_match_ptr(spear_rtc_id_table),
0486 },
0487 };
0488
0489 module_platform_driver(spear_rtc_driver);
0490
0491 MODULE_ALIAS("platform:rtc-spear");
0492 MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
0493 MODULE_DESCRIPTION("ST SPEAr Realtime Clock Driver (RTC)");
0494 MODULE_LICENSE("GPL");