xref: /freebsd/sys/dev/adb/adb_kbd.c (revision 62cfcf62f627e5093fb37026a6d8c98e4d2ef04c)
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         .probe =	akbd_probe,
202         .init =		akbd_init,
203         .term =		akbd_term,
204         .intr =		akbd_interrupt,
205         .test_if =	akbd_test_if,
206         .enable =	akbd_enable,
207         .disable =	akbd_disable,
208         .read =		akbd_read,
209         .check =	akbd_check,
210         .read_char =	akbd_read_char,
211         .check_char =	akbd_check_char,
212         .ioctl =	akbd_ioctl,
213         .lock =		akbd_lock,
214         .clear_state =	akbd_clear_state,
215         .get_state =	akbd_get_state,
216         .set_state =	akbd_set_state,
217         .poll =		akbd_poll,
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",
374 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc,
375 		    0, adb_fn_keys, "I",
376 		    "Set the Fn keys to be their F-key type as default");
377 	}
378 
379 	return (0);
380 }
381 
382 static int
383 adb_kbd_detach(device_t dev)
384 {
385 	struct adb_kbd_softc *sc;
386 	keyboard_t *kbd;
387 
388 	sc = device_get_softc(dev);
389 
390 	adb_set_autopoll(dev,0);
391 	callout_stop(&sc->sc_repeater);
392 
393 	mtx_lock(&sc->sc_mutex);
394 
395 	kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
396 	          device_get_unit(dev)));
397 
398 	kbdd_disable(kbd);
399 
400 #ifdef KBD_INSTALL_CDEV
401 	kbd_detach(kbd);
402 #endif
403 
404 	kbdd_term(kbd);
405 
406 	mtx_unlock(&sc->sc_mutex);
407 
408 	mtx_destroy(&sc->sc_mutex);
409 	cv_destroy(&sc->sc_cv);
410 
411 	return (0);
412 }
413 
414 static u_int
415 adb_kbd_receive_packet(device_t dev, u_char status,
416     u_char command, u_char reg, int len, u_char *data)
417 {
418 	struct adb_kbd_softc *sc;
419 
420 	sc = device_get_softc(dev);
421 
422 	if (command != ADB_COMMAND_TALK)
423 		return 0;
424 
425 	if (reg != 0 || len != 2)
426 		return (0);
427 
428 	mtx_lock(&sc->sc_mutex);
429 		/* 0x7f is always the power button */
430 		if (data[0] == 0x7f) {
431 			devctl_notify("PMU", "Button", "pressed", NULL);
432 			mtx_unlock(&sc->sc_mutex);
433 			return (0);
434 		} else if (data[0] == 0xff) {
435 			mtx_unlock(&sc->sc_mutex);
436 			return (0);	/* Ignore power button release. */
437 		}
438 		if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
439 			/* Fake the down/up cycle for caps lock */
440 			sc->buffer[sc->buffers++] = data[0] & 0x7f;
441 			sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
442 		} else {
443 			sc->buffer[sc->buffers++] = data[0];
444 		}
445 		if (sc->buffer[sc->buffers-1] < 0xff)
446 			sc->last_press = sc->buffer[sc->buffers-1];
447 
448 		if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
449 			/* Fake the down/up cycle for caps lock */
450 			sc->buffer[sc->buffers++] = data[1] & 0x7f;
451 			sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
452 		} else {
453 			sc->buffer[sc->buffers++] = data[1];
454 		}
455 
456 		if (sc->buffer[sc->buffers-1] < 0xff)
457 			sc->last_press = sc->buffer[sc->buffers-1];
458 
459 		/* Stop any existing key repeating */
460 		callout_stop(&sc->sc_repeater);
461 
462 		/* Schedule a repeat callback on keydown */
463 		if (!(sc->last_press & (1 << 7))) {
464 			callout_reset(&sc->sc_repeater,
465 			    ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
466 		}
467 	mtx_unlock(&sc->sc_mutex);
468 
469 	cv_broadcast(&sc->sc_cv);
470 
471 	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
472 		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
473 			 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
474 	}
475 
476 	return (0);
477 }
478 
479 static void
480 akbd_repeat(void *xsc) {
481 	struct adb_kbd_softc *sc = xsc;
482 	int notify_kbd = 0;
483 
484 	/* Fake an up/down key repeat so long as we have the
485 	   free buffers */
486 	mtx_lock(&sc->sc_mutex);
487 		if (sc->buffers < 7) {
488 			sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
489 			sc->buffer[sc->buffers++] = sc->last_press;
490 
491 			notify_kbd = 1;
492 		}
493 	mtx_unlock(&sc->sc_mutex);
494 
495 	if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
496 	    && KBD_IS_BUSY(&sc->sc_kbd)) {
497 		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
498 		    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
499 	}
500 
501 	/* Reschedule the callout */
502 	callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
503 	    akbd_repeat, sc);
504 }
505 
506 static int
507 akbd_configure(int flags)
508 {
509 	return 0;
510 }
511 
512 static int
513 akbd_probe(int unit, void *arg, int flags)
514 {
515 	return 0;
516 }
517 
518 static int
519 akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
520 {
521 	return 0;
522 }
523 
524 static int
525 akbd_term(keyboard_t *kbd)
526 {
527 	return 0;
528 }
529 
530 static int
531 akbd_interrupt(keyboard_t *kbd, void *arg)
532 {
533 	return 0;
534 }
535 
536 static int
537 akbd_test_if(keyboard_t *kbd)
538 {
539 	return 0;
540 }
541 
542 static int
543 akbd_enable(keyboard_t *kbd)
544 {
545 	KBD_ACTIVATE(kbd);
546 	return (0);
547 }
548 
549 static int
550 akbd_disable(keyboard_t *kbd)
551 {
552 	struct adb_kbd_softc *sc;
553 	sc = (struct adb_kbd_softc *)(kbd);
554 
555 	callout_stop(&sc->sc_repeater);
556 	KBD_DEACTIVATE(kbd);
557 	return (0);
558 }
559 
560 static int
561 akbd_read(keyboard_t *kbd, int wait)
562 {
563 	return (0);
564 }
565 
566 static int
567 akbd_check(keyboard_t *kbd)
568 {
569 	struct adb_kbd_softc *sc;
570 
571 	if (!KBD_IS_ACTIVE(kbd))
572 		return (FALSE);
573 
574 	sc = (struct adb_kbd_softc *)(kbd);
575 
576 	mtx_lock(&sc->sc_mutex);
577 #ifdef AKBD_EMULATE_ATKBD
578 		if (sc->at_buffered_char[0]) {
579 			mtx_unlock(&sc->sc_mutex);
580 			return (TRUE);
581 		}
582 #endif
583 
584 		if (sc->buffers > 0) {
585 			mtx_unlock(&sc->sc_mutex);
586 			return (TRUE);
587 		}
588 	mtx_unlock(&sc->sc_mutex);
589 
590 	return (FALSE);
591 }
592 
593 static u_int
594 akbd_read_char(keyboard_t *kbd, int wait)
595 {
596 	struct adb_kbd_softc *sc;
597 	uint16_t key;
598 	uint8_t adb_code;
599 	int i;
600 
601 	sc = (struct adb_kbd_softc *)(kbd);
602 
603 	mtx_lock(&sc->sc_mutex);
604 
605 #if defined(AKBD_EMULATE_ATKBD)
606 	if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
607 		key = sc->at_buffered_char[0];
608 		if (key & SCAN_PREFIX) {
609 			sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
610 			key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
611 		} else {
612 			sc->at_buffered_char[0] = sc->at_buffered_char[1];
613 			sc->at_buffered_char[1] = 0;
614 		}
615 
616 		mtx_unlock(&sc->sc_mutex);
617 
618 		return (key);
619 	}
620 #endif
621 
622 	if (!sc->buffers && wait)
623 		cv_wait(&sc->sc_cv,&sc->sc_mutex);
624 
625 	if (!sc->buffers) {
626 		mtx_unlock(&sc->sc_mutex);
627 		return (NOKEY);
628 	}
629 
630 	adb_code = sc->buffer[0];
631 
632 	for (i = 1; i < sc->buffers; i++)
633 		sc->buffer[i-1] = sc->buffer[i];
634 
635 	sc->buffers--;
636 
637 	#ifdef AKBD_EMULATE_ATKBD
638 		key = adb_to_at_scancode_map[adb_code & 0x7f];
639 		if (sc->sc_mode == K_CODE) {
640 			/* Add the key-release bit */
641 			key |= adb_code & 0x80;
642 		} else if (sc->sc_mode == K_RAW) {
643 			/*
644 			 * In the raw case, we have to emulate the gross
645 			 * variable-length AT keyboard thing. Since this code
646 			 * is copied from sunkbd, which is the same code
647 			 * as ukbd, it might be nice to have this centralized.
648 			 */
649 
650 			key = keycode2scancode(key,
651 			    0, adb_code & 0x80);
652 
653 			if (key & SCAN_PREFIX) {
654 				if (key & SCAN_PREFIX_CTL) {
655 					sc->at_buffered_char[0] =
656 					    0x1d | (key & SCAN_RELEASE);
657 					sc->at_buffered_char[1] =
658 					    key & ~SCAN_PREFIX;
659 				} else if (key & SCAN_PREFIX_SHIFT) {
660 					sc->at_buffered_char[0] =
661 					    0x2a | (key & SCAN_RELEASE);
662 					sc->at_buffered_char[1] =
663 					    key & ~SCAN_PREFIX_SHIFT;
664 				} else {
665 					sc->at_buffered_char[0] =
666 					    key & ~SCAN_PREFIX;
667 					sc->at_buffered_char[1] = 0;
668 				}
669 
670 				key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
671 			}
672 		}
673 	#else
674 		key = adb_code;
675 	#endif
676 
677 	mtx_unlock(&sc->sc_mutex);
678 
679 	return (key);
680 }
681 
682 static int
683 akbd_check_char(keyboard_t *kbd)
684 {
685 	if (!KBD_IS_ACTIVE(kbd))
686 		return (FALSE);
687 
688 	return (akbd_check(kbd));
689 }
690 
691 static int
692 set_typematic(keyboard_t *kbd, int code)
693 {
694 	/* These numbers are in microseconds, so convert to ticks */
695 
696 	static int delays[] = { 250, 500, 750, 1000 };
697 	static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
698 				68,  76,  84,  92, 100, 110, 118, 126,
699 				136, 152, 168, 184, 200, 220, 236, 252,
700 				272, 304, 336, 368, 400, 440, 472, 504 };
701 
702 	if (code & ~0x7f)
703 		return EINVAL;
704 	kbd->kb_delay1 = delays[(code >> 5) & 3];
705 	kbd->kb_delay2 = rates[code & 0x1f];
706 	return 0;
707 }
708 
709 static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
710 {
711 	struct adb_kbd_softc *sc;
712 	uint16_t r2;
713 	int error;
714 
715 	sc = (struct adb_kbd_softc *)(kbd);
716 	error = 0;
717 
718 	switch (cmd) {
719 	case KDGKBMODE:
720 		*(int *)data = sc->sc_mode;
721 		break;
722 	case KDSKBMODE:
723 		switch (*(int *)data) {
724 		case K_XLATE:
725 			if (sc->sc_mode != K_XLATE) {
726 				/* make lock key state and LED state match */
727 				sc->sc_state &= ~LOCK_MASK;
728 				sc->sc_state |= KBD_LED_VAL(kbd);
729 			}
730 			/* FALLTHROUGH */
731 		case K_RAW:
732 		case K_CODE:
733 			if (sc->sc_mode != *(int *)data)
734 				sc->sc_mode = *(int *)data;
735 			break;
736 		default:
737 			error = EINVAL;
738 			break;
739 		}
740 
741 		break;
742 
743 	case KDGETLED:
744 		*(int *)data = KBD_LED_VAL(kbd);
745 		break;
746 
747 	case KDSKBSTATE:
748 		if (*(int *)data & ~LOCK_MASK) {
749 			error = EINVAL;
750 			break;
751 		}
752 		sc->sc_state &= ~LOCK_MASK;
753 		sc->sc_state |= *(int *)data;
754 
755 		/* FALLTHROUGH */
756 
757 	case KDSETLED:
758 		KBD_LED_VAL(kbd) = *(int *)data;
759 
760 		if (!sc->have_led_control)
761 			break;
762 
763 		r2 = (~0 & 0x04) | 3;
764 
765 		if (*(int *)data & NLKED)
766 			r2 &= ~1;
767 		if (*(int *)data & CLKED)
768 			r2 &= ~2;
769 		if (*(int *)data & SLKED)
770 			r2 &= ~4;
771 
772 		adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
773 			sizeof(uint16_t),(u_char *)&r2);
774 
775 		break;
776 
777 	case KDGKBSTATE:
778 		*(int *)data = sc->sc_state & LOCK_MASK;
779 		break;
780 
781 	case KDSETREPEAT:
782 		if (!KBD_HAS_DEVICE(kbd))
783 			return 0;
784 		if (((int *)data)[1] < 0)
785 			return EINVAL;
786 		if (((int *)data)[0] < 0)
787 			return EINVAL;
788 		else if (((int *)data)[0] == 0)  /* fastest possible value */
789 			kbd->kb_delay1 = 200;
790 		else
791 			kbd->kb_delay1 = ((int *)data)[0];
792 		kbd->kb_delay2 = ((int *)data)[1];
793 
794 		break;
795 
796 	case KDSETRAD:
797 		error = set_typematic(kbd, *(int *)data);
798 		break;
799 
800 	case PIO_KEYMAP:
801 	case OPIO_KEYMAP:
802 	case PIO_KEYMAPENT:
803 	case PIO_DEADKEYMAP:
804 	default:
805 		return (genkbd_commonioctl(kbd, cmd, data));
806 	}
807 
808 	return (error);
809 }
810 
811 static int akbd_lock(keyboard_t *kbd, int lock)
812 {
813 	return (0);
814 }
815 
816 static void akbd_clear_state(keyboard_t *kbd)
817 {
818 	struct adb_kbd_softc *sc;
819 
820 	sc = (struct adb_kbd_softc *)(kbd);
821 
822 	mtx_lock(&sc->sc_mutex);
823 
824 	sc->buffers = 0;
825 	callout_stop(&sc->sc_repeater);
826 
827 #if defined(AKBD_EMULATE_ATKBD)
828 	sc->at_buffered_char[0] = 0;
829 	sc->at_buffered_char[1] = 0;
830 #endif
831 	mtx_unlock(&sc->sc_mutex);
832 }
833 
834 static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
835 {
836 	return (0);
837 }
838 
839 static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
840 {
841 	return (0);
842 }
843 
844 static int akbd_poll(keyboard_t *kbd, int on)
845 {
846 	return (0);
847 }
848 
849 static int
850 akbd_modevent(module_t mod, int type, void *data)
851 {
852 	switch (type) {
853 	case MOD_LOAD:
854 		kbd_add_driver(&akbd_kbd_driver);
855 		break;
856 
857 	case MOD_UNLOAD:
858 		kbd_delete_driver(&akbd_kbd_driver);
859 		break;
860 
861 	default:
862 		return (EOPNOTSUPP);
863 	}
864 
865 	return (0);
866 }
867 
868 static int
869 adb_fn_keys(SYSCTL_HANDLER_ARGS)
870 {
871 	struct adb_kbd_softc *sc = arg1;
872 	int error;
873 	uint16_t is_fn_enabled;
874 	unsigned int is_fn_enabled_sysctl;
875 
876 	adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
877 	is_fn_enabled &= 1;
878 	is_fn_enabled_sysctl = is_fn_enabled;
879 	error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
880 
881 	if (error || !req->newptr)
882 		return (error);
883 
884 	is_fn_enabled = is_fn_enabled_sysctl;
885 	if (is_fn_enabled != 1 && is_fn_enabled != 0)
886 		return (EINVAL);
887 
888 	adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
889 	return (0);
890 }
891 
892 DEV_MODULE(akbd, akbd_modevent, NULL);
893 
894