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_time64_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_time64_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 113 alarmsecs = rtc_tm_to_time64(&wkalrm->time); 114 115 spin_lock_irq(&rtc->lock); 116 117 /* Disable alarm during update */ 118 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 119 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp & ~LPC32XX_RTC_CTRL_MATCH0); 120 121 rtc_writel(rtc, LPC32XX_RTC_MATCH0, alarmsecs); 122 123 rtc->alarm_enabled = wkalrm->enabled; 124 if (wkalrm->enabled) { 125 rtc_writel(rtc, LPC32XX_RTC_INTSTAT, 126 LPC32XX_RTC_INTSTAT_MATCH0); 127 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp | 128 LPC32XX_RTC_CTRL_MATCH0); 129 } 130 131 spin_unlock_irq(&rtc->lock); 132 133 return 0; 134 } 135 136 static int lpc32xx_rtc_alarm_irq_enable(struct device *dev, 137 unsigned int enabled) 138 { 139 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 140 u32 tmp; 141 142 spin_lock_irq(&rtc->lock); 143 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 144 145 if (enabled) { 146 rtc->alarm_enabled = 1; 147 tmp |= LPC32XX_RTC_CTRL_MATCH0; 148 } else { 149 rtc->alarm_enabled = 0; 150 tmp &= ~LPC32XX_RTC_CTRL_MATCH0; 151 } 152 153 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); 154 spin_unlock_irq(&rtc->lock); 155 156 return 0; 157 } 158 159 static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) 160 { 161 struct lpc32xx_rtc *rtc = dev; 162 163 spin_lock(&rtc->lock); 164 165 /* Disable alarm interrupt */ 166 rtc_writel(rtc, LPC32XX_RTC_CTRL, 167 rtc_readl(rtc, LPC32XX_RTC_CTRL) & 168 ~LPC32XX_RTC_CTRL_MATCH0); 169 rtc->alarm_enabled = 0; 170 171 /* 172 * Write a large value to the match value so the RTC won't 173 * keep firing the match status 174 */ 175 rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); 176 rtc_writel(rtc, LPC32XX_RTC_INTSTAT, LPC32XX_RTC_INTSTAT_MATCH0); 177 178 spin_unlock(&rtc->lock); 179 180 rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); 181 182 return IRQ_HANDLED; 183 } 184 185 static const struct rtc_class_ops lpc32xx_rtc_ops = { 186 .read_time = lpc32xx_rtc_read_time, 187 .set_mmss = lpc32xx_rtc_set_mmss, 188 .read_alarm = lpc32xx_rtc_read_alarm, 189 .set_alarm = lpc32xx_rtc_set_alarm, 190 .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, 191 }; 192 193 static int lpc32xx_rtc_probe(struct platform_device *pdev) 194 { 195 struct resource *res; 196 struct lpc32xx_rtc *rtc; 197 int err; 198 u32 tmp; 199 200 rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); 201 if (unlikely(!rtc)) 202 return -ENOMEM; 203 204 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 205 rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res); 206 if (IS_ERR(rtc->rtc_base)) 207 return PTR_ERR(rtc->rtc_base); 208 209 spin_lock_init(&rtc->lock); 210 211 /* 212 * The RTC is on a separate power domain and can keep it's state 213 * across a chip power cycle. If the RTC has never been previously 214 * setup, then set it up now for the first time. 215 */ 216 tmp = rtc_readl(rtc, LPC32XX_RTC_CTRL); 217 if (rtc_readl(rtc, LPC32XX_RTC_KEY) != LPC32XX_RTC_KEY_ONSW_LOADVAL) { 218 tmp &= ~(LPC32XX_RTC_CTRL_SW_RESET | 219 LPC32XX_RTC_CTRL_CNTR_DIS | 220 LPC32XX_RTC_CTRL_MATCH0 | 221 LPC32XX_RTC_CTRL_MATCH1 | 222 LPC32XX_RTC_CTRL_ONSW_MATCH0 | 223 LPC32XX_RTC_CTRL_ONSW_MATCH1 | 224 LPC32XX_RTC_CTRL_ONSW_FORCE_HI); 225 rtc_writel(rtc, LPC32XX_RTC_CTRL, tmp); 226 227 /* Clear latched interrupt states */ 228 rtc_writel(rtc, LPC32XX_RTC_MATCH0, 0xFFFFFFFF); 229 rtc_writel(rtc, LPC32XX_RTC_INTSTAT, 230 LPC32XX_RTC_INTSTAT_MATCH0 | 231 LPC32XX_RTC_INTSTAT_MATCH1 | 232 LPC32XX_RTC_INTSTAT_ONSW); 233 234 /* Write key value to RTC so it won't reload on reset */ 235 rtc_writel(rtc, LPC32XX_RTC_KEY, 236 LPC32XX_RTC_KEY_ONSW_LOADVAL); 237 } else { 238 rtc_writel(rtc, LPC32XX_RTC_CTRL, 239 tmp & ~LPC32XX_RTC_CTRL_MATCH0); 240 } 241 242 platform_set_drvdata(pdev, rtc); 243 244 rtc->rtc = devm_rtc_allocate_device(&pdev->dev); 245 if (IS_ERR(rtc->rtc)) 246 return PTR_ERR(rtc->rtc); 247 248 rtc->rtc->ops = &lpc32xx_rtc_ops; 249 rtc->rtc->range_max = U32_MAX; 250 251 err = rtc_register_device(rtc->rtc); 252 if (err) 253 return err; 254 255 /* 256 * IRQ is enabled after device registration in case alarm IRQ 257 * is pending upon suspend exit. 258 */ 259 rtc->irq = platform_get_irq(pdev, 0); 260 if (rtc->irq < 0) { 261 dev_warn(&pdev->dev, "Can't get interrupt resource\n"); 262 } else { 263 if (devm_request_irq(&pdev->dev, rtc->irq, 264 lpc32xx_rtc_alarm_interrupt, 265 0, pdev->name, rtc) < 0) { 266 dev_warn(&pdev->dev, "Can't request interrupt.\n"); 267 rtc->irq = -1; 268 } else { 269 device_init_wakeup(&pdev->dev, 1); 270 } 271 } 272 273 return 0; 274 } 275 276 static int lpc32xx_rtc_remove(struct platform_device *pdev) 277 { 278 struct lpc32xx_rtc *rtc = platform_get_drvdata(pdev); 279 280 if (rtc->irq >= 0) 281 device_init_wakeup(&pdev->dev, 0); 282 283 return 0; 284 } 285 286 #ifdef CONFIG_PM 287 static int lpc32xx_rtc_suspend(struct device *dev) 288 { 289 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 290 291 if (rtc->irq >= 0) { 292 if (device_may_wakeup(dev)) 293 enable_irq_wake(rtc->irq); 294 else 295 disable_irq_wake(rtc->irq); 296 } 297 298 return 0; 299 } 300 301 static int lpc32xx_rtc_resume(struct device *dev) 302 { 303 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 304 305 if (rtc->irq >= 0 && device_may_wakeup(dev)) 306 disable_irq_wake(rtc->irq); 307 308 return 0; 309 } 310 311 /* Unconditionally disable the alarm */ 312 static int lpc32xx_rtc_freeze(struct device *dev) 313 { 314 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 315 316 spin_lock_irq(&rtc->lock); 317 318 rtc_writel(rtc, LPC32XX_RTC_CTRL, 319 rtc_readl(rtc, LPC32XX_RTC_CTRL) & 320 ~LPC32XX_RTC_CTRL_MATCH0); 321 322 spin_unlock_irq(&rtc->lock); 323 324 return 0; 325 } 326 327 static int lpc32xx_rtc_thaw(struct device *dev) 328 { 329 struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); 330 331 if (rtc->alarm_enabled) { 332 spin_lock_irq(&rtc->lock); 333 334 rtc_writel(rtc, LPC32XX_RTC_CTRL, 335 rtc_readl(rtc, LPC32XX_RTC_CTRL) | 336 LPC32XX_RTC_CTRL_MATCH0); 337 338 spin_unlock_irq(&rtc->lock); 339 } 340 341 return 0; 342 } 343 344 static const struct dev_pm_ops lpc32xx_rtc_pm_ops = { 345 .suspend = lpc32xx_rtc_suspend, 346 .resume = lpc32xx_rtc_resume, 347 .freeze = lpc32xx_rtc_freeze, 348 .thaw = lpc32xx_rtc_thaw, 349 .restore = lpc32xx_rtc_resume 350 }; 351 352 #define LPC32XX_RTC_PM_OPS (&lpc32xx_rtc_pm_ops) 353 #else 354 #define LPC32XX_RTC_PM_OPS NULL 355 #endif 356 357 #ifdef CONFIG_OF 358 static const struct of_device_id lpc32xx_rtc_match[] = { 359 { .compatible = "nxp,lpc3220-rtc" }, 360 { } 361 }; 362 MODULE_DEVICE_TABLE(of, lpc32xx_rtc_match); 363 #endif 364 365 static struct platform_driver lpc32xx_rtc_driver = { 366 .probe = lpc32xx_rtc_probe, 367 .remove = lpc32xx_rtc_remove, 368 .driver = { 369 .name = "rtc-lpc32xx", 370 .pm = LPC32XX_RTC_PM_OPS, 371 .of_match_table = of_match_ptr(lpc32xx_rtc_match), 372 }, 373 }; 374 375 module_platform_driver(lpc32xx_rtc_driver); 376 377 MODULE_AUTHOR("Kevin Wells <wellsk40@gmail.com"); 378 MODULE_DESCRIPTION("RTC driver for the LPC32xx SoC"); 379 MODULE_LICENSE("GPL"); 380 MODULE_ALIAS("platform:rtc-lpc32xx"); 381