/* * Interrupt handling in Real-Time. Play sounds with PC speaker. * * (C) Michael Barabanov, 1997 * (C) FSMLabs 1999. baraban@fsmlabs.com * Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991 * Any use of this code must include this notice. * */ #include #include #include #include #include #define FIFO_NO 3 static int filter(int x) { static int oldx; int ret; if (x & 0x80) { x = 382 - x; } ret = x > oldx; oldx = x; return ret; } unsigned int intr_handler(unsigned int irq, struct pt_regs *regs) { char data; char temp; (void) CMOS_READ(RTC_REG_C); /* clear IRQ */ if (rtf_get(FIFO_NO, &data, 1) > 0) { data = filter(data); /* if (data) conpr("1"); else conpr("0"); */ temp = rtl_inb(0x61); temp &= 0xfc; if (data) { temp |= 3; } outb(temp,0x61); } rtl_hard_enable_irq (8); return 0; } char save_cmos_A; char save_cmos_B; int init_module(void) { char ctemp; if (!I8253_channel2_free()) { conpr("RTLinux sound: can't use channel 2; bailing out\n"); return -1; } rtf_create(FIFO_NO, 4000); /* this is just to ensure that the output of the counter is 1 */ outb_p(0xb0, 0x43); /* binary, mode 0, LSB/MSB, ch 2 */ outb_p(0x1, 0x42); outb_p(0x0, 0x42); rtl_request_irq (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); rtl_hard_enable_irq (8); (void) CMOS_READ(RTC_REG_C); return 0; } void cleanup_module(void) { rtf_destroy(FIFO_NO); outb_p(0xb6, 0x43); /* restore the original mode */ CMOS_WRITE(save_cmos_A, RTC_REG_A); CMOS_WRITE(save_cmos_B, RTC_REG_B); rtl_free_irq(8); }