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/adi_hal_internal.h"
16 #define CLEAR_RTC_INT(mask) \
17 do{ ANA_REG_SET(ANA_RTC_INT_CLR, mask); \
18 while(ANA_REG_GET(ANA_RTC_INT_RSTS) & mask); \
21 void rtc_clean_all_int(void)
23 CLEAR_RTC_INT(RTC_INT_ALL_MSK);
25 #define mdelay(_ms) udelay(_ms*1000)
26 #define SPRD_RTC_POWEROFF_ALARM (0x1 << 8)
28 static inline unsigned get_sec(void)
30 unsigned sec, sec_bak;
31 sec = ANA_REG_GET(ANA_RTC_SEC_CNT) & RTC_SEC_MASK;
33 sec_bak = ANA_REG_GET(ANA_RTC_SEC_CNT) & RTC_SEC_MASK;
42 static inline unsigned get_min(void)
44 unsigned min, min_bak;
45 min = ANA_REG_GET(ANA_RTC_MIN_CNT) & RTC_MIN_MASK;
47 min_bak = ANA_REG_GET(ANA_RTC_MIN_CNT) & RTC_MIN_MASK;
56 static inline unsigned get_hour(void)
58 unsigned hour, hour_bak;
59 hour = ANA_REG_GET(ANA_RTC_HOUR_CNT) & RTC_HOUR_MASK;
61 hour_bak = ANA_REG_GET(ANA_RTC_HOUR_CNT) & RTC_HOUR_MASK;
70 static inline unsigned get_day(void)
72 unsigned day, day_bak;
73 day = ANA_REG_GET(ANA_RTC_DAY_CNT) & RTC_DAY_MASK;
75 day_bak = ANA_REG_GET(ANA_RTC_DAY_CNT) & RTC_DAY_MASK;
85 unsigned long sprd_rtc_get_sec(void)
87 unsigned sec, min, hour, day;
88 unsigned first = 0, second = 0;
96 second = ((((day*24) + hour)*60 + min)*60 + sec);
97 if((second - first) == 0)
103 void sprd_rtc_set_alarm_sec(unsigned long secs);
104 void sprd_rtc_set_sec(unsigned long secs)
106 unsigned sec, min, hour, day;
107 unsigned set_mask = 0, int_rsts;
111 temp = (secs - sec)/60;
113 temp = (temp - min)/60;
115 temp = (temp - hour)/24;
119 ANA_REG_OR(ANA_RTC_INT_CLR, RTC_UPD_TIME_MASK);
121 if(sec != get_sec()){
122 ANA_REG_SET(ANA_RTC_SEC_UPDATE, sec);
123 set_mask |= RTC_SEC_ACK_BIT;
125 if(min != get_min()){
126 ANA_REG_SET(ANA_RTC_MIN_UPDATE, min);
127 set_mask |= RTC_MIN_ACK_BIT;
129 if(hour != get_hour()){
130 ANA_REG_SET(ANA_RTC_HOUR_UPDATE, hour);
131 set_mask |= RTC_HOUR_ACK_BIT;
133 if(day != get_day()){
134 ANA_REG_SET(ANA_RTC_DAY_UPDATE, day);
135 set_mask |= RTC_DAY_ACK_BIT;
138 //wait till all update done
141 int_rsts = ANA_REG_GET(ANA_RTC_INT_RSTS) & RTC_UPD_TIME_MASK;
143 if(set_mask == int_rsts)
146 ANA_REG_OR(ANA_RTC_INT_CLR, RTC_UPD_TIME_MASK);
151 unsigned long sprd_rtc_get_alarm_sec(void)
153 unsigned sec, min, hour, day;
154 day = ANA_REG_GET(ANA_RTC_DAY_ALM) & RTC_DAY_MASK;
155 hour = ANA_REG_GET(ANA_RTC_HOUR_ALM) & RTC_HOUR_MASK;
156 min = ANA_REG_GET(ANA_RTC_MIN_ALM) & RTC_MIN_MASK;
157 sec = ANA_REG_GET(ANA_RTC_SEC_ALM) & RTC_SEC_MASK;
159 return ((((day*24) + hour)*60 + min)*60 + sec);
161 void sprd_rtc_set_alarm_sec(unsigned long secs)
163 unsigned sec, min, hour, day;
166 temp = (secs - sec)/60;
168 temp = (temp - min)/60;
170 temp = (temp - hour)/24;
172 ANA_REG_SET(ANA_RTC_SEC_ALM, sec);
173 ANA_REG_SET(ANA_RTC_MIN_ALM, min);
174 ANA_REG_SET(ANA_RTC_HOUR_ALM, hour);
175 ANA_REG_SET(ANA_RTC_DAY_ALM, day);
181 int sprd_clean_rtc(void)
184 ANA_REG_AND(ANA_RTC_INT_EN, ~(RTC_INT_ALL_MSK)); // disable all interrupt
186 ANA_REG_OR(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_RTC_EN); //rtc enable
187 ANA_REG_OR(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_RTC_EN); //rtc rtc clock enable
189 CLEAR_RTC_INT(RTC_INT_ALL_MSK);
191 sprd_rtc_set_alarm_sec(0);
192 printf("now time sec %lu\n", sprd_rtc_get_sec());
193 printf("now alarm sec %lu\n", sprd_rtc_get_alarm_sec());
196 void sprd_rtc_init(void)
198 ANA_REG_OR(ANA_REG_GLB_ARM_MODULE_EN, BIT_ANA_RTC_EN); //rtc enable
199 ANA_REG_OR(ANA_REG_GLB_RTC_CLK_EN, BIT_RTC_RTC_EN); //rtc rtc clock enable
202 int sprd_is_poweroff_alarm(void)
206 poweroff_alarm = ANA_REG_GET(ANA_RTC_SPG_VALUE);
207 if (poweroff_alarm & SPRD_RTC_POWEROFF_ALARM) {
208 ANA_REG_SET(ANA_RTC_SPG_UPD,
209 poweroff_alarm & (~SPRD_RTC_POWEROFF_ALARM));