]>
Commit | Line | Data |
---|---|---|
39ba774f PYC |
1 | /* |
2 | * Faraday FTRTC010 Real Time Clock | |
3 | * | |
4 | * (C) Copyright 2009 Faraday Technology | |
5 | * Po-Yu Chuang <ratbert@faraday-tech.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program; if not, write to the Free Software | |
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
20 | */ | |
21 | ||
22 | #include <config.h> | |
23 | #include <common.h> | |
24 | #include <rtc.h> | |
25 | #include <asm/io.h> | |
26 | ||
27 | struct ftrtc010 { | |
28 | unsigned int sec; /* 0x00 */ | |
29 | unsigned int min; /* 0x04 */ | |
30 | unsigned int hour; /* 0x08 */ | |
31 | unsigned int day; /* 0x0c */ | |
32 | unsigned int alarm_sec; /* 0x10 */ | |
33 | unsigned int alarm_min; /* 0x14 */ | |
34 | unsigned int alarm_hour; /* 0x18 */ | |
35 | unsigned int record; /* 0x1c */ | |
36 | unsigned int cr; /* 0x20 */ | |
0284816e ML |
37 | unsigned int wsec; /* 0x24 */ |
38 | unsigned int wmin; /* 0x28 */ | |
39 | unsigned int whour; /* 0x2c */ | |
40 | unsigned int wday; /* 0x30 */ | |
41 | unsigned int intr; /* 0x34 */ | |
42 | unsigned int div; /* 0x38 */ | |
43 | unsigned int rev; /* 0x3c */ | |
39ba774f PYC |
44 | }; |
45 | ||
46 | /* | |
47 | * RTC Control Register | |
48 | */ | |
49 | #define FTRTC010_CR_ENABLE (1 << 0) | |
50 | #define FTRTC010_CR_INTERRUPT_SEC (1 << 1) /* per second irq */ | |
51 | #define FTRTC010_CR_INTERRUPT_MIN (1 << 2) /* per minute irq */ | |
52 | #define FTRTC010_CR_INTERRUPT_HR (1 << 3) /* per hour irq */ | |
53 | #define FTRTC010_CR_INTERRUPT_DAY (1 << 4) /* per day irq */ | |
54 | ||
55 | static struct ftrtc010 *rtc = (struct ftrtc010 *)CONFIG_FTRTC010_BASE; | |
56 | ||
57 | static void ftrtc010_enable(void) | |
58 | { | |
59 | writel(FTRTC010_CR_ENABLE, &rtc->cr); | |
60 | } | |
61 | ||
62 | /* | |
63 | * return current time in seconds | |
64 | */ | |
65 | static unsigned long ftrtc010_time(void) | |
66 | { | |
67 | unsigned long day; | |
68 | unsigned long hour; | |
69 | unsigned long minute; | |
70 | unsigned long second; | |
71 | unsigned long second2; | |
72 | ||
73 | do { | |
74 | second = readl(&rtc->sec); | |
75 | day = readl(&rtc->day); | |
76 | hour = readl(&rtc->hour); | |
77 | minute = readl(&rtc->min); | |
78 | second2 = readl(&rtc->sec); | |
79 | } while (second != second2); | |
80 | ||
81 | return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; | |
82 | } | |
83 | ||
84 | /* | |
85 | * Get the current time from the RTC | |
86 | */ | |
87 | ||
88 | int rtc_get(struct rtc_time *tmp) | |
89 | { | |
90 | unsigned long now; | |
91 | ||
92 | debug("%s(): record register: %x\n", | |
93 | __func__, readl(&rtc->record)); | |
94 | ||
0284816e ML |
95 | #ifdef CONFIG_FTRTC010_PCLK |
96 | now = (ftrtc010_time() + readl(&rtc->record)) / RTC_DIV_COUNT; | |
97 | #else /* CONFIG_FTRTC010_EXTCLK */ | |
39ba774f | 98 | now = ftrtc010_time() + readl(&rtc->record); |
0284816e | 99 | #endif |
39ba774f PYC |
100 | |
101 | to_tm(now, tmp); | |
102 | ||
103 | return 0; | |
104 | } | |
105 | ||
106 | /* | |
107 | * Set the RTC | |
108 | */ | |
109 | int rtc_set(struct rtc_time *tmp) | |
110 | { | |
111 | unsigned long new; | |
112 | unsigned long now; | |
113 | ||
114 | debug("%s(): DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", | |
115 | __func__, | |
116 | tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, | |
117 | tmp->tm_hour, tmp->tm_min, tmp->tm_sec); | |
118 | ||
119 | new = mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour, | |
120 | tmp->tm_min, tmp->tm_sec); | |
121 | ||
122 | now = ftrtc010_time(); | |
123 | ||
124 | debug("%s(): write %lx to record register\n", __func__, new - now); | |
125 | ||
126 | writel(new - now, &rtc->record); | |
127 | ||
128 | return 0; | |
129 | } | |
130 | ||
131 | void rtc_reset(void) | |
132 | { | |
133 | debug("%s()\n", __func__); | |
134 | ftrtc010_enable(); | |
135 | } |