1384740dcSRalf Baechle /* 2384740dcSRalf Baechle * This file is subject to the terms and conditions of the GNU General Public 3384740dcSRalf Baechle * License. See the file "COPYING" in the main directory of this archive 4384740dcSRalf Baechle * for more details. 5384740dcSRalf Baechle * 6384740dcSRalf Baechle * Machine dependent access functions for RTC registers. 7384740dcSRalf Baechle */ 8384740dcSRalf Baechle #ifndef __ASM_MC146818_TIME_H 9384740dcSRalf Baechle #define __ASM_MC146818_TIME_H 10384740dcSRalf Baechle 11384740dcSRalf Baechle #include <linux/bcd.h> 12384740dcSRalf Baechle #include <linux/mc146818rtc.h> 13384740dcSRalf Baechle #include <linux/time.h> 14384740dcSRalf Baechle 15384740dcSRalf Baechle /* 16384740dcSRalf Baechle * For check timing call set_rtc_mmss() 500ms; used in timer interrupt. 17384740dcSRalf Baechle */ 18384740dcSRalf Baechle #define USEC_AFTER 500000 19384740dcSRalf Baechle #define USEC_BEFORE 500000 20384740dcSRalf Baechle 21384740dcSRalf Baechle /* 22384740dcSRalf Baechle * In order to set the CMOS clock precisely, set_rtc_mmss has to be 23384740dcSRalf Baechle * called 500 ms after the second nowtime has started, because when 24384740dcSRalf Baechle * nowtime is written into the registers of the CMOS clock, it will 25384740dcSRalf Baechle * jump to the next second precisely 500 ms later. Check the Motorola 26384740dcSRalf Baechle * MC146818A or Dallas DS12887 data sheet for details. 27384740dcSRalf Baechle * 28384740dcSRalf Baechle * BUG: This routine does not handle hour overflow properly; it just 29384740dcSRalf Baechle * sets the minutes. Usually you'll only notice that after reboot! 30384740dcSRalf Baechle */ 31384740dcSRalf Baechle static inline int mc146818_set_rtc_mmss(unsigned long nowtime) 32384740dcSRalf Baechle { 33384740dcSRalf Baechle int real_seconds, real_minutes, cmos_minutes; 34384740dcSRalf Baechle unsigned char save_control, save_freq_select; 35384740dcSRalf Baechle int retval = 0; 36384740dcSRalf Baechle unsigned long flags; 37384740dcSRalf Baechle 38384740dcSRalf Baechle spin_lock_irqsave(&rtc_lock, flags); 39384740dcSRalf Baechle save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ 40384740dcSRalf Baechle CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 41384740dcSRalf Baechle 42384740dcSRalf Baechle save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ 43384740dcSRalf Baechle CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 44384740dcSRalf Baechle 45384740dcSRalf Baechle cmos_minutes = CMOS_READ(RTC_MINUTES); 46384740dcSRalf Baechle if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 47*02112dbcSAdrian Bunk cmos_minutes = bcd2bin(cmos_minutes); 48384740dcSRalf Baechle 49384740dcSRalf Baechle /* 50384740dcSRalf Baechle * since we're only adjusting minutes and seconds, 51384740dcSRalf Baechle * don't interfere with hour overflow. This avoids 52384740dcSRalf Baechle * messing with unknown time zones but requires your 53384740dcSRalf Baechle * RTC not to be off by more than 15 minutes 54384740dcSRalf Baechle */ 55384740dcSRalf Baechle real_seconds = nowtime % 60; 56384740dcSRalf Baechle real_minutes = nowtime / 60; 57384740dcSRalf Baechle if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) 58384740dcSRalf Baechle real_minutes += 30; /* correct for half hour time zone */ 59384740dcSRalf Baechle real_minutes %= 60; 60384740dcSRalf Baechle 61384740dcSRalf Baechle if (abs(real_minutes - cmos_minutes) < 30) { 62384740dcSRalf Baechle if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 63*02112dbcSAdrian Bunk real_seconds = bin2bcd(real_seconds); 64*02112dbcSAdrian Bunk real_minutes = bin2bcd(real_minutes); 65384740dcSRalf Baechle } 66384740dcSRalf Baechle CMOS_WRITE(real_seconds, RTC_SECONDS); 67384740dcSRalf Baechle CMOS_WRITE(real_minutes, RTC_MINUTES); 68384740dcSRalf Baechle } else { 69384740dcSRalf Baechle printk(KERN_WARNING 70384740dcSRalf Baechle "set_rtc_mmss: can't update from %d to %d\n", 71384740dcSRalf Baechle cmos_minutes, real_minutes); 72384740dcSRalf Baechle retval = -1; 73384740dcSRalf Baechle } 74384740dcSRalf Baechle 75384740dcSRalf Baechle /* The following flags have to be released exactly in this order, 76384740dcSRalf Baechle * otherwise the DS12887 (popular MC146818A clone with integrated 77384740dcSRalf Baechle * battery and quartz) will not reset the oscillator and will not 78384740dcSRalf Baechle * update precisely 500 ms later. You won't find this mentioned in 79384740dcSRalf Baechle * the Dallas Semiconductor data sheets, but who believes data 80384740dcSRalf Baechle * sheets anyway ... -- Markus Kuhn 81384740dcSRalf Baechle */ 82384740dcSRalf Baechle CMOS_WRITE(save_control, RTC_CONTROL); 83384740dcSRalf Baechle CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 84384740dcSRalf Baechle spin_unlock_irqrestore(&rtc_lock, flags); 85384740dcSRalf Baechle 86384740dcSRalf Baechle return retval; 87384740dcSRalf Baechle } 88384740dcSRalf Baechle 89384740dcSRalf Baechle static inline unsigned long mc146818_get_cmos_time(void) 90384740dcSRalf Baechle { 91384740dcSRalf Baechle unsigned int year, mon, day, hour, min, sec; 92384740dcSRalf Baechle unsigned long flags; 93384740dcSRalf Baechle 94384740dcSRalf Baechle spin_lock_irqsave(&rtc_lock, flags); 95384740dcSRalf Baechle 96384740dcSRalf Baechle do { 97384740dcSRalf Baechle sec = CMOS_READ(RTC_SECONDS); 98384740dcSRalf Baechle min = CMOS_READ(RTC_MINUTES); 99384740dcSRalf Baechle hour = CMOS_READ(RTC_HOURS); 100384740dcSRalf Baechle day = CMOS_READ(RTC_DAY_OF_MONTH); 101384740dcSRalf Baechle mon = CMOS_READ(RTC_MONTH); 102384740dcSRalf Baechle year = CMOS_READ(RTC_YEAR); 103384740dcSRalf Baechle } while (sec != CMOS_READ(RTC_SECONDS)); 104384740dcSRalf Baechle 105384740dcSRalf Baechle if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 106*02112dbcSAdrian Bunk sec = bcd2bin(sec); 107*02112dbcSAdrian Bunk min = bcd2bin(min); 108*02112dbcSAdrian Bunk hour = bcd2bin(hour); 109*02112dbcSAdrian Bunk day = bcd2bin(day); 110*02112dbcSAdrian Bunk mon = bcd2bin(mon); 111*02112dbcSAdrian Bunk year = bcd2bin(year); 112384740dcSRalf Baechle } 113384740dcSRalf Baechle spin_unlock_irqrestore(&rtc_lock, flags); 114384740dcSRalf Baechle year = mc146818_decode_year(year); 115384740dcSRalf Baechle 116384740dcSRalf Baechle return mktime(year, mon, day, hour, min, sec); 117384740dcSRalf Baechle } 118384740dcSRalf Baechle 119384740dcSRalf Baechle #endif /* __ASM_MC146818_TIME_H */ 120