include/asm-generic/rtc.h
changeset 0 aa628870c1d3
child 2 d1f6d8b6f81c
equal deleted inserted replaced
-1:000000000000 0:aa628870c1d3
       
     1 /* 
       
     2  * include/asm-generic/rtc.h
       
     3  *
       
     4  * Author: Tom Rini <trini@mvista.com>
       
     5  *
       
     6  * Based on:
       
     7  * drivers/char/rtc.c
       
     8  *
       
     9  * Please read the COPYING file for all license details.
       
    10  */
       
    11 
       
    12 #ifndef __ASM_RTC_H__
       
    13 #define __ASM_RTC_H__
       
    14 
       
    15 #include <linux/mc146818rtc.h>
       
    16 #include <linux/rtc.h>
       
    17 #include <linux/bcd.h>
       
    18 #include <linux/delay.h>
       
    19 
       
    20 #define RTC_PIE 0x40		/* periodic interrupt enable */
       
    21 #define RTC_AIE 0x20		/* alarm interrupt enable */
       
    22 #define RTC_UIE 0x10		/* update-finished interrupt enable */
       
    23 
       
    24 /* some dummy definitions */
       
    25 #define RTC_BATT_BAD 0x100	/* battery bad */
       
    26 #define RTC_SQWE 0x08		/* enable square-wave output */
       
    27 #define RTC_DM_BINARY 0x04	/* all time/date values are BCD if clear */
       
    28 #define RTC_24H 0x02		/* 24 hour mode - else hours bit 7 means pm */
       
    29 #define RTC_DST_EN 0x01	        /* auto switch DST - works f. USA only */
       
    30 
       
    31 /*
       
    32  * Returns true if a clock update is in progress
       
    33  */
       
    34 static inline unsigned char rtc_is_updating(void)
       
    35 {
       
    36 	unsigned char uip;
       
    37 	unsigned long flags;
       
    38 
       
    39 	spin_lock_irqsave(&rtc_lock, flags);
       
    40 	uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
       
    41 	spin_unlock_irqrestore(&rtc_lock, flags);
       
    42 	return uip;
       
    43 }
       
    44 
       
    45 static inline unsigned int get_rtc_time(struct rtc_time *time)
       
    46 {
       
    47 	unsigned char ctrl;
       
    48 	unsigned long flags;
       
    49 
       
    50 #ifdef CONFIG_MACH_DECSTATION
       
    51 	unsigned int real_year;
       
    52 #endif
       
    53 
       
    54 	/*
       
    55 	 * read RTC once any update in progress is done. The update
       
    56 	 * can take just over 2ms. We wait 20ms. There is no need to
       
    57 	 * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
       
    58 	 * If you need to know *exactly* when a second has started, enable
       
    59 	 * periodic update complete interrupts, (via ioctl) and then 
       
    60 	 * immediately read /dev/rtc which will block until you get the IRQ.
       
    61 	 * Once the read clears, read the RTC time (again via ioctl). Easy.
       
    62 	 */
       
    63 	if (rtc_is_updating())
       
    64 		mdelay(20);
       
    65 
       
    66 	/*
       
    67 	 * Only the values that we read from the RTC are set. We leave
       
    68 	 * tm_wday, tm_yday and tm_isdst untouched. Even though the
       
    69 	 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
       
    70 	 * by the RTC when initially set to a non-zero value.
       
    71 	 */
       
    72 	spin_lock_irqsave(&rtc_lock, flags);
       
    73 	time->tm_sec = CMOS_READ(RTC_SECONDS);
       
    74 	time->tm_min = CMOS_READ(RTC_MINUTES);
       
    75 	time->tm_hour = CMOS_READ(RTC_HOURS);
       
    76 	time->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
       
    77 	time->tm_mon = CMOS_READ(RTC_MONTH);
       
    78 	time->tm_year = CMOS_READ(RTC_YEAR);
       
    79 #ifdef CONFIG_MACH_DECSTATION
       
    80 	real_year = CMOS_READ(RTC_DEC_YEAR);
       
    81 #endif
       
    82 	ctrl = CMOS_READ(RTC_CONTROL);
       
    83 	spin_unlock_irqrestore(&rtc_lock, flags);
       
    84 
       
    85 	if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
       
    86 	{
       
    87 		time->tm_sec = bcd2bin(time->tm_sec);
       
    88 		time->tm_min = bcd2bin(time->tm_min);
       
    89 		time->tm_hour = bcd2bin(time->tm_hour);
       
    90 		time->tm_mday = bcd2bin(time->tm_mday);
       
    91 		time->tm_mon = bcd2bin(time->tm_mon);
       
    92 		time->tm_year = bcd2bin(time->tm_year);
       
    93 	}
       
    94 
       
    95 #ifdef CONFIG_MACH_DECSTATION
       
    96 	time->tm_year += real_year - 72;
       
    97 #endif
       
    98 
       
    99 	/*
       
   100 	 * Account for differences between how the RTC uses the values
       
   101 	 * and how they are defined in a struct rtc_time;
       
   102 	 */
       
   103 	if (time->tm_year <= 69)
       
   104 		time->tm_year += 100;
       
   105 
       
   106 	time->tm_mon--;
       
   107 
       
   108 	return RTC_24H;
       
   109 }
       
   110 
       
   111 /* Set the current date and time in the real time clock. */
       
   112 static inline int set_rtc_time(struct rtc_time *time)
       
   113 {
       
   114 	unsigned long flags;
       
   115 	unsigned char mon, day, hrs, min, sec;
       
   116 	unsigned char save_control, save_freq_select;
       
   117 	unsigned int yrs;
       
   118 #ifdef CONFIG_MACH_DECSTATION
       
   119 	unsigned int real_yrs, leap_yr;
       
   120 #endif
       
   121 
       
   122 	yrs = time->tm_year;
       
   123 	mon = time->tm_mon + 1;   /* tm_mon starts at zero */
       
   124 	day = time->tm_mday;
       
   125 	hrs = time->tm_hour;
       
   126 	min = time->tm_min;
       
   127 	sec = time->tm_sec;
       
   128 
       
   129 	if (yrs > 255)	/* They are unsigned */
       
   130 		return -EINVAL;
       
   131 
       
   132 	spin_lock_irqsave(&rtc_lock, flags);
       
   133 #ifdef CONFIG_MACH_DECSTATION
       
   134 	real_yrs = yrs;
       
   135 	leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
       
   136 			!((yrs + 1900) % 400));
       
   137 	yrs = 72;
       
   138 
       
   139 	/*
       
   140 	 * We want to keep the year set to 73 until March
       
   141 	 * for non-leap years, so that Feb, 29th is handled
       
   142 	 * correctly.
       
   143 	 */
       
   144 	if (!leap_yr && mon < 3) {
       
   145 		real_yrs--;
       
   146 		yrs = 73;
       
   147 	}
       
   148 #endif
       
   149 	/* These limits and adjustments are independent of
       
   150 	 * whether the chip is in binary mode or not.
       
   151 	 */
       
   152 	if (yrs > 169) {
       
   153 		spin_unlock_irqrestore(&rtc_lock, flags);
       
   154 		return -EINVAL;
       
   155 	}
       
   156 
       
   157 	if (yrs >= 100)
       
   158 		yrs -= 100;
       
   159 
       
   160 	if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
       
   161 	    || RTC_ALWAYS_BCD) {
       
   162 		sec = bin2bcd(sec);
       
   163 		min = bin2bcd(min);
       
   164 		hrs = bin2bcd(hrs);
       
   165 		day = bin2bcd(day);
       
   166 		mon = bin2bcd(mon);
       
   167 		yrs = bin2bcd(yrs);
       
   168 	}
       
   169 
       
   170 	save_control = CMOS_READ(RTC_CONTROL);
       
   171 	CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
       
   172 	save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
       
   173 	CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
       
   174 
       
   175 #ifdef CONFIG_MACH_DECSTATION
       
   176 	CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
       
   177 #endif
       
   178 	CMOS_WRITE(yrs, RTC_YEAR);
       
   179 	CMOS_WRITE(mon, RTC_MONTH);
       
   180 	CMOS_WRITE(day, RTC_DAY_OF_MONTH);
       
   181 	CMOS_WRITE(hrs, RTC_HOURS);
       
   182 	CMOS_WRITE(min, RTC_MINUTES);
       
   183 	CMOS_WRITE(sec, RTC_SECONDS);
       
   184 
       
   185 	CMOS_WRITE(save_control, RTC_CONTROL);
       
   186 	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
       
   187 
       
   188 	spin_unlock_irqrestore(&rtc_lock, flags);
       
   189 
       
   190 	return 0;
       
   191 }
       
   192 
       
   193 static inline unsigned int get_rtc_ss(void)
       
   194 {
       
   195 	struct rtc_time h;
       
   196 
       
   197 	get_rtc_time(&h);
       
   198 	return h.tm_sec;
       
   199 }
       
   200 
       
   201 static inline int get_rtc_pll(struct rtc_pll_info *pll)
       
   202 {
       
   203 	return -EINVAL;
       
   204 }
       
   205 static inline int set_rtc_pll(struct rtc_pll_info *pll)
       
   206 {
       
   207 	return -EINVAL;
       
   208 }
       
   209 
       
   210 #endif /* __ASM_RTC_H__ */