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
61static int adb_kbd_probe(device_t dev);
62static int adb_kbd_attach(device_t dev);
63static int adb_kbd_detach(device_t dev);
64static void akbd_repeat(void *xsc);
65static int adb_fn_keys(SYSCTL_HANDLER_ARGS);
66
67static 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
70struct 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
94static 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
108static driver_t adb_kbd_driver = {
109	"akbd",
110	adb_kbd_methods,
111	sizeof(struct adb_kbd_softc),
112};
113
114static devclass_t adb_kbd_devclass;
115
116DRIVER_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
129static 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
138static int
139keycode2scancode(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 */
180static int              akbd_configure(int flags);
181static kbd_probe_t      akbd_probe;
182static kbd_init_t       akbd_init;
183static kbd_term_t       akbd_term;
184static kbd_intr_t       akbd_interrupt;
185static kbd_test_if_t    akbd_test_if;
186static kbd_enable_t     akbd_enable;
187static kbd_disable_t    akbd_disable;
188static kbd_read_t       akbd_read;
189static kbd_check_t      akbd_check;
190static kbd_read_char_t  akbd_read_char;
191static kbd_check_char_t akbd_check_char;
192static kbd_ioctl_t      akbd_ioctl;
193static kbd_lock_t       akbd_lock;
194static kbd_clear_state_t akbd_clear_state;
195static kbd_get_state_t  akbd_get_state;
196static kbd_set_state_t  akbd_set_state;
197static kbd_poll_mode_t  akbd_poll;
198
199keyboard_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
219KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
220
221static int
222adb_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
276static int
277ms_to_ticks(int ms)
278{
279	if (hz > 1000)
280		return ms*(hz/1000);
281
282	return ms/(1000/hz);
283}
284
285static int
286adb_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
381static int
382adb_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
413static u_int
414adb_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
478static void
479akbd_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
505static int
506akbd_configure(int flags)
507{
508	return 0;
509}
510
511static int
512akbd_probe(int unit, void *arg, int flags)
513{
514	return 0;
515}
516
517static int
518akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
519{
520	return 0;
521}
522
523static int
524akbd_term(keyboard_t *kbd)
525{
526	return 0;
527}
528
529static int
530akbd_interrupt(keyboard_t *kbd, void *arg)
531{
532	return 0;
533}
534
535static int
536akbd_test_if(keyboard_t *kbd)
537{
538	return 0;
539}
540
541static int
542akbd_enable(keyboard_t *kbd)
543{
544	KBD_ACTIVATE(kbd);
545	return (0);
546}
547
548static int
549akbd_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
559static int
560akbd_read(keyboard_t *kbd, int wait)
561{
562	return (0);
563}
564
565static int
566akbd_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
592static u_int
593akbd_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
681static int
682akbd_check_char(keyboard_t *kbd)
683{
684	if (!KBD_IS_ACTIVE(kbd))
685		return (FALSE);
686
687	return (akbd_check(kbd));
688}
689
690static int
691set_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
708static 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
810static int akbd_lock(keyboard_t *kbd, int lock)
811{
812	return (0);
813}
814
815static 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
833static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
834{
835	return (0);
836}
837
838static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
839{
840	return (0);
841}
842
843static int akbd_poll(keyboard_t *kbd, int on)
844{
845	return (0);
846}
847
848static int
849akbd_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
867static int
868adb_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
891DEV_MODULE(akbd, akbd_modevent, NULL);
892