tristate "Generic /dev/rtc emulation" if !SUN3
depends on !ATARI
default y if SUN3
+ ---help---
+ If you say Y here and create a character special file /dev/rtc with
+ major number 10 and minor number 135 using mknod ("man mknod"), you
+ will get access to the real time clock (or hardware clock) built
+ into your computer.
+
+ It reports status information via the file /proc/driver/rtc and its
+ behaviour is set by various ioctls on /dev/rtc. If you enable the
+ "extended RTC operation" below it will also provide an emulation
+ for RTC_UIE which is required by some programs and may improve
+ precision in some cases.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module is called genrtc.o. If you want to compile it as a module,
+ say M here and read <file:Documentation/modules.txt>. To load the
+ module automatically add 'alias char-major-10-135 genrtc' to your
+ /etc/modules.conf
+
+config GEN_RTC_X
+ bool "Extended RTC operation"
+ depends on GEN_RTC
+ help
+ Provides an emulation for RTC_UIE which is required by some programs
+ and may improve precision of the generic RTC support in some cases.
config UNIX98_PTYS
bool "Unix98 PTY support"
#endif /* !CONFIG_SUN3 */
EXPORT_SYMBOL(m68k_debug_device);
EXPORT_SYMBOL(mach_hwclk);
+EXPORT_SYMBOL(mach_get_ss);
+EXPORT_SYMBOL(mach_get_rtc_pll);
+EXPORT_SYMBOL(mach_set_rtc_pll);
EXPORT_SYMBOL(dump_fpu);
EXPORT_SYMBOL(dump_thread);
EXPORT_SYMBOL(strnlen);
unsigned long (*mach_gettimeoffset) (void);
int (*mach_hwclk) (int, struct rtc_time*) = NULL;
int (*mach_set_clock_mmss) (unsigned long) = NULL;
+unsigned int (*mach_get_ss)(void) = NULL;
int (*mach_get_rtc_pll)(struct rtc_pll_info *) = NULL;
int (*mach_set_rtc_pll)(struct rtc_pll_info *) = NULL;
void (*mach_reset)( void );
extern unsigned long q40_gettimeoffset (void);
extern int q40_hwclk (int, struct rtc_time *);
+extern unsigned int q40_get_ss (void);
extern int q40_set_clock_mmss (unsigned long);
+static int q40_get_rtc_pll(struct rtc_pll_info *pll);
+static int q40_set_rtc_pll(struct rtc_pll_info *pll);
extern void q40_reset (void);
void q40_halt(void);
extern void q40_waitbut(void);
mach_init_IRQ = q40_init_IRQ;
mach_gettimeoffset = q40_gettimeoffset;
mach_hwclk = q40_hwclk;
+ mach_get_ss = q40_get_ss;
+ mach_get_rtc_pll = q40_get_rtc_pll;
+ mach_set_rtc_pll = q40_set_rtc_pll;
mach_set_clock_mmss = q40_set_clock_mmss;
mach_reset = q40_reset;
return 0;
}
+unsigned int q40_get_ss()
+{
+ return bcd2bin(Q40_RTC_SECS);
+}
+
/*
* Set the minutes and seconds from seconds value 'nowtime'. Fail if
* clock is out by > 30 minutes. Logic lifted from atari code.
return retval;
}
+
+/* get and set PLL calibration of RTC clock */
+#define Q40_RTC_PLL_MASK ((1<<5)-1)
+#define Q40_RTC_PLL_SIGN (1<<5)
+
+static int q40_get_rtc_pll(struct rtc_pll_info *pll)
+{
+ int tmp=Q40_RTC_CTRL;
+ pll->pll_value = tmp & Q40_RTC_PLL_MASK;
+ if (tmp & Q40_RTC_PLL_SIGN)
+ pll->pll_value = -pll->pll_value;
+ pll->pll_max=31;
+ pll->pll_min=-31;
+ pll->pll_posmult=512;
+ pll->pll_negmult=256;
+ pll->pll_clock=125829120;
+ return 0;
+}
+
+static int q40_set_rtc_pll(struct rtc_pll_info *pll)
+{
+ if (!pll->pll_ctrl){
+ /* the docs are a bit unclear so I am doublesetting */
+ /* RTC_WRITE here ... */
+ int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) |
+ Q40_RTC_WRITE;
+ Q40_RTC_CTRL |= Q40_RTC_WRITE;
+ Q40_RTC_CTRL = tmp;
+ Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
+ return 0;
+ } else
+ return -EINVAL;
+}
/* machine dependent timer functions */
extern unsigned long (*mach_gettimeoffset)(void);
extern int (*mach_hwclk)(int, struct rtc_time*);
+extern unsigned int (*mach_get_ss)(void);
extern int (*mach_get_rtc_pll)(struct rtc_pll_info *);
extern int (*mach_set_rtc_pll)(struct rtc_pll_info *);
extern int (*mach_set_clock_mmss)(unsigned long);
#ifdef __KERNEL__
+#include <linux/rtc.h>
#include <asm/machdep.h>
/* a few implementation details for the emulation : */
return mach_hwclk(1, time);
}
+static inline unsigned int get_rtc_ss(void)
+{
+ if (mach_get_ss)
+ return mach_get_ss();
+ else{
+ struct rtc_time h;
+
+ get_rtc_time(&h);
+ return h.tm_sec;
+ }
+}
+
static inline int get_rtc_pll(struct rtc_pll_info *pll)
{
if (mach_get_rtc_pll)