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