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