File: irqsig.c

package info (click to toggle)
rtlinux 3.1pre3-3
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 4,896 kB
  • ctags: 4,228
  • sloc: ansic: 26,204; sh: 2,069; makefile: 1,414; perl: 855; tcl: 489; asm: 380; cpp: 42
file content (124 lines) | stat: -rw-r--r-- 2,530 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * Interrupt handling in Real-Time. Play sounds with PC speaker.
 * Signal version
 *
 * (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 <linux/mc146818rtc.h>

#include <rtl_fifo.h>
#include <rtl_core.h>
#include <rtl_time.h>
#include <rtl.h>
#include <signal.h>
#include <sys/utsname.h>
#include <time.h>

#define FIFO_NO 3
#define RTC_IRQ 8

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(int sig) {
	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 = inb(0x61);            
		temp &= 0xfc;
		if (data) {
			temp |= 3;
		}
		outb(temp,0x61);
	}
	rtl_hard_enable_irq (RTC_IRQ);
}

char save_cmos_A;
char save_cmos_B;


int init_module(void)
{
	char ctemp;
	int ret;
	time_t t;

	struct utsname name;
	ret = uname(&name);
/* 	rtl_printf("sysname %s, version %s\n", name.sysname, name.version); */

	t = time(NULL);
/* 	rtl_printf("time() returned %d\n", t); */

	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);

	{
		struct sigaction act;
		act.sa_handler = intr_handler;
		act.sa_flags = SA_FOCUS;
		act.sa_focus = 1 << rtl_getcpuid();
		sigaction (RTL_SIGIRQMIN + RTC_IRQ, &act, NULL);
	}

	/* 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 (RTC_IRQ);
	(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);
	{
		struct sigaction act;
		act.sa_handler = SIG_IGN;
		act.sa_flags = 0;
		sigaction (RTL_SIGIRQMIN + RTC_IRQ, &act, NULL);
	}

}