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