1/* 2 * include/asm-parisc/rtc.h 3 * 4 * Copyright 2002 Randolph CHung <tausq@debian.org> 5 * 6 * Based on: include/asm-ppc/rtc.h and the genrtc driver in the 7 * 2.4 parisc linux tree 8 */ 9 10#ifndef __ASM_RTC_H__ 11#define __ASM_RTC_H__ 12 13#ifdef __KERNEL__ 14 15#include <linux/rtc.h> 16 17#include <asm/pdc.h> 18 19#define SECS_PER_HOUR (60 * 60) 20#define SECS_PER_DAY (SECS_PER_HOUR * 24) 21 22 23#define RTC_PIE 0x40 /* periodic interrupt enable */ 24#define RTC_AIE 0x20 /* alarm interrupt enable */ 25#define RTC_UIE 0x10 /* update-finished interrupt enable */ 26 27#define RTC_BATT_BAD 0x100 /* battery bad */ 28 29/* some dummy definitions */ 30#define RTC_SQWE 0x08 /* enable square-wave output */ 31#define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */ 32#define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */ 33#define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */ 34 35# define __isleap(year) \ 36 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) 37 38/* How many days come before each month (0-12). */ 39static const unsigned short int __mon_yday[2][13] = 40{ 41 /* Normal years. */ 42 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 43 /* Leap years. */ 44 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 45}; 46 47static inline unsigned int get_rtc_time(struct rtc_time *wtime) 48{ 49 struct pdc_tod tod_data; 50 long int days, rem, y; 51 const unsigned short int *ip; 52 53 memset(wtime, 0, sizeof(*wtime)); 54 if (pdc_tod_read(&tod_data) < 0) 55 return RTC_24H | RTC_BATT_BAD; 56 57 // most of the remainder of this function is: 58// Copyright (C) 1991, 1993, 1997, 1998 Free Software Foundation, Inc. 59// This was originally a part of the GNU C Library. 60// It is distributed under the GPL, and was swiped from offtime.c 61 62 63 days = tod_data.tod_sec / SECS_PER_DAY; 64 rem = tod_data.tod_sec % SECS_PER_DAY; 65 66 wtime->tm_hour = rem / SECS_PER_HOUR; 67 rem %= SECS_PER_HOUR; 68 wtime->tm_min = rem / 60; 69 wtime->tm_sec = rem % 60; 70 71 y = 1970; 72 73#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) 74#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) 75 76 while (days < 0 || days >= (__isleap (y) ? 366 : 365)) 77 { 78 /* Guess a corrected year, assuming 365 days per year. */ 79 long int yg = y + days / 365 - (days % 365 < 0); 80 81 /* Adjust DAYS and Y to match the guessed year. */ 82 days -= ((yg - y) * 365 83 + LEAPS_THRU_END_OF (yg - 1) 84 - LEAPS_THRU_END_OF (y - 1)); 85 y = yg; 86 } 87 wtime->tm_year = y - 1900; 88 89 ip = __mon_yday[__isleap(y)]; 90 for (y = 11; days < (long int) ip[y]; --y) 91 continue; 92 days -= ip[y]; 93 wtime->tm_mon = y; 94 wtime->tm_mday = days + 1; 95 96 return RTC_24H; 97} 98 99static int set_rtc_time(struct rtc_time *wtime) 100{ 101 u_int32_t secs; 102 103 secs = mktime(wtime->tm_year + 1900, wtime->tm_mon + 1, wtime->tm_mday, 104 wtime->tm_hour, wtime->tm_min, wtime->tm_sec); 105 106 if(pdc_tod_set(secs, 0) < 0) 107 return -1; 108 else 109 return 0; 110 111} 112 113static inline unsigned int get_rtc_ss(void) 114{ 115 struct rtc_time h; 116 117 get_rtc_time(&h); 118 return h.tm_sec; 119} 120 121static inline int get_rtc_pll(struct rtc_pll_info *pll) 122{ 123 return -EINVAL; 124} 125static inline int set_rtc_pll(struct rtc_pll_info *pll) 126{ 127 return -EINVAL; 128} 129 130#endif /* __KERNEL__ */ 131#endif /* __ASM_RTC_H__ */ 132