akbd.c revision 1.3.2.3 1 1.3.2.3 scottr /* $NetBSD: akbd.c,v 1.3.2.3 1999/03/10 16:00:15 scottr Exp $ */
2 1.1 ender
3 1.1 ender /*
4 1.1 ender * Copyright (C) 1998 Colin Wood
5 1.1 ender * All rights reserved.
6 1.1 ender *
7 1.1 ender * Redistribution and use in source and binary forms, with or without
8 1.1 ender * modification, are permitted provided that the following conditions
9 1.1 ender * are met:
10 1.1 ender * 1. Redistributions of source code must retain the above copyright
11 1.1 ender * notice, this list of conditions and the following disclaimer.
12 1.1 ender * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 ender * notice, this list of conditions and the following disclaimer in the
14 1.1 ender * documentation and/or other materials provided with the distribution.
15 1.1 ender * 3. All advertising materials mentioning features or use of this software
16 1.1 ender * must display the following acknowledgement:
17 1.1 ender * This product includes software developed by Colin Wood.
18 1.1 ender * 4. The name of the author may not be used to endorse or promote products
19 1.1 ender * derived from this software without specific prior written permission.
20 1.1 ender *
21 1.1 ender * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1 ender * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.1 ender * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.1 ender * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.1 ender * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.1 ender * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.1 ender * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.1 ender * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.1 ender * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 1.1 ender * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.1 ender */
32 1.1 ender
33 1.1 ender #include <sys/param.h>
34 1.1 ender #include <sys/device.h>
35 1.1 ender #include <sys/fcntl.h>
36 1.1 ender #include <sys/poll.h>
37 1.1 ender #include <sys/select.h>
38 1.1 ender #include <sys/proc.h>
39 1.1 ender #include <sys/signalvar.h>
40 1.1 ender #include <sys/systm.h>
41 1.1 ender
42 1.3.2.1 scottr #include "aed.h"
43 1.3.2.1 scottr #include "wskbd.h"
44 1.3.2.1 scottr
45 1.3.2.1 scottr #include <dev/wscons/wsconsio.h>
46 1.3.2.1 scottr #include <dev/wscons/wskbdvar.h>
47 1.3.2.1 scottr #include <dev/wscons/wsksymdef.h>
48 1.3.2.1 scottr #include <dev/wscons/wsksymvar.h>
49 1.3.2.1 scottr
50 1.1 ender #include <machine/autoconf.h>
51 1.3.2.1 scottr #include <machine/cpu.h>
52 1.3.2.1 scottr #define KEYBOARD_ARRAY
53 1.3.2.1 scottr #include <machine/keyboard.h>
54 1.3.2.3 scottr #include <machine/viareg.h>
55 1.1 ender
56 1.1 ender #include <mac68k/mac68k/macrom.h>
57 1.1 ender #include <mac68k/dev/adbvar.h>
58 1.1 ender #include <mac68k/dev/aedvar.h>
59 1.3.2.1 scottr #include <macppc/dev/akbdmap.h>
60 1.3.2.1 scottr #include <mac68k/dev/akbdvar.h>
61 1.3.2.1 scottr #include <mac68k/dev/amsvar.h>
62 1.1 ender
63 1.1 ender /*
64 1.1 ender * Function declarations.
65 1.1 ender */
66 1.3.2.1 scottr static int akbdmatch __P((struct device *, struct cfdata *, void *));
67 1.3.2.1 scottr static void akbdattach __P((struct device *, struct device *, void *));
68 1.1 ender void kbd_adbcomplete __P((caddr_t buffer, caddr_t data_area, int adb_command));
69 1.3.2.1 scottr static void kbd_processevent __P((adb_event_t *event, struct akbd_softc *));
70 1.1 ender #ifdef notyet
71 1.1 ender static u_char getleds __P((int));
72 1.3.2.1 scottr static int setleds __P((struct akbd_softc *, u_char));
73 1.3.2.1 scottr static void blinkleds __P((struct akbd_softc *));
74 1.1 ender #endif
75 1.1 ender
76 1.1 ender /*
77 1.1 ender * Local variables.
78 1.1 ender */
79 1.1 ender static volatile int kbd_done; /* Did ADBOp() complete? */
80 1.1 ender
81 1.1 ender /* Driver definition. */
82 1.3.2.1 scottr struct cfattach akbd_ca = {
83 1.3.2.1 scottr sizeof(struct akbd_softc), akbdmatch, akbdattach
84 1.3.2.1 scottr };
85 1.3.2.1 scottr
86 1.3.2.1 scottr extern struct cfdriver akbd_cd;
87 1.3.2.1 scottr
88 1.3.2.1 scottr int kbd_intr __P((adb_event_t *event));
89 1.3.2.1 scottr int akbd_enable __P((void *, int));
90 1.3.2.1 scottr void akbd_set_leds __P((void *, int));
91 1.3.2.1 scottr int akbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
92 1.3.2.1 scottr
93 1.3.2.1 scottr struct wskbd_accessops akbd_accessops = {
94 1.3.2.1 scottr akbd_enable,
95 1.3.2.1 scottr akbd_set_leds,
96 1.3.2.1 scottr akbd_ioctl,
97 1.3.2.1 scottr };
98 1.3.2.1 scottr
99 1.3.2.1 scottr void akbd_cngetc __P((void *, u_int *, int *));
100 1.3.2.1 scottr void akbd_cnpollc __P((void *, int));
101 1.3.2.1 scottr int akbd_cnattach __P((void));
102 1.3.2.1 scottr
103 1.3.2.1 scottr struct wskbd_consops akbd_consops = {
104 1.3.2.1 scottr akbd_cngetc,
105 1.3.2.1 scottr akbd_cnpollc,
106 1.3.2.1 scottr };
107 1.3.2.1 scottr
108 1.3.2.1 scottr struct wskbd_mapdata akbd_keymapdata = {
109 1.3.2.1 scottr akbd_keydesctab,
110 1.3.2.1 scottr KB_US,
111 1.1 ender };
112 1.1 ender
113 1.3.2.1 scottr static int akbd_is_console __P((void));
114 1.1 ender
115 1.1 ender static int
116 1.3.2.1 scottr akbdmatch(parent, cf, aux)
117 1.1 ender struct device *parent;
118 1.1 ender struct cfdata *cf;
119 1.1 ender void *aux;
120 1.1 ender {
121 1.1 ender struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
122 1.1 ender
123 1.1 ender if (aa_args->origaddr == ADBADDR_KBD)
124 1.1 ender return 1;
125 1.1 ender else
126 1.1 ender return 0;
127 1.1 ender }
128 1.1 ender
129 1.1 ender static void
130 1.3.2.1 scottr akbdattach(parent, self, aux)
131 1.1 ender struct device *parent, *self;
132 1.1 ender void *aux;
133 1.1 ender {
134 1.1 ender ADBSetInfoBlock adbinfo;
135 1.3.2.1 scottr struct akbd_softc *sc = (struct akbd_softc *)self;
136 1.1 ender struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
137 1.1 ender int count, error;
138 1.1 ender short cmd;
139 1.1 ender u_char buffer[9];
140 1.3.2.1 scottr #if NWSKBD > 0
141 1.3.2.1 scottr struct wskbddev_attach_args a;
142 1.3.2.1 scottr #endif
143 1.1 ender
144 1.1 ender sc->origaddr = aa_args->origaddr;
145 1.1 ender sc->adbaddr = aa_args->adbaddr;
146 1.1 ender sc->handler_id = aa_args->handler_id;
147 1.1 ender
148 1.1 ender sc->sc_leds = (u_int8_t)0x00; /* initially off */
149 1.1 ender
150 1.1 ender adbinfo.siServiceRtPtr = (Ptr)adb_kbd_asmcomplete;
151 1.1 ender adbinfo.siDataAreaAddr = (caddr_t)sc;
152 1.1 ender
153 1.1 ender switch (sc->handler_id) {
154 1.1 ender case ADB_STDKBD:
155 1.1 ender printf("standard keyboard\n");
156 1.1 ender break;
157 1.1 ender case ADB_ISOKBD:
158 1.1 ender printf("standard keyboard (ISO layout)\n");
159 1.1 ender break;
160 1.1 ender case ADB_EXTKBD:
161 1.1 ender kbd_done = 0;
162 1.1 ender cmd = (((sc->adbaddr << 4) & 0xf0) | 0x0d ); /* talk R1 */
163 1.1 ender ADBOp((Ptr)buffer, (Ptr)extdms_complete,
164 1.1 ender (Ptr)&kbd_done, cmd);
165 1.1 ender
166 1.1 ender /* Wait until done, but no more than 2 secs */
167 1.1 ender count = 40000;
168 1.1 ender while (!kbd_done && count-- > 0)
169 1.1 ender delay(50);
170 1.1 ender
171 1.1 ender /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
172 1.1 ender if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
173 1.1 ender printf("Mouseman (non-EMP) pseudo keyboard\n");
174 1.1 ender adbinfo.siServiceRtPtr = (Ptr)0;
175 1.1 ender adbinfo.siDataAreaAddr = (Ptr)0;
176 1.1 ender } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
177 1.1 ender printf("Trackman (non-EMP) pseudo keyboard\n");
178 1.1 ender adbinfo.siServiceRtPtr = (Ptr)0;
179 1.1 ender adbinfo.siDataAreaAddr = (Ptr)0;
180 1.1 ender } else {
181 1.1 ender printf("extended keyboard\n");
182 1.1 ender #ifdef notyet
183 1.1 ender blinkleds(sc);
184 1.1 ender #endif
185 1.1 ender }
186 1.1 ender break;
187 1.1 ender case ADB_EXTISOKBD:
188 1.1 ender printf("extended keyboard (ISO layout)\n");
189 1.1 ender #ifdef notyet
190 1.1 ender blinkleds(sc);
191 1.1 ender #endif
192 1.1 ender break;
193 1.1 ender case ADB_KBDII:
194 1.1 ender printf("keyboard II\n");
195 1.1 ender break;
196 1.1 ender case ADB_ISOKBDII:
197 1.1 ender printf("keyboard II (ISO layout)\n");
198 1.1 ender break;
199 1.1 ender case ADB_PBKBD:
200 1.1 ender printf("PowerBook keyboard\n");
201 1.1 ender break;
202 1.1 ender case ADB_PBISOKBD:
203 1.1 ender printf("PowerBook keyboard (ISO layout)\n");
204 1.1 ender break;
205 1.1 ender case ADB_ADJKPD:
206 1.1 ender printf("adjustable keypad\n");
207 1.1 ender break;
208 1.1 ender case ADB_ADJKBD:
209 1.1 ender printf("adjustable keyboard\n");
210 1.1 ender break;
211 1.1 ender case ADB_ADJISOKBD:
212 1.1 ender printf("adjustable keyboard (ISO layout)\n");
213 1.1 ender break;
214 1.1 ender case ADB_ADJJAPKBD:
215 1.1 ender printf("adjustable keyboard (Japanese layout)\n");
216 1.1 ender break;
217 1.1 ender case ADB_PBEXTISOKBD:
218 1.1 ender printf("PowerBook extended keyboard (ISO layout)\n");
219 1.1 ender break;
220 1.1 ender case ADB_PBEXTJAPKBD:
221 1.1 ender printf("PowerBook extended keyboard (Japanese layout)\n");
222 1.1 ender break;
223 1.3.2.1 scottr case ADB_JPKBDII:
224 1.3.2.1 scottr printf("keyboard II (Japanese layout)\n");
225 1.3.2.1 scottr break;
226 1.1 ender case ADB_PBEXTKBD:
227 1.1 ender printf("PowerBook extended keyboard\n");
228 1.1 ender break;
229 1.1 ender case ADB_DESIGNKBD:
230 1.1 ender printf("extended keyboard\n");
231 1.1 ender #ifdef notyet
232 1.1 ender blinkleds(sc);
233 1.1 ender #endif
234 1.1 ender break;
235 1.3.2.1 scottr case ADB_PBJPKBD:
236 1.3.2.1 scottr printf("PowerBook keyboard (Japanese layout)\n");
237 1.3.2.1 scottr break;
238 1.1 ender default:
239 1.1 ender printf("mapped device (%d)\n", sc->handler_id);
240 1.1 ender break;
241 1.1 ender }
242 1.1 ender error = SetADBInfo(&adbinfo, sc->adbaddr);
243 1.1 ender #ifdef ADB_DEBUG
244 1.1 ender if (adb_debug)
245 1.3.2.1 scottr printf("akbd: returned %d from SetADBInfo\n", error);
246 1.1 ender #endif
247 1.1 ender
248 1.3.2.1 scottr #if NWSKBD > 0
249 1.3.2.1 scottr a.console = akbd_is_console();
250 1.3.2.1 scottr a.keymap = &akbd_keymapdata;
251 1.3.2.1 scottr a.accessops = &akbd_accessops;
252 1.3.2.1 scottr a.accesscookie = sc;
253 1.3.2.1 scottr
254 1.3.2.1 scottr sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
255 1.3.2.1 scottr #endif
256 1.1 ender }
257 1.1 ender
258 1.1 ender
259 1.1 ender /*
260 1.1 ender * Handle putting the keyboard data received from the ADB into
261 1.1 ender * an ADB event record.
262 1.1 ender */
263 1.1 ender void
264 1.1 ender kbd_adbcomplete(buffer, data_area, adb_command)
265 1.1 ender caddr_t buffer;
266 1.1 ender caddr_t data_area;
267 1.1 ender int adb_command;
268 1.1 ender {
269 1.1 ender adb_event_t event;
270 1.3.2.1 scottr struct akbd_softc *ksc;
271 1.1 ender int adbaddr;
272 1.1 ender #ifdef ADB_DEBUG
273 1.1 ender int i;
274 1.1 ender
275 1.1 ender if (adb_debug)
276 1.1 ender printf("adb: transaction completion\n");
277 1.1 ender #endif
278 1.1 ender
279 1.1 ender adbaddr = (adb_command & 0xf0) >> 4;
280 1.3.2.1 scottr ksc = (struct akbd_softc *)data_area;
281 1.1 ender
282 1.1 ender event.addr = adbaddr;
283 1.1 ender event.hand_id = ksc->handler_id;
284 1.1 ender event.def_addr = ksc->origaddr;
285 1.1 ender event.byte_count = buffer[0];
286 1.1 ender memcpy(event.bytes, buffer + 1, event.byte_count);
287 1.1 ender
288 1.1 ender #ifdef ADB_DEBUG
289 1.1 ender if (adb_debug) {
290 1.3.2.1 scottr printf("akbd: from %d at %d (org %d) %d:", event.addr,
291 1.1 ender event.hand_id, event.def_addr, buffer[0]);
292 1.1 ender for (i = 1; i <= buffer[0]; i++)
293 1.1 ender printf(" %x", buffer[i]);
294 1.1 ender printf("\n");
295 1.1 ender }
296 1.1 ender #endif
297 1.1 ender
298 1.1 ender microtime(&event.timestamp);
299 1.1 ender
300 1.1 ender kbd_processevent(&event, ksc);
301 1.1 ender }
302 1.1 ender
303 1.1 ender /*
304 1.1 ender * Given a keyboard ADB event, record the keycodes and call the key
305 1.1 ender * repeat handler, optionally passing the event through the mouse
306 1.1 ender * button emulation handler first.
307 1.1 ender */
308 1.1 ender static void
309 1.1 ender kbd_processevent(event, ksc)
310 1.1 ender adb_event_t *event;
311 1.3.2.1 scottr struct akbd_softc *ksc;
312 1.1 ender {
313 1.1 ender adb_event_t new_event;
314 1.1 ender
315 1.1 ender new_event = *event;
316 1.1 ender new_event.u.k.key = event->bytes[0];
317 1.1 ender new_event.bytes[1] = 0xff;
318 1.3.2.1 scottr #if NWSKBD > 0
319 1.3.2.1 scottr kbd_intr(&new_event);
320 1.3.2.1 scottr #endif
321 1.3.2.1 scottr #if NAED > 0
322 1.1 ender aed_input(&new_event);
323 1.3.2.1 scottr #endif
324 1.1 ender if (event->bytes[1] != 0xff) {
325 1.1 ender new_event.u.k.key = event->bytes[1];
326 1.1 ender new_event.bytes[0] = event->bytes[1];
327 1.1 ender new_event.bytes[1] = 0xff;
328 1.3.2.1 scottr #if NWSKBD > 0
329 1.3.2.1 scottr kbd_intr(&new_event);
330 1.3.2.1 scottr #endif
331 1.3.2.1 scottr #if NAED > 0
332 1.1 ender aed_input(&new_event);
333 1.3.2.1 scottr #endif
334 1.1 ender }
335 1.1 ender
336 1.1 ender }
337 1.1 ender
338 1.1 ender #ifdef notyet
339 1.1 ender /*
340 1.1 ender * Get the actual hardware LED state and convert it to softc format.
341 1.1 ender */
342 1.1 ender static u_char
343 1.1 ender getleds(addr)
344 1.1 ender int addr;
345 1.1 ender {
346 1.1 ender short cmd;
347 1.1 ender u_char buffer[9], leds;
348 1.1 ender
349 1.1 ender leds = 0x00; /* all off */
350 1.1 ender buffer[0] = 0;
351 1.1 ender kbd_done = 0;
352 1.1 ender
353 1.1 ender /* talk R2 */
354 1.1 ender cmd = ((addr & 0xf) << 4) | 0x0c | 0x02;
355 1.1 ender ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
356 1.1 ender while (!kbd_done)
357 1.1 ender /* busy-wait until done */ ;
358 1.1 ender
359 1.1 ender if (buffer[0] > 0)
360 1.1 ender leds = ~(buffer[2]) & 0x07;
361 1.1 ender
362 1.1 ender return (leds);
363 1.1 ender }
364 1.1 ender
365 1.1 ender /*
366 1.1 ender * Set the keyboard LED's.
367 1.1 ender *
368 1.1 ender * Automatically translates from ioctl/softc format to the
369 1.1 ender * actual keyboard register format
370 1.1 ender */
371 1.1 ender static int
372 1.1 ender setleds(ksc, leds)
373 1.3.2.1 scottr struct akbd_softc *ksc;
374 1.1 ender u_char leds;
375 1.1 ender {
376 1.1 ender int addr;
377 1.1 ender short cmd;
378 1.1 ender u_char buffer[9];
379 1.1 ender
380 1.1 ender if ((leds & 0x07) == (ksc->sc_leds & 0x07))
381 1.1 ender return (0);
382 1.1 ender
383 1.2 ender addr = ksc->adbaddr;
384 1.1 ender buffer[0] = 0;
385 1.1 ender kbd_done = 0;
386 1.1 ender
387 1.1 ender /* talk R2 */
388 1.1 ender cmd = ((addr & 0xf) << 4) | 0x0c | 0x02;
389 1.1 ender ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
390 1.1 ender while (!kbd_done)
391 1.1 ender /* busy-wait until done */ ;
392 1.1 ender
393 1.1 ender if (buffer[0] == 0)
394 1.1 ender return (EIO);
395 1.1 ender
396 1.1 ender leds = ~leds & 0x07;
397 1.1 ender buffer[2] &= 0xf8;
398 1.1 ender buffer[2] |= leds;
399 1.1 ender
400 1.1 ender /* listen R2 */
401 1.1 ender cmd = ((addr & 0xf) << 4) | 0x08 | 0x02;
402 1.1 ender ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
403 1.1 ender while (!kbd_done)
404 1.1 ender /* busy-wait until done */ ;
405 1.1 ender
406 1.1 ender /* talk R2 */
407 1.1 ender cmd = ((addr & 0xf) << 4) | 0x0c | 0x02;
408 1.1 ender ADBOp((Ptr)buffer, (Ptr)extdms_complete, (Ptr)&kbd_done, cmd);
409 1.1 ender while (!kbd_done)
410 1.1 ender /* busy-wait until done */ ;
411 1.1 ender
412 1.1 ender if (buffer[0] == 0)
413 1.1 ender return (EIO);
414 1.1 ender
415 1.1 ender ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07;
416 1.1 ender
417 1.1 ender if ((buffer[2] & 0xf8) != leds)
418 1.1 ender return (EIO);
419 1.1 ender else
420 1.1 ender return (0);
421 1.1 ender }
422 1.1 ender
423 1.1 ender /*
424 1.1 ender * Toggle all of the LED's on and off, just for show.
425 1.1 ender */
426 1.1 ender static void
427 1.1 ender blinkleds(ksc)
428 1.3.2.1 scottr struct akbd_softc *ksc;
429 1.1 ender {
430 1.1 ender int addr, i;
431 1.1 ender u_char blinkleds, origleds;
432 1.1 ender
433 1.2 ender addr = ksc->adbaddr;
434 1.1 ender origleds = getleds(addr);
435 1.1 ender blinkleds = LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK;
436 1.1 ender
437 1.1 ender (void)setleds(ksc, blinkleds);
438 1.1 ender
439 1.1 ender for (i = 0; i < 10000; i++)
440 1.1 ender delay(50);
441 1.1 ender
442 1.1 ender /* make sure that we restore the LED settings */
443 1.1 ender i = 10;
444 1.1 ender do {
445 1.1 ender (void)setleds(ksc, (u_char)0x00);
446 1.1 ender } while (setleds(ksc, (u_char)0x00) && (i-- > 0));
447 1.1 ender
448 1.1 ender return;
449 1.1 ender }
450 1.1 ender #endif
451 1.1 ender
452 1.1 ender int
453 1.3.2.1 scottr akbd_is_console()
454 1.3.2.1 scottr {
455 1.3.2.1 scottr extern struct mac68k_machine_S mac68k_machine;
456 1.3.2.1 scottr
457 1.3.2.1 scottr return ((mac68k_machine.serial_console & 0x03) == 0);
458 1.3.2.1 scottr }
459 1.3.2.1 scottr
460 1.3.2.1 scottr int
461 1.3.2.1 scottr akbd_enable(v, on)
462 1.3.2.1 scottr void *v;
463 1.3.2.1 scottr int on;
464 1.3.2.1 scottr {
465 1.3.2.1 scottr return 0;
466 1.3.2.1 scottr }
467 1.3.2.1 scottr
468 1.3.2.1 scottr void
469 1.3.2.1 scottr akbd_set_leds(v, on)
470 1.3.2.1 scottr void *v;
471 1.3.2.1 scottr int on;
472 1.3.2.1 scottr {
473 1.3.2.1 scottr }
474 1.3.2.1 scottr
475 1.3.2.1 scottr int
476 1.3.2.1 scottr akbd_ioctl(v, cmd, data, flag, p)
477 1.3.2.1 scottr void *v;
478 1.3.2.1 scottr u_long cmd;
479 1.1 ender caddr_t data;
480 1.3.2.1 scottr int flag;
481 1.1 ender struct proc *p;
482 1.1 ender {
483 1.3.2.1 scottr switch (cmd) {
484 1.1 ender
485 1.3.2.1 scottr case WSKBDIO_GTYPE:
486 1.3.2.1 scottr *(int *)data = 0; /* XXX */
487 1.3.2.1 scottr return 0;
488 1.3.2.1 scottr case WSKBDIO_SETLEDS:
489 1.3.2.1 scottr return 0;
490 1.3.2.1 scottr case WSKBDIO_GETLEDS:
491 1.3.2.1 scottr *(int *)data = 0;
492 1.3.2.1 scottr return 0;
493 1.3.2.2 scottr case WSKBDIO_BELL:
494 1.3.2.2 scottr case WSKBDIO_COMPLEXBELL:
495 1.3.2.2 scottr #define d ((struct wskbd_bell_data *)data)
496 1.3.2.2 scottr mac68k_ring_bell(d->pitch, d->period * HZ / 1000, 100);
497 1.3.2.2 scottr /* comes in as msec, goes out as ticks; volume ignored */
498 1.3.2.2 scottr #undef d
499 1.3.2.2 scottr return (0);
500 1.3.2.1 scottr }
501 1.3.2.1 scottr /* kbdioctl(...); */
502 1.1 ender
503 1.3.2.1 scottr return -1;
504 1.3.2.1 scottr }
505 1.3.2.1 scottr
506 1.3.2.1 scottr static int polledkey;
507 1.3.2.1 scottr extern int adb_polling;
508 1.3.2.1 scottr
509 1.3.2.1 scottr int
510 1.3.2.1 scottr kbd_intr(event)
511 1.3.2.1 scottr adb_event_t *event;
512 1.3.2.1 scottr {
513 1.3.2.1 scottr int key, press, val;
514 1.3.2.1 scottr int type;
515 1.3.2.1 scottr
516 1.3.2.1 scottr struct akbd_softc *sc = akbd_cd.cd_devs[0];
517 1.3.2.1 scottr
518 1.3.2.1 scottr key = event->u.k.key;
519 1.3.2.1 scottr press = ADBK_PRESS(key);
520 1.3.2.1 scottr val = ADBK_KEYVAL(key);
521 1.3.2.1 scottr
522 1.3.2.1 scottr type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
523 1.3.2.1 scottr
524 1.3.2.1 scottr if (key == 185) { /* Caps Lock released */
525 1.3.2.1 scottr type = WSCONS_EVENT_KEY_DOWN;
526 1.3.2.1 scottr wskbd_input(sc->sc_wskbddev, type, val);
527 1.3.2.1 scottr type = WSCONS_EVENT_KEY_UP;
528 1.3.2.1 scottr }
529 1.3.2.1 scottr
530 1.3.2.1 scottr if (adb_polling)
531 1.3.2.1 scottr polledkey = key;
532 1.3.2.1 scottr else
533 1.3.2.1 scottr wskbd_input(sc->sc_wskbddev, type, val);
534 1.3.2.1 scottr
535 1.3.2.1 scottr return 0;
536 1.3.2.1 scottr }
537 1.3.2.1 scottr
538 1.3.2.1 scottr int
539 1.3.2.1 scottr akbd_cnattach()
540 1.3.2.1 scottr {
541 1.3.2.1 scottr if (!akbd_is_console())
542 1.3.2.1 scottr return -1;
543 1.3.2.1 scottr
544 1.3.2.1 scottr wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
545 1.3.2.1 scottr
546 1.3.2.1 scottr return 0;
547 1.3.2.1 scottr }
548 1.3.2.1 scottr
549 1.3.2.1 scottr void
550 1.3.2.1 scottr akbd_cngetc(v, type, data)
551 1.3.2.1 scottr void *v;
552 1.3.2.1 scottr u_int *type;
553 1.3.2.1 scottr int *data;
554 1.3.2.1 scottr {
555 1.3.2.3 scottr int intbits, key, press, val;
556 1.3.2.1 scottr int s;
557 1.3.2.1 scottr
558 1.3.2.1 scottr s = splhigh();
559 1.3.2.1 scottr
560 1.3.2.1 scottr polledkey = -1;
561 1.3.2.1 scottr adb_polling = 1;
562 1.3.2.1 scottr
563 1.3.2.1 scottr while (polledkey == -1) {
564 1.3.2.3 scottr intbits = via_reg(VIA1, vIFR);
565 1.3.2.3 scottr
566 1.3.2.3 scottr if (intbits & V1IF_ADBRDY) {
567 1.3.2.3 scottr mrg_adbintr();
568 1.3.2.3 scottr via_reg(VIA1, vIFR) = V1IF_ADBRDY;
569 1.3.2.3 scottr }
570 1.3.2.3 scottr if (intbits & 0x10) {
571 1.3.2.3 scottr mrg_pmintr();
572 1.3.2.3 scottr via_reg(VIA1, vIFR) = 0x10;
573 1.3.2.3 scottr }
574 1.1 ender }
575 1.3.2.1 scottr
576 1.3.2.1 scottr adb_polling = 0;
577 1.3.2.1 scottr splx(s);
578 1.3.2.1 scottr
579 1.3.2.1 scottr key = polledkey;
580 1.3.2.1 scottr press = ADBK_PRESS(key);
581 1.3.2.1 scottr val = ADBK_KEYVAL(key);
582 1.3.2.1 scottr
583 1.3.2.1 scottr *data = val;
584 1.3.2.1 scottr *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
585 1.3.2.1 scottr }
586 1.3.2.1 scottr
587 1.3.2.1 scottr void
588 1.3.2.1 scottr akbd_cnpollc(v, on)
589 1.3.2.1 scottr void *v;
590 1.3.2.1 scottr int on;
591 1.3.2.1 scottr {
592 1.1 ender }
593