0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/ioport.h>
0013 #include <linux/delay.h>
0014 #include <linux/spinlock.h>
0015 #include <linux/rtc.h>
0016 #include <linux/bcd.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/io.h>
0019 #include <linux/slab.h>
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #define DAVINCI_PRTCIF_PID 0x00
0031 #define PRTCIF_CTLR 0x04
0032 #define PRTCIF_LDATA 0x08
0033 #define PRTCIF_UDATA 0x0C
0034 #define PRTCIF_INTEN 0x10
0035 #define PRTCIF_INTFLG 0x14
0036
0037
0038 #define PRTCIF_CTLR_BUSY BIT(31)
0039 #define PRTCIF_CTLR_SIZE BIT(25)
0040 #define PRTCIF_CTLR_DIR BIT(24)
0041 #define PRTCIF_CTLR_BENU_MSB BIT(23)
0042 #define PRTCIF_CTLR_BENU_3RD_BYTE BIT(22)
0043 #define PRTCIF_CTLR_BENU_2ND_BYTE BIT(21)
0044 #define PRTCIF_CTLR_BENU_LSB BIT(20)
0045 #define PRTCIF_CTLR_BENU_MASK (0x00F00000)
0046 #define PRTCIF_CTLR_BENL_MSB BIT(19)
0047 #define PRTCIF_CTLR_BENL_3RD_BYTE BIT(18)
0048 #define PRTCIF_CTLR_BENL_2ND_BYTE BIT(17)
0049 #define PRTCIF_CTLR_BENL_LSB BIT(16)
0050 #define PRTCIF_CTLR_BENL_MASK (0x000F0000)
0051
0052
0053 #define PRTCIF_INTEN_RTCSS BIT(1)
0054 #define PRTCIF_INTEN_RTCIF BIT(0)
0055 #define PRTCIF_INTEN_MASK (PRTCIF_INTEN_RTCSS \
0056 | PRTCIF_INTEN_RTCIF)
0057
0058
0059 #define PRTCIF_INTFLG_RTCSS BIT(1)
0060 #define PRTCIF_INTFLG_RTCIF BIT(0)
0061 #define PRTCIF_INTFLG_MASK (PRTCIF_INTFLG_RTCSS \
0062 | PRTCIF_INTFLG_RTCIF)
0063
0064
0065 #define PRTCSS_RTC_INTC_EXTENA1 (0x0C)
0066 #define PRTCSS_RTC_CTRL (0x10)
0067 #define PRTCSS_RTC_WDT (0x11)
0068 #define PRTCSS_RTC_TMR0 (0x12)
0069 #define PRTCSS_RTC_TMR1 (0x13)
0070 #define PRTCSS_RTC_CCTRL (0x14)
0071 #define PRTCSS_RTC_SEC (0x15)
0072 #define PRTCSS_RTC_MIN (0x16)
0073 #define PRTCSS_RTC_HOUR (0x17)
0074 #define PRTCSS_RTC_DAY0 (0x18)
0075 #define PRTCSS_RTC_DAY1 (0x19)
0076 #define PRTCSS_RTC_AMIN (0x1A)
0077 #define PRTCSS_RTC_AHOUR (0x1B)
0078 #define PRTCSS_RTC_ADAY0 (0x1C)
0079 #define PRTCSS_RTC_ADAY1 (0x1D)
0080 #define PRTCSS_RTC_CLKC_CNT (0x20)
0081
0082
0083 #define PRTCSS_RTC_INTC_EXTENA1_MASK (0x07)
0084
0085
0086 #define PRTCSS_RTC_CTRL_WDTBUS BIT(7)
0087 #define PRTCSS_RTC_CTRL_WEN BIT(6)
0088 #define PRTCSS_RTC_CTRL_WDRT BIT(5)
0089 #define PRTCSS_RTC_CTRL_WDTFLG BIT(4)
0090 #define PRTCSS_RTC_CTRL_TE BIT(3)
0091 #define PRTCSS_RTC_CTRL_TIEN BIT(2)
0092 #define PRTCSS_RTC_CTRL_TMRFLG BIT(1)
0093 #define PRTCSS_RTC_CTRL_TMMD BIT(0)
0094
0095
0096 #define PRTCSS_RTC_CCTRL_CALBUSY BIT(7)
0097 #define PRTCSS_RTC_CCTRL_DAEN BIT(5)
0098 #define PRTCSS_RTC_CCTRL_HAEN BIT(4)
0099 #define PRTCSS_RTC_CCTRL_MAEN BIT(3)
0100 #define PRTCSS_RTC_CCTRL_ALMFLG BIT(2)
0101 #define PRTCSS_RTC_CCTRL_AIEN BIT(1)
0102 #define PRTCSS_RTC_CCTRL_CAEN BIT(0)
0103
0104 static DEFINE_SPINLOCK(davinci_rtc_lock);
0105
0106 struct davinci_rtc {
0107 struct rtc_device *rtc;
0108 void __iomem *base;
0109 int irq;
0110 };
0111
0112 static inline void rtcif_write(struct davinci_rtc *davinci_rtc,
0113 u32 val, u32 addr)
0114 {
0115 writel(val, davinci_rtc->base + addr);
0116 }
0117
0118 static inline u32 rtcif_read(struct davinci_rtc *davinci_rtc, u32 addr)
0119 {
0120 return readl(davinci_rtc->base + addr);
0121 }
0122
0123 static inline void rtcif_wait(struct davinci_rtc *davinci_rtc)
0124 {
0125 while (rtcif_read(davinci_rtc, PRTCIF_CTLR) & PRTCIF_CTLR_BUSY)
0126 cpu_relax();
0127 }
0128
0129 static inline void rtcss_write(struct davinci_rtc *davinci_rtc,
0130 unsigned long val, u8 addr)
0131 {
0132 rtcif_wait(davinci_rtc);
0133
0134 rtcif_write(davinci_rtc, PRTCIF_CTLR_BENL_LSB | addr, PRTCIF_CTLR);
0135 rtcif_write(davinci_rtc, val, PRTCIF_LDATA);
0136
0137 rtcif_wait(davinci_rtc);
0138 }
0139
0140 static inline u8 rtcss_read(struct davinci_rtc *davinci_rtc, u8 addr)
0141 {
0142 rtcif_wait(davinci_rtc);
0143
0144 rtcif_write(davinci_rtc, PRTCIF_CTLR_DIR | PRTCIF_CTLR_BENL_LSB | addr,
0145 PRTCIF_CTLR);
0146
0147 rtcif_wait(davinci_rtc);
0148
0149 return rtcif_read(davinci_rtc, PRTCIF_LDATA);
0150 }
0151
0152 static inline void davinci_rtcss_calendar_wait(struct davinci_rtc *davinci_rtc)
0153 {
0154 while (rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
0155 PRTCSS_RTC_CCTRL_CALBUSY)
0156 cpu_relax();
0157 }
0158
0159 static irqreturn_t davinci_rtc_interrupt(int irq, void *class_dev)
0160 {
0161 struct davinci_rtc *davinci_rtc = class_dev;
0162 unsigned long events = 0;
0163 u32 irq_flg;
0164 u8 alm_irq, tmr_irq;
0165 u8 rtc_ctrl, rtc_cctrl;
0166 int ret = IRQ_NONE;
0167
0168 irq_flg = rtcif_read(davinci_rtc, PRTCIF_INTFLG) &
0169 PRTCIF_INTFLG_RTCSS;
0170
0171 alm_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) &
0172 PRTCSS_RTC_CCTRL_ALMFLG;
0173
0174 tmr_irq = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL) &
0175 PRTCSS_RTC_CTRL_TMRFLG;
0176
0177 if (irq_flg) {
0178 if (alm_irq) {
0179 events |= RTC_IRQF | RTC_AF;
0180 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
0181 rtc_cctrl |= PRTCSS_RTC_CCTRL_ALMFLG;
0182 rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
0183 } else if (tmr_irq) {
0184 events |= RTC_IRQF | RTC_PF;
0185 rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
0186 rtc_ctrl |= PRTCSS_RTC_CTRL_TMRFLG;
0187 rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
0188 }
0189
0190 rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS,
0191 PRTCIF_INTFLG);
0192 rtc_update_irq(davinci_rtc->rtc, 1, events);
0193
0194 ret = IRQ_HANDLED;
0195 }
0196
0197 return ret;
0198 }
0199
0200 static int
0201 davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
0202 {
0203 struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0204 u8 rtc_ctrl;
0205 unsigned long flags;
0206 int ret = 0;
0207
0208 spin_lock_irqsave(&davinci_rtc_lock, flags);
0209
0210 rtc_ctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CTRL);
0211
0212 switch (cmd) {
0213 case RTC_WIE_ON:
0214 rtc_ctrl |= PRTCSS_RTC_CTRL_WEN | PRTCSS_RTC_CTRL_WDTFLG;
0215 break;
0216 case RTC_WIE_OFF:
0217 rtc_ctrl &= ~PRTCSS_RTC_CTRL_WEN;
0218 break;
0219 default:
0220 ret = -ENOIOCTLCMD;
0221 }
0222
0223 rtcss_write(davinci_rtc, rtc_ctrl, PRTCSS_RTC_CTRL);
0224
0225 spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0226
0227 return ret;
0228 }
0229
0230 static void convertfromdays(u16 days, struct rtc_time *tm)
0231 {
0232 int tmp_days, year, mon;
0233
0234 for (year = 2000;; year++) {
0235 tmp_days = rtc_year_days(1, 12, year);
0236 if (days >= tmp_days)
0237 days -= tmp_days;
0238 else {
0239 for (mon = 0;; mon++) {
0240 tmp_days = rtc_month_days(mon, year);
0241 if (days >= tmp_days) {
0242 days -= tmp_days;
0243 } else {
0244 tm->tm_year = year - 1900;
0245 tm->tm_mon = mon;
0246 tm->tm_mday = days + 1;
0247 break;
0248 }
0249 }
0250 break;
0251 }
0252 }
0253 }
0254
0255 static void convert2days(u16 *days, struct rtc_time *tm)
0256 {
0257 int i;
0258 *days = 0;
0259
0260 for (i = 2000; i < 1900 + tm->tm_year; i++)
0261 *days += rtc_year_days(1, 12, i);
0262
0263 *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year);
0264 }
0265
0266 static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm)
0267 {
0268 struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0269 u16 days = 0;
0270 u8 day0, day1;
0271 unsigned long flags;
0272
0273 spin_lock_irqsave(&davinci_rtc_lock, flags);
0274
0275 davinci_rtcss_calendar_wait(davinci_rtc);
0276 tm->tm_sec = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_SEC));
0277
0278 davinci_rtcss_calendar_wait(davinci_rtc);
0279 tm->tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_MIN));
0280
0281 davinci_rtcss_calendar_wait(davinci_rtc);
0282 tm->tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_HOUR));
0283
0284 davinci_rtcss_calendar_wait(davinci_rtc);
0285 day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY0);
0286
0287 davinci_rtcss_calendar_wait(davinci_rtc);
0288 day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_DAY1);
0289
0290 spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0291
0292 days |= day1;
0293 days <<= 8;
0294 days |= day0;
0295
0296 convertfromdays(days, tm);
0297
0298 return 0;
0299 }
0300
0301 static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm)
0302 {
0303 struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0304 u16 days;
0305 u8 rtc_cctrl;
0306 unsigned long flags;
0307
0308 convert2days(&days, tm);
0309
0310 spin_lock_irqsave(&davinci_rtc_lock, flags);
0311
0312 davinci_rtcss_calendar_wait(davinci_rtc);
0313 rtcss_write(davinci_rtc, bin2bcd(tm->tm_sec), PRTCSS_RTC_SEC);
0314
0315 davinci_rtcss_calendar_wait(davinci_rtc);
0316 rtcss_write(davinci_rtc, bin2bcd(tm->tm_min), PRTCSS_RTC_MIN);
0317
0318 davinci_rtcss_calendar_wait(davinci_rtc);
0319 rtcss_write(davinci_rtc, bin2bcd(tm->tm_hour), PRTCSS_RTC_HOUR);
0320
0321 davinci_rtcss_calendar_wait(davinci_rtc);
0322 rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_DAY0);
0323
0324 davinci_rtcss_calendar_wait(davinci_rtc);
0325 rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_DAY1);
0326
0327 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
0328 rtc_cctrl |= PRTCSS_RTC_CCTRL_CAEN;
0329 rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
0330
0331 spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0332
0333 return 0;
0334 }
0335
0336 static int davinci_rtc_alarm_irq_enable(struct device *dev,
0337 unsigned int enabled)
0338 {
0339 struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0340 unsigned long flags;
0341 u8 rtc_cctrl = rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL);
0342
0343 spin_lock_irqsave(&davinci_rtc_lock, flags);
0344
0345 if (enabled)
0346 rtc_cctrl |= PRTCSS_RTC_CCTRL_DAEN |
0347 PRTCSS_RTC_CCTRL_HAEN |
0348 PRTCSS_RTC_CCTRL_MAEN |
0349 PRTCSS_RTC_CCTRL_ALMFLG |
0350 PRTCSS_RTC_CCTRL_AIEN;
0351 else
0352 rtc_cctrl &= ~PRTCSS_RTC_CCTRL_AIEN;
0353
0354 davinci_rtcss_calendar_wait(davinci_rtc);
0355 rtcss_write(davinci_rtc, rtc_cctrl, PRTCSS_RTC_CCTRL);
0356
0357 spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0358
0359 return 0;
0360 }
0361
0362 static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0363 {
0364 struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0365 u16 days = 0;
0366 u8 day0, day1;
0367 unsigned long flags;
0368
0369 alm->time.tm_sec = 0;
0370
0371 spin_lock_irqsave(&davinci_rtc_lock, flags);
0372
0373 davinci_rtcss_calendar_wait(davinci_rtc);
0374 alm->time.tm_min = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AMIN));
0375
0376 davinci_rtcss_calendar_wait(davinci_rtc);
0377 alm->time.tm_hour = bcd2bin(rtcss_read(davinci_rtc, PRTCSS_RTC_AHOUR));
0378
0379 davinci_rtcss_calendar_wait(davinci_rtc);
0380 day0 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY0);
0381
0382 davinci_rtcss_calendar_wait(davinci_rtc);
0383 day1 = rtcss_read(davinci_rtc, PRTCSS_RTC_ADAY1);
0384
0385 spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0386 days |= day1;
0387 days <<= 8;
0388 days |= day0;
0389
0390 convertfromdays(days, &alm->time);
0391
0392 alm->pending = !!(rtcss_read(davinci_rtc,
0393 PRTCSS_RTC_CCTRL) &
0394 PRTCSS_RTC_CCTRL_AIEN);
0395 alm->enabled = alm->pending && device_may_wakeup(dev);
0396
0397 return 0;
0398 }
0399
0400 static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0401 {
0402 struct davinci_rtc *davinci_rtc = dev_get_drvdata(dev);
0403 unsigned long flags;
0404 u16 days;
0405
0406 convert2days(&days, &alm->time);
0407
0408 spin_lock_irqsave(&davinci_rtc_lock, flags);
0409
0410 davinci_rtcss_calendar_wait(davinci_rtc);
0411 rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_min), PRTCSS_RTC_AMIN);
0412
0413 davinci_rtcss_calendar_wait(davinci_rtc);
0414 rtcss_write(davinci_rtc, bin2bcd(alm->time.tm_hour), PRTCSS_RTC_AHOUR);
0415
0416 davinci_rtcss_calendar_wait(davinci_rtc);
0417 rtcss_write(davinci_rtc, days & 0xFF, PRTCSS_RTC_ADAY0);
0418
0419 davinci_rtcss_calendar_wait(davinci_rtc);
0420 rtcss_write(davinci_rtc, (days & 0xFF00) >> 8, PRTCSS_RTC_ADAY1);
0421
0422 spin_unlock_irqrestore(&davinci_rtc_lock, flags);
0423
0424 return 0;
0425 }
0426
0427 static const struct rtc_class_ops davinci_rtc_ops = {
0428 .ioctl = davinci_rtc_ioctl,
0429 .read_time = davinci_rtc_read_time,
0430 .set_time = davinci_rtc_set_time,
0431 .alarm_irq_enable = davinci_rtc_alarm_irq_enable,
0432 .read_alarm = davinci_rtc_read_alarm,
0433 .set_alarm = davinci_rtc_set_alarm,
0434 };
0435
0436 static int __init davinci_rtc_probe(struct platform_device *pdev)
0437 {
0438 struct device *dev = &pdev->dev;
0439 struct davinci_rtc *davinci_rtc;
0440 int ret = 0;
0441
0442 davinci_rtc = devm_kzalloc(&pdev->dev, sizeof(struct davinci_rtc), GFP_KERNEL);
0443 if (!davinci_rtc)
0444 return -ENOMEM;
0445
0446 davinci_rtc->irq = platform_get_irq(pdev, 0);
0447 if (davinci_rtc->irq < 0)
0448 return davinci_rtc->irq;
0449
0450 davinci_rtc->base = devm_platform_ioremap_resource(pdev, 0);
0451 if (IS_ERR(davinci_rtc->base))
0452 return PTR_ERR(davinci_rtc->base);
0453
0454 platform_set_drvdata(pdev, davinci_rtc);
0455
0456 davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev);
0457 if (IS_ERR(davinci_rtc->rtc))
0458 return PTR_ERR(davinci_rtc->rtc);
0459
0460 davinci_rtc->rtc->ops = &davinci_rtc_ops;
0461 davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
0462 davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1;
0463
0464 rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG);
0465 rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
0466 rtcss_write(davinci_rtc, 0, PRTCSS_RTC_INTC_EXTENA1);
0467
0468 rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CTRL);
0469 rtcss_write(davinci_rtc, 0, PRTCSS_RTC_CCTRL);
0470
0471 ret = devm_request_irq(dev, davinci_rtc->irq, davinci_rtc_interrupt,
0472 0, "davinci_rtc", davinci_rtc);
0473 if (ret < 0) {
0474 dev_err(dev, "unable to register davinci RTC interrupt\n");
0475 return ret;
0476 }
0477
0478
0479 rtcif_write(davinci_rtc, PRTCIF_INTEN_RTCSS, PRTCIF_INTEN);
0480 rtcss_write(davinci_rtc, PRTCSS_RTC_INTC_EXTENA1_MASK,
0481 PRTCSS_RTC_INTC_EXTENA1);
0482
0483 rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL);
0484
0485 device_init_wakeup(&pdev->dev, 0);
0486
0487 return devm_rtc_register_device(davinci_rtc->rtc);
0488 }
0489
0490 static int __exit davinci_rtc_remove(struct platform_device *pdev)
0491 {
0492 struct davinci_rtc *davinci_rtc = platform_get_drvdata(pdev);
0493
0494 device_init_wakeup(&pdev->dev, 0);
0495
0496 rtcif_write(davinci_rtc, 0, PRTCIF_INTEN);
0497
0498 return 0;
0499 }
0500
0501 static struct platform_driver davinci_rtc_driver = {
0502 .remove = __exit_p(davinci_rtc_remove),
0503 .driver = {
0504 .name = "rtc_davinci",
0505 },
0506 };
0507
0508 module_platform_driver_probe(davinci_rtc_driver, davinci_rtc_probe);
0509
0510 MODULE_AUTHOR("Miguel Aguilar <miguel.aguilar@ridgerun.com>");
0511 MODULE_DESCRIPTION("Texas Instruments DaVinci PRTC Driver");
0512 MODULE_LICENSE("GPL");