adb_kbd.c revision 261068
1193323Sed/*-
2193323Sed * Copyright (C) 2008 Nathan Whitehorn
3193323Sed * All rights reserved.
4193323Sed *
5193323Sed * Redistribution and use in source and binary forms, with or without
6193323Sed * modification, are permitted provided that the following conditions
7193323Sed * are met:
8193323Sed * 1. Redistributions of source code must retain the above copyright
9193323Sed *    notice, this list of conditions and the following disclaimer.
10193323Sed * 2. Redistributions in binary form must reproduce the above copyright
11193323Sed *    notice, this list of conditions and the following disclaimer in the
12193323Sed *    documentation and/or other materials provided with the distribution.
13193323Sed *
14193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15193323Sed * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16193323Sed * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17193323Sed * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18193323Sed * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19193323Sed * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20193323Sed * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21193323Sed * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22193323Sed * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23193323Sed * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24193323Sed *
25193323Sed * $FreeBSD: head/sys/dev/adb/adb_kbd.c 261068 2014-01-23 01:09:33Z jhibbits $
26193323Sed */
27193323Sed
28193323Sed#include <sys/cdefs.h>
29193323Sed#include <sys/param.h>
30193323Sed#include <sys/systm.h>
31193323Sed#include <sys/module.h>
32193323Sed#include <sys/bus.h>
33193323Sed#include <sys/conf.h>
34193323Sed#include <sys/kbio.h>
35193323Sed#include <sys/condvar.h>
36193323Sed#include <sys/callout.h>
37193323Sed#include <sys/kernel.h>
38193323Sed#include <sys/sysctl.h>
39193323Sed
40193323Sed#include <machine/bus.h>
41193323Sed
42193323Sed#include "opt_kbd.h"
43193323Sed#include <dev/kbd/kbdreg.h>
44198090Srdivacky#include <dev/kbd/kbdtables.h>
45193323Sed#include <dev/ofw/openfirm.h>
46193323Sed#include <dev/ofw/ofw_bus.h>
47193323Sed
48193323Sed#include <vm/vm.h>
49193323Sed#include <vm/pmap.h>
50193323Sed
51193323Sed#include "adb.h"
52193323Sed
53193323Sed#define KBD_DRIVER_NAME "akbd"
54193323Sed
55193323Sed#define AKBD_EMULATE_ATKBD 1
56193323Sed
57193323Sedstatic int adb_kbd_probe(device_t dev);
58193323Sedstatic int adb_kbd_attach(device_t dev);
59193323Sedstatic int adb_kbd_detach(device_t dev);
60193323Sedstatic void akbd_repeat(void *xsc);
61193323Sedstatic int adb_fn_keys(SYSCTL_HANDLER_ARGS);
62198090Srdivacky
63198090Srdivackystatic u_int adb_kbd_receive_packet(device_t dev, u_char status,
64193323Sed	u_char command, u_char reg, int len, u_char *data);
65193323Sed
66193323Sedstruct adb_kbd_softc {
67193323Sed	keyboard_t sc_kbd;
68193323Sed
69193323Sed	device_t sc_dev;
70193323Sed	struct mtx sc_mutex;
71193323Sed	struct cv  sc_cv;
72193323Sed
73193323Sed	int sc_mode;
74193323Sed	int sc_state;
75193323Sed
76193323Sed	int have_led_control;
77193323Sed
78193323Sed	uint8_t buffer[8];
79193323Sed#ifdef AKBD_EMULATE_ATKBD
80193323Sed	uint8_t at_buffered_char[2];
81193323Sed#endif
82193323Sed	volatile int buffers;
83195340Sed
84193323Sed	struct callout sc_repeater;
85198090Srdivacky	int sc_repeatstart;
86198090Srdivacky	int sc_repeatcontinue;
87198090Srdivacky	uint8_t last_press;
88193323Sed};
89193323Sed
90193323Sedstatic device_method_t adb_kbd_methods[] = {
91193323Sed	/* Device interface */
92193323Sed	DEVMETHOD(device_probe,         adb_kbd_probe),
93193323Sed        DEVMETHOD(device_attach,        adb_kbd_attach),
94195340Sed        DEVMETHOD(device_detach,        adb_kbd_detach),
95193323Sed        DEVMETHOD(device_shutdown,      bus_generic_shutdown),
96193323Sed        DEVMETHOD(device_suspend,       bus_generic_suspend),
97193323Sed        DEVMETHOD(device_resume,        bus_generic_resume),
98193323Sed
99193323Sed	/* ADB interface */
100193323Sed	DEVMETHOD(adb_receive_packet,	adb_kbd_receive_packet),
101193323Sed
102193323Sed	{ 0, 0 }
103193323Sed};
104193323Sed
105193323Sedstatic driver_t adb_kbd_driver = {
106193323Sed	"akbd",
107193323Sed	adb_kbd_methods,
108193323Sed	sizeof(struct adb_kbd_softc),
109193323Sed};
110193323Sed
111193323Sedstatic devclass_t adb_kbd_devclass;
112193323Sed
113193323SedDRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
114193323Sed
115193323Sed#ifdef AKBD_EMULATE_ATKBD
116193323Sed
117193323Sed#define	SCAN_PRESS		0x000
118193323Sed#define	SCAN_RELEASE		0x080
119193323Sed#define	SCAN_PREFIX_E0		0x100
120193323Sed#define	SCAN_PREFIX_E1		0x200
121193323Sed#define	SCAN_PREFIX_CTL		0x400
122193323Sed#define	SCAN_PREFIX_SHIFT	0x800
123193323Sed#define	SCAN_PREFIX		(SCAN_PREFIX_E0 | SCAN_PREFIX_E1 |	\
124193323Sed				SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
125193323Sed
126193323Sedstatic const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
127193323Sed	44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
128193323Sed	10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
129193323Sed	51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
130193323Sed	100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
131193323Sed	0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
132193323Sed	66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
133193323Sed	62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
134193323Sed
135193323Sedstatic int
136193323Sedkeycode2scancode(int keycode, int shift, int up)
137193323Sed{
138193323Sed	static const int scan[] = {
139193323Sed		/* KP enter, right ctrl, KP divide */
140193323Sed		0x1c , 0x1d , 0x35 ,
141193323Sed		/* print screen */
142193323Sed		0x37 | SCAN_PREFIX_SHIFT,
143193323Sed		/* right alt, home, up, page up, left, right, end */
144193323Sed		0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
145193323Sed		/* down, page down, insert, delete */
146193323Sed		0x50, 0x51, 0x52, 0x53,
147193323Sed		/* pause/break (see also below) */
148193323Sed		0x46,
149193323Sed		/*
150193323Sed		 * MS: left window, right window, menu
151193323Sed		 * also Sun: left meta, right meta, compose
152193323Sed		 */
153193323Sed		0x5b, 0x5c, 0x5d,
154193323Sed		/* Sun type 6 USB */
155193323Sed		/* help, stop, again, props, undo, front, copy */
156193323Sed		0x68, 0x5e, 0x5f, 0x60,	0x61, 0x62, 0x63,
157198090Srdivacky		/* open, paste, find, cut, audiomute, audiolower, audioraise */
158198090Srdivacky		0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
159198090Srdivacky		/* power */
160198090Srdivacky		0x20
161198090Srdivacky	};
162198090Srdivacky	int scancode;
163198090Srdivacky
164198090Srdivacky	scancode = keycode;
165198090Srdivacky	if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0])))
166198090Srdivacky	scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
167198090Srdivacky	/* pause/break */
168198090Srdivacky	if ((keycode == 104) && !(shift & CTLS))
169198090Srdivacky		scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
170198090Srdivacky	if (shift & SHIFTS)
171198090Srdivacky		scancode &= ~SCAN_PREFIX_SHIFT;
172198090Srdivacky	return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
173193323Sed}
174193323Sed#endif
175193323Sed
176193323Sed/* keyboard driver declaration */
177193323Sedstatic int              akbd_configure(int flags);
178193323Sedstatic kbd_probe_t      akbd_probe;
179193323Sedstatic kbd_init_t       akbd_init;
180193323Sedstatic kbd_term_t       akbd_term;
181193323Sedstatic kbd_intr_t       akbd_interrupt;
182193323Sedstatic kbd_test_if_t    akbd_test_if;
183193323Sedstatic kbd_enable_t     akbd_enable;
184193323Sedstatic kbd_disable_t    akbd_disable;
185193323Sedstatic kbd_read_t       akbd_read;
186193323Sedstatic kbd_check_t      akbd_check;
187193323Sedstatic kbd_read_char_t  akbd_read_char;
188193323Sedstatic kbd_check_char_t akbd_check_char;
189193323Sedstatic kbd_ioctl_t      akbd_ioctl;
190193323Sedstatic kbd_lock_t       akbd_lock;
191193323Sedstatic kbd_clear_state_t akbd_clear_state;
192193323Sedstatic kbd_get_state_t  akbd_get_state;
193193323Sedstatic kbd_set_state_t  akbd_set_state;
194193323Sedstatic kbd_poll_mode_t  akbd_poll;
195193323Sed
196193323Sedkeyboard_switch_t akbdsw = {
197193323Sed        akbd_probe,
198193323Sed        akbd_init,
199193323Sed        akbd_term,
200193323Sed        akbd_interrupt,
201193323Sed        akbd_test_if,
202193323Sed        akbd_enable,
203193323Sed        akbd_disable,
204193323Sed        akbd_read,
205193323Sed        akbd_check,
206193323Sed        akbd_read_char,
207193323Sed        akbd_check_char,
208193323Sed        akbd_ioctl,
209193323Sed        akbd_lock,
210193323Sed        akbd_clear_state,
211193323Sed        akbd_get_state,
212193323Sed        akbd_set_state,
213193323Sed        genkbd_get_fkeystr,
214193323Sed        akbd_poll,
215193323Sed        genkbd_diag,
216193323Sed};
217193323Sed
218193323SedKEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
219193323Sed
220193323Sedstatic int
221193323Sedadb_kbd_probe(device_t dev)
222193323Sed{
223193323Sed	uint8_t type;
224193323Sed
225193323Sed	type = adb_get_device_type(dev);
226193323Sed
227193323Sed	if (type != ADB_DEVICE_KEYBOARD)
228193323Sed		return (ENXIO);
229193323Sed
230193323Sed	switch(adb_get_device_handler(dev)) {
231193323Sed	case 1:
232193323Sed		device_set_desc(dev,"Apple Standard Keyboard");
233193323Sed		break;
234193323Sed	case 2:
235193323Sed		device_set_desc(dev,"Apple Extended Keyboard");
236193323Sed		break;
237198090Srdivacky	case 4:
238193323Sed		device_set_desc(dev,"Apple ISO Keyboard");
239193323Sed		break;
240193323Sed	case 5:
241193323Sed		device_set_desc(dev,"Apple Extended ISO Keyboard");
242193323Sed		break;
243193323Sed	case 8:
244193323Sed		device_set_desc(dev,"Apple Keyboard II");
245193323Sed		break;
246193323Sed	case 9:
247193323Sed		device_set_desc(dev,"Apple ISO Keyboard II");
248193323Sed		break;
249193323Sed	case 12:
250193323Sed		device_set_desc(dev,"PowerBook Keyboard");
251193323Sed		break;
252193323Sed	case 13:
253193323Sed		device_set_desc(dev,"PowerBook ISO Keyboard");
254193323Sed		break;
255193323Sed	case 24:
256193323Sed		device_set_desc(dev,"PowerBook Extended Keyboard");
257193323Sed		break;
258193323Sed	case 27:
259193323Sed		device_set_desc(dev,"Apple Design Keyboard");
260193323Sed		break;
261193323Sed	case 195:
262193323Sed		device_set_desc(dev,"PowerBook G3 Keyboard");
263193323Sed		break;
264193323Sed	case 196:
265193323Sed		device_set_desc(dev,"iBook Keyboard");
266193323Sed		break;
267193323Sed	default:
268193323Sed		device_set_desc(dev,"ADB Keyboard");
269193323Sed		break;
270193323Sed	}
271193323Sed
272193323Sed	return (0);
273193323Sed}
274193323Sed
275193323Sedstatic int
276193323Sedms_to_ticks(int ms)
277193323Sed{
278193323Sed	if (hz > 1000)
279193323Sed		return ms*(hz/1000);
280193323Sed
281193323Sed	return ms/(1000/hz);
282193323Sed}
283193323Sed
284193323Sedstatic int
285193323Sedadb_kbd_attach(device_t dev)
286193323Sed{
287193323Sed	struct adb_kbd_softc *sc;
288193323Sed	keyboard_switch_t *sw;
289193323Sed	uint32_t fkeys;
290193323Sed	phandle_t handle;
291198090Srdivacky
292198090Srdivacky	sw = kbd_get_switch(KBD_DRIVER_NAME);
293193323Sed	if (sw == NULL) {
294193323Sed		return ENXIO;
295193323Sed	}
296193323Sed
297193323Sed	sc = device_get_softc(dev);
298193323Sed	sc->sc_dev = dev;
299193323Sed	sc->sc_mode = K_RAW;
300193323Sed	sc->sc_state = 0;
301193323Sed	sc->have_led_control = 0;
302193323Sed	sc->buffers = 0;
303198090Srdivacky
304193323Sed	/* Try stepping forward to the extended keyboard protocol */
305193323Sed	adb_set_device_handler(dev,3);
306193323Sed
307193323Sed	mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
308193323Sed	cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
309193323Sed	callout_init(&sc->sc_repeater, 0);
310193323Sed
311193323Sed#ifdef AKBD_EMULATE_ATKBD
312193323Sed	kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
313193323Sed	kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
314193323Sed            sizeof(fkey_tab) / sizeof(fkey_tab[0]));
315193323Sed#else
316193323Sed	#error ADB raw mode not implemented
317193323Sed#endif
318193323Sed
319193323Sed	KBD_FOUND_DEVICE(&sc->sc_kbd);
320193323Sed	KBD_PROBE_DONE(&sc->sc_kbd);
321193323Sed	KBD_INIT_DONE(&sc->sc_kbd);
322193323Sed	KBD_CONFIG_DONE(&sc->sc_kbd);
323193323Sed
324193323Sed	(*sw->enable)(&sc->sc_kbd);
325193323Sed
326193323Sed	kbd_register(&sc->sc_kbd);
327193323Sed
328193323Sed#ifdef KBD_INSTALL_CDEV
329193323Sed	if (kbd_attach(&sc->sc_kbd)) {
330193323Sed		adb_kbd_detach(dev);
331193323Sed		return ENXIO;
332193323Sed	}
333198090Srdivacky#endif
334198090Srdivacky
335198090Srdivacky	/* Check if we can read out the LED state from
336198090Srdivacky	   this keyboard by reading the key state register */
337198090Srdivacky	if (adb_read_register(dev, 2, NULL) == 2)
338198090Srdivacky		sc->have_led_control = 1;
339193323Sed
340193323Sed	adb_set_autopoll(dev,1);
341195340Sed
342198090Srdivacky	handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
343195340Sed	if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
344195340Sed	    &fkeys, sizeof(fkeys)) != -1) {
345193323Sed		static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
346195340Sed		    "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
347195340Sed		struct sysctl_ctx_list *ctx;
348195340Sed		struct sysctl_oid *tree;
349193323Sed		int i;
350193323Sed
351193323Sed		if (bootverbose)
352193323Sed			device_printf(dev, "Keyboard has embedded Fn keys\n");
353193323Sed
354193323Sed		for (i = 0; i < 12; i++) {
355193323Sed			uint32_t keyval;
356193323Sed			char buf[3];
357193323Sed			if (OF_getprop(handle, key_names[i], &keyval,
358195340Sed			    sizeof(keyval)) < 0)
359193323Sed				continue;
360193323Sed			buf[0] = 1;
361193323Sed			buf[1] = i+1;
362193323Sed			buf[2] = keyval;
363193323Sed			adb_write_register(dev, 0, 3, buf);
364193323Sed		}
365193323Sed		adb_write_register(dev, 1, 2, &(uint16_t){0});
366193323Sed
367193323Sed		ctx = device_get_sysctl_ctx(dev);
368193323Sed		tree = device_get_sysctl_tree(dev);
369193323Sed
370193323Sed		SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
371193323Sed		    "fn_keys_function_as_primary", CTLTYPE_INT | CTLFLAG_RW, sc,
372193323Sed		    0, adb_fn_keys, "I",
373193323Sed		    "Set the Fn keys to be their F-key type as default");
374193323Sed	}
375193323Sed
376193323Sed	return (0);
377193323Sed}
378193323Sed
379193323Sedstatic int
380193323Sedadb_kbd_detach(device_t dev)
381193574Sed{
382193323Sed	struct adb_kbd_softc *sc;
383193323Sed	keyboard_t *kbd;
384193323Sed
385193323Sed	sc = device_get_softc(dev);
386193323Sed
387193323Sed	adb_set_autopoll(dev,0);
388193323Sed	callout_stop(&sc->sc_repeater);
389193323Sed
390193323Sed	mtx_lock(&sc->sc_mutex);
391193323Sed
392198090Srdivacky	kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
393198090Srdivacky	          device_get_unit(dev)));
394198090Srdivacky
395198090Srdivacky	kbdd_disable(kbd);
396198090Srdivacky
397198090Srdivacky#ifdef KBD_INSTALL_CDEV
398198090Srdivacky	kbd_detach(kbd);
399198090Srdivacky#endif
400198090Srdivacky
401198090Srdivacky	kbdd_term(kbd);
402198090Srdivacky
403198090Srdivacky	mtx_unlock(&sc->sc_mutex);
404198090Srdivacky
405198090Srdivacky	mtx_destroy(&sc->sc_mutex);
406198090Srdivacky	cv_destroy(&sc->sc_cv);
407198090Srdivacky
408198090Srdivacky	return (0);
409198090Srdivacky}
410198090Srdivacky
411198090Srdivackystatic u_int
412198090Srdivackyadb_kbd_receive_packet(device_t dev, u_char status,
413198090Srdivacky    u_char command, u_char reg, int len, u_char *data)
414198090Srdivacky{
415198090Srdivacky	struct adb_kbd_softc *sc;
416198090Srdivacky
417198090Srdivacky	sc = device_get_softc(dev);
418198090Srdivacky
419198090Srdivacky	if (command != ADB_COMMAND_TALK)
420198090Srdivacky		return 0;
421198090Srdivacky
422198090Srdivacky	if (reg != 0 || len != 2)
423198090Srdivacky		return (0);
424198090Srdivacky
425198090Srdivacky	mtx_lock(&sc->sc_mutex);
426198090Srdivacky		/* 0x7f is always the power button */
427198090Srdivacky		if (data[0] == 0x7f && devctl_process_running()) {
428198090Srdivacky			devctl_notify("PMU", "Button", "pressed", NULL);
429198090Srdivacky			mtx_unlock(&sc->sc_mutex);
430198090Srdivacky			return (0);
431198090Srdivacky		} else if (data[0] == 0xff) {
432198090Srdivacky			mtx_unlock(&sc->sc_mutex);
433198090Srdivacky			return (0);	/* Ignore power button release. */
434198090Srdivacky		}
435198090Srdivacky		if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
436198090Srdivacky			/* Fake the down/up cycle for caps lock */
437198090Srdivacky			sc->buffer[sc->buffers++] = data[0] & 0x7f;
438198090Srdivacky			sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
439198090Srdivacky		} else {
440198090Srdivacky			sc->buffer[sc->buffers++] = data[0];
441198090Srdivacky		}
442198090Srdivacky		if (sc->buffer[sc->buffers-1] < 0xff)
443198090Srdivacky			sc->last_press = sc->buffer[sc->buffers-1];
444198090Srdivacky
445198090Srdivacky		if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
446198090Srdivacky			/* Fake the down/up cycle for caps lock */
447198090Srdivacky			sc->buffer[sc->buffers++] = data[1] & 0x7f;
448198090Srdivacky			sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
449198090Srdivacky		} else {
450198090Srdivacky			sc->buffer[sc->buffers++] = data[1];
451198090Srdivacky		}
452198090Srdivacky
453198090Srdivacky		if (sc->buffer[sc->buffers-1] < 0xff)
454198090Srdivacky			sc->last_press = sc->buffer[sc->buffers-1];
455198090Srdivacky
456198090Srdivacky		/* Stop any existing key repeating */
457193323Sed		callout_stop(&sc->sc_repeater);
458193323Sed
459193323Sed		/* Schedule a repeat callback on keydown */
460193323Sed		if (!(sc->last_press & (1 << 7))) {
461			callout_reset(&sc->sc_repeater,
462			    ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
463		}
464	mtx_unlock(&sc->sc_mutex);
465
466	cv_broadcast(&sc->sc_cv);
467
468	if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
469		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
470			 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
471	}
472
473	return (0);
474}
475
476static void
477akbd_repeat(void *xsc) {
478	struct adb_kbd_softc *sc = xsc;
479	int notify_kbd = 0;
480
481	/* Fake an up/down key repeat so long as we have the
482	   free buffers */
483	mtx_lock(&sc->sc_mutex);
484		if (sc->buffers < 7) {
485			sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
486			sc->buffer[sc->buffers++] = sc->last_press;
487
488			notify_kbd = 1;
489		}
490	mtx_unlock(&sc->sc_mutex);
491
492	if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
493	    && KBD_IS_BUSY(&sc->sc_kbd)) {
494		sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
495		    KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
496	}
497
498	/* Reschedule the callout */
499	callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
500	    akbd_repeat, sc);
501}
502
503static int
504akbd_configure(int flags)
505{
506	return 0;
507}
508
509static int
510akbd_probe(int unit, void *arg, int flags)
511{
512	return 0;
513}
514
515static int
516akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
517{
518	return 0;
519}
520
521static int
522akbd_term(keyboard_t *kbd)
523{
524	return 0;
525}
526
527static int
528akbd_interrupt(keyboard_t *kbd, void *arg)
529{
530	return 0;
531}
532
533static int
534akbd_test_if(keyboard_t *kbd)
535{
536	return 0;
537}
538
539static int
540akbd_enable(keyboard_t *kbd)
541{
542	KBD_ACTIVATE(kbd);
543	return (0);
544}
545
546static int
547akbd_disable(keyboard_t *kbd)
548{
549	struct adb_kbd_softc *sc;
550	sc = (struct adb_kbd_softc *)(kbd);
551
552	callout_stop(&sc->sc_repeater);
553	KBD_DEACTIVATE(kbd);
554	return (0);
555}
556
557static int
558akbd_read(keyboard_t *kbd, int wait)
559{
560	return (0);
561}
562
563static int
564akbd_check(keyboard_t *kbd)
565{
566	struct adb_kbd_softc *sc;
567
568	if (!KBD_IS_ACTIVE(kbd))
569		return (FALSE);
570
571	sc = (struct adb_kbd_softc *)(kbd);
572
573	mtx_lock(&sc->sc_mutex);
574#ifdef AKBD_EMULATE_ATKBD
575		if (sc->at_buffered_char[0]) {
576			mtx_unlock(&sc->sc_mutex);
577			return (TRUE);
578		}
579#endif
580
581		if (sc->buffers > 0) {
582			mtx_unlock(&sc->sc_mutex);
583			return (TRUE);
584		}
585	mtx_unlock(&sc->sc_mutex);
586
587	return (FALSE);
588}
589
590static u_int
591akbd_read_char(keyboard_t *kbd, int wait)
592{
593	struct adb_kbd_softc *sc;
594	uint16_t key;
595	uint8_t adb_code;
596	int i;
597
598	sc = (struct adb_kbd_softc *)(kbd);
599
600	mtx_lock(&sc->sc_mutex);
601
602#if defined(AKBD_EMULATE_ATKBD)
603	if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
604		key = sc->at_buffered_char[0];
605		if (key & SCAN_PREFIX) {
606			sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
607			key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
608		} else {
609			sc->at_buffered_char[0] = sc->at_buffered_char[1];
610			sc->at_buffered_char[1] = 0;
611		}
612
613		mtx_unlock(&sc->sc_mutex);
614
615		return (key);
616	}
617#endif
618
619	if (!sc->buffers && wait)
620		cv_wait(&sc->sc_cv,&sc->sc_mutex);
621
622	if (!sc->buffers) {
623		mtx_unlock(&sc->sc_mutex);
624		return (NOKEY);
625	}
626
627	adb_code = sc->buffer[0];
628
629	for (i = 1; i < sc->buffers; i++)
630		sc->buffer[i-1] = sc->buffer[i];
631
632	sc->buffers--;
633
634	#ifdef AKBD_EMULATE_ATKBD
635		key = adb_to_at_scancode_map[adb_code & 0x7f];
636		if (sc->sc_mode == K_CODE) {
637			/* Add the key-release bit */
638			key |= adb_code & 0x80;
639		} else if (sc->sc_mode == K_RAW) {
640			/*
641			 * In the raw case, we have to emulate the gross
642			 * variable-length AT keyboard thing. Since this code
643			 * is copied from sunkbd, which is the same code
644			 * as ukbd, it might be nice to have this centralized.
645			 */
646
647			key = keycode2scancode(key,
648			    0, adb_code & 0x80);
649
650			if (key & SCAN_PREFIX) {
651				if (key & SCAN_PREFIX_CTL) {
652					sc->at_buffered_char[0] =
653					    0x1d | (key & SCAN_RELEASE);
654					sc->at_buffered_char[1] =
655					    key & ~SCAN_PREFIX;
656				} else if (key & SCAN_PREFIX_SHIFT) {
657					sc->at_buffered_char[0] =
658					    0x2a | (key & SCAN_RELEASE);
659					sc->at_buffered_char[1] =
660					    key & ~SCAN_PREFIX_SHIFT;
661				} else {
662					sc->at_buffered_char[0] =
663					    key & ~SCAN_PREFIX;
664					sc->at_buffered_char[1] = 0;
665				}
666
667				key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
668			}
669		}
670	#else
671		key = adb_code;
672	#endif
673
674	mtx_unlock(&sc->sc_mutex);
675
676	return (key);
677}
678
679static int
680akbd_check_char(keyboard_t *kbd)
681{
682	if (!KBD_IS_ACTIVE(kbd))
683		return (FALSE);
684
685	return (akbd_check(kbd));
686}
687
688static int
689set_typematic(keyboard_t *kbd, int code)
690{
691	/* These numbers are in microseconds, so convert to ticks */
692
693	static int delays[] = { 250, 500, 750, 1000 };
694	static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
695				68,  76,  84,  92, 100, 110, 118, 126,
696				136, 152, 168, 184, 200, 220, 236, 252,
697				272, 304, 336, 368, 400, 440, 472, 504 };
698
699	if (code & ~0x7f)
700		return EINVAL;
701	kbd->kb_delay1 = delays[(code >> 5) & 3];
702	kbd->kb_delay2 = rates[code & 0x1f];
703	return 0;
704}
705
706static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
707{
708	struct adb_kbd_softc *sc;
709	uint16_t r2;
710	int error;
711
712	sc = (struct adb_kbd_softc *)(kbd);
713	error = 0;
714
715	switch (cmd) {
716	case KDGKBMODE:
717		*(int *)data = sc->sc_mode;
718		break;
719	case KDSKBMODE:
720		switch (*(int *)data) {
721		case K_XLATE:
722			if (sc->sc_mode != K_XLATE) {
723				/* make lock key state and LED state match */
724				sc->sc_state &= ~LOCK_MASK;
725				sc->sc_state |= KBD_LED_VAL(kbd);
726			}
727			/* FALLTHROUGH */
728		case K_RAW:
729		case K_CODE:
730			if (sc->sc_mode != *(int *)data)
731				sc->sc_mode = *(int *)data;
732			break;
733		default:
734			error = EINVAL;
735			break;
736		}
737
738		break;
739
740	case KDGETLED:
741		*(int *)data = KBD_LED_VAL(kbd);
742		break;
743
744	case KDSKBSTATE:
745		if (*(int *)data & ~LOCK_MASK) {
746			error = EINVAL;
747			break;
748		}
749		sc->sc_state &= ~LOCK_MASK;
750		sc->sc_state |= *(int *)data;
751
752		/* FALLTHROUGH */
753
754	case KDSETLED:
755		KBD_LED_VAL(kbd) = *(int *)data;
756
757		if (!sc->have_led_control)
758			break;
759
760		r2 = (~0 & 0x04) | 3;
761
762		if (*(int *)data & NLKED)
763			r2 &= ~1;
764		if (*(int *)data & CLKED)
765			r2 &= ~2;
766		if (*(int *)data & SLKED)
767			r2 &= ~4;
768
769		adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
770			sizeof(uint16_t),(u_char *)&r2);
771
772		break;
773
774	case KDGKBSTATE:
775		*(int *)data = sc->sc_state & LOCK_MASK;
776		break;
777
778	case KDSETREPEAT:
779		if (!KBD_HAS_DEVICE(kbd))
780			return 0;
781		if (((int *)data)[1] < 0)
782			return EINVAL;
783		if (((int *)data)[0] < 0)
784			return EINVAL;
785		else if (((int *)data)[0] == 0)  /* fastest possible value */
786			kbd->kb_delay1 = 200;
787		else
788			kbd->kb_delay1 = ((int *)data)[0];
789		kbd->kb_delay2 = ((int *)data)[1];
790
791		break;
792
793	case KDSETRAD:
794		error = set_typematic(kbd, *(int *)data);
795		break;
796
797	case PIO_KEYMAP:
798	case OPIO_KEYMAP:
799	case PIO_KEYMAPENT:
800	case PIO_DEADKEYMAP:
801	default:
802		return (genkbd_commonioctl(kbd, cmd, data));
803	}
804
805	return (error);
806}
807
808static int akbd_lock(keyboard_t *kbd, int lock)
809{
810	return (0);
811}
812
813static void akbd_clear_state(keyboard_t *kbd)
814{
815	struct adb_kbd_softc *sc;
816
817	sc = (struct adb_kbd_softc *)(kbd);
818
819	mtx_lock(&sc->sc_mutex);
820
821	sc->buffers = 0;
822	callout_stop(&sc->sc_repeater);
823
824#if defined(AKBD_EMULATE_ATKBD)
825	sc->at_buffered_char[0] = 0;
826	sc->at_buffered_char[1] = 0;
827#endif
828	mtx_unlock(&sc->sc_mutex);
829}
830
831static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
832{
833	return (0);
834}
835
836static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
837{
838	return (0);
839}
840
841static int akbd_poll(keyboard_t *kbd, int on)
842{
843	return (0);
844}
845
846static int
847akbd_modevent(module_t mod, int type, void *data)
848{
849	switch (type) {
850	case MOD_LOAD:
851		kbd_add_driver(&akbd_kbd_driver);
852		break;
853
854	case MOD_UNLOAD:
855		kbd_delete_driver(&akbd_kbd_driver);
856		break;
857
858	default:
859		return (EOPNOTSUPP);
860	}
861
862	return (0);
863}
864
865static int
866adb_fn_keys(SYSCTL_HANDLER_ARGS)
867{
868	struct adb_kbd_softc *sc = arg1;
869	int error;
870	uint16_t is_fn_enabled;
871	unsigned int is_fn_enabled_sysctl;
872
873	adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
874	is_fn_enabled &= 1;
875	is_fn_enabled_sysctl = is_fn_enabled;
876	error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
877
878	if (error || !req->newptr)
879		return (error);
880
881	is_fn_enabled = is_fn_enabled_sysctl;
882	if (is_fn_enabled != 1 && is_fn_enabled != 0)
883		return (EINVAL);
884
885	adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
886	return (0);
887}
888
889DEV_MODULE(akbd, akbd_modevent, NULL);
890
891