]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
39ba774f PYC |
2 | /* |
3 | * Faraday FTRTC010 Real Time Clock | |
4 | * | |
5 | * (C) Copyright 2009 Faraday Technology | |
6 | * Po-Yu Chuang <[email protected]> | |
39ba774f PYC |
7 | */ |
8 | ||
9 | #include <config.h> | |
10 | #include <common.h> | |
11 | #include <rtc.h> | |
12 | #include <asm/io.h> | |
13 | ||
14 | struct ftrtc010 { | |
15 | unsigned int sec; /* 0x00 */ | |
16 | unsigned int min; /* 0x04 */ | |
17 | unsigned int hour; /* 0x08 */ | |
18 | unsigned int day; /* 0x0c */ | |
19 | unsigned int alarm_sec; /* 0x10 */ | |
20 | unsigned int alarm_min; /* 0x14 */ | |
21 | unsigned int alarm_hour; /* 0x18 */ | |
22 | unsigned int record; /* 0x1c */ | |
23 | unsigned int cr; /* 0x20 */ | |
0284816e ML |
24 | unsigned int wsec; /* 0x24 */ |
25 | unsigned int wmin; /* 0x28 */ | |
26 | unsigned int whour; /* 0x2c */ | |
27 | unsigned int wday; /* 0x30 */ | |
28 | unsigned int intr; /* 0x34 */ | |
29 | unsigned int div; /* 0x38 */ | |
30 | unsigned int rev; /* 0x3c */ | |
39ba774f PYC |
31 | }; |
32 | ||
33 | /* | |
34 | * RTC Control Register | |
35 | */ | |
36 | #define FTRTC010_CR_ENABLE (1 << 0) | |
37 | #define FTRTC010_CR_INTERRUPT_SEC (1 << 1) /* per second irq */ | |
38 | #define FTRTC010_CR_INTERRUPT_MIN (1 << 2) /* per minute irq */ | |
39 | #define FTRTC010_CR_INTERRUPT_HR (1 << 3) /* per hour irq */ | |
40 | #define FTRTC010_CR_INTERRUPT_DAY (1 << 4) /* per day irq */ | |
41 | ||
42 | static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE; | |
43 | ||
44 | static void ftrtc010_enable(void) | |
45 | { | |
46 | writel(FTRTC010_CR_ENABLE, &rtc->cr); | |
47 | } | |
48 | ||
49 | /* | |
50 | * return current time in seconds | |
51 | */ | |
52 | static unsigned long ftrtc010_time(void) | |
53 | { | |
54 | unsigned long day; | |
55 | unsigned long hour; | |
56 | unsigned long minute; | |
57 | unsigned long second; | |
58 | unsigned long second2; | |
59 | ||
60 | do { | |
61 | second = readl(&rtc->sec); | |
62 | day = readl(&rtc->day); | |
63 | hour = readl(&rtc->hour); | |
64 | minute = readl(&rtc->min); | |
65 | second2 = readl(&rtc->sec); | |
66 | } while (second != second2); | |
67 | ||
68 | return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; | |
69 | } | |
70 | ||
71 | /* | |
72 | * Get the current time from the RTC | |
73 | */ | |
74 | ||
75 | int rtc_get(struct rtc_time *tmp) | |
76 | { | |
77 | unsigned long now; | |
78 | ||
79 | debug("%s(): record register: %x\n", | |
80 | __func__, readl(&rtc->record)); | |
81 | ||
0284816e ML |
82 | #ifdef CONFIG_FTRTC010_PCLK |
83 | now = (ftrtc010_time() + readl(&rtc->record)) / RTC_DIV_COUNT; | |
84 | #else /* CONFIG_FTRTC010_EXTCLK */ | |
39ba774f | 85 | now = ftrtc010_time() + readl(&rtc->record); |
0284816e | 86 | #endif |
39ba774f | 87 | |
9f9276c3 | 88 | rtc_to_tm(now, tmp); |
39ba774f PYC |
89 | |
90 | return 0; | |
91 | } | |
92 | ||
93 | /* | |
94 | * Set the RTC | |
95 | */ | |
96 | int rtc_set(struct rtc_time *tmp) | |
97 | { | |
98 | unsigned long new; | |
99 | unsigned long now; | |
100 | ||
101 | debug("%s(): DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", | |
102 | __func__, | |
103 | tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, | |
104 | tmp->tm_hour, tmp->tm_min, tmp->tm_sec); | |
105 | ||
71420983 | 106 | new = rtc_mktime(tmp); |
39ba774f PYC |
107 | |
108 | now = ftrtc010_time(); | |
109 | ||
110 | debug("%s(): write %lx to record register\n", __func__, new - now); | |
111 | ||
112 | writel(new - now, &rtc->record); | |
113 | ||
114 | return 0; | |
115 | } | |
116 | ||
117 | void rtc_reset(void) | |
118 | { | |
119 | debug("%s()\n", __func__); | |
120 | ftrtc010_enable(); | |
121 | } |