1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  *	@(#)kbms_if.c	8.1 (Berkeley) 06/11/93
11  */
12 
13 /* Keyboard Mouse Gate-array control routine */
14 
15 #include <machine/adrsmap.h>
16 
17 #include "ms.h"
18 #include "bm.h"
19 
20 #include <sys/param.h>
21 #include <news3400/sio/scc.h>
22 
23 #if defined(news3200)
24 #include <sys/time.h>
25 #include <news3400/iop/mouse.h>
26 #endif
27 
28 typedef struct kbm_sw {
29 	u_char *stat_port;	/* Status port */
30 	u_char *data_port;	/* Data port */
31 	u_char *intr_port;	/* Interrupt port */
32 	u_char *reset_port;	/* Reset port */
33 	u_char *init1_port;	/* Initialize port 1 */
34 	u_char *init2_port;	/* Initialize port 2 */
35 	u_char *buzz_port;	/* Buzzer port */
36 	u_char *buzzf_port;	/* Buzzer frequency port */
37 	u_char intr_en;		/* Data for Interrupt Enable */
38 	u_char intr_in;		/* Interrupt Occur flag */
39 	u_char data_rdy;	/* Data Ready flag */
40 	u_char init1;		/* Speed */
41 	u_char init2;		/* Clock */
42 	u_char buzzf;		/* Buzzer frequency */
43 } Kbm_sw;
44 
45 #define OFF 0x80
46 struct kbm_sw Kbm_port[] = {
47 	{
48 #ifdef news3400
49 		(u_char *) MOUSE_STAT,
50 #else
51 		(u_char *) KEYB_STAT,
52 #endif
53 		(u_char *) MOUSE_DATA,
54 		(u_char *) MOUSE_INTE,
55 		(u_char *) MOUSE_RESET,
56 		(u_char *) MOUSE_INIT1,
57 		(u_char *) MOUSE_INIT2,
58 		(u_char *) KEYB_BUZZ,
59 		(u_char *) KEYB_BUZZF,
60 		RX_MSINTE,
61 		RX_MSINT,
62 		RX_MSRDY,
63 #ifdef news3400
64 		0x80,	/* 1200 bps */
65 		0,
66 		0
67 #else
68 		1,
69 		0xe0,
70 		0x0a
71 #endif
72 	},
73 	{
74 		(u_char *) KEYB_STAT,
75 		(u_char *) KEYB_DATA,
76 		(u_char *) KEYB_INTE,
77 		(u_char *) KEYB_RESET,
78 		(u_char *) KEYB_INIT1,
79 		(u_char *) KEYB_INIT2,
80 		(u_char *) KEYB_BUZZ,
81 		(u_char *) KEYB_BUZZF,
82 		RX_KBINTE,
83 		RX_KBINT,
84 		RX_KBRDY,
85 #ifdef news3400
86 		0xf0,	/* 9600 bps */
87 		0,
88 		0
89 #else
90 		0,
91 		0xc0,
92 		0x0a
93 #endif
94 	}
95 };
96 
97 kbm_open(chan)
98 	int chan;
99 {
100 	register Kbm_sw *kbm = &Kbm_port[chan];
101 
102 #ifdef news3400
103 	/*
104 	 * Reset KB I/F.
105 	 * Disable KB interrupt.
106 	 * Clear KB overrun flag.
107 	 */
108 	*(volatile u_char *)kbm->reset_port = (u_char)0x01;
109 	*(volatile u_char *)kbm->init1_port = kbm->init1;
110 	if (chan == SCC_MOUSE)
111 		*(volatile u_char *)kbm->intr_port |= kbm->intr_en;
112 #else
113 	*kbm->reset_port = (u_char)0;
114 	*kbm->intr_port = (u_char)1;
115 #endif
116 	kbd_flush();
117 }
118 
119 kbm_close(chan)
120 	int chan;
121 {
122 	register Kbm_sw *kbm = &Kbm_port[chan];
123 
124 #ifdef news3400
125 	*(volatile u_char *)kbm->reset_port = (u_char)0x01;
126 #else
127 	*kbm->reset_port = (u_char)0;
128 	*kbm->intr_port = (u_char)0;
129 #endif
130 }
131 
132 kbm_rint(chan)
133 	int chan;
134 {
135 #ifdef news3400
136 	volatile u_char *port = (volatile u_char *)Kbm_port[chan].data_port;
137 	volatile u_char *stat = (volatile u_char *)Kbm_port[chan].stat_port;
138 	volatile u_char *inte = (volatile u_char *)Kbm_port[chan].intr_port;
139 #else
140 	register u_char *port = Kbm_port[chan].data_port;
141 	register u_char *stat = Kbm_port[chan].stat_port;
142 	register u_char *inte = Kbm_port[chan].intr_port;
143 #endif
144 	int rdy = Kbm_port[chan].data_rdy;
145 	u_char code;
146 
147 #ifdef news3400
148 	*inte &= ~Kbm_port[chan].intr_en;
149 #endif
150 
151 	while (*stat & rdy) {
152 		code = *port;
153 		switch (chan) {
154 		    case SCC_MOUSE: {
155 #if NMS > 0
156 			extern int _ms_helper();
157 
158 			if (xputc(code, SCC_MOUSE) < 0)
159 				printf("mouse queue overflow\n");
160 			/* KU:XXX softcall? */
161 			timeout(_ms_helper, (caddr_t)0, 0);
162 #endif
163 			break;
164 		    }
165 		    case SCC_KEYBOARD: {
166 #if NBM > 0
167 			extern int kb_softint();
168 
169 			if (xputc(code, SCC_KEYBOARD) < 0)
170 				printf("keyboard queue overflow\n");
171 			/* KU:XXX softcall? */
172 			timeout(kb_softint, (caddr_t)0, 0);
173 #endif
174 			break;
175 		    }
176 		    default:
177 			printf("kb or ms stray intr\n");
178 			break;
179 		}
180 	}
181 
182 #ifdef news3400
183 	*inte |= Kbm_port[chan].intr_en;
184 #else
185 	*inte = 1;
186 #endif
187 }
188 
189 
190 kbm_write(chan, buf, count)
191 	int chan;
192 	char *buf;
193 	register int count;
194 {
195 	register u_char *port = Kbm_port[chan].buzz_port;
196 	int c_save = count;
197 
198 #ifdef news3400
199 	*port = count / 3;
200 #endif
201 
202 	return (c_save);
203 }
204 
205 int
206 kbm_getc(chan)
207 	int chan;
208 {
209 #ifdef news3400
210 	volatile u_char *port = (volatile u_char *)Kbm_port[chan].data_port;
211 	volatile u_char *stat = (volatile u_char *)Kbm_port[chan].stat_port;
212 #else
213 	register u_char *port = Kbm_port[chan].data_port;
214 	register u_char *stat = Kbm_port[chan].stat_port;
215 #endif
216 	int rdy = Kbm_port[chan].data_rdy;
217 
218 	if (*stat & rdy)
219 		return (*port & 0xff);
220 	else
221 		return (-1);
222 }
223