/* * Set current time and date in RTC */ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) { unsigned long cr; dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); /* Stop Time/Calendar from counting */ cr = at91_rtc_read(AT91_RTC_CR); at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); at91_rtc_write_ier(AT91_RTC_ACKUPD); wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ at91_rtc_write_idr(AT91_RTC_ACKUPD); at91_rtc_write(AT91_RTC_TIMR, bin2bcd(tm->tm_sec) << 0 | bin2bcd(tm->tm_min) << 8 | bin2bcd(tm->tm_hour) << 16); at91_rtc_write(AT91_RTC_CALR, bin2bcd((tm->tm_year + 1900) / 100) /* century */ | bin2bcd(tm->tm_year % 100) << 8 /* year */ | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */ | bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */ | bin2bcd(tm->tm_mday) << 24); /* Restart Time/Calendar */ cr = at91_rtc_read(AT91_RTC_CR); at91_rtc_write(AT91_RTC_CR, cr & ~(AT91_RTC_UPDCAL | AT91_RTC_UPDTIM)); return 0; }
/* * Set alarm time and date in RTC */ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_time tm; at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm); tm.tm_mon = alrm->time.tm_mon; tm.tm_mday = alrm->time.tm_mday; tm.tm_hour = alrm->time.tm_hour; tm.tm_min = alrm->time.tm_min; tm.tm_sec = alrm->time.tm_sec; at91_rtc_write_idr(AT91_RTC_ALARM); at91_rtc_write(AT91_RTC_TIMALR, bin2bcd(tm.tm_sec) << 0 | bin2bcd(tm.tm_min) << 8 | bin2bcd(tm.tm_hour) << 16 | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN); at91_rtc_write(AT91_RTC_CALALR, bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */ | bin2bcd(tm.tm_mday) << 24 | AT91_RTC_DATEEN | AT91_RTC_MTHEN); if (alrm->enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); at91_rtc_write_ier(AT91_RTC_ALARM); } dev_dbg(dev, "%s(): %ptR\n", __func__, &tm); return 0; }
static int at91_rtc_resume(struct device *dev) { if (at91_rtc_imr) { if (device_may_wakeup(dev)) disable_irq_wake(irq); else at91_rtc_write_ier(at91_rtc_imr); } return 0; }
static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { dev_dbg(dev, "%s(): cmd=%08x\n", __func__, enabled); if (enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); at91_rtc_write_ier(AT91_RTC_ALARM); } else at91_rtc_write_idr(AT91_RTC_ALARM); return 0; }