// #define MODULE #include #include #include #include static int filter(int x) { static int oldx; int ret; if (x & 0x80) { x = 382 - x; } ret = x > oldx; oldx = x; return ret; } void intr_handler(void) { char data; char temp; (void) CMOS_READ(RTC_REG_C); /* clear IRQ */ if (rtf_get(0, &data, 1) > 0) { data = filter(data); temp = inb(0x61); temp &= 0xfd; temp |= (data & 1) << 1; outb(temp,0x61); } } char save_cmos_A; char save_cmos_B; int init_module(void) { char ctemp; rtf_create(0, 4000); /* enable counter 2 */ outb_p(inb_p(0x61)|3, 0x61); /* this is just to ensure that the output of the counter is 1 */ outb_p(0xb0, 0x43); outb_p(3, 0x42); outb_p(00, 0x42); request_RTirq(8, intr_handler); /* program the RTC to interrupt at 8192 Hz */ save_cmos_A = CMOS_READ(RTC_REG_A); save_cmos_B = CMOS_READ(RTC_REG_B); CMOS_WRITE(0x23, RTC_REG_A); /* 32kHz Time Base, 8192 Hz interrupt frequency */ ctemp = CMOS_READ(RTC_REG_B); ctemp &= 0x8f; /* Clear */ ctemp |= 0x40; /* Periodic interrupt enable */ CMOS_WRITE(ctemp, RTC_REG_B); (void) CMOS_READ(RTC_REG_C); return 0; } void cleanup_module(void) { rtf_destroy(0); CMOS_WRITE(save_cmos_A, RTC_REG_A); CMOS_WRITE(save_cmos_B, RTC_REG_B); free_RTirq(8); }