static int sunxi_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct rtc_time *alm_tm = &alrm->time;
	void __iomem *base = sunxi_rtc_base;
	unsigned int alarm_en;
	unsigned int alarm_tmp = 0;
	unsigned int date_tmp = 0;

    alarm_tmp = readl(base + SUNXI_RTC_ALARM_DD_HH_MM_SS_REG);
	date_tmp = readl(base + SUNXI_RTC_DATE_REG);
	
    alm_tm->tm_sec  = ALARM_GET_SEC_VALUE(alarm_tmp);
    alm_tm->tm_min  = ALARM_GET_MIN_VALUE(alarm_tmp);
    alm_tm->tm_hour = ALARM_GET_HOUR_VALUE(alarm_tmp);    
        
	alm_tm->tm_mday = DATE_GET_DAY_VALUE(date_tmp);
	alm_tm->tm_mon  = DATE_GET_MON_VALUE(date_tmp);
	alm_tm->tm_year = DATE_GET_YEAR_VALUE(date_tmp);

    alm_tm->tm_year += 110;
    alm_tm->tm_mon  -= 1;
    
    alarm_en = readl(base + SUNXI_ALARM_INT_CTRL_REG);
    if(alarm_en&&RTC_ALARM_COUNT_INT_EN)
    	alrm->enabled = 1;
	
	return 0;
}
/* Time read/write */
static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
{
	unsigned int have_retried = 0;
	void __iomem *base = sunxi_rtc_base;
	unsigned int date_tmp = 0;
	unsigned int time_tmp = 0;

    /*only for alarm losc err occur.*/
    if(losc_err_flag) {
		rtc_tm->tm_sec  = 0;
		rtc_tm->tm_min  = 0;
		rtc_tm->tm_hour = 0;
		
		rtc_tm->tm_mday = 0;
		rtc_tm->tm_mon  = 0;
		rtc_tm->tm_year = 0;
		return -1;
    }

retry_get_time:
	_dev_info(dev,"sunxi_rtc_gettime\n");
    /*first to get the date, then time, because the sec turn to 0 will effect the date;*/
	date_tmp = readl(base + SUNXI_RTC_DATE_REG);
	time_tmp = readl(base + SUNXI_RTC_TIME_REG);

	rtc_tm->tm_sec  = TIME_GET_SEC_VALUE(time_tmp);
	rtc_tm->tm_min  = TIME_GET_MIN_VALUE(time_tmp);
	rtc_tm->tm_hour = TIME_GET_HOUR_VALUE(time_tmp);	
	
	rtc_tm->tm_mday = DATE_GET_DAY_VALUE(date_tmp);
	rtc_tm->tm_mon  = DATE_GET_MON_VALUE(date_tmp);
	rtc_tm->tm_year = DATE_GET_YEAR_VALUE(date_tmp);

	/* the only way to work out wether the system was mid-update
	 * when we read it is to check the second counter, and if it
	 * is zero, then we re-try the entire read
	 */
	if (rtc_tm->tm_sec == 0 && !have_retried) {
		have_retried = 1;
		goto retry_get_time;
	}

	rtc_tm->tm_year += 110;
	rtc_tm->tm_mon  -= 1;
	_dev_info(dev,"read time %d-%d-%d %d:%d:%d\n",
	       rtc_tm->tm_year + 1900, rtc_tm->tm_mon + 1, rtc_tm->tm_mday,
	       rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);

	return 0;
}
static int sunxi_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct rtc_time *alm_tm = &alrm->time;
	void __iomem *base = sunxi_rtc_base;
	unsigned int alarm_en;
	unsigned long alarm_count = 0;
	unsigned long alarm_current = 0;
	unsigned long alarm_gap = 0;
	unsigned long alarm_gap_day = 0;
	unsigned long alarm_gap_hour = 0;
	unsigned long alarm_gap_minute = 0;
	unsigned long alarm_gap_second = 0;
	unsigned int date_tmp = 0;

    alarm_count = readl(base + SUNXI_RTC_ALARM_COUNTER_REG);
    alarm_current = readl(base + SUNXI_RTC_ALARM_CURRENT_REG);
    
	date_tmp = readl(base + SUNXI_RTC_DATE_REG);
	
	alarm_gap = alarm_count - alarm_count;
	
    alarm_gap_day = alarm_gap/(3600*24);//day
    alarm_gap_hour = (alarm_gap - alarm_gap_day*24*60*60)/3600;//hour
    alarm_gap_minute = (alarm_gap - alarm_gap_day*24*60*60 - alarm_gap_hour*60*60)/60;//minute
    alarm_gap_second = alarm_gap - alarm_gap_day*24*60*60 - alarm_gap_hour*60*60-alarm_gap_minute*60;//second
    if(alarm_gap_day > 31) {
    	dev_err(dev, "The alarm time is too long,we assume the alarm ranges from 0 to 31\n");
    	return -EINVAL;
    }
    
	alm_tm->tm_mday = DATE_GET_DAY_VALUE(date_tmp);
	alm_tm->tm_mon  = DATE_GET_MON_VALUE(date_tmp);
	alm_tm->tm_year = DATE_GET_YEAR_VALUE(date_tmp);

    alm_tm->tm_year += 70;
    alm_tm->tm_mon  -= 1;

    alarm_en = readl(base + SUNXI_ALARM_INT_CTRL_REG);
    if(alarm_en&&RTC_ALARM_COUNT_INT_EN)
    	alrm->enabled = 1;
	
	return 0;
}