FreeBSD/Linux Kernel Cross Reference
sys/dev/adb/adb_kbd.c
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: releng/12.0/sys/dev/adb/adb_kbd.c 326255 2017-11-27 14:52:40Z pfg $
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
Cache object: 8c06713452c839024e9daa91ffc93e82
|