1 #include "pxa260/pxa260.h"
2 #include "pxa260/pxa260_RTC.h"
3 
4 #include <sys/time.h>
5 
6 
7 
rtcCurTime(void)8 static UInt32 rtcCurTime(void){
9 
10    struct timeval tv;
11 
12    gettimeofday(&tv, NULL);
13 
14    return tv.tv_sec;
15 }
16 
pxa260rtcPrvUpdate(Pxa260rtc * rtc)17 void pxa260rtcPrvUpdate(Pxa260rtc* rtc){
18 
19 	UInt32 time = rtcCurTime();
20 
21 	if(rtc->lastSeenTime != time){	//do not triger alarm more than once per second please
22 
23 		if((rtc->RTSR & 0x4) && (time + rtc->RCNR_offset == rtc->RTAR)){	//check alarm
24 			rtc->RTSR |= 1;
25 		}
26 		if(rtc->RTSR & 0x8){							//send HZ interrupt
27 			rtc->RTSR |= 2;
28 		}
29 	}
30 	pxa260icInt(rtc->ic, PXA260_I_RTC_ALM, (rtc->RTSR & 1) != 0);
31 	pxa260icInt(rtc->ic, PXA260_I_RTC_HZ, (rtc->RTSR & 2) != 0);
32 }
33 
pxa260rtcPrvMemAccessF(void * userData,UInt32 pa,UInt8 size,Boolean write,void * buf)34 static Boolean pxa260rtcPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){
35 
36 	Pxa260rtc* rtc = userData;
37 	UInt32 val = 0;
38 
39 	if(size != 4) {
40 		err_str(__FILE__ ": Unexpected ");
41 	//	err_str(write ? "write" : "read");
42 	//	err_str(" of ");
43 	//	err_dec(size);
44 	//	err_str(" bytes to 0x");
45 	//	err_hex(pa);
46 	//	err_str("\r\n");
47 		return true;		//we do not support non-word accesses
48 	}
49 
50 	pa = (pa - PXA260_RTC_BASE) >> 2;
51 
52    debugLog("PXA260 RTC access:0x%04X, write:%d, PC:0x%08X\n", pa, write, pxa260GetPc());
53 
54 	if(write){
55 		val = *(UInt32*)buf;
56 
57 		switch(pa){
58 			case 0:
59 				rtc->RCNR_offset = rtcCurTime() - val;
60 				break;
61 
62 			case 1:
63 				rtc->RTAR = val;
64 				pxa260rtcPrvUpdate(rtc);
65 				break;
66 
67 			case 2:
68 				rtc->RTSR = (val &~ 3UL) | ((rtc->RTSR &~ val) & 3UL);
69 				pxa260rtcPrvUpdate(rtc);
70 				break;
71 
72 			case 3:
73 				if(!(rtc->RTTR & 0x80000000UL)) rtc->RTTR = val;
74 				break;
75 		}
76 	}
77 	else{
78 		switch(pa){
79 			case 0:
80 				val = rtcCurTime() - rtc->RCNR_offset;
81 				break;
82 
83 			case 1:
84 				val = rtc->RTAR;
85 				break;
86 
87 			case 2:
88 				val = rtc->RTSR;
89 				break;
90 
91 			case 3:
92 				val = rtc->RTTR;
93 				break;
94 		}
95 		*(UInt32*)buf = val;
96 	}
97 
98 	return true;
99 }
100 
101 
pxa260rtcInit(Pxa260rtc * rtc,Pxa260ic * ic)102 void pxa260rtcInit(Pxa260rtc* rtc, Pxa260ic* ic){
103 
104 	__mem_zero(rtc, sizeof(Pxa260rtc));
105 	rtc->ic = ic;
106 	rtc->RCNR_offset = 0;
107 	rtc->RTTR = 0x7FFF;	//nice default value
108 	rtc->lastSeenTime = rtcCurTime();
109    //return memRegionAdd(physMem, PXA260_RTC_BASE, PXA260_RTC_SIZE, pxa260rtcPrvMemAccessF, rtc);
110 }
111 
pxa260rtcUpdate(Pxa260rtc * rtc)112 void pxa260rtcUpdate(Pxa260rtc* rtc){
113 	pxa260rtcPrvUpdate(rtc);
114 }
115