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