1 /* 2 * Copyright (C) 2010 NXP Semiconductors 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * You should have received a copy of the GNU General Public License along 10 * with this program; if not, write to the Free Software Foundation, Inc., 11 * 675 Mass Ave, Cambridge, MA 02139, USA. 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/platform_device.h> 18 #include <linux/spinlock.h> 19 #include <linux/rtc.h> 20 #include <linux/slab.h> 21 #include <linux/io.h> 22 #include <linux/of.h> 23 24 /* 25 * Clock and Power control register offsets 26 */ 27 #define LPC32XX_RTC_UCOUNT 0x00 28 #define LPC32XX_RTC_DCOUNT 0x04 29 #define LPC32XX_RTC_MATCH0 0x08 30 #define LPC32XX_RTC_MATCH1 0x0C 31 #define LPC32XX_RTC_CTRL 0x10 32 #define LPC32XX_RTC_INTSTAT 0x14 33 #define LPC32XX_RTC_KEY 0x18 34 #define LPC32XX_RTC_SRAM 0x80 35 36 #define LPC32XX_RTC_CTRL_MATCH0 (1 << 0) 37 #define LPC32XX_RTC_CTRL_MATCH1 (1 << 1) 38 #define LPC32XX_RTC_CTRL_ONSW_MATCH0 (1 << 2) 39 #define LPC32XX_RTC_CTRL_ONSW_MATCH1 (1 << 3) 40 #define LPC32XX_RTC_CTRL_SW_RESET (1 << 4) 41 #define LPC32XX_RTC_CTRL_CNTR_DIS (1 << 6) 42 #define LPC32XX_RTC_CTRL_ONSW_FORCE_HI (1 << 7) 43 44 #define LPC32XX_RTC_INTSTAT_MATCH0 (1 << 0) 45 #define LPC32XX_RTC_INTSTAT_MATCH1 (1 << 1) 46 #define LPC32XX_RTC_INTSTAT_ONSW (1 << 2) 47 48 #define LPC32XX_RTC_KEY_ONSW_LOADVAL 0xB5C13F27 49 50 #define rtc_readl(dev, reg) \ 51 __raw_readl((dev)->rtc_base + (reg)) 52 #define rtc_writel(dev, reg, val) \ 53 __raw_writel((val), (dev)->rtc_base + (reg)) 54 55 struct lpc32xx_rtc { 56 void __iomem *rtc_base; 57 int irq; 58 unsigned char alarm_enabled; 59 struct rtc_device *rtc; 60 spinlock_t lock; 61 }; 62 63 static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time) 64 { 65 unsigned long elapsed_sec; 66 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 67 68 elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT); 69 rtc_time_to_tm(elapsed_sec, time); 70 71 return 0; 72 } 73 74 static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs) 75 { 76 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 77 u32 tmp; 78 79 spin_lock_irq(&rtc->lock); 80 81 /* RTC must be disabled during count update */ 82 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 83 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | LPC32XX_RTC_CTRL_CNTR_DIS); 84 rtc_writel(rtc, LPC32XX_RTC_UCOUNT, secs); 85 rtc_writel(rtc, LPC32XX_RTC_DCOUNT, 0xFFFFFFFF - secs); 86 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp &= ~LPC32XX_RTC_CTRL_CNTR_DIS); 87 88 spin_unlock_irq(&rtc->lock); 89 90 return 0; 91 } 92 93 static int lpc32xx_rtc_read_alarm(struct device *dev, 94 struct rtc_wkalrm *wkalrm) 95 { 96 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 97 98 rtc_time_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time); 99 wkalrm->enabled = rtc->alarm_enabled; 100 wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) & 101 LPC32XX_RTC_INTSTAT_MATCH0); 102 103 return rtc_valid_tm(&wkalrm->time); 104 } 105 106 static int lpc32xx_rtc_set_alarm(struct device *dev, 107 struct rtc_wkalrm *wkalrm) 108 { 109 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 110 unsigned long alarmsecs; 111 u32 tmp; 112 int ret; 113 114 ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs); 115 if (ret < 0) { 116 dev_warn(dev, "Failed to convert time: %d\n", ret); 117 return ret; 118 } 119 120 spin_lock_irq(&rtc->lock); 121 122 /* Disable alarm during update */ 123 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 124 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp & ~LPC32XX_RTC_CTRL_MATCH0); 125 126 rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs); 127 128 rtc->alarm_enabled = wkalrm->enabled; 129 if (wkalrm->enabled) { 130 rtc_writel(rtc, LPC32XX_RTC_INTSTAT, 131 LPC32XX_RTC_INTSTAT_MATCH0); 132 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | 133 LPC32XX_RTC_CTRL_MATCH0); 134 } 135 136 spin_unlock_irq(&rtc->lock); 137 138 return 0; 139 } 140 141 static int lpc32xx_rtc_alarm_irq_enable(struct device *dev, 142 unsigned int enabled) 143 { 144 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 145 u32 tmp; 146 147 spin_lock_irq(&rtc->lock); 148 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 149 150 if (enabled) { 151 rtc->alarm_enabled = 1; 152 tmp |= LPC32XX_RTC_CTRL_MATCH0; 153 } else { 154 rtc->alarm_enabled = 0; 155 tmp &= ~LPC32XX_RTC_CTRL_MATCH0; 156 } 157 158 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); 159 spin_unlock_irq(&rtc->lock); 160 161 return 0; 162 } 163 164 static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) 165 { 166 struct lpc32xx_rtc *rtc = dev; 167 168 spin_lock(&rtc->lock); 169 170 /* Disable alarm interrupt */ 171 rtc_writel(rtc, LPC32XX_RTC_CTRL, 172 rtc_readl(rtc, LPC32XX_RTC_CTRL) & 173 ~LPC32XX_RTC_CTRL_MATCH0); 174 rtc->alarm_enabled = 0; 175 176 /* 177 * Write a large value to the match value so the RTC won't 178 * keep firing the match status 179 */ 180 rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); 181 rtc_writel(rtc, LPC32XX_RTC_INTSTAT, LPC32XX_RTC_INTSTAT_MATCH0); 182 183 spin_unlock(&rtc->lock); 184 185 rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); 186 187 return IRQ_HANDLED; 188 } 189 190 static const struct rtc_class_ops lpc32xx_rtc_ops = { 191 .read_time = lpc32xx_rtc_read_time, 192 .set_mmss = lpc32xx_rtc_set_mmss, 193 .read_alarm = lpc32xx_rtc_read_alarm, 194 .set_alarm = lpc32xx_rtc_set_alarm, 195 .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, 196 }; 197 198 static int lpc32xx_rtc_probe(struct platform_device *pdev) 199 { 200 struct resource *res; 201 struct lpc32xx_rtc *rtc; 202 int err; 203 u32 tmp; 204 205 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 206 if (unlikely(!rtc)) 207 return -ENOMEM; 208 209 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 210 rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res); 211 if (IS_ERR(rtc->rtc_base)) 212 return PTR_ERR(rtc->rtc_base); 213 214 spin_lock_init(&rtc->lock); 215 216 /* 217 * The RTC is on a separate power domain and can keep it's state 218 * across a chip power cycle. If the RTC has never been previously 219 * setup, then set it up now for the first time. 220 */ 221 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 222 if (rtc_readl(rtc, LPC32XX_RTC_KEY) != LPC32XX_RTC_KEY_ONSW_LOADVAL) { 223 tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET | 224 LPC32XX_RTC_CTRL_CNTR_DIS | 225 LPC32XX_RTC_CTRL_MATCH0 | 226 LPC32XX_RTC_CTRL_MATCH1 | 227 LPC32XX_RTC_CTRL_ONSW_MATCH0 | 228 LPC32XX_RTC_CTRL_ONSW_MATCH1 | 229 LPC32XX_RTC_CTRL_ONSW_FORCE_HI); 230 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); 231 232 /* Clear latched interrupt states */ 233 rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); 234 rtc_writel(rtc, LPC32XX_RTC_INTSTAT, 235 LPC32XX_RTC_INTSTAT_MATCH0 | 236 LPC32XX_RTC_INTSTAT_MATCH1 | 237 LPC32XX_RTC_INTSTAT_ONSW); 238 239 /* Write key value to RTC so it won't reload on reset */ 240 rtc_writel(rtc, LPC32XX_RTC_KEY, 241 LPC32XX_RTC_KEY_ONSW_LOADVAL); 242 } else { 243 rtc_writel(rtc, LPC32XX_RTC_CTRL, 244 tmp & ~LPC32XX_RTC_CTRL_MATCH0); 245 } 246 247 platform_set_drvdata(pdev, rtc); 248 249 rtc->rtc = devm_rtc_allocate_device(&pdev->dev); 250 if (IS_ERR(rtc->rtc)) 251 return PTR_ERR(rtc->rtc); 252 253 rtc->rtc->ops = &lpc32xx_rtc_ops; 254 rtc->rtc->range_max = U32_MAX; 255 256 err = rtc_register_device(rtc->rtc); 257 if (err) 258 return err; 259 260 /* 261 * IRQ is enabled after device registration in case alarm IRQ 262 * is pending upon suspend exit. 263 */ 264 rtc->irq = platform_get_irq(pdev, 0); 265 if (rtc->irq < 0) { 266 dev_warn(&pdev->dev, "Can't get interrupt resource\n"); 267 } else { 268 if (devm_request_irq(&pdev->dev, rtc->irq, 269 lpc32xx_rtc_alarm_interrupt, 270 0, pdev->name, rtc) < 0) { 271 dev_warn(&pdev->dev, "Can't request interrupt.\n"); 272 rtc->irq = -1; 273 } else { 274 device_init_wakeup(&pdev->dev, 1); 275 } 276 } 277 278 return 0; 279 } 280 281 static int lpc32xx_rtc_remove(struct platform_device *pdev) 282 { 283 struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); 284 285 if (rtc->irq >= 0) 286 device_init_wakeup(&pdev->dev, 0); 287 288 return 0; 289 } 290 291 #ifdef CONFIG_PM 292 static int lpc32xx_rtc_suspend(struct device *dev) 293 { 294 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 295 296 if (rtc->irq >= 0) { 297 if (device_may_wakeup(dev)) 298 enable_irq_wake(rtc->irq); 299 else 300 disable_irq_wake(rtc->irq); 301 } 302 303 return 0; 304 } 305 306 static int lpc32xx_rtc_resume(struct device *dev) 307 { 308 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 309 310 if (rtc->irq >= 0 && device_may_wakeup(dev)) 311 disable_irq_wake(rtc->irq); 312 313 return 0; 314 } 315 316 /* Unconditionally disable the alarm */ 317 static int lpc32xx_rtc_freeze(struct device *dev) 318 { 319 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 320 321 spin_lock_irq(&rtc->lock); 322 323 rtc_writel(rtc, LPC32XX_RTC_CTRL, 324 rtc_readl(rtc, LPC32XX_RTC_CTRL) & 325 ~LPC32XX_RTC_CTRL_MATCH0); 326 327 spin_unlock_irq(&rtc->lock); 328 329 return 0; 330 } 331 332 static int lpc32xx_rtc_thaw(struct device *dev) 333 { 334 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 335 336 if (rtc->alarm_enabled) { 337 spin_lock_irq(&rtc->lock); 338 339 rtc_writel(rtc, LPC32XX_RTC_CTRL, 340 rtc_readl(rtc, LPC32XX_RTC_CTRL) | 341 LPC32XX_RTC_CTRL_MATCH0); 342 343 spin_unlock_irq(&rtc->lock); 344 } 345 346 return 0; 347 } 348 349 static const struct dev_pm_ops lpc32xx_rtc_pm_ops = { 350 .suspend = lpc32xx_rtc_suspend, 351 .resume = lpc32xx_rtc_resume, 352 .freeze = lpc32xx_rtc_freeze, 353 .thaw = lpc32xx_rtc_thaw, 354 .restore = lpc32xx_rtc_resume 355 }; 356 357 #define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops) 358 #else 359 #define LPC32XX_RTC_PM_OPS NULL 360 #endif 361 362 #ifdef CONFIG_OF 363 static const struct of_device_id lpc32xx_rtc_match[] = { 364 { .compatible = "nxp,lpc3220-rtc" }, 365 { } 366 }; 367 MODULE_DEVICE_TABLE(of, lpc32xx_rtc_match); 368 #endif 369 370 static struct platform_driver lpc32xx_rtc_driver = { 371 .probe = lpc32xx_rtc_probe, 372 .remove = lpc32xx_rtc_remove, 373 .driver = { 374 .name = "rtc-lpc32xx", 375 .pm = LPC32XX_RTC_PM_OPS, 376 .of_match_table = of_match_ptr(lpc32xx_rtc_match), 377 }, 378 }; 379 380 module_platform_driver(lpc32xx_rtc_driver); 381 382 MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); 383 MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); 384 MODULE_LICENSE("GPL"); 385 MODULE_ALIAS("platform:rtc-lpc32xx"); 386