1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * drivers/rtc/rtc-spear.c 4 * 5 * Copyright (C) 2010 ST Microelectronics 6 * Rajeev Kumar<rajeev-dlh.kumar@st.com> 7 */ 8 9 #include <linux/bcd.h> 10 #include <linux/clk.h> 11 #include <linux/delay.h> 12 #include <linux/init.h> 13 #include <linux/io.h> 14 #include <linux/irq.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/rtc.h> 19 #include <linux/slab.h> 20 #include <linux/spinlock.h> 21 22 /* RTC registers */ 23 #define TIME_REG 0x00 24 #define DATE_REG 0x04 25 #define ALARM_TIME_REG 0x08 26 #define ALARM_DATE_REG 0x0C 27 #define CTRL_REG 0x10 28 #define STATUS_REG 0x14 29 30 /* TIME_REG & ALARM_TIME_REG */ 31 #define SECONDS_UNITS (0xf<<0) /* seconds units position */ 32 #define SECONDS_TENS (0x7<<4) /* seconds tens position */ 33 #define MINUTES_UNITS (0xf<<8) /* minutes units position */ 34 #define MINUTES_TENS (0x7<<12) /* minutes tens position */ 35 #define HOURS_UNITS (0xf<<16) /* hours units position */ 36 #define HOURS_TENS (0x3<<20) /* hours tens position */ 37 38 /* DATE_REG & ALARM_DATE_REG */ 39 #define DAYS_UNITS (0xf<<0) /* days units position */ 40 #define DAYS_TENS (0x3<<4) /* days tens position */ 41 #define MONTHS_UNITS (0xf<<8) /* months units position */ 42 #define MONTHS_TENS (0x1<<12) /* months tens position */ 43 #define YEARS_UNITS (0xf<<16) /* years units position */ 44 #define YEARS_TENS (0xf<<20) /* years tens position */ 45 #define YEARS_HUNDREDS (0xf<<24) /* years hundereds position */ 46 #define YEARS_MILLENIUMS (0xf<<28) /* years millenium position */ 47 48 /* MASK SHIFT TIME_REG & ALARM_TIME_REG*/ 49 #define SECOND_SHIFT 0x00 /* seconds units */ 50 #define MINUTE_SHIFT 0x08 /* minutes units position */ 51 #define HOUR_SHIFT 0x10 /* hours units position */ 52 #define MDAY_SHIFT 0x00 /* Month day shift */ 53 #define MONTH_SHIFT 0x08 /* Month shift */ 54 #define YEAR_SHIFT 0x10 /* Year shift */ 55 56 #define SECOND_MASK 0x7F 57 #define MIN_MASK 0x7F 58 #define HOUR_MASK 0x3F 59 #define DAY_MASK 0x3F 60 #define MONTH_MASK 0x7F 61 #define YEAR_MASK 0xFFFF 62 63 /* date reg equal to time reg, for debug only */ 64 #define TIME_BYP (1<<9) 65 #define INT_ENABLE (1<<31) /* interrupt enable */ 66 67 /* STATUS_REG */ 68 #define CLK_UNCONNECTED (1<<0) 69 #define PEND_WR_TIME (1<<2) 70 #define PEND_WR_DATE (1<<3) 71 #define LOST_WR_TIME (1<<4) 72 #define LOST_WR_DATE (1<<5) 73 #define RTC_INT_MASK (1<<31) 74 #define STATUS_BUSY (PEND_WR_TIME | PEND_WR_DATE) 75 #define STATUS_FAIL (LOST_WR_TIME | LOST_WR_DATE) 76 77 struct spear_rtc_config { 78 struct rtc_device *rtc; 79 struct clk *clk; 80 spinlock_t lock; 81 void __iomem *ioaddr; 82 unsigned int irq_wake; 83 }; 84 85 static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config) 86 { 87 unsigned int val; 88 unsigned long flags; 89 90 spin_lock_irqsave(&config->lock, flags); 91 val = readl(config->ioaddr + STATUS_REG); 92 val |= RTC_INT_MASK; 93 writel(val, config->ioaddr + STATUS_REG); 94 spin_unlock_irqrestore(&config->lock, flags); 95 } 96 97 static inline void spear_rtc_enable_interrupt(struct spear_rtc_config *config) 98 { 99 unsigned int val; 100 101 val = readl(config->ioaddr + CTRL_REG); 102 if (!(val & INT_ENABLE)) { 103 spear_rtc_clear_interrupt(config); 104 val |= INT_ENABLE; 105 writel(val, config->ioaddr + CTRL_REG); 106 } 107 } 108 109 static inline void spear_rtc_disable_interrupt(struct spear_rtc_config *config) 110 { 111 unsigned int val; 112 113 val = readl(config->ioaddr + CTRL_REG); 114 if (val & INT_ENABLE) { 115 val &= ~INT_ENABLE; 116 writel(val, config->ioaddr + CTRL_REG); 117 } 118 } 119 120 static inline int is_write_complete(struct spear_rtc_config *config) 121 { 122 int ret = 0; 123 unsigned long flags; 124 125 spin_lock_irqsave(&config->lock, flags); 126 if ((readl(config->ioaddr + STATUS_REG)) & STATUS_FAIL) 127 ret = -EIO; 128 spin_unlock_irqrestore(&config->lock, flags); 129 130 return ret; 131 } 132 133 static void rtc_wait_not_busy(struct spear_rtc_config *config) 134 { 135 int status, count = 0; 136 unsigned long flags; 137 138 /* Assuming BUSY may stay active for 80 msec) */ 139 for (count = 0; count < 80; count++) { 140 spin_lock_irqsave(&config->lock, flags); 141 status = readl(config->ioaddr + STATUS_REG); 142 spin_unlock_irqrestore(&config->lock, flags); 143 if ((status & STATUS_BUSY) == 0) 144 break; 145 /* check status busy, after each msec */ 146 msleep(1); 147 } 148 } 149 150 static irqreturn_t spear_rtc_irq(int irq, void *dev_id) 151 { 152 struct spear_rtc_config *config = dev_id; 153 unsigned long events = 0; 154 unsigned int irq_data; 155 156 spin_lock(&config->lock); 157 irq_data = readl(config->ioaddr + STATUS_REG); 158 spin_unlock(&config->lock); 159 160 if ((irq_data & RTC_INT_MASK)) { 161 spear_rtc_clear_interrupt(config); 162 events = RTC_IRQF | RTC_AF; 163 rtc_update_irq(config->rtc, 1, events); 164 return IRQ_HANDLED; 165 } else 166 return IRQ_NONE; 167 168 } 169 170 static void tm2bcd(struct rtc_time *tm) 171 { 172 tm->tm_sec = bin2bcd(tm->tm_sec); 173 tm->tm_min = bin2bcd(tm->tm_min); 174 tm->tm_hour = bin2bcd(tm->tm_hour); 175 tm->tm_mday = bin2bcd(tm->tm_mday); 176 tm->tm_mon = bin2bcd(tm->tm_mon + 1); 177 tm->tm_year = bin2bcd(tm->tm_year); 178 } 179 180 static void bcd2tm(struct rtc_time *tm) 181 { 182 tm->tm_sec = bcd2bin(tm->tm_sec); 183 tm->tm_min = bcd2bin(tm->tm_min); 184 tm->tm_hour = bcd2bin(tm->tm_hour); 185 tm->tm_mday = bcd2bin(tm->tm_mday); 186 tm->tm_mon = bcd2bin(tm->tm_mon) - 1; 187 /* epoch == 1900 */ 188 tm->tm_year = bcd2bin(tm->tm_year); 189 } 190 191 /* 192 * spear_rtc_read_time - set the time 193 * @dev: rtc device in use 194 * @tm: holds date and time 195 * 196 * This function read time and date. On success it will return 0 197 * otherwise -ve error is returned. 198 */ 199 static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm) 200 { 201 struct spear_rtc_config *config = dev_get_drvdata(dev); 202 unsigned int time, date; 203 204 /* we don't report wday/yday/isdst ... */ 205 rtc_wait_not_busy(config); 206 207 do { 208 time = readl(config->ioaddr + TIME_REG); 209 date = readl(config->ioaddr + DATE_REG); 210 } while (time == readl(config->ioaddr + TIME_REG)); 211 tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK; 212 tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK; 213 tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK; 214 tm->tm_mday = (date >> MDAY_SHIFT) & DAY_MASK; 215 tm->tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK; 216 tm->tm_year = (date >> YEAR_SHIFT) & YEAR_MASK; 217 218 bcd2tm(tm); 219 return 0; 220 } 221 222 /* 223 * spear_rtc_set_time - set the time 224 * @dev: rtc device in use 225 * @tm: holds date and time 226 * 227 * This function set time and date. On success it will return 0 228 * otherwise -ve error is returned. 229 */ 230 static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) 231 { 232 struct spear_rtc_config *config = dev_get_drvdata(dev); 233 unsigned int time, date; 234 235 tm2bcd(tm); 236 237 rtc_wait_not_busy(config); 238 time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) | 239 (tm->tm_hour << HOUR_SHIFT); 240 date = (tm->tm_mday << MDAY_SHIFT) | (tm->tm_mon << MONTH_SHIFT) | 241 (tm->tm_year << YEAR_SHIFT); 242 writel(time, config->ioaddr + TIME_REG); 243 writel(date, config->ioaddr + DATE_REG); 244 245 return is_write_complete(config); 246 } 247 248 /* 249 * spear_rtc_read_alarm - read the alarm time 250 * @dev: rtc device in use 251 * @alm: holds alarm date and time 252 * 253 * This function read alarm time and date. On success it will return 0 254 * otherwise -ve error is returned. 255 */ 256 static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) 257 { 258 struct spear_rtc_config *config = dev_get_drvdata(dev); 259 unsigned int time, date; 260 261 rtc_wait_not_busy(config); 262 263 time = readl(config->ioaddr + ALARM_TIME_REG); 264 date = readl(config->ioaddr + ALARM_DATE_REG); 265 alm->time.tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK; 266 alm->time.tm_min = (time >> MINUTE_SHIFT) & MIN_MASK; 267 alm->time.tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK; 268 alm->time.tm_mday = (date >> MDAY_SHIFT) & DAY_MASK; 269 alm->time.tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK; 270 alm->time.tm_year = (date >> YEAR_SHIFT) & YEAR_MASK; 271 272 bcd2tm(&alm->time); 273 alm->enabled = readl(config->ioaddr + CTRL_REG) & INT_ENABLE; 274 275 return 0; 276 } 277 278 /* 279 * spear_rtc_set_alarm - set the alarm time 280 * @dev: rtc device in use 281 * @alm: holds alarm date and time 282 * 283 * This function set alarm time and date. On success it will return 0 284 * otherwise -ve error is returned. 285 */ 286 static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) 287 { 288 struct spear_rtc_config *config = dev_get_drvdata(dev); 289 unsigned int time, date; 290 int err; 291 292 tm2bcd(&alm->time); 293 294 rtc_wait_not_busy(config); 295 296 time = (alm->time.tm_sec << SECOND_SHIFT) | (alm->time.tm_min << 297 MINUTE_SHIFT) | (alm->time.tm_hour << HOUR_SHIFT); 298 date = (alm->time.tm_mday << MDAY_SHIFT) | (alm->time.tm_mon << 299 MONTH_SHIFT) | (alm->time.tm_year << YEAR_SHIFT); 300 301 writel(time, config->ioaddr + ALARM_TIME_REG); 302 writel(date, config->ioaddr + ALARM_DATE_REG); 303 err = is_write_complete(config); 304 if (err < 0) 305 return err; 306 307 if (alm->enabled) 308 spear_rtc_enable_interrupt(config); 309 else 310 spear_rtc_disable_interrupt(config); 311 312 return 0; 313 } 314 315 static int spear_alarm_irq_enable(struct device *dev, unsigned int enabled) 316 { 317 struct spear_rtc_config *config = dev_get_drvdata(dev); 318 int ret = 0; 319 320 spear_rtc_clear_interrupt(config); 321 322 switch (enabled) { 323 case 0: 324 /* alarm off */ 325 spear_rtc_disable_interrupt(config); 326 break; 327 case 1: 328 /* alarm on */ 329 spear_rtc_enable_interrupt(config); 330 break; 331 default: 332 ret = -EINVAL; 333 break; 334 } 335 336 return ret; 337 } 338 339 static const struct rtc_class_ops spear_rtc_ops = { 340 .read_time = spear_rtc_read_time, 341 .set_time = spear_rtc_set_time, 342 .read_alarm = spear_rtc_read_alarm, 343 .set_alarm = spear_rtc_set_alarm, 344 .alarm_irq_enable = spear_alarm_irq_enable, 345 }; 346 347 static int spear_rtc_probe(struct platform_device *pdev) 348 { 349 struct spear_rtc_config *config; 350 int status = 0; 351 int irq; 352 353 config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); 354 if (!config) 355 return -ENOMEM; 356 357 config->rtc = devm_rtc_allocate_device(&pdev->dev); 358 if (IS_ERR(config->rtc)) 359 return PTR_ERR(config->rtc); 360 361 /* alarm irqs */ 362 irq = platform_get_irq(pdev, 0); 363 if (irq < 0) 364 return irq; 365 366 status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name, 367 config); 368 if (status) { 369 dev_err(&pdev->dev, "Alarm interrupt IRQ%d already claimed\n", 370 irq); 371 return status; 372 } 373 374 config->ioaddr = devm_platform_ioremap_resource(pdev, 0); 375 if (IS_ERR(config->ioaddr)) 376 return PTR_ERR(config->ioaddr); 377 378 config->clk = devm_clk_get(&pdev->dev, NULL); 379 if (IS_ERR(config->clk)) 380 return PTR_ERR(config->clk); 381 382 status = clk_prepare_enable(config->clk); 383 if (status < 0) 384 return status; 385 386 spin_lock_init(&config->lock); 387 platform_set_drvdata(pdev, config); 388 389 config->rtc->ops = &spear_rtc_ops; 390 config->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; 391 config->rtc->range_min = RTC_TIMESTAMP_END_9999; 392 393 status = devm_rtc_register_device(config->rtc); 394 if (status) 395 goto err_disable_clock; 396 397 if (!device_can_wakeup(&pdev->dev)) 398 device_init_wakeup(&pdev->dev, 1); 399 400 return 0; 401 402 err_disable_clock: 403 clk_disable_unprepare(config->clk); 404 405 return status; 406 } 407 408 static int spear_rtc_remove(struct platform_device *pdev) 409 { 410 struct spear_rtc_config *config = platform_get_drvdata(pdev); 411 412 spear_rtc_disable_interrupt(config); 413 clk_disable_unprepare(config->clk); 414 device_init_wakeup(&pdev->dev, 0); 415 416 return 0; 417 } 418 419 #ifdef CONFIG_PM_SLEEP 420 static int spear_rtc_suspend(struct device *dev) 421 { 422 struct platform_device *pdev = to_platform_device(dev); 423 struct spear_rtc_config *config = platform_get_drvdata(pdev); 424 int irq; 425 426 irq = platform_get_irq(pdev, 0); 427 if (device_may_wakeup(&pdev->dev)) { 428 if (!enable_irq_wake(irq)) 429 config->irq_wake = 1; 430 } else { 431 spear_rtc_disable_interrupt(config); 432 clk_disable(config->clk); 433 } 434 435 return 0; 436 } 437 438 static int spear_rtc_resume(struct device *dev) 439 { 440 struct platform_device *pdev = to_platform_device(dev); 441 struct spear_rtc_config *config = platform_get_drvdata(pdev); 442 int irq; 443 444 irq = platform_get_irq(pdev, 0); 445 446 if (device_may_wakeup(&pdev->dev)) { 447 if (config->irq_wake) { 448 disable_irq_wake(irq); 449 config->irq_wake = 0; 450 } 451 } else { 452 clk_enable(config->clk); 453 spear_rtc_enable_interrupt(config); 454 } 455 456 return 0; 457 } 458 #endif 459 460 static SIMPLE_DEV_PM_OPS(spear_rtc_pm_ops, spear_rtc_suspend, spear_rtc_resume); 461 462 static void spear_rtc_shutdown(struct platform_device *pdev) 463 { 464 struct spear_rtc_config *config = platform_get_drvdata(pdev); 465 466 spear_rtc_disable_interrupt(config); 467 clk_disable(config->clk); 468 } 469 470 #ifdef CONFIG_OF 471 static const struct of_device_id spear_rtc_id_table[] = { 472 { .compatible = "st,spear600-rtc" }, 473 {} 474 }; 475 MODULE_DEVICE_TABLE(of, spear_rtc_id_table); 476 #endif 477 478 static struct platform_driver spear_rtc_driver = { 479 .probe = spear_rtc_probe, 480 .remove = spear_rtc_remove, 481 .shutdown = spear_rtc_shutdown, 482 .driver = { 483 .name = "rtc-spear", 484 .pm = &spear_rtc_pm_ops, 485 .of_match_table = of_match_ptr(spear_rtc_id_table), 486 }, 487 }; 488 489 module_platform_driver(spear_rtc_driver); 490 491 MODULE_ALIAS("platform:rtc-spear"); 492 MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>"); 493 MODULE_DESCRIPTION("ST SPEAr Realtime Clock Driver (RTC)"); 494 MODULE_LICENSE("GPL"); 495