patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / include / asm-sh / mc146818rtc.h
1 /*
2  * Machine dependent access functions for RTC registers.
3  */
4 #ifndef _ASM_MC146818RTC_H
5 #define _ASM_MC146818RTC_H
6
7 #ifdef CONFIG_SH_MPC1211
8 #undef  _ASM_MC146818RTC_H
9 #undef  RTC_IRQ
10 #include <asm/mpc1211/mc146818rtc.h>
11 #else
12
13 #include <asm/rtc.h>
14
15 #define RTC_ALWAYS_BCD  1
16
17 /* FIXME:RTC Interrupt feature is not implemented yet. */
18 #undef  RTC_IRQ
19
20 #if defined(CONFIG_CPU_SH3)
21 #define RTC_PORT(n)             (R64CNT+(n)*2)
22 #define CMOS_READ(addr)         __CMOS_READ(addr,b)
23 #define CMOS_WRITE(val,addr)    __CMOS_WRITE(val,addr,b)
24
25 #elif defined(CONFIG_SH_SECUREEDGE5410)
26 #include <asm/snapgear/io.h>
27
28 #define RTC_PORT(n)             SECUREEDGE_IOPORT_ADDR
29 #define CMOS_READ(addr)         secureedge5410_cmos_read(addr)
30 #define CMOS_WRITE(val,addr)    secureedge5410_cmos_write(val,addr)
31 extern unsigned char secureedge5410_cmos_read(int addr);
32 extern void secureedge5410_cmos_write(unsigned char val, int addr);
33
34 #elif defined(CONFIG_CPU_SH4)
35 #define RTC_PORT(n)             (R64CNT+(n)*4)
36 #define CMOS_READ(addr)         __CMOS_READ(addr,w)
37 #define CMOS_WRITE(val,addr)    __CMOS_WRITE(val,addr,w)
38 #endif
39
40 #define __CMOS_READ(addr, s) ({                                         \
41         unsigned char val=0, rcr1, rcr2, r64cnt, retry;                 \
42         switch(addr) {                                                  \
43                 case RTC_SECONDS:                                       \
44                         val = ctrl_inb(RSECCNT);                        \
45                         break;                                          \
46                 case RTC_SECONDS_ALARM:                                 \
47                         val = ctrl_inb(RSECAR);                         \
48                         break;                                          \
49                 case RTC_MINUTES:                                       \
50                         val = ctrl_inb(RMINCNT);                        \
51                         break;                                          \
52                 case RTC_MINUTES_ALARM:                                 \
53                         val = ctrl_inb(RMINAR);                         \
54                         break;                                          \
55                 case RTC_HOURS:                                         \
56                         val = ctrl_inb(RHRCNT);                         \
57                         break;                                          \
58                 case RTC_HOURS_ALARM:                                   \
59                         val = ctrl_inb(RHRAR);                          \
60                         break;                                          \
61                 case RTC_DAY_OF_WEEK:                                   \
62                         val = ctrl_inb(RWKCNT);                         \
63                         break;                                          \
64                 case RTC_DAY_OF_MONTH:                                  \
65                         val = ctrl_inb(RDAYCNT);                        \
66                         break;                                          \
67                 case RTC_MONTH:                                         \
68                         val = ctrl_inb(RMONCNT);                        \
69                         break;                                          \
70                 case RTC_YEAR:                                          \
71                         val = ctrl_in##s(RYRCNT);                       \
72                         break;                                          \
73                 case RTC_REG_A: /* RTC_FREQ_SELECT */                   \
74                         rcr2 = ctrl_inb(RCR2);                          \
75                         val = (rcr2 & RCR2_PESMASK) >> 4;               \
76                         rcr1 = ctrl_inb(RCR1);                          \
77                         rcr1 = (rcr1 & (RCR1_CIE | RCR1_AIE)) | RCR1_AF;\
78                         retry = 0;                                      \
79                         do {                                            \
80                                 ctrl_outb(rcr1, RCR1); /* clear CF */   \
81                                 r64cnt = ctrl_inb(R64CNT);              \
82                         } while((ctrl_inb(RCR1) & RCR1_CF) && retry++ < 1000);\
83                         r64cnt ^= RTC_BIT_INVERTED;                     \
84                         if(r64cnt == 0x7f || r64cnt == 0)               \
85                                 val |= RTC_UIP;                         \
86                         break;                                          \
87                 case RTC_REG_B: /* RTC_CONTROL */                       \
88                         rcr1 = ctrl_inb(RCR1);                          \
89                         rcr2 = ctrl_inb(RCR2);                          \
90                         if(rcr1 & RCR1_CIE)     val |= RTC_UIE;         \
91                         if(rcr1 & RCR1_AIE)     val |= RTC_AIE;         \
92                         if(rcr2 & RCR2_PESMASK) val |= RTC_PIE;         \
93                         if(!(rcr2 & RCR2_START))val |= RTC_SET;         \
94                         val |= RTC_24H;                                 \
95                         break;                                          \
96                 case RTC_REG_C: /* RTC_INTR_FLAGS */                    \
97                         rcr1 = ctrl_inb(RCR1);                          \
98                         rcr1 &= ~(RCR1_CF | RCR1_AF);                   \
99                         ctrl_outb(rcr1, RCR1);                          \
100                         rcr2 = ctrl_inb(RCR2);                          \
101                         rcr2 &= ~RCR2_PEF;                              \
102                         ctrl_outb(rcr2, RCR2);                          \
103                         break;                                          \
104                 case RTC_REG_D: /* RTC_VALID */                         \
105                         /* Always valid ... */                          \
106                         val = RTC_VRT;                                  \
107                         break;                                          \
108                 default:                                                \
109                         break;                                          \
110         }                                                               \
111         val;                                                            \
112 })
113
114 #define __CMOS_WRITE(val, addr, s) ({                                   \
115         unsigned char rcr1,rcr2;                                        \
116         switch(addr) {                                                  \
117                 case RTC_SECONDS:                                       \
118                         ctrl_outb(val, RSECCNT);                        \
119                         break;                                          \
120                 case RTC_SECONDS_ALARM:                                 \
121                         ctrl_outb(val, RSECAR);                         \
122                         break;                                          \
123                 case RTC_MINUTES:                                       \
124                         ctrl_outb(val, RMINCNT);                        \
125                         break;                                          \
126                 case RTC_MINUTES_ALARM:                                 \
127                         ctrl_outb(val, RMINAR);                         \
128                         break;                                          \
129                 case RTC_HOURS:                                         \
130                         ctrl_outb(val, RHRCNT);                         \
131                         break;                                          \
132                 case RTC_HOURS_ALARM:                                   \
133                         ctrl_outb(val, RHRAR);                          \
134                         break;                                          \
135                 case RTC_DAY_OF_WEEK:                                   \
136                         ctrl_outb(val, RWKCNT);                         \
137                         break;                                          \
138                 case RTC_DAY_OF_MONTH:                                  \
139                         ctrl_outb(val, RDAYCNT);                        \
140                         break;                                          \
141                 case RTC_MONTH:                                         \
142                         ctrl_outb(val, RMONCNT);                        \
143                         break;                                          \
144                 case RTC_YEAR:                                          \
145                         ctrl_out##s((ctrl_in##s(RYRCNT) & 0xff00) | (val & 0xff), RYRCNT);\
146                         break;                                          \
147                 case RTC_REG_A: /* RTC_FREQ_SELECT */                   \
148                         rcr2 = ctrl_inb(RCR2);                          \
149                         if((val & RTC_DIV_CTL) == RTC_DIV_RESET2)       \
150                                 rcr2 |= RCR2_RESET;                     \
151                         ctrl_outb(rcr2, RCR2);                          \
152                         break;                                          \
153                 case RTC_REG_B: /* RTC_CONTROL */                       \
154                         rcr1 = (ctrl_inb(RCR1) & 0x99) | RCR1_AF;       \
155                         if(val & RTC_AIE) rcr1 |= RCR1_AIE;             \
156                         else              rcr1 &= ~RCR1_AIE;            \
157                         if(val & RTC_UIE) rcr1 |= RCR1_CIE;             \
158                         else              rcr1 &= ~RCR1_CIE;            \
159                         ctrl_outb(rcr1, RCR1);                          \
160                         rcr2 = ctrl_inb(RCR2);                          \
161                         if(val & RTC_SET) rcr2 &= ~RCR2_START;          \
162                         else              rcr2 |= RCR2_START;           \
163                         ctrl_outb(rcr2, RCR2);                          \
164                         break;                                          \
165                 case RTC_REG_C: /* RTC_INTR_FLAGS */                    \
166                         break;                                          \
167                 case RTC_REG_D: /* RTC_VALID */                         \
168                         break;                                          \
169                 default:                                                \
170                         break;                                          \
171         }                                                               \
172 })
173
174 #endif /* CONFIG_SH_MPC1211 */
175 #endif /* _ASM_MC146818RTC_H */