Subversion Repositories shark

Rev

Rev 422 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
422 giacomo 1
/*
2
 * inclue/asm-generic/rtc.h
3
 *
4
 * Author: Tom Rini <trini@mvista.com>
5
 *
6
 * Based on:
7
 * drivers/char/rtc.c
8
 *
9
 * Please read the COPYING file for all license details.
10
 */
11
 
12
#ifndef __ASM_RTC_H__
13
#define __ASM_RTC_H__
14
 
15
#ifdef __KERNEL__
16
 
17
#include <linux/mc146818rtc.h>
18
#include <linux/rtc.h>
19
#include <linux/bcd.h>
20
 
21
#define RTC_PIE 0x40            /* periodic interrupt enable */
22
#define RTC_AIE 0x20            /* alarm interrupt enable */
23
#define RTC_UIE 0x10            /* update-finished interrupt enable */
24
 
25
/* some dummy definitions */
26
#define RTC_BATT_BAD 0x100      /* battery bad */
27
#define RTC_SQWE 0x08           /* enable square-wave output */
28
#define RTC_DM_BINARY 0x04      /* all time/date values are BCD if clear */
29
#define RTC_24H 0x02            /* 24 hour mode - else hours bit 7 means pm */
30
#define RTC_DST_EN 0x01         /* auto switch DST - works f. USA only */
31
 
32
/*
33
 * Returns true if a clock update is in progress
34
 */
35
static inline unsigned char rtc_is_updating(void)
36
{
37
        unsigned char uip;
38
 
39
        spin_lock_irq(&rtc_lock);
40
        uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
41
        spin_unlock_irq(&rtc_lock);
42
        return uip;
43
}
44
 
45
static inline unsigned int get_rtc_time(struct rtc_time *time)
46
{
47
        unsigned long uip_watchdog = jiffies;
48
        unsigned char ctrl;
49
#ifdef CONFIG_DECSTATION
50
        unsigned int real_year;
51
#endif
52
 
53
        /*
54
         * read RTC once any update in progress is done. The update
55
         * can take just over 2ms. We wait 10 to 20ms. There is no need to
56
         * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
57
         * If you need to know *exactly* when a second has started, enable
58
         * periodic update complete interrupts, (via ioctl) and then
59
         * immediately read /dev/rtc which will block until you get the IRQ.
60
         * Once the read clears, read the RTC time (again via ioctl). Easy.
61
         */
62
 
63
        if (rtc_is_updating() != 0)
64
                while (jiffies - uip_watchdog < 2*HZ/100) {
65
                        barrier();
66
                        cpu_relax();
67
                }
68
 
69
        /*
70
         * Only the values that we read from the RTC are set. We leave
71
         * tm_wday, tm_yday and tm_isdst untouched. Even though the
72
         * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
73
         * by the RTC when initially set to a non-zero value.
74
         */
75
        spin_lock_irq(&rtc_lock);
76
        time->tm_sec = CMOS_READ(RTC_SECONDS);
77
        time->tm_min = CMOS_READ(RTC_MINUTES);
78
        time->tm_hour = CMOS_READ(RTC_HOURS);
79
        time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
80
        time->tm_mon = CMOS_READ(RTC_MONTH);
81
        time->tm_year = CMOS_READ(RTC_YEAR);
82
#ifdef CONFIG_DECSTATION
83
        real_year = CMOS_READ(RTC_DEC_YEAR);
84
#endif
85
        ctrl = CMOS_READ(RTC_CONTROL);
86
        spin_unlock_irq(&rtc_lock);
87
 
88
        if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
89
        {
90
                BCD_TO_BIN(time->tm_sec);
91
                BCD_TO_BIN(time->tm_min);
92
                BCD_TO_BIN(time->tm_hour);
93
                BCD_TO_BIN(time->tm_mday);
94
                BCD_TO_BIN(time->tm_mon);
95
                BCD_TO_BIN(time->tm_year);
96
        }
97
 
98
#ifdef CONFIG_DECSTATION
99
        time->tm_year += real_year - 72;
100
#endif
101
 
102
        /*
103
         * Account for differences between how the RTC uses the values
104
         * and how they are defined in a struct rtc_time;
105
         */
106
        if (time->tm_year <= 69)
107
                time->tm_year += 100;
108
 
109
        time->tm_mon--;
110
 
111
        return RTC_24H;
112
}
113
 
