xref: /freebsd/sys/dev/adb/adb_kbd.c (revision ab40f58ccfe6c07ebefddc72f4661a52fe746353)
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/module.h>
34 #include <sys/bus.h>
35 #include <sys/conf.h>
36 #include <sys/kbio.h>
37 #include <sys/condvar.h>
38 #include <sys/callout.h>
39 #include <sys/kernel.h>
40 #include <sys/sysctl.h>
41 
42 #include <machine/bus.h>
43 
44 #include "opt_kbd.h"
45 #include <dev/kbd/kbdreg.h>
46 #include <dev/kbd/kbdtables.h>
47 #include <dev/ofw/openfirm.h>
48 #include <dev/ofw/ofw_bus.h>
49 
50 #include <vm/vm.h>
51 #include <vm/pmap.h>
52 
53 #include "adb.h"
54 
55 #define KBD_DRIVER_NAME "akbd"
56 
57 #define AKBD_EMULATE_ATKBD 1
58 
59 static int adb_kbd_probe(device_t dev);
60 static int adb_kbd_attach(device_t dev);
61 static int adb_kbd_detach(device_t dev);
62 static void akbd_repeat(void *xsc);
63 static int adb_fn_keys(SYSCTL_HANDLER_ARGS);
64 
65 static u_int adb_kbd_receive_packet(device_t dev, u_char status,
66 	u_char command, u_char reg, int len, u_char *data);
67 
68 struct adb_kbd_softc {
69 	keyboard_t sc_kbd;
70 
71 	device_t sc_dev;
72 	struct mtx sc_mutex;
73 	struct cv  sc_cv;
74 
75 	int sc_mode;
76 	int sc_state;
77 
78 	int have_led_control;
79 
80 	uint8_t buffer[8];
81 #ifdef AKBD_EMULATE_ATKBD
82 	uint8_t at_buffered_char[2];
83 #endif
84 	volatile int buffers;
85 
86 	struct callout sc_repeater;
87 	int sc_repeatstart;
88 	int sc_repeatcontinue;
89 	uint8_t last_press;
90 };
91 
92 static device_method_t adb_kbd_methods[] = {
93 	/* Device interface */
94 	DEVMETHOD(device_probe,         adb_kbd_probe),
95         DEVMETHOD(device_attach,        adb_kbd_attach),
96         DEVMETHOD(device_detach,        adb_kbd_detach),
97         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
98         DEVMETHOD(device_suspend,       bus_generic_suspend),
99         DEVMETHOD(device_resume,        bus_generic_resume),
100 
101 	/* ADB interface */
102 	DEVMETHOD(adb_receive_packet,	adb_kbd_receive_packet),
103 
104 	{ 0, 0 }
105 };
106 
107 static driver_t adb_kbd_driver = {
108 	"akbd",
109 	adb_kbd_methods,
110 	sizeof(struct adb_kbd_softc),
111 };
112 
113 static devclass_t adb_kbd_devclass;
114 
115 DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
116 
117 #ifdef AKBD_EMULATE_ATKBD
118 
119 #define	SCAN_PRESS		0x000
120 #define	SCAN_RELEASE		0x080
121 #define	SCAN_PREFIX_E0		0x100
122 #define	SCAN_PREFIX_E1		0x200
123 #define	SCAN_PREFIX_CTL		0x400
124 #define	SCAN_PREFIX_SHIFT	0x800
125 #define	SCAN_PREFIX		(SCAN_PREFIX_E0 | SCAN_PREFIX_E1 |	\
126 				SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
127 
128 static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
129 	44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
130 	10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
131 	51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
132 	100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
133 	0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
134 	66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
135 	62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
136 
137 static int
138 keycode2scancode(int keycode, int shift, int up)
139 {
140 	static const int scan[] = {
141 		/* KP enter, right ctrl, KP divide */
142 		0x1c , 0x1d , 0x35 ,
143 		/* print screen */
144 		0x37 | SCAN_PREFIX_SHIFT,
145 		/* right alt, home, up, page up, left, right, end */
146 		0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
147 		/* down, page down, insert, delete */
148 		0x50, 0x51, 0x52, 0x53,
149 		/* pause/break (see also below) */
150 		0x46,
151 		/*
152 		 * MS: left window, right window, menu
153 		 * also Sun: left meta, right meta, compose
154 		 */
155 		0x5b, 0x5c, 0x5d,
156 		/* Sun type 6 USB */
157 		/* help, stop, again, props, undo, front, copy */
158 		0x68, 0x5e, 0x5f, 0x60,	0x61, 0x62, 0x63,
159 		/* open, paste, find, cut, audiomute, audiolower, audioraise */
160 		0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
161 		/* power */
162 		0x20
163 	};
164 	int scancode;
165 
166 	scancode = keycode;
167 	if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
168 	scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
169 	/* pause/break */
170 	if ((keycode == 104) && !(shift & CTLS))
171 		scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
172 	if (shift & SHIFTS)
173 		scancode &= ~SCAN_PREFIX_SHIFT;
174 	return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
175 }
176 #endif
177 
178 /* keyboard driver declaration */
179 static int              akbd_configure(int flags);
180 static kbd_probe_t      akbd_probe;
181 static kbd_init_t       akbd_init;
182 static kbd_term_t       akbd_term;
183 static kbd_intr_t       akbd_interrupt;
184 static kbd_test_if_t    akbd_test_if;
185 static kbd_enable_t     akbd_enable;
186 static kbd_disable_t    akbd_disable;
187 static kbd_read_t       akbd_read;
188 static kbd_check_t      akbd_check;
189 static kbd_read_char_t  akbd_read_char;
190 static kbd_check_char_t akbd_check_char;
191 static kbd_ioctl_t      akbd_ioctl;
192 static kbd_lock_t       akbd_lock;
193 static kbd_clear_state_t akbd_clear_state;
194 static kbd_get_state_t  akbd_get_state;
195 static kbd_set_state_t  akbd_set_state;
196 static kbd_poll_mode_t  akbd_poll;
197 
198 keyboard_switch_t akbdsw = {
199         akbd_probe,
200         akbd_init,
201         akbd_term,
202         akbd_interrupt,
203         akbd_test_if,
204         akbd_enable,
205         akbd_disable,
206         akbd_read,
207         akbd_check,
208         akbd_read_char,
209         akbd_check_char,
210         akbd_ioctl,
211         akbd_lock,
212         akbd_clear_state,
213         akbd_get_state,
214         akbd_set_state,
215         genkbd_get_fkeystr,
216         akbd_poll,
217         genkbd_diag,
218 };
219 
220 KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
221 
222 static int
223 adb_kbd_probe(device_t dev)
224 {
225 	uint8_t type;
226 
227 	type = adb_get_device_type(dev);
228 
229 	if (type != ADB_DEVICE_KEYBOARD)
230 		return (ENXIO);
231 
232 	switch(adb_get_device_handler(dev)) {
233 	case 1:
234 		device_set_desc(dev,"Apple Standard Keyboard");
235 		break;
236 	case 2:
237 		device_set_desc(dev,"Apple Extended Keyboard");
238 		break;
239 	case 4:
240 		device_set_desc(dev,"Apple ISO Keyboard");
241 		break;
242 	case 5:
243 		device_set_desc(dev,"Apple Extended ISO Keyboard");
244 		break;
245 	case 8:
246 		device_set_desc(dev,"Apple Keyboard II");
247 		break;
248 	case 9:
249 		device_set_desc(dev,"Apple ISO Keyboard II");
250 		break;
251 	case 12:
252 		device_set_desc(dev,"PowerBook Keyboard");
253 		break;
254 	case 13:
255 		device_set_desc(dev,"PowerBook ISO Keyboard");
256 		break;
257 	case 24:
258 		device_set_desc(dev,"PowerBook Extended Keyboard");
259 		break;
260 	case 27:
261 		device_set_desc(dev,"Apple Design Keyboard");
262 		break;
263 	case 195:
264 		device_set_desc(dev,"PowerBook G3 Keyboard");
265 		break;
266 	case 196:
267 		device_set_desc(dev,"iBook Keyboard");
268 		break;
269 	default:
270 		device_set_desc(dev,"ADB Keyboard");
271 		break;
272 	}
273 
274 	return (0);
275 }
276 
277 static int
278 ms_to_ticks(int ms)
279 {
280 	if (hz > 1000)
281 		return ms*(hz/1000);
282 
283 	return ms/(1000/hz);
284 }
285 
286 static int
287 adb_kbd_attach(device_t dev)
288 {
289 	struct adb_kbd_softc *sc;
290 	keyboard_switch_t *sw;
291 	uint32_t fkeys;
292 	phandle_t handle;
293 
294 	sw = kbd_get_switch(KBD_DRIVER_NAME);
295 	if (sw == NULL) {
296 		return ENXIO;
297 	}
298 
299 	sc = device_get_softc(dev);
300 	sc->sc_dev = dev;
301 	sc->sc_mode = K_RAW;
302 	sc->sc_state = 0;
303 	sc->have_led_control = 0;
304 	sc->buffers = 0;
305 
306 	/* Try stepping forward to the extended keyboard protocol */
307 	adb_set_device_handler(dev,3);
308 
309 	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
310 	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
311 	callout_init(&sc->sc_repeater, 0);
312 
313 #ifdef AKBD_EMULATE_ATKBD
314 	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
315 	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
316             sizeof(fkey_tab) / sizeof(fkey_tab[0]));
317 #else
318 	#error ADB raw mode not implemented
319 #endif
320 
321 	KBD_FOUND_DEVICE(&sc->sc_kbd);
322 	KBD_PROBE_DONE(&sc->sc_kbd);
323 	KBD_INIT_DONE(&sc->sc_kbd);
324 	KBD_CONFIG_DONE(&sc->sc_kbd);
325 
326 	(*sw->enable)(&sc->sc_kbd);
327 
328 	kbd_register(&sc->sc_kbd);
329 
330 #ifdef KBD_INSTALL_CDEV
331 	if (kbd_attach(&sc->sc_kbd)) {
332 		adb_kbd_detach(dev);
333 		return ENXIO;
334 	}
335 #endif
336 
337 	/* Check if we can read out the LED state from
338 	   this keyboard by reading the key state register */
339 	if (adb_read_register(dev, 2, NULL) == 2)
340 		sc->have_led_control = 1;
341 
342 	adb_set_autopoll(dev,1);
343 
344 	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
345 	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
346 	    &fkeys, sizeof(fkeys)) != -1) {
347 		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
348 		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
349 		struct sysctl_ctx_list *ctx;
350 		struct sysctl_oid *tree;
351 		int i;
352 
353 		if (bootverbose)
354 			device_printf(dev, "Keyboard has embedded Fn keys\n");
355 
356 		for (i = 0; i < 12; i++) {
357 			uint32_t keyval;
358 			char buf[3];
359 			if (OF_getprop(handle, key_names[i], &keyval,
360 			    sizeof(keyval)) < 0)
361 				continue;
362 			buf[0] = 1;
363 			buf[1] = i+1;
364 			buf[2] = keyval;
365 			adb_write_register(dev, 0, 3, buf);
366 		}
367 		adb_write_register(dev, 1, 2, &(uint16_t){0});
368 
369 		ctx = device_get_sysctl_ctx(dev);
370 		tree = device_get_sysctl_tree(dev);
371 
372 		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
373 		    "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, 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 
893