static int rtc_settime(struct sunxi_rtc *rtc_dev, struct rtc_time *tm) { int actual_year, actual_month, leap_year = 0, reg_val; actual_year = tm->tm_year + 1900; /* tm_year is from 1900 in linux */ actual_month = tm->tm_mon + 1; /* month is 1..12 in RTC reg but 0..11 in linux */ leap_year = IS_LEAP_YEAR(actual_year); pr_info("%s(%d): time to set %d-%d-%d %d:%d:%d\n", __func__, __LINE__, actual_year, actual_month, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); /* prevent the application seting the error time */ if (!time_valid(tm)) { #if 1 pr_err("%s(%d) err: date %d-%d-%d %d:%d:%d invalid!\n", __func__, __LINE__, actual_year, actual_month, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); return -EINVAL; #else pr_info("%s(%d) err: date %d-%d-%d %d:%d:%d invalid, so reset to 1970-1-1 00:00:00\n", __func__, __LINE__, actual_year, actual_month, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_sec = 0; tm->tm_min = 0; tm->tm_hour = 0; tm->tm_mday = 0; tm->tm_mon = 0; /* 0 is month 1(January) */ tm->tm_year = 70; /* tm_year=0 is 1900, so tm_year=70 is 1970 */ actual_year = tm->tm_year + 1900; /* refresh actual_year for actual_year_to_reg_year below */ actual_month = tm->tm_mon + 1; /* refresh actual_month for below */ leap_year = IS_LEAP_YEAR(actual_year); /* refresh leap_year flag for below */ #endif } /* set time */ rtc_write_reg(rtc_dev->ac100, RTC_SEC_REG_OFF, bin2bcd(tm->tm_sec) & 0x7f); rtc_write_reg(rtc_dev->ac100, RTC_MIN_REG_OFF, bin2bcd(tm->tm_min) & 0x7f); rtc_write_reg(rtc_dev->ac100, RTC_HOU_REG_OFF, bin2bcd(tm->tm_hour) & 0x3f); rtc_write_reg(rtc_dev->ac100, RTC_WEE_REG_OFF, bin2bcd(tm->tm_wday) & 0x7); rtc_write_reg(rtc_dev->ac100, RTC_DAY_REG_OFF, bin2bcd(tm->tm_mday) & 0x3f); rtc_write_reg(rtc_dev->ac100, RTC_MON_REG_OFF, bin2bcd(actual_month) & 0x1f); /* set year */ reg_val = actual_year_to_reg_year(actual_year); reg_val = bin2bcd(reg_val) & 0xff; if (leap_year) reg_val |= LEAP_YEAR_FLAG; rtc_write_reg(rtc_dev->ac100, RTC_YEA_REG_OFF, reg_val); /* set write trig bit */ rtc_write_reg(rtc_dev->ac100, RTC_UPD_TRIG_OFF, RTC_WRITE_RTIG_FLAG); mdelay(30); /* delay 30ms to wait write stable */ pr_info("%s(%d): set time %d-%d-%d %d:%d:%d success!\n", __func__, __LINE__, actual_year, actual_month, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); return 0; }
int main_timer_valid(main_timer_t *timer) { assert(timer!=NULL); if(time_valid(&timer->time)==0) return 0; if(menu_valid(&timer->menu)==0) return 0; if(timer->flags.no_flags!=0) return 0; return 1; }
static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct platform_device *pdev = to_platform_device(dev); struct sunxi_rtc *rtc_dev = platform_get_drvdata(pdev); struct rtc_time *tm_set = &alrm->time, tm_now; unsigned long time_set = 0, time_now = 0; int ret = 0; ret = sunxi_rtc_read_time(dev, &tm_now); pr_info("%s(%d): time to set (%d-%d-%d %d:%d:%d), get cur time (%d-%d-%d %d:%d:%d)\n", __func__, __LINE__, tm_set->tm_year + 1900, tm_set->tm_mon + 1, tm_set->tm_mday, tm_set->tm_hour, tm_set->tm_min, tm_set->tm_sec, tm_now.tm_year + 1900, tm_now.tm_mon + 1, tm_now.tm_mday, tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec); /* prevent the application seting the error time */ if (!time_valid(tm_set)) { pr_err("%s(%d) err: time to set is not valid!\n", __func__, __LINE__); return -EINVAL; } /* if alarm date is before now, omit it */ rtc_tm_to_time(tm_set, &time_set); rtc_tm_to_time(&tm_now, &time_now); if (!ret && time_set <= time_now) { pr_err("%s(%d) err: the day has been passed!\n", __func__, __LINE__); return -EINVAL; } mutex_lock(&rtc_dev->mutex); /* disable alarm */ alarm_disable(rtc_dev); /* set alarm time */ if (alarm_settime(rtc_dev, &alrm->time)) { mutex_unlock(&rtc_dev->mutex); pr_err("%s(%d) err: set alarm time failed!\n", __func__, __LINE__); return -EINVAL; } pr_info("%s(%d): alarm->enabled=%d\n", __func__, __LINE__, alrm->enabled); /* enable alarm if flag set */ if (alrm->enabled) { arisc_enable_nmi_irq(); /* temperally, but no better way */ alarm_enable(rtc_dev); } mutex_unlock(&rtc_dev->mutex); return 0; }
static int rtc_gettime(struct sunxi_rtc *rtc_dev, struct rtc_time *tm) { struct rtc_time time_tmp; int tmp; /* get sec */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_SEC_REG_OFF); time_tmp.tm_sec = bcd2bin(tmp & 0x7f); /* get min */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_MIN_REG_OFF); time_tmp.tm_min = bcd2bin(tmp & 0x7f); /* get hour */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_HOU_REG_OFF); time_tmp.tm_hour = bcd2bin(tmp & 0x3f); /* get week day */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_WEE_REG_OFF); time_tmp.tm_wday = bcd2bin(tmp & 0x7); /* get day */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_DAY_REG_OFF); time_tmp.tm_mday = bcd2bin(tmp & 0x3f); /* get month */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_MON_REG_OFF); time_tmp.tm_mon = bcd2bin(tmp & 0x1f); time_tmp.tm_mon -= 1; /* month is 1..12 in RTC reg but 0..11 in linux */ /* get year */ tmp = rtc_read_reg(rtc_dev->ac100, RTC_YEA_REG_OFF); tmp = bcd2bin(tmp & 0xff); time_tmp.tm_year = reg_year_to_actual_year(tmp) - 1900; /* in linux, tm_year=0 is 1900 */ pr_info("%s(%d): read time %d-%d-%d %d:%d:%d\n", __func__, __LINE__, time_tmp.tm_year + 1900, time_tmp.tm_mon + 1, time_tmp.tm_mday, time_tmp.tm_hour, time_tmp.tm_min, time_tmp.tm_sec); /* check if time read from rtc reg is OK */ if (!time_valid(&time_tmp)) { pr_err("%s(%d) err: retrieved date/time is not valid.\n", __func__, __LINE__); return -EIO; } *tm = time_tmp; return 0; }
static int alarm_gettime(struct sunxi_rtc *rtc_dev, struct rtc_time *tm) { int reg_val; /* get sec */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_SEC_REG_OFF); tm->tm_sec = bcd2bin(reg_val & 0x7f); /* get minute */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_MIN_REG_OFF); tm->tm_min = bcd2bin(reg_val & 0x7f); /* get hour */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_HOU_REG_OFF); tm->tm_hour = bcd2bin(reg_val & 0x3f); /* get week */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_WEEK_REG_OFF); tm->tm_wday = bcd2bin(reg_val & 0x7); /* get day */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_DAY_REG_OFF); tm->tm_mday = bcd2bin(reg_val & 0x3f); /* get month */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_MON_REG_OFF); reg_val = bcd2bin(reg_val & 0x1f); tm->tm_mon = reg_val - 1; /* month is 1..12 in RTC reg but 0..11 in linux */ /* get year */ reg_val = rtc_read_reg(rtc_dev->ac100, ALM_YEA_REG_OFF); reg_val = bcd2bin(reg_val & 0xff); tm->tm_year = reg_year_to_actual_year(reg_val) - 1900; /* tm_year is from 1900 in linux */ pr_info("%s(%d): get alarm time %d-%d-%d %d:%d:%d success!\n", __func__, __LINE__, tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); /* check if time read from rtc reg is OK */ if (!time_valid(tm)) { pr_err("%s(%d) err: get time is not valid.\n", __func__, __LINE__); return -EIO; } return 0; }