3 * Copyright (C) 2011 Spreadtrum Communication Inc
4 * Author: Mark Yang<markyang@spreadtrum.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
12 #include "asm/arch/bits.h"
13 #include "asm/arch/rtc_reg_v3.h"
14 #include "asm/arch/regs_ana.h"
15 #include "asm/arch/adi_hal_internal.h"
17 #define CLEAR_RTC_INT(mask) \
18 do{ ANA_REG_SET(ANA_RTC_INT_CLR, mask); \
19 while(ANA_REG_GET(ANA_RTC_INT_RSTS) & mask); \
22 #define mdelay(_ms) udelay(_ms*1000)
24 static inline unsigned get_sec(void)
26 unsigned sec, sec_bak;
27 sec = ANA_REG_GET(ANA_RTC_SEC_CNT) & RTC_SEC_MASK;
29 sec_bak = ANA_REG_GET(ANA_RTC_SEC_CNT) & RTC_SEC_MASK;
38 static inline unsigned get_min(void)
40 unsigned min, min_bak;
41 min = ANA_REG_GET(ANA_RTC_MIN_CNT) & RTC_MIN_MASK;
43 min_bak = ANA_REG_GET(ANA_RTC_MIN_CNT) & RTC_MIN_MASK;
52 static inline unsigned get_hour(void)
54 unsigned hour, hour_bak;
55 hour = ANA_REG_GET(ANA_RTC_HOUR_CNT) & RTC_HOUR_MASK;
57 hour_bak = ANA_REG_GET(ANA_RTC_HOUR_CNT) & RTC_HOUR_MASK;
66 static inline unsigned get_day(void)
68 unsigned day, day_bak;
69 day = ANA_REG_GET(ANA_RTC_DAY_CNT) & RTC_DAY_MASK;
71 day_bak = ANA_REG_GET(ANA_RTC_DAY_CNT) & RTC_DAY_MASK;
81 unsigned long sprd_rtc_get_sec(void)
83 unsigned sec, min, hour, day;
84 unsigned first = 0, second = 0;
92 second = ((((day*24) + hour)*60 + min)*60 + sec);
93 if((second - first) == 0)
99 void sprd_rtc_set_alarm_sec(unsigned long secs);
100 void sprd_rtc_set_sec(unsigned long secs)
102 unsigned sec, min, hour, day;
103 unsigned set_mask = 0, int_rsts;
107 temp = (secs - sec)/60;
109 temp = (temp - min)/60;
111 temp = (temp - hour)/24;
115 ANA_REG_OR(ANA_RTC_INT_CLR, RTC_UPD_TIME_MASK);
117 if(sec != get_sec()){
118 ANA_REG_SET(ANA_RTC_SEC_UPDATE, sec);
119 set_mask |= RTC_SEC_ACK_BIT;
121 if(min != get_min()){
122 ANA_REG_SET(ANA_RTC_MIN_UPDATE, min);
123 set_mask |= RTC_MIN_ACK_BIT;
125 if(hour != get_hour()){
126 ANA_REG_SET(ANA_RTC_HOUR_UPDATE, hour);
127 set_mask |= RTC_HOUR_ACK_BIT;
129 if(day != get_day()){
130 ANA_REG_SET(ANA_RTC_DAY_UPDATE, day);
131 set_mask |= RTC_DAY_ACK_BIT;
134 //wait till all update done
137 int_rsts = ANA_REG_GET(ANA_RTC_INT_RSTS) & RTC_UPD_TIME_MASK;
139 if(set_mask == int_rsts)
142 ANA_REG_OR(ANA_RTC_INT_CLR, RTC_UPD_TIME_MASK);
147 unsigned long sprd_rtc_get_alarm_sec(void)
149 unsigned sec, min, hour, day;
150 day = ANA_REG_GET(ANA_RTC_DAY_ALM) & RTC_DAY_MASK;
151 hour = ANA_REG_GET(ANA_RTC_HOUR_ALM) & RTC_HOUR_MASK;
152 min = ANA_REG_GET(ANA_RTC_MIN_ALM) & RTC_MIN_MASK;
153 sec = ANA_REG_GET(ANA_RTC_SEC_ALM) & RTC_SEC_MASK;
155 return ((((day*24) + hour)*60 + min)*60 + sec);
157 void sprd_rtc_set_alarm_sec(unsigned long secs)
159 unsigned sec, min, hour, day;
162 temp = (secs - sec)/60;
164 temp = (temp - min)/60;
166 temp = (temp - hour)/24;
168 ANA_REG_SET(ANA_RTC_SEC_ALM, sec);
169 ANA_REG_SET(ANA_RTC_MIN_ALM, min);
170 ANA_REG_SET(ANA_RTC_HOUR_ALM, hour);
171 ANA_REG_SET(ANA_RTC_DAY_ALM, day);
177 int sprd_clean_rtc(void)
180 ANA_REG_AND(ANA_RTC_INT_EN, ~(RTC_INT_ALL_MSK)); // disable all interrupt
181 ANA_REG_OR(ANA_APB_CLK_EN, AGEN_RTC_EN | AGEN_RTC_RTC_EN); //enable rtc device
182 CLEAR_RTC_INT(RTC_INT_ALL_MSK);
184 sprd_rtc_set_alarm_sec(0);
185 printf("now time sec %lu\n", sprd_rtc_get_sec());
186 printf("now alarm sec %lu\n", sprd_rtc_get_alarm_sec());
190 void sprd_rtc_init(void)
192 ANA_REG_OR(ANA_APB_CLK_EN, AGEN_RTC_EN | AGEN_RTC_RTC_EN); //enable rtc device