114
/* Set the current date and time in the real time clock. */
115
static inline int set_rtc_time(struct rtc_time *time)
116
{
117
        unsigned char mon, day, hrs, min, sec;
118
        unsigned char save_control, save_freq_select;
119
        unsigned int yrs;
120
#ifdef CONFIG_DECSTATION
121
        unsigned int real_yrs, leap_yr;
122
#endif
123
 
124
        yrs = time->tm_year;
125
        mon = time->tm_mon + 1;   /* tm_mon starts at zero */
126
        day = time->tm_mday;
127
        hrs = time->tm_hour;
128
        min = time->tm_min;
129
        sec = time->tm_sec;
130
 
131
        if (yrs > 255)  /* They are unsigned */
132
                return -EINVAL;
133
 
134
        spin_lock_irq(&rtc_lock);
135
#ifdef CONFIG_DECSTATION
136
        real_yrs = yrs;
137
        leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
138
                        !((yrs + 1900) % 400));
139
        yrs = 72;
140
 
141
        /*
142
         * We want to keep the year set to 73 until March
143
         * for non-leap years, so that Feb, 29th is handled
144
         * correctly.
145
         */
146
        if (!leap_yr && mon < 3) {
147
                real_yrs--;
148
                yrs = 73;
149
        }
150
#endif
151
        /* These limits and adjustments are independent of
152
         * whether the chip is in binary mode or not.
153
         */
154
        if (yrs > 169) {
155
                spin_unlock_irq(&rtc_lock);
156
                return -EINVAL;
157
        }
158
 
159
        if (yrs >= 100)
160
                yrs -= 100;
161
 
162
        if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
163
            || RTC_ALWAYS_BCD) {
164
                BIN_TO_BCD(sec);
165
                BIN_TO_BCD(min);
166
                BIN_TO_BCD(hrs);
167
                BIN_TO_BCD(day);
168
                BIN_TO_BCD(mon);
169
                BIN_TO_BCD(yrs);
170
        }
171
 
172
        save_control = CMOS_READ(RTC_CONTROL);
173
        CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
174
        save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
175
        CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
176
 
177
#ifdef CONFIG_DECSTATION
178
        CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
179
#endif
180
        CMOS_WRITE(yrs, RTC_YEAR);
181
        CMOS_WRITE(mon, RTC_MONTH);
182
        CMOS_WRITE(day, RTC_DAY_OF_MONTH);
183
        CMOS_WRITE(hrs, RTC_HOURS);
184
        CMOS_WRITE(min, RTC_MINUTES);
185
        CMOS_WRITE(sec, RTC_SECONDS);
186
 
187
        CMOS_WRITE(save_control, RTC_CONTROL);
188
        CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
189
 
190
        spin_unlock_irq(&rtc_lock);
191
 
192
        return 0;
193
}
194
 
195
static inline unsigned int get_rtc_ss(void)
196
{
197
        struct rtc_time h;
198
 
199
        get_rtc_time(&h);
200
        return h.tm_sec;
201
}
202
 
203
static inline int get_rtc_pll(struct rtc_pll_info *pll)
204
{
205
        return -EINVAL;
206
}
207
static inline int set_rtc_pll(struct rtc_pll_info *pll)
208
{
209
        return -EINVAL;
210
}
211
 
212
#endif /* __KERNEL__ */
213
#endif /* __ASM_RTC_H__ */