177 lines
		
	
	
	
		
			4.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			177 lines
		
	
	
	
		
			4.9 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * 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 */
 |