mc146818rtc.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
- /*
- * 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 */