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