root/drivers/rtc/rtc-lpc32xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. lpc32xx_rtc_read_time
  2. lpc32xx_rtc_set_time
  3. lpc32xx_rtc_read_alarm
  4. lpc32xx_rtc_set_alarm
  5. lpc32xx_rtc_alarm_irq_enable
  6. lpc32xx_rtc_alarm_interrupt
  7. lpc32xx_rtc_probe
  8. lpc32xx_rtc_remove
  9. lpc32xx_rtc_suspend
  10. lpc32xx_rtc_resume
  11. lpc32xx_rtc_freeze
  12. lpc32xx_rtc_thaw

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

/* [<][>][^][v][top][bottom][index][help] */