patch-2.4.6 linux/include/asm-sh/mc146818rtc.h

Next file: linux/include/asm-sh/pci-sh7751.h
Previous file: linux/include/asm-sh/machvec.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.5/linux/include/asm-sh/mc146818rtc.h linux/include/asm-sh/mc146818rtc.h
@@ -0,0 +1,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 */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)