diff options
Diffstat (limited to 'include/asm-sh/mc146818rtc.h')
-rw-r--r-- | include/asm-sh/mc146818rtc.h | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/include/asm-sh/mc146818rtc.h b/include/asm-sh/mc146818rtc.h new file mode 100644 index 000000000000..1707cfb2915d --- /dev/null +++ b/include/asm-sh/mc146818rtc.h @@ -0,0 +1,176 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#ifdef CONFIG_SH_MPC1211 +#undef _ASM_MC146818RTC_H +#undef RTC_IRQ +#include <asm/mpc1211/mc146818rtc.h> +#else + +#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(CONFIG_CPU_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(CONFIG_SH_SECUREEDGE5410) +#include <asm/snapgear/io.h> + +#define RTC_PORT(n) SECUREEDGE_IOPORT_ADDR +#define CMOS_READ(addr) secureedge5410_cmos_read(addr) +#define CMOS_WRITE(val,addr) secureedge5410_cmos_write(val,addr) +extern unsigned char secureedge5410_cmos_read(int addr); +extern void secureedge5410_cmos_write(unsigned char val, int addr); + +#elif defined(CONFIG_CPU_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 /* CONFIG_SH_MPC1211 */ +#endif /* _ASM_MC146818RTC_H */ |