xref: /freebsd/sys/dev/adb/adb_kbd.c (revision 0edc114ac0b998b06235da32bec24d55c10206cd)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (C) 2008 Nathan Whitehorn
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #include <sys/cdefs.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/lock.h>
34 #include <sys/module.h>
35 #include <sys/mutex.h>
36 #include <sys/bus.h>
37 #include <sys/conf.h>
38 #include <sys/kbio.h>
39 #include <sys/condvar.h>
40 #include <sys/callout.h>
41 #include <sys/kernel.h>
42 #include <sys/sysctl.h>
43 
44 #include <machine/bus.h>
45 
46 #include "opt_kbd.h"
47 #include <dev/kbd/kbdreg.h>
48 #include <dev/kbd/kbdtables.h>
49 #include <dev/ofw/openfirm.h>
50 #include <dev/ofw/ofw_bus.h>
51 
52 #include <vm/vm.h>
53 #include <vm/pmap.h>
54 
55 #include "adb.h"
56 
57 #define KBD_DRIVER_NAME "akbd"
58 
59 #define AKBD_EMULATE_ATKBD 1
60 
61 static int adb_kbd_probe(device_t dev);
62 static int adb_kbd_attach(device_t dev);
63 static int adb_kbd_detach(device_t dev);
64 static void akbd_repeat(void *xsc);
65 static int adb_fn_keys(SYSCTL_HANDLER_ARGS);
66 
67 static u_int adb_kbd_receive_packet(device_t dev, u_char status,
68 	u_char command, u_char reg, int len, u_char *data);
69 
70 struct adb_kbd_softc {
71 	keyboard_t sc_kbd;
72 
73 	device_t sc_dev;
74 	struct mtx sc_mutex;
75 	struct cv  sc_cv;
76 
77 	int sc_mode;
78 	int sc_state;
79 
80 	int have_led_control;
81 
82 	uint8_t buffer[8];
83 #ifdef AKBD_EMULATE_ATKBD
84 	uint8_t at_buffered_char[2];
85 #endif
86 	volatile int buffers;
87 
88 	struct callout sc_repeater;
89 	int sc_repeatstart;
90 	int sc_repeatcontinue;
91 	uint8_t last_press;
92 };
93 
94 static device_method_t adb_kbd_methods[] = {
95 	/* Device interface */
96 	DEVMETHOD(device_probe,         adb_kbd_probe),
97         DEVMETHOD(device_attach,        adb_kbd_attach),
98         DEVMETHOD(device_detach,        adb_kbd_detach),
99         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
100         DEVMETHOD(device_suspend,       bus_generic_suspend),
101         DEVMETHOD(device_resume,        bus_generic_resume),
102 
103 	/* ADB interface */
104 	DEVMETHOD(adb_receive_packet,	adb_kbd_receive_packet),
105 
106 	{ 0, 0 }
107 };
108 
109 static driver_t adb_kbd_driver = {
110 	"akbd",
111 	adb_kbd_methods,
112 	sizeof(struct adb_kbd_softc),
113 };
114 
115 static devclass_t adb_kbd_devclass;
116 
117 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
118 
119 #ifdef AKBD_EMULATE_ATKBD
120 
121 #define	SCAN_PRESS		0x000
122 #define	SCAN_RELEASE		0x080
123 #define	SCAN_PREFIX_E0		0x100
124 #define	SCAN_PREFIX_E1		0x200
125 #define	SCAN_PREFIX_CTL		0x400
126 #define	SCAN_PREFIX_SHIFT	0x800
127 #define	SCAN_PREFIX		(SCAN_PREFIX_E0 | SCAN_PREFIX_E1 |	\
128 				SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
129 
130 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
131 	44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
132 	10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
133 	51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
134 	100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
135 	0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
136 	66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
137 	62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
138 
139 static int
140 keycode2scancode(int keycode, int shift, int up)
141 {
142 	static const int scan[] = {
143 		/* KP enter, right ctrl, KP divide */
144 		0x1c , 0x1d , 0x35 ,
145 		/* print screen */
146 		0x37 | SCAN_PREFIX_SHIFT,
147 		/* right alt, home, up, page up, left, right, end */
148 		0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
149 		/* down, page down, insert, delete */
150 		0x50, 0x51, 0x52, 0x53,
151 		/* pause/break (see also below) */
152 		0x46,
153 		/*
154 		 * MS: left window, right window, menu
155 		 * also Sun: left meta, right meta, compose
156 		 */
157 		0x5b, 0x5c, 0x5d,
158 		/* Sun type 6 USB */
159 		/* help, stop, again, props, undo, front, copy */
160 		0x68, 0x5e, 0x5f, 0x60,	0x61, 0x62, 0x63,
161 		/* open, paste, find, cut, audiomute, audiolower, audioraise */
162 		0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
163 		/* power */
164 		0x20
165 	};
166 	int scancode;
167 
168 	scancode = keycode;
169 	if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
170 	scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
171 	/* pause/break */
172 	if ((keycode == 104) && !(shift & CTLS))
173 		scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
174 	if (shift & SHIFTS)
175 		scancode &= ~SCAN_PREFIX_SHIFT;
176 	return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
177 }
178 #endif
179 
180 /* keyboard driver declaration */
181 static int              akbd_configure(int flags);
182 static kbd_probe_t      akbd_probe;
183 static kbd_init_t       akbd_init;
184 static kbd_term_t       akbd_term;
185 static kbd_intr_t       akbd_interrupt;
186 static kbd_test_if_t    akbd_test_if;
187 static kbd_enable_t     akbd_enable;
188 static kbd_disable_t    akbd_disable;
189 static kbd_read_t       akbd_read;
190 static kbd_check_t      akbd_check;
191 static kbd_read_char_t  akbd_read_char;
192 static kbd_check_char_t akbd_check_char;
193 static kbd_ioctl_t      akbd_ioctl;
194 static kbd_lock_t       akbd_lock;
195 static kbd_clear_state_t akbd_clear_state;
196 static kbd_get_state_t  akbd_get_state;
197 static kbd_set_state_t  akbd_set_state;
198 static kbd_poll_mode_t  akbd_poll;
199 
200 keyboard_switch_t akbdsw = {
201         akbd_probe,
202         akbd_init,
203         akbd_term,
204         akbd_interrupt,
205         akbd_test_if,
206         akbd_enable,
207         akbd_disable,
208         akbd_read,
209         akbd_check,
210         akbd_read_char,
211         akbd_check_char,
212         akbd_ioctl,
213         akbd_lock,
214         akbd_clear_state,
215         akbd_get_state,
216         akbd_set_state,
217         genkbd_get_fkeystr,
218         akbd_poll,
219         genkbd_diag,
220 };
221 
222 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
223 
224 static int
225 adb_kbd_probe(device_t dev)
226 {
227 	uint8_t type;
228 
229 	type = adb_get_device_type(dev);
230 
231 	if (type != ADB_DEVICE_KEYBOARD)
232 		return (ENXIO);
233 
234 	switch(adb_get_device_handler(dev)) {
235 	case 1:
236 		device_set_desc(dev,"Apple Standard Keyboard");
237 		break;
238 	case 2:
239 		device_set_desc(dev,"Apple Extended Keyboard");
240 		break;
241 	case 4:
242 		device_set_desc(dev,"Apple ISO Keyboard");
243 		break;
244 	case 5:
245 		device_set_desc(dev,"Apple Extended ISO Keyboard");
246 		break;
247 	case 8:
248 		device_set_desc(dev,"Apple Keyboard II");
249 		break;
250 	case 9:
251 		device_set_desc(dev,"Apple ISO Keyboard II");
252 		break;
253 	case 12:
254 		device_set_desc(dev,"PowerBook Keyboard");
255 		break;
256 	case 13:
257 		device_set_desc(dev,"PowerBook ISO Keyboard");
258 		break;
259 	case 24:
260 		device_set_desc(dev,"PowerBook Extended Keyboard");
261 		break;
262 	case 27:
263 		device_set_desc(dev,"Apple Design Keyboard");
264 		break;
265 	case 195:
266 		device_set_desc(dev,"PowerBook G3 Keyboard");
267 		break;
268 	case 196:
269 		device_set_desc(dev,"iBook Keyboard");
270 		break;
271 	default:
272 		device_set_desc(dev,"ADB Keyboard");
273 		break;
274 	}
275 
276 	return (0);
277 }
278 
279 static int
280 ms_to_ticks(int ms)
281 {
282 	if (hz > 1000)
283 		return ms*(hz/1000);
284 
285 	return ms/(1000/hz);
286 }
287 
288 static int
289 adb_kbd_attach(device_t dev)
290 {
291 	struct adb_kbd_softc *sc;
292 	keyboard_switch_t *sw;
293 	uint32_t fkeys;
294 	phandle_t handle;
295 
296 	sw = kbd_get_switch(KBD_DRIVER_NAME);
297 	if (sw == NULL) {
298 		return ENXIO;
299 	}
300 
301 	sc = device_get_softc(dev);
302 	sc->sc_dev = dev;
303 	sc->sc_mode = K_RAW;
304 	sc->sc_state = 0;
305 	sc->have_led_control = 0;
306 	sc->buffers = 0;
307 
308 	/* Try stepping forward to the extended keyboard protocol */
309 	adb_set_device_handler(dev,3);
310 
311 	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
312 	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
313 	callout_init(&sc->sc_repeater, 0);
314 
315 #ifdef AKBD_EMULATE_ATKBD
316 	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
317 	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
318             sizeof(fkey_tab) / sizeof(fkey_tab[0]));
319 #else
320 	#error ADB raw mode not implemented
321 #endif
322 
323 	KBD_FOUND_DEVICE(&sc->sc_kbd);
324 	KBD_PROBE_DONE(&sc->sc_kbd);
325 	KBD_INIT_DONE(&sc->sc_kbd);
326 	KBD_CONFIG_DONE(&sc->sc_kbd);
327 
328 	(*sw->enable)(&sc->sc_kbd);
329 
330 	kbd_register(&sc->sc_kbd);
331 
332 #ifdef KBD_INSTALL_CDEV
333 	if (kbd_attach(&sc->sc_kbd)) {
334 		adb_kbd_detach(dev);
335 		return ENXIO;
336 	}
337 #endif
338 
339 	/* Check if we can read out the LED state from
340 	   this keyboard by reading the key state register */
341 	if (adb_read_register(dev, 2, NULL) == 2)
342 		sc->have_led_control = 1;
343 
344 	adb_set_autopoll(dev,1);
345 
346 	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
347 	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
348 	    &fkeys, sizeof(fkeys)) != -1) {
349 		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
350 		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
351 		struct sysctl_ctx_list *ctx;
352 		struct sysctl_oid *tree;
353 		int i;
354 
355 		if (bootverbose)
356 			device_printf(dev, "Keyboard has embedded Fn keys\n");
357 
358 		for (i = 0; i < 12; i++) {
359 			uint32_t keyval;
360 			char buf[3];
361 			if (OF_getprop(handle, key_names[i], &keyval,
362 			    sizeof(keyval)) < 0)
363 				continue;
364 			buf[0] = 1;
365 			buf[1] = i+1;
366 			buf[2] = keyval;
367 			adb_write_register(dev, 0, 3, buf);
368 		}
369 		adb_write_register(dev, 1, 2, &(uint16_t){0});
370 
371 		ctx = device_get_sysctl_ctx(dev);
372 		tree = device_get_sysctl_tree(dev);
373 
374 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
375 		    "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
376 		    0, adb_fn_keys, "I",
377 		    "Set the Fn keys to be their F-key type as default");
378 	}
379 
380 	return (0);
381 }
382 
383 static int
384 adb_kbd_detach(device_t dev)
385 {
386 	struct adb_kbd_softc *sc;
387 	keyboard_t *kbd;
388 
389 	sc = device_get_softc(dev);
390 
391 	adb_set_autopoll(dev,0);
392 	callout_stop(&sc->sc_repeater);
393 
394 	mtx_lock(&sc->sc_mutex);
395 
396 	kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
397 	          device_get_unit(dev)));
398 
399 	kbdd_disable(kbd);
400 
401 #ifdef KBD_INSTALL_CDEV
402 	kbd_detach(kbd);
403 #endif
404 
405 	kbdd_term(kbd);
406 
407 	mtx_unlock(&sc->sc_mutex);
408 
409 	mtx_destroy(&sc->sc_mutex);
410 	cv_destroy(&sc->sc_cv);
411 
412 	return (0);
413 }
414 
415 static u_int
416 adb_kbd_receive_packet(device_t dev, u_char status,
417     u_char command, u_char reg, int len, u_char *data)
418 {
419 	struct adb_kbd_softc *sc;
420 
421 	sc = device_get_softc(dev);
422 
423 	if (command != ADB_COMMAND_TALK)
424 		return 0;
425 
426 	if (reg != 0 || len != 2)
427 		return (0);
428 
429 	mtx_lock(&sc->sc_mutex);
430 		/* 0x7f is always the power button */
431 		if (data[0] == 0x7f) {
432 			devctl_notify("PMU", "Button", "pressed", NULL);
433 			mtx_unlock(&sc->sc_mutex);
434 			return (0);
435 		} else if (data[0] == 0xff) {
436 			mtx_unlock(&sc->sc_mutex);
437 			return (0);	/* Ignore power button release. */
438 		}
439 		if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
440 			/* Fake the down/up cycle for caps lock */
441 			sc->buffer[sc->buffers++] = data[0] & 0x7f;
442 			sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
443 		} else {
444 			sc->buffer[sc->buffers++] = data[0];
445 		}
446 		if (sc->buffer[sc->buffers-1] < 0xff)
447 			sc->last_press = sc->buffer[sc->buffers-1];
448 
449 		if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
450 			/* Fake the down/up cycle for caps lock */
451 			sc->buffer[sc->buffers++] = data[1] & 0x7f;
452 			sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
453 		} else {
454 			sc->buffer[sc->buffers++] = data[1];
455 		}
456 
457 		if (sc->buffer[sc->buffers-1] < 0xff)
458 			sc->last_press = sc->buffer[sc->buffers-1];
459 
460 		/* Stop any existing key repeating */
461 		callout_stop(&sc->sc_repeater);
462 
463 		/* Schedule a repeat callback on keydown */
464 		if (!(sc->last_press & (1 << 7))) {
465 			callout_reset(&sc->sc_repeater,
466 			    ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
467 		}
468 	mtx_unlock(&sc->sc_mutex);
469 
470 	cv_broadcast(&sc->sc_cv);
471 
472 	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
473 		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
474 			 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
475 	}
476 
477 	return (0);
478 }
479 
480 static void
481 akbd_repeat(void *xsc) {
482 	struct adb_kbd_softc *sc = xsc;
483 	int notify_kbd = 0;
484 
485 	/* Fake an up/down key repeat so long as we have the
486 	   free buffers */
487 	mtx_lock(&sc->sc_mutex);
488 		if (sc->buffers < 7) {
489 			sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
490 			sc->buffer[sc->buffers++] = sc->last_press;
491 
492 			notify_kbd = 1;
493 		}
494 	mtx_unlock(&sc->sc_mutex);
495 
496 	if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
497 	    && KBD_IS_BUSY(&sc->sc_kbd)) {
498 		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
499 		    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
500 	}
501 
502 	/* Reschedule the callout */
503 	callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
504 	    akbd_repeat, sc);
505 }
506 
507 static int
508 akbd_configure(int flags)
509 {
510 	return 0;
511 }
512 
513 static int
514 akbd_probe(int unit, void *arg, int flags)
515 {
516 	return 0;
517 }
518 
519 static int
520 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
521 {
522 	return 0;
523 }
524 
525 static int
526 akbd_term(keyboard_t *kbd)
527 {
528 	return 0;
529 }
530 
531 static int
532 akbd_interrupt(keyboard_t *kbd, void *arg)
533 {
534 	return 0;
535 }
536 
537 static int
538 akbd_test_if(keyboard_t *kbd)
539 {
540 	return 0;
541 }
542 
543 static int
544 akbd_enable(keyboard_t *kbd)
545 {
546 	KBD_ACTIVATE(kbd);
547 	return (0);
548 }
549 
550 static int
551 akbd_disable(keyboard_t *kbd)
552 {
553 	struct adb_kbd_softc *sc;
554 	sc = (struct adb_kbd_softc *)(kbd);
555 
556 	callout_stop(&sc->sc_repeater);
557 	KBD_DEACTIVATE(kbd);
558 	return (0);
559 }
560 
561 static int
562 akbd_read(keyboard_t *kbd, int wait)
563 {
564 	return (0);
565 }
566 
567 static int
568 akbd_check(keyboard_t *kbd)
569 {
570 	struct adb_kbd_softc *sc;
571 
572 	if (!KBD_IS_ACTIVE(kbd))
573 		return (FALSE);
574 
575 	sc = (struct adb_kbd_softc *)(kbd);
576 
577 	mtx_lock(&sc->sc_mutex);
578 #ifdef AKBD_EMULATE_ATKBD
579 		if (sc->at_buffered_char[0]) {
580 			mtx_unlock(&sc->sc_mutex);
581 			return (TRUE);
582 		}
583 #endif
584 
585 		if (sc->buffers > 0) {
586 			mtx_unlock(&sc->sc_mutex);
587 			return (TRUE);
588 		}
589 	mtx_unlock(&sc->sc_mutex);
590 
591 	return (FALSE);
592 }
593 
594 static u_int
595 akbd_read_char(keyboard_t *kbd, int wait)
596 {
597 	struct adb_kbd_softc *sc;
598 	uint16_t key;
599 	uint8_t adb_code;
600 	int i;
601 
602 	sc = (struct adb_kbd_softc *)(kbd);
603 
604 	mtx_lock(&sc->sc_mutex);
605 
606 #if defined(AKBD_EMULATE_ATKBD)
607 	if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
608 		key = sc->at_buffered_char[0];
609 		if (key & SCAN_PREFIX) {
610 			sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
611 			key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
612 		} else {
613 			sc->at_buffered_char[0] = sc->at_buffered_char[1];
614 			sc->at_buffered_char[1] = 0;
615 		}
616 
617 		mtx_unlock(&sc->sc_mutex);
618 
619 		return (key);
620 	}
621 #endif
622 
623 	if (!sc->buffers && wait)
624 		cv_wait(&sc->sc_cv,&sc->sc_mutex);
625 
626 	if (!sc->buffers) {
627 		mtx_unlock(&sc->sc_mutex);
628 		return (NOKEY);
629 	}
630 
631 	adb_code = sc->buffer[0];
632 
633 	for (i = 1; i < sc->buffers; i++)
634 		sc->buffer[i-1] = sc->buffer[i];
635 
636 	sc->buffers--;
637 
638 	#ifdef AKBD_EMULATE_ATKBD
639 		key = adb_to_at_scancode_map[adb_code & 0x7f];
640 		if (sc->sc_mode == K_CODE) {
641 			/* Add the key-release bit */
642 			key |= adb_code & 0x80;
643 		} else if (sc->sc_mode == K_RAW) {
644 			/*
645 			 * In the raw case, we have to emulate the gross
646 			 * variable-length AT keyboard thing. Since this code
647 			 * is copied from sunkbd, which is the same code
648 			 * as ukbd, it might be nice to have this centralized.
649 			 */
650 
651 			key = keycode2scancode(key,
652 			    0, adb_code & 0x80);
653 
654 			if (key & SCAN_PREFIX) {
655 				if (key & SCAN_PREFIX_CTL) {
656 					sc->at_buffered_char[0] =
657 					    0x1d | (key & SCAN_RELEASE);
658 					sc->at_buffered_char[1] =
659 					    key & ~SCAN_PREFIX;
660 				} else if (key & SCAN_PREFIX_SHIFT) {
661 					sc->at_buffered_char[0] =
662 					    0x2a | (key & SCAN_RELEASE);
663 					sc->at_buffered_char[1] =
664 					    key & ~SCAN_PREFIX_SHIFT;
665 				} else {
666 					sc->at_buffered_char[0] =
667 					    key & ~SCAN_PREFIX;
668 					sc->at_buffered_char[1] = 0;
669 				}
670 
671 				key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
672 			}
673 		}
674 	#else
675 		key = adb_code;
676 	#endif
677 
678 	mtx_unlock(&sc->sc_mutex);
679 
680 	return (key);
681 }
682 
683 static int
684 akbd_check_char(keyboard_t *kbd)
685 {
686 	if (!KBD_IS_ACTIVE(kbd))
687 		return (FALSE);
688 
689 	return (akbd_check(kbd));
690 }
691 
692 static int
693 set_typematic(keyboard_t *kbd, int code)
694 {
695 	/* These numbers are in microseconds, so convert to ticks */
696 
697 	static int delays[] = { 250, 500, 750, 1000 };
698 	static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
699 				68,  76,  84,  92, 100, 110, 118, 126,
700 				136, 152, 168, 184, 200, 220, 236, 252,
701 				272, 304, 336, 368, 400, 440, 472, 504 };
702 
703 	if (code & ~0x7f)
704 		return EINVAL;
705 	kbd->kb_delay1 = delays[(code >> 5) & 3];
706 	kbd->kb_delay2 = rates[code & 0x1f];
707 	return 0;
708 }
709 
710 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
711 {
712 	struct adb_kbd_softc *sc;
713 	uint16_t r2;
714 	int error;
715 
716 	sc = (struct adb_kbd_softc *)(kbd);
717 	error = 0;
718 
719 	switch (cmd) {
720 	case KDGKBMODE:
721 		*(int *)data = sc->sc_mode;
722 		break;
723 	case KDSKBMODE:
724 		switch (*(int *)data) {
725 		case K_XLATE:
726 			if (sc->sc_mode != K_XLATE) {
727 				/* make lock key state and LED state match */
728 				sc->sc_state &= ~LOCK_MASK;
729 				sc->sc_state |= KBD_LED_VAL(kbd);
730 			}
731 			/* FALLTHROUGH */
732 		case K_RAW:
733 		case K_CODE:
734 			if (sc->sc_mode != *(int *)data)
735 				sc->sc_mode = *(int *)data;
736 			break;
737 		default:
738 			error = EINVAL;
739 			break;
740 		}
741 
742 		break;
743 
744 	case KDGETLED:
745 		*(int *)data = KBD_LED_VAL(kbd);
746 		break;
747 
748 	case KDSKBSTATE:
749 		if (*(int *)data & ~LOCK_MASK) {
750 			error = EINVAL;
751 			break;
752 		}
753 		sc->sc_state &= ~LOCK_MASK;
754 		sc->sc_state |= *(int *)data;
755 
756 		/* FALLTHROUGH */
757 
758 	case KDSETLED:
759 		KBD_LED_VAL(kbd) = *(int *)data;
760 
761 		if (!sc->have_led_control)
762 			break;
763 
764 		r2 = (~0 & 0x04) | 3;
765 
766 		if (*(int *)data & NLKED)
767 			r2 &= ~1;
768 		if (*(int *)data & CLKED)
769 			r2 &= ~2;
770 		if (*(int *)data & SLKED)
771 			r2 &= ~4;
772 
773 		adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
774 			sizeof(uint16_t),(u_char *)&r2);
775 
776 		break;
777 
778 	case KDGKBSTATE:
779 		*(int *)data = sc->sc_state & LOCK_MASK;
780 		break;
781 
782 	case KDSETREPEAT:
783 		if (!KBD_HAS_DEVICE(kbd))
784 			return 0;
785 		if (((int *)data)[1] < 0)
786 			return EINVAL;
787 		if (((int *)data)[0] < 0)
788 			return EINVAL;
789 		else if (((int *)data)[0] == 0)  /* fastest possible value */
790 			kbd->kb_delay1 = 200;
791 		else
792 			kbd->kb_delay1 = ((int *)data)[0];
793 		kbd->kb_delay2 = ((int *)data)[1];
794 
795 		break;
796 
797 	case KDSETRAD:
798 		error = set_typematic(kbd, *(int *)data);
799 		break;
800 
801 	case PIO_KEYMAP:
802 	case OPIO_KEYMAP:
803 	case PIO_KEYMAPENT:
804 	case PIO_DEADKEYMAP:
805 	default:
806 		return (genkbd_commonioctl(kbd, cmd, data));
807 	}
808 
809 	return (error);
810 }
811 
812 static int akbd_lock(keyboard_t *kbd, int lock)
813 {
814 	return (0);
815 }
816 
817 static void akbd_clear_state(keyboard_t *kbd)
818 {
819 	struct adb_kbd_softc *sc;
820 
821 	sc = (struct adb_kbd_softc *)(kbd);
822 
823 	mtx_lock(&sc->sc_mutex);
824 
825 	sc->buffers = 0;
826 	callout_stop(&sc->sc_repeater);
827 
828 #if defined(AKBD_EMULATE_ATKBD)
829 	sc->at_buffered_char[0] = 0;
830 	sc->at_buffered_char[1] = 0;
831 #endif
832 	mtx_unlock(&sc->sc_mutex);
833 }
834 
835 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
836 {
837 	return (0);
838 }
839 
840 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
841 {
842 	return (0);
843 }
844 
845 static int akbd_poll(keyboard_t *kbd, int on)
846 {
847 	return (0);
848 }
849 
850 static int
851 akbd_modevent(module_t mod, int type, void *data)
852 {
853 	switch (type) {
854 	case MOD_LOAD:
855 		kbd_add_driver(&akbd_kbd_driver);
856 		break;
857 
858 	case MOD_UNLOAD:
859 		kbd_delete_driver(&akbd_kbd_driver);
860 		break;
861 
862 	default:
863 		return (EOPNOTSUPP);
864 	}
865 
866 	return (0);
867 }
868 
869 static int
870 adb_fn_keys(SYSCTL_HANDLER_ARGS)
871 {
872 	struct adb_kbd_softc *sc = arg1;
873 	int error;
874 	uint16_t is_fn_enabled;
875 	unsigned int is_fn_enabled_sysctl;
876 
877 	adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
878 	is_fn_enabled &= 1;
879 	is_fn_enabled_sysctl = is_fn_enabled;
880 	error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
881 
882 	if (error || !req->newptr)
883 		return (error);
884 
885 	is_fn_enabled = is_fn_enabled_sysctl;
886 	if (is_fn_enabled != 1 && is_fn_enabled != 0)
887 		return (EINVAL);
888 
889 	adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
890 	return (0);
891 }
892 
893 DEV_MODULE(akbd, akbd_modevent, NULL);
894 
895