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
kbm_open(chan)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
kbm_close(chan)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
kbm_rint(chan)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
kbm_write(chan,buf,count)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
kbm_getc(chan)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