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; }