akbd.c revision 1.19 1 1.19 christos /* $NetBSD: akbd.c,v 1.19 2007/03/04 06:00:07 christos 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.16 lukem
33 1.16 lukem #include <sys/cdefs.h>
34 1.19 christos __KERNEL_RCSID(0, "$NetBSD: akbd.c,v 1.19 2007/03/04 06:00:07 christos Exp $");
35 1.1 ender
36 1.5 scottr #include "opt_adb.h"
37 1.5 scottr
38 1.1 ender #include <sys/param.h>
39 1.1 ender #include <sys/device.h>
40 1.1 ender #include <sys/fcntl.h>
41 1.1 ender #include <sys/poll.h>
42 1.1 ender #include <sys/select.h>
43 1.1 ender #include <sys/proc.h>
44 1.1 ender #include <sys/signalvar.h>
45 1.1 ender #include <sys/systm.h>
46 1.12 thorpej #include <sys/kernel.h>
47 1.1 ender
48 1.5 scottr #include "aed.h"
49 1.5 scottr #include "wskbd.h"
50 1.5 scottr
51 1.5 scottr #include <dev/wscons/wsconsio.h>
52 1.5 scottr #include <dev/wscons/wskbdvar.h>
53 1.5 scottr #include <dev/wscons/wsksymdef.h>
54 1.5 scottr #include <dev/wscons/wsksymvar.h>
55 1.5 scottr
56 1.1 ender #include <machine/autoconf.h>
57 1.5 scottr #include <machine/cpu.h>
58 1.5 scottr #define KEYBOARD_ARRAY
59 1.5 scottr #include <machine/keyboard.h>
60 1.5 scottr #include <machine/viareg.h>
61 1.1 ender
62 1.1 ender #include <mac68k/mac68k/macrom.h>
63 1.1 ender #include <mac68k/dev/adbvar.h>
64 1.1 ender #include <mac68k/dev/aedvar.h>
65 1.6 ender #include <mac68k/dev/akbdmap.h>
66 1.5 scottr #include <mac68k/dev/akbdvar.h>
67 1.5 scottr #include <mac68k/dev/amsvar.h>
68 1.1 ender
69 1.1 ender /*
70 1.1 ender * Function declarations.
71 1.1 ender */
72 1.17 chs static int akbdmatch(struct device *, struct cfdata *, void *);
73 1.17 chs static void akbdattach(struct device *, struct device *, void *);
74 1.19 christos void kbd_adbcomplete(void *, void *, int);
75 1.17 chs static void kbd_processevent(adb_event_t *, struct akbd_softc *);
76 1.1 ender #ifdef notyet
77 1.17 chs static u_char getleds(int);
78 1.17 chs static int setleds(struct akbd_softc *, u_char);
79 1.17 chs static void blinkleds(struct akbd_softc *);
80 1.1 ender #endif
81 1.1 ender
82 1.1 ender /*
83 1.1 ender * Local variables.
84 1.1 ender */
85 1.1 ender
86 1.1 ender /* Driver definition. */
87 1.15 thorpej CFATTACH_DECL(akbd, sizeof(struct akbd_softc),
88 1.15 thorpej akbdmatch, akbdattach, NULL, NULL);
89 1.5 scottr
90 1.5 scottr extern struct cfdriver akbd_cd;
91 1.5 scottr
92 1.17 chs int kbd_intr(adb_event_t *, struct akbd_softc *);
93 1.17 chs int akbd_enable(void *, int);
94 1.17 chs void akbd_set_leds(void *, int);
95 1.19 christos int akbd_ioctl(void *, u_long, void *, int, struct lwp *);
96 1.5 scottr
97 1.5 scottr struct wskbd_accessops akbd_accessops = {
98 1.5 scottr akbd_enable,
99 1.5 scottr akbd_set_leds,
100 1.5 scottr akbd_ioctl,
101 1.5 scottr };
102 1.5 scottr
103 1.17 chs void akbd_cngetc(void *, u_int *, int *);
104 1.17 chs void akbd_cnpollc(void *, int);
105 1.17 chs int akbd_cnattach(void);
106 1.5 scottr
107 1.5 scottr struct wskbd_consops akbd_consops = {
108 1.5 scottr akbd_cngetc,
109 1.5 scottr akbd_cnpollc,
110 1.5 scottr };
111 1.5 scottr
112 1.5 scottr struct wskbd_mapdata akbd_keymapdata = {
113 1.5 scottr akbd_keydesctab,
114 1.5 scottr KB_US,
115 1.1 ender };
116 1.1 ender
117 1.17 chs static int akbd_is_console(void);
118 1.1 ender
119 1.1 ender static int
120 1.17 chs akbdmatch(struct device *parent, struct cfdata *cf, void *aux)
121 1.1 ender {
122 1.1 ender struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
123 1.1 ender
124 1.1 ender if (aa_args->origaddr == ADBADDR_KBD)
125 1.1 ender return 1;
126 1.1 ender else
127 1.1 ender return 0;
128 1.1 ender }
129 1.1 ender
130 1.1 ender static void
131 1.17 chs akbdattach(struct device *parent, struct device *self, void *aux)
132 1.1 ender {
133 1.1 ender ADBSetInfoBlock adbinfo;
134 1.5 scottr struct akbd_softc *sc = (struct akbd_softc *)self;
135 1.1 ender struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
136 1.10 scottr int error, kbd_done;
137 1.1 ender short cmd;
138 1.1 ender u_char buffer[9];
139 1.5 scottr #if NWSKBD > 0
140 1.5 scottr struct wskbddev_attach_args a;
141 1.17 chs static int akbd_console_initted;
142 1.8 scottr int wskbd_eligible;
143 1.8 scottr
144 1.8 scottr wskbd_eligible = 1;
145 1.5 scottr #endif
146 1.1 ender
147 1.1 ender sc->origaddr = aa_args->origaddr;
148 1.1 ender sc->adbaddr = aa_args->adbaddr;
149 1.1 ender sc->handler_id = aa_args->handler_id;
150 1.1 ender
151 1.1 ender sc->sc_leds = (u_int8_t)0x00; /* initially off */
152 1.1 ender
153 1.1 ender adbinfo.siServiceRtPtr = (Ptr)adb_kbd_asmcomplete;
154 1.19 christos adbinfo.siDataAreaAddr = (void *)sc;
155 1.1 ender
156 1.1 ender switch (sc->handler_id) {
157 1.1 ender case ADB_STDKBD:
158 1.1 ender printf("standard keyboard\n");
159 1.1 ender break;
160 1.1 ender case ADB_ISOKBD:
161 1.1 ender printf("standard keyboard (ISO layout)\n");
162 1.1 ender break;
163 1.1 ender case ADB_EXTKBD:
164 1.7 scottr cmd = ADBTALK(sc->adbaddr, 1);
165 1.10 scottr kbd_done =
166 1.10 scottr (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0);
167 1.1 ender
168 1.1 ender /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
169 1.1 ender if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
170 1.1 ender printf("Mouseman (non-EMP) pseudo keyboard\n");
171 1.1 ender adbinfo.siServiceRtPtr = (Ptr)0;
172 1.1 ender adbinfo.siDataAreaAddr = (Ptr)0;
173 1.8 scottr #if NWSKBD > 0
174 1.8 scottr wskbd_eligible = 0;
175 1.8 scottr #endif /* NWSKBD > 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.8 scottr #if NWSKBD > 0
181 1.8 scottr wskbd_eligible = 0;
182 1.8 scottr #endif /* NWSKBD > 0 */
183 1.1 ender } else {
184 1.1 ender printf("extended keyboard\n");
185 1.1 ender #ifdef notyet
186 1.1 ender blinkleds(sc);
187 1.1 ender #endif
188 1.1 ender }
189 1.1 ender break;
190 1.1 ender case ADB_EXTISOKBD:
191 1.1 ender printf("extended keyboard (ISO layout)\n");
192 1.1 ender #ifdef notyet
193 1.1 ender blinkleds(sc);
194 1.1 ender #endif
195 1.1 ender break;
196 1.1 ender case ADB_KBDII:
197 1.1 ender printf("keyboard II\n");
198 1.1 ender break;
199 1.1 ender case ADB_ISOKBDII:
200 1.1 ender printf("keyboard II (ISO layout)\n");
201 1.1 ender break;
202 1.1 ender case ADB_PBKBD:
203 1.1 ender printf("PowerBook keyboard\n");
204 1.1 ender break;
205 1.1 ender case ADB_PBISOKBD:
206 1.1 ender printf("PowerBook keyboard (ISO layout)\n");
207 1.1 ender break;
208 1.1 ender case ADB_ADJKPD:
209 1.1 ender printf("adjustable keypad\n");
210 1.8 scottr #if NWSKBD > 0
211 1.8 scottr wskbd_eligible = 0;
212 1.8 scottr #endif /* NWSKBD > 0 */
213 1.1 ender break;
214 1.1 ender case ADB_ADJKBD:
215 1.1 ender printf("adjustable keyboard\n");
216 1.1 ender break;
217 1.1 ender case ADB_ADJISOKBD:
218 1.1 ender printf("adjustable keyboard (ISO layout)\n");
219 1.1 ender break;
220 1.1 ender case ADB_ADJJAPKBD:
221 1.1 ender printf("adjustable keyboard (Japanese layout)\n");
222 1.1 ender break;
223 1.1 ender case ADB_PBEXTISOKBD:
224 1.1 ender printf("PowerBook extended keyboard (ISO layout)\n");
225 1.1 ender break;
226 1.1 ender case ADB_PBEXTJAPKBD:
227 1.1 ender printf("PowerBook extended keyboard (Japanese layout)\n");
228 1.1 ender break;
229 1.5 scottr case ADB_JPKBDII:
230 1.5 scottr printf("keyboard II (Japanese layout)\n");
231 1.5 scottr break;
232 1.1 ender case ADB_PBEXTKBD:
233 1.1 ender printf("PowerBook extended keyboard\n");
234 1.1 ender break;
235 1.1 ender case ADB_DESIGNKBD:
236 1.1 ender printf("extended keyboard\n");
237 1.1 ender #ifdef notyet
238 1.1 ender blinkleds(sc);
239 1.1 ender #endif
240 1.1 ender break;
241 1.5 scottr case ADB_PBJPKBD:
242 1.5 scottr printf("PowerBook keyboard (Japanese layout)\n");
243 1.5 scottr break;
244 1.1 ender default:
245 1.1 ender printf("mapped device (%d)\n", sc->handler_id);
246 1.8 scottr #if NWSKBD > 0
247 1.8 scottr wskbd_eligible = 0;
248 1.8 scottr #endif /* NWSKBD > 0 */
249 1.1 ender break;
250 1.1 ender }
251 1.1 ender error = SetADBInfo(&adbinfo, sc->adbaddr);
252 1.1 ender #ifdef ADB_DEBUG
253 1.1 ender if (adb_debug)
254 1.5 scottr printf("akbd: returned %d from SetADBInfo\n", error);
255 1.1 ender #endif
256 1.1 ender
257 1.5 scottr #if NWSKBD > 0
258 1.11 scottr if (akbd_is_console() && wskbd_eligible)
259 1.11 scottr a.console = (++akbd_console_initted == 1);
260 1.11 scottr else
261 1.11 scottr a.console = 0;
262 1.5 scottr a.keymap = &akbd_keymapdata;
263 1.5 scottr a.accessops = &akbd_accessops;
264 1.5 scottr a.accesscookie = sc;
265 1.5 scottr
266 1.5 scottr sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
267 1.5 scottr #endif
268 1.1 ender }
269 1.1 ender
270 1.1 ender
271 1.1 ender /*
272 1.1 ender * Handle putting the keyboard data received from the ADB into
273 1.1 ender * an ADB event record.
274 1.1 ender */
275 1.1 ender void
276 1.19 christos kbd_adbcomplete(void *buffer, void *data_area, int adb_command)
277 1.1 ender {
278 1.1 ender adb_event_t event;
279 1.5 scottr struct akbd_softc *ksc;
280 1.1 ender int adbaddr;
281 1.1 ender #ifdef ADB_DEBUG
282 1.1 ender int i;
283 1.1 ender
284 1.1 ender if (adb_debug)
285 1.1 ender printf("adb: transaction completion\n");
286 1.1 ender #endif
287 1.1 ender
288 1.7 scottr adbaddr = ADB_CMDADDR(adb_command);
289 1.5 scottr ksc = (struct akbd_softc *)data_area;
290 1.1 ender
291 1.1 ender event.addr = adbaddr;
292 1.1 ender event.hand_id = ksc->handler_id;
293 1.1 ender event.def_addr = ksc->origaddr;
294 1.1 ender event.byte_count = buffer[0];
295 1.1 ender memcpy(event.bytes, buffer + 1, event.byte_count);
296 1.1 ender
297 1.1 ender #ifdef ADB_DEBUG
298 1.1 ender if (adb_debug) {
299 1.5 scottr printf("akbd: from %d at %d (org %d) %d:", event.addr,
300 1.1 ender event.hand_id, event.def_addr, buffer[0]);
301 1.1 ender for (i = 1; i <= buffer[0]; i++)
302 1.1 ender printf(" %x", buffer[i]);
303 1.1 ender printf("\n");
304 1.1 ender }
305 1.1 ender #endif
306 1.1 ender
307 1.1 ender microtime(&event.timestamp);
308 1.1 ender
309 1.1 ender kbd_processevent(&event, ksc);
310 1.1 ender }
311 1.1 ender
312 1.1 ender /*
313 1.1 ender * Given a keyboard ADB event, record the keycodes and call the key
314 1.1 ender * repeat handler, optionally passing the event through the mouse
315 1.1 ender * button emulation handler first.
316 1.1 ender */
317 1.1 ender static void
318 1.17 chs kbd_processevent(adb_event_t *event, struct akbd_softc *ksc)
319 1.1 ender {
320 1.1 ender adb_event_t new_event;
321 1.1 ender
322 1.1 ender new_event = *event;
323 1.1 ender new_event.u.k.key = event->bytes[0];
324 1.1 ender new_event.bytes[1] = 0xff;
325 1.5 scottr #if NAED > 0
326 1.5 scottr if (adb_polling || !aed_input(&new_event))
327 1.5 scottr #endif
328 1.5 scottr #if NWSKBD > 0
329 1.9 scottr if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
330 1.10 scottr kbd_intr(&new_event, ksc);
331 1.5 scottr #else
332 1.5 scottr /* do nothing */ ;
333 1.5 scottr #endif
334 1.1 ender if (event->bytes[1] != 0xff) {
335 1.1 ender new_event.u.k.key = event->bytes[1];
336 1.1 ender new_event.bytes[0] = event->bytes[1];
337 1.1 ender new_event.bytes[1] = 0xff;
338 1.5 scottr #if NAED > 0
339 1.5 scottr if (adb_polling || !aed_input(&new_event))
340 1.5 scottr #endif
341 1.5 scottr #if NWSKBD > 0
342 1.9 scottr if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
343 1.10 scottr kbd_intr(&new_event, ksc);
344 1.5 scottr #else
345 1.5 scottr /* do nothing */ ;
346 1.5 scottr #endif
347 1.1 ender }
348 1.1 ender
349 1.1 ender }
350 1.1 ender
351 1.1 ender #ifdef notyet
352 1.1 ender /*
353 1.1 ender * Get the actual hardware LED state and convert it to softc format.
354 1.1 ender */
355 1.1 ender static u_char
356 1.17 chs getleds(int addr)
357 1.1 ender {
358 1.1 ender short cmd;
359 1.1 ender u_char buffer[9], leds;
360 1.1 ender
361 1.1 ender leds = 0x00; /* all off */
362 1.1 ender buffer[0] = 0;
363 1.1 ender
364 1.7 scottr cmd = ADBTALK(addr, 2);
365 1.10 scottr if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 &&
366 1.10 scottr buffer[0] > 0)
367 1.1 ender leds = ~(buffer[2]) & 0x07;
368 1.1 ender
369 1.1 ender return (leds);
370 1.1 ender }
371 1.1 ender
372 1.1 ender /*
373 1.1 ender * Set the keyboard LED's.
374 1.1 ender *
375 1.1 ender * Automatically translates from ioctl/softc format to the
376 1.1 ender * actual keyboard register format
377 1.1 ender */
378 1.1 ender static int
379 1.17 chs setleds(struct akbd_softc *ksc, u_char leds)
380 1.1 ender {
381 1.1 ender int addr;
382 1.1 ender short cmd;
383 1.1 ender u_char buffer[9];
384 1.1 ender
385 1.1 ender if ((leds & 0x07) == (ksc->sc_leds & 0x07))
386 1.1 ender return (0);
387 1.1 ender
388 1.2 ender addr = ksc->adbaddr;
389 1.1 ender buffer[0] = 0;
390 1.1 ender
391 1.7 scottr cmd = ADBTALK(addr, 2);
392 1.10 scottr if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0)
393 1.1 ender return (EIO);
394 1.1 ender
395 1.1 ender leds = ~leds & 0x07;
396 1.1 ender buffer[2] &= 0xf8;
397 1.1 ender buffer[2] |= leds;
398 1.1 ender
399 1.7 scottr cmd = ADBLISTEN(addr, 2);
400 1.10 scottr adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
401 1.1 ender
402 1.1 ender /* talk R2 */
403 1.7 scottr cmd = ADBTALK(addr, 2);
404 1.10 scottr if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0)
405 1.1 ender return (EIO);
406 1.1 ender
407 1.1 ender ksc->sc_leds = ~((u_int8_t)buffer[2]) & 0x07;
408 1.1 ender
409 1.1 ender if ((buffer[2] & 0xf8) != leds)
410 1.1 ender return (EIO);
411 1.1 ender else
412 1.1 ender return (0);
413 1.1 ender }
414 1.1 ender
415 1.1 ender /*
416 1.1 ender * Toggle all of the LED's on and off, just for show.
417 1.1 ender */
418 1.1 ender static void
419 1.17 chs blinkleds(struct akbd_softc *ksc)
420 1.1 ender {
421 1.1 ender int addr, i;
422 1.1 ender u_char blinkleds, origleds;
423 1.1 ender
424 1.2 ender addr = ksc->adbaddr;
425 1.1 ender origleds = getleds(addr);
426 1.1 ender blinkleds = LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK;
427 1.1 ender
428 1.1 ender (void)setleds(ksc, blinkleds);
429 1.1 ender
430 1.1 ender for (i = 0; i < 10000; i++)
431 1.1 ender delay(50);
432 1.1 ender
433 1.1 ender /* make sure that we restore the LED settings */
434 1.1 ender i = 10;
435 1.1 ender do {
436 1.1 ender (void)setleds(ksc, (u_char)0x00);
437 1.1 ender } while (setleds(ksc, (u_char)0x00) && (i-- > 0));
438 1.1 ender
439 1.1 ender return;
440 1.1 ender }
441 1.1 ender #endif
442 1.1 ender
443 1.1 ender int
444 1.17 chs akbd_is_console(void)
445 1.5 scottr {
446 1.5 scottr extern struct mac68k_machine_S mac68k_machine;
447 1.5 scottr
448 1.10 scottr return ((mac68k_machine.serial_console & 0x03) == 0);
449 1.5 scottr }
450 1.5 scottr
451 1.5 scottr int
452 1.17 chs akbd_enable(void *v, int on)
453 1.5 scottr {
454 1.5 scottr return 0;
455 1.5 scottr }
456 1.5 scottr
457 1.5 scottr void
458 1.17 chs akbd_set_leds(void *v, int on)
459 1.5 scottr {
460 1.5 scottr }
461 1.5 scottr
462 1.5 scottr int
463 1.19 christos akbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
464 1.1 ender {
465 1.5 scottr switch (cmd) {
466 1.1 ender
467 1.5 scottr case WSKBDIO_GTYPE:
468 1.5 scottr *(int *)data = 0; /* XXX */
469 1.5 scottr return 0;
470 1.5 scottr case WSKBDIO_SETLEDS:
471 1.5 scottr return 0;
472 1.5 scottr case WSKBDIO_GETLEDS:
473 1.5 scottr *(int *)data = 0;
474 1.5 scottr return 0;
475 1.5 scottr case WSKBDIO_BELL:
476 1.5 scottr case WSKBDIO_COMPLEXBELL:
477 1.5 scottr #define d ((struct wskbd_bell_data *)data)
478 1.12 thorpej mac68k_ring_bell(d->pitch, d->period * hz / 1000, 100);
479 1.5 scottr /* comes in as msec, goes out as ticks; volume ignored */
480 1.5 scottr #undef d
481 1.5 scottr return (0);
482 1.5 scottr }
483 1.5 scottr /* kbdioctl(...); */
484 1.1 ender
485 1.13 atatat return EPASSTHROUGH;
486 1.5 scottr }
487 1.5 scottr
488 1.5 scottr static int polledkey;
489 1.5 scottr extern int adb_polling;
490 1.5 scottr
491 1.5 scottr int
492 1.17 chs kbd_intr(adb_event_t *event, struct akbd_softc *sc)
493 1.5 scottr {
494 1.5 scottr int key, press, val;
495 1.5 scottr int type;
496 1.5 scottr
497 1.5 scottr key = event->u.k.key;
498 1.5 scottr press = ADBK_PRESS(key);
499 1.5 scottr val = ADBK_KEYVAL(key);
500 1.5 scottr
501 1.5 scottr type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
502 1.5 scottr
503 1.5 scottr if (key == 185) { /* Caps Lock released */
504 1.5 scottr type = WSCONS_EVENT_KEY_DOWN;
505 1.5 scottr wskbd_input(sc->sc_wskbddev, type, val);
506 1.5 scottr type = WSCONS_EVENT_KEY_UP;
507 1.5 scottr }
508 1.5 scottr
509 1.5 scottr if (adb_polling)
510 1.5 scottr polledkey = key;
511 1.5 scottr else
512 1.5 scottr wskbd_input(sc->sc_wskbddev, type, val);
513 1.5 scottr
514 1.5 scottr return 0;
515 1.5 scottr }
516 1.5 scottr
517 1.5 scottr int
518 1.17 chs akbd_cnattach(void)
519 1.5 scottr {
520 1.5 scottr wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
521 1.5 scottr
522 1.5 scottr return 0;
523 1.5 scottr }
524 1.5 scottr
525 1.5 scottr void
526 1.17 chs akbd_cngetc(void *v, u_int *type, int *data)
527 1.5 scottr {
528 1.5 scottr int intbits, key, press, val;
529 1.5 scottr int s;
530 1.5 scottr
531 1.5 scottr s = splhigh();
532 1.5 scottr
533 1.5 scottr polledkey = -1;
534 1.5 scottr adb_polling = 1;
535 1.5 scottr
536 1.5 scottr while (polledkey == -1) {
537 1.5 scottr intbits = via_reg(VIA1, vIFR);
538 1.5 scottr
539 1.5 scottr if (intbits & V1IF_ADBRDY) {
540 1.5 scottr mrg_adbintr();
541 1.5 scottr via_reg(VIA1, vIFR) = V1IF_ADBRDY;
542 1.5 scottr }
543 1.5 scottr if (intbits & 0x10) {
544 1.5 scottr mrg_pmintr();
545 1.5 scottr via_reg(VIA1, vIFR) = 0x10;
546 1.5 scottr }
547 1.1 ender }
548 1.5 scottr
549 1.5 scottr adb_polling = 0;
550 1.5 scottr splx(s);
551 1.5 scottr
552 1.5 scottr key = polledkey;
553 1.5 scottr press = ADBK_PRESS(key);
554 1.5 scottr val = ADBK_KEYVAL(key);
555 1.5 scottr
556 1.5 scottr *data = val;
557 1.5 scottr *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
558 1.5 scottr }
559 1.5 scottr
560 1.5 scottr void
561 1.17 chs akbd_cnpollc(void *v, int on)
562 1.5 scottr {
563 1.1 ender }
564