Deleted Added
sdiff udiff text old ( 185724 ) new ( 186906 )
full compact
1/*-
2 * Copyright (C) 2008 Nathan Whitehorn
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * $FreeBSD: head/sys/dev/adb/adb_kbd.c 186906 2009-01-08 17:47:45Z nwhitehorn $
26 */
27
28#include <sys/cdefs.h>
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/module.h>
32#include <sys/bus.h>
33#include <sys/conf.h>
34#include <sys/kbio.h>
35#include <sys/condvar.h>
36#include <sys/callout.h>
37#include <sys/kernel.h>
38
39#include <machine/bus.h>
40
41#include "opt_kbd.h"
42#include <dev/kbd/kbdreg.h>
43#include <dev/kbd/kbdtables.h>
44
45#include <vm/vm.h>
46#include <vm/pmap.h>
47
48#include "adb.h"
49
50#define KBD_DRIVER_NAME "akbd"
51
52#define AKBD_EMULATE_ATKBD 1
53
54static int adb_kbd_probe(device_t dev);
55static int adb_kbd_attach(device_t dev);
56static int adb_kbd_detach(device_t dev);
57static void akbd_repeat(void *xsc);
58
59static u_int adb_kbd_receive_packet(device_t dev, u_char status,
60 u_char command, u_char reg, int len, u_char *data);
61
62struct adb_kbd_softc {
63 keyboard_t sc_kbd;
64
65 device_t sc_dev;
66 struct mtx sc_mutex;
67 struct cv sc_cv;
68
69 int sc_mode;
70 int sc_state;
71
72 int have_led_control;
73
74 uint8_t buffer[8];
75#ifdef AKBD_EMULATE_ATKBD
76 uint8_t at_buffered_char[2];
77#endif
78 volatile int buffers;
79
80 struct callout sc_repeater;
81 int sc_repeatstart;
82 int sc_repeatcontinue;
83 uint8_t last_press;
84};
85
86static device_method_t adb_kbd_methods[] = {
87 /* Device interface */
88 DEVMETHOD(device_probe, adb_kbd_probe),
89 DEVMETHOD(device_attach, adb_kbd_attach),
90 DEVMETHOD(device_detach, adb_kbd_detach),
91 DEVMETHOD(device_shutdown, bus_generic_shutdown),
92 DEVMETHOD(device_suspend, bus_generic_suspend),
93 DEVMETHOD(device_resume, bus_generic_resume),
94
95 /* ADB interface */
96 DEVMETHOD(adb_receive_packet, adb_kbd_receive_packet),
97
98 { 0, 0 }
99};
100
101static driver_t adb_kbd_driver = {
102 "akbd",
103 adb_kbd_methods,
104 sizeof(struct adb_kbd_softc),
105};
106
107static devclass_t adb_kbd_devclass;
108
109DRIVER_MODULE(akbd, adb, adb_kbd_driver, adb_kbd_devclass, 0, 0);
110
111#ifdef AKBD_EMULATE_ATKBD
112
113#define SCAN_PRESS 0x000
114#define SCAN_RELEASE 0x080
115#define SCAN_PREFIX_E0 0x100
116#define SCAN_PREFIX_E1 0x200
117#define SCAN_PREFIX_CTL 0x400
118#define SCAN_PREFIX_SHIFT 0x800
119#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
120 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
121
122static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
123 44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
124 10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
125 51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
126 100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
127 0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
128 66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
129 62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
130
131static int
132keycode2scancode(int keycode, int shift, int up)
133{
134 static const int scan[] = {
135 /* KP enter, right ctrl, KP divide */
136 0x1c , 0x1d , 0x35 ,
137 /* print screen */
138 0x37 | SCAN_PREFIX_SHIFT,
139 /* right alt, home, up, page up, left, right, end */
140 0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
141 /* down, page down, insert, delete */
142 0x50, 0x51, 0x52, 0x53,
143 /* pause/break (see also below) */
144 0x46,
145 /*
146 * MS: left window, right window, menu
147 * also Sun: left meta, right meta, compose
148 */
149 0x5b, 0x5c, 0x5d,
150 /* Sun type 6 USB */
151 /* help, stop, again, props, undo, front, copy */
152 0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
153 /* open, paste, find, cut, audiomute, audiolower, audioraise */
154 0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
155 /* power */
156 0x20
157 };
158 int scancode;
159
160 scancode = keycode;
161 if ((keycode >= 89) && (keycode < 89 + sizeof(scan) / sizeof(scan[0])))
162 scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
163 /* pause/break */
164 if ((keycode == 104) && !(shift & CTLS))
165 scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
166 if (shift & SHIFTS)
167 scancode &= ~SCAN_PREFIX_SHIFT;
168 return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
169}
170#endif
171
172/* keyboard driver declaration */
173static int akbd_configure(int flags);
174static kbd_probe_t akbd_probe;
175static kbd_init_t akbd_init;
176static kbd_term_t akbd_term;
177static kbd_intr_t akbd_interrupt;
178static kbd_test_if_t akbd_test_if;
179static kbd_enable_t akbd_enable;
180static kbd_disable_t akbd_disable;
181static kbd_read_t akbd_read;
182static kbd_check_t akbd_check;
183static kbd_read_char_t akbd_read_char;
184static kbd_check_char_t akbd_check_char;
185static kbd_ioctl_t akbd_ioctl;
186static kbd_lock_t akbd_lock;
187static kbd_clear_state_t akbd_clear_state;
188static kbd_get_state_t akbd_get_state;
189static kbd_set_state_t akbd_set_state;
190static kbd_poll_mode_t akbd_poll;
191
192keyboard_switch_t akbdsw = {
193 akbd_probe,
194 akbd_init,
195 akbd_term,
196 akbd_interrupt,
197 akbd_test_if,
198 akbd_enable,
199 akbd_disable,
200 akbd_read,
201 akbd_check,
202 akbd_read_char,
203 akbd_check_char,
204 akbd_ioctl,
205 akbd_lock,
206 akbd_clear_state,
207 akbd_get_state,
208 akbd_set_state,
209 genkbd_get_fkeystr,
210 akbd_poll,
211 genkbd_diag,
212};
213
214KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
215
216static int
217adb_kbd_probe(device_t dev)
218{
219 uint8_t type;
220
221 type = adb_get_device_type(dev);
222
223 if (type != ADB_DEVICE_KEYBOARD)
224 return (ENXIO);
225
226 switch(adb_get_device_handler(dev)) {
227 case 1:
228 device_set_desc(dev,"Apple Standard Keyboard");
229 break;
230 case 2:
231 device_set_desc(dev,"Apple Extended Keyboard");
232 break;
233 case 4:
234 device_set_desc(dev,"Apple ISO Keyboard");
235 break;
236 case 5:
237 device_set_desc(dev,"Apple Extended ISO Keyboard");
238 break;
239 case 8:
240 device_set_desc(dev,"Apple Keyboard II");
241 break;
242 case 9:
243 device_set_desc(dev,"Apple ISO Keyboard II");
244 break;
245 case 12:
246 device_set_desc(dev,"PowerBook Keyboard");
247 break;
248 case 13:
249 device_set_desc(dev,"PowerBook ISO Keyboard");
250 break;
251 case 24:
252 device_set_desc(dev,"PowerBook Extended Keyboard");
253 break;
254 case 27:
255 device_set_desc(dev,"Apple Design Keyboard");
256 break;
257 case 195:
258 device_set_desc(dev,"PowerBook G3 Keyboard");
259 break;
260 case 196:
261 device_set_desc(dev,"iBook Keyboard");
262 break;
263 default:
264 device_set_desc(dev,"ADB Keyboard");
265 break;
266 }
267
268 return (0);
269}
270
271static int
272ms_to_ticks(int ms)
273{
274 if (hz > 1000)
275 return ms*(hz/1000);
276
277 return ms/(1000/hz);
278}
279
280static int
281adb_kbd_attach(device_t dev)
282{
283 struct adb_kbd_softc *sc;
284 keyboard_switch_t *sw;
285
286 sw = kbd_get_switch(KBD_DRIVER_NAME);
287 if (sw == NULL) {
288 return ENXIO;
289 }
290
291 sc = device_get_softc(dev);
292 sc->sc_dev = dev;
293 sc->sc_mode = K_RAW;
294 sc->sc_state = 0;
295 sc->have_led_control = 0;
296 sc->buffers = 0;
297
298 /* Try stepping forward to the extended keyboard protocol */
299 adb_set_device_handler(dev,3);
300
301 mtx_init(&sc->sc_mutex,KBD_DRIVER_NAME,MTX_DEF,0);
302 cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
303 callout_init(&sc->sc_repeater, 0);
304
305#ifdef AKBD_EMULATE_ATKBD
306 kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
307 kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
308 sizeof(fkey_tab) / sizeof(fkey_tab[0]));
309#else
310 #error ADB raw mode not implemented
311#endif
312
313 KBD_FOUND_DEVICE(&sc->sc_kbd);
314 KBD_PROBE_DONE(&sc->sc_kbd);
315 KBD_INIT_DONE(&sc->sc_kbd);
316 KBD_CONFIG_DONE(&sc->sc_kbd);
317
318 (*sw->enable)(&sc->sc_kbd);
319
320 kbd_register(&sc->sc_kbd);
321
322#ifdef KBD_INSTALL_CDEV
323 if (kbd_attach(&sc->sc_kbd)) {
324 adb_kbd_detach(dev);
325 return ENXIO;
326 }
327#endif
328
329 /* Check if we can read out the LED state from
330 this keyboard by reading the key state register */
331 if (adb_read_register(dev, 2, NULL) == 2)
332 sc->have_led_control = 1;
333
334 adb_set_autopoll(dev,1);
335
336 return (0);
337}
338
339static int
340adb_kbd_detach(device_t dev)
341{
342 struct adb_kbd_softc *sc;
343 keyboard_t *kbd;
344
345 sc = device_get_softc(dev);
346
347 adb_set_autopoll(dev,0);
348 callout_stop(&sc->sc_repeater);
349
350 mtx_lock(&sc->sc_mutex);
351
352 kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
353 device_get_unit(dev)));
354
355 kbdd_disable(kbd);
356
357#ifdef KBD_INSTALL_CDEV
358 kbd_detach(kbd);
359#endif
360
361 kbdd_term(kbd);
362
363 mtx_unlock(&sc->sc_mutex);
364
365 mtx_destroy(&sc->sc_mutex);
366 cv_destroy(&sc->sc_cv);
367
368 return (0);
369}
370
371static u_int
372adb_kbd_receive_packet(device_t dev, u_char status,
373 u_char command, u_char reg, int len, u_char *data)
374{
375 struct adb_kbd_softc *sc;
376
377 sc = device_get_softc(dev);
378
379 if (command != ADB_COMMAND_TALK)
380 return 0;
381
382 if (reg != 0 || len != 2)
383 return (0);
384
385 mtx_lock(&sc->sc_mutex);
386 if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
387 /* Fake the down/up cycle for caps lock */
388 sc->buffer[sc->buffers++] = data[0] & 0x7f;
389 sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
390 } else {
391 sc->buffer[sc->buffers++] = data[0];
392 }
393
394 if (sc->buffer[sc->buffers-1] < 0xff)
395 sc->last_press = sc->buffer[sc->buffers-1];
396
397 if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
398 /* Fake the down/up cycle for caps lock */
399 sc->buffer[sc->buffers++] = data[1] & 0x7f;
400 sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
401 } else {
402 sc->buffer[sc->buffers++] = data[1];
403 }
404
405 if (sc->buffer[sc->buffers-1] < 0xff)
406 sc->last_press = sc->buffer[sc->buffers-1];
407
408 /* Stop any existing key repeating */
409 callout_stop(&sc->sc_repeater);
410
411 /* Schedule a repeat callback on keydown */
412 if (!(sc->last_press & (1 << 7))) {
413 callout_reset(&sc->sc_repeater,
414 ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
415 }
416 mtx_unlock(&sc->sc_mutex);
417
418 cv_broadcast(&sc->sc_cv);
419
420 if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
421 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
422 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
423 }
424
425 return (0);
426}
427
428static void
429akbd_repeat(void *xsc) {
430 struct adb_kbd_softc *sc = xsc;
431 int notify_kbd = 0;
432
433 /* Fake an up/down key repeat so long as we have the
434 free buffers */
435 mtx_lock(&sc->sc_mutex);
436 if (sc->buffers < 7) {
437 sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
438 sc->buffer[sc->buffers++] = sc->last_press;
439
440 notify_kbd = 1;
441 }
442 mtx_unlock(&sc->sc_mutex);
443
444 if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
445 && KBD_IS_BUSY(&sc->sc_kbd)) {
446 sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
447 KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
448 }
449
450 /* Reschedule the callout */
451 callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
452 akbd_repeat, sc);
453}
454
455static int
456akbd_configure(int flags)
457{
458 return 0;
459}
460
461static int
462akbd_probe(int unit, void *arg, int flags)
463{
464 return 0;
465}
466
467static int
468akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
469{
470 return 0;
471}
472
473static int
474akbd_term(keyboard_t *kbd)
475{
476 return 0;
477}
478
479static int
480akbd_interrupt(keyboard_t *kbd, void *arg)
481{
482 return 0;
483}
484
485static int
486akbd_test_if(keyboard_t *kbd)
487{
488 return 0;
489}
490
491static int
492akbd_enable(keyboard_t *kbd)
493{
494 KBD_ACTIVATE(kbd);
495 return (0);
496}
497
498static int
499akbd_disable(keyboard_t *kbd)
500{
501 struct adb_kbd_softc *sc;
502 sc = (struct adb_kbd_softc *)(kbd);
503
504 callout_stop(&sc->sc_repeater);
505 KBD_DEACTIVATE(kbd);
506 return (0);
507}
508
509static int
510akbd_read(keyboard_t *kbd, int wait)
511{
512 return (0);
513}
514
515static int
516akbd_check(keyboard_t *kbd)
517{
518 struct adb_kbd_softc *sc;
519
520 if (!KBD_IS_ACTIVE(kbd))
521 return (FALSE);
522
523 sc = (struct adb_kbd_softc *)(kbd);
524
525 mtx_lock(&sc->sc_mutex);
526#ifdef AKBD_EMULATE_ATKBD
527 if (sc->at_buffered_char[0]) {
528 mtx_unlock(&sc->sc_mutex);
529 return (TRUE);
530 }
531#endif
532
533 if (sc->buffers > 0) {
534 mtx_unlock(&sc->sc_mutex);
535 return (TRUE);
536 }
537 mtx_unlock(&sc->sc_mutex);
538
539 return (FALSE);
540}
541
542static u_int
543akbd_read_char(keyboard_t *kbd, int wait)
544{
545 struct adb_kbd_softc *sc;
546 uint16_t key;
547 uint8_t adb_code;
548 int i;
549
550 sc = (struct adb_kbd_softc *)(kbd);
551
552 mtx_lock(&sc->sc_mutex);
553
554#if defined(AKBD_EMULATE_ATKBD)
555 if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
556 key = sc->at_buffered_char[0];
557 if (key & SCAN_PREFIX) {
558 sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
559 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
560 } else {
561 sc->at_buffered_char[0] = sc->at_buffered_char[1];
562 sc->at_buffered_char[1] = 0;
563 }
564
565 mtx_unlock(&sc->sc_mutex);
566
567 return (key);
568 }
569#endif
570
571 if (!sc->buffers && wait)
572 cv_wait(&sc->sc_cv,&sc->sc_mutex);
573
574 if (!sc->buffers) {
575 mtx_unlock(&sc->sc_mutex);
576 return (0);
577 }
578
579 adb_code = sc->buffer[0];
580
581 for (i = 1; i < sc->buffers; i++)
582 sc->buffer[i-1] = sc->buffer[i];
583
584 sc->buffers--;
585
586 #ifdef AKBD_EMULATE_ATKBD
587 key = adb_to_at_scancode_map[adb_code & 0x7f];
588 if (sc->sc_mode == K_CODE) {
589 /* Add the key-release bit */
590 key |= adb_code & 0x80;
591 } else if (sc->sc_mode == K_RAW) {
592 /*
593 * In the raw case, we have to emulate the gross
594 * variable-length AT keyboard thing. Since this code
595 * is copied from sunkbd, which is the same code
596 * as ukbd, it might be nice to have this centralized.
597 */
598
599 key = keycode2scancode(key,
600 0, adb_code & 0x80);
601
602 if (key & SCAN_PREFIX) {
603 if (key & SCAN_PREFIX_CTL) {
604 sc->at_buffered_char[0] =
605 0x1d | (key & SCAN_RELEASE);
606 sc->at_buffered_char[1] =
607 key & ~SCAN_PREFIX;
608 } else if (key & SCAN_PREFIX_SHIFT) {
609 sc->at_buffered_char[0] =
610 0x2a | (key & SCAN_RELEASE);
611 sc->at_buffered_char[1] =
612 key & ~SCAN_PREFIX_SHIFT;
613 } else {
614 sc->at_buffered_char[0] =
615 key & ~SCAN_PREFIX;
616 sc->at_buffered_char[1] = 0;
617 }
618
619 key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
620 }
621 }
622 #else
623 key = adb_code;
624 #endif
625
626 mtx_unlock(&sc->sc_mutex);
627
628 return (key);
629}
630
631static int
632akbd_check_char(keyboard_t *kbd)
633{
634 if (!KBD_IS_ACTIVE(kbd))
635 return (FALSE);
636
637 return (akbd_check(kbd));
638}
639
640static int
641set_typematic(keyboard_t *kbd, int code)
642{
643 /* These numbers are in microseconds, so convert to ticks */
644
645 static int delays[] = { 250, 500, 750, 1000 };
646 static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63,
647 68, 76, 84, 92, 100, 110, 118, 126,
648 136, 152, 168, 184, 200, 220, 236, 252,
649 272, 304, 336, 368, 400, 440, 472, 504 };
650
651 if (code & ~0x7f)
652 return EINVAL;
653 kbd->kb_delay1 = delays[(code >> 5) & 3];
654 kbd->kb_delay2 = rates[code & 0x1f];
655 return 0;
656}
657
658static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
659{
660 struct adb_kbd_softc *sc;
661 uint16_t r2;
662 int error;
663
664 sc = (struct adb_kbd_softc *)(kbd);
665 error = 0;
666
667 switch (cmd) {
668 case KDGKBMODE:
669 *(int *)data = sc->sc_mode;
670 break;
671 case KDSKBMODE:
672 switch (*(int *)data) {
673 case K_XLATE:
674 if (sc->sc_mode != K_XLATE) {
675 /* make lock key state and LED state match */
676 sc->sc_state &= ~LOCK_MASK;
677 sc->sc_state |= KBD_LED_VAL(kbd);
678 }
679 /* FALLTHROUGH */
680 case K_RAW:
681 case K_CODE:
682 if (sc->sc_mode != *(int *)data)
683 sc->sc_mode = *(int *)data;
684 break;
685 default:
686 error = EINVAL;
687 break;
688 }
689
690 break;
691
692 case KDGETLED:
693 *(int *)data = KBD_LED_VAL(kbd);
694 break;
695
696 case KDSKBSTATE:
697 if (*(int *)data & ~LOCK_MASK) {
698 error = EINVAL;
699 break;
700 }
701 sc->sc_state &= ~LOCK_MASK;
702 sc->sc_state |= *(int *)data;
703
704 /* FALLTHROUGH */
705
706 case KDSETLED:
707 KBD_LED_VAL(kbd) = *(int *)data;
708
709 if (!sc->have_led_control)
710 break;
711
712 r2 = (~0 & 0x04) | 3;
713
714 if (*(int *)data & NLKED)
715 r2 &= ~1;
716 if (*(int *)data & CLKED)
717 r2 &= ~2;
718 if (*(int *)data & SLKED)
719 r2 &= ~4;
720
721 adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
722 sizeof(uint16_t),(u_char *)&r2);
723
724 break;
725
726 case KDGKBSTATE:
727 *(int *)data = sc->sc_state & LOCK_MASK;
728 break;
729
730 case KDSETREPEAT:
731 if (!KBD_HAS_DEVICE(kbd))
732 return 0;
733 if (((int *)data)[1] < 0)
734 return EINVAL;
735 if (((int *)data)[0] < 0)
736 return EINVAL;
737 else if (((int *)data)[0] == 0) /* fastest possible value */
738 kbd->kb_delay1 = 200;
739 else
740 kbd->kb_delay1 = ((int *)data)[0];
741 kbd->kb_delay2 = ((int *)data)[1];
742
743 break;
744
745 case KDSETRAD:
746 error = set_typematic(kbd, *(int *)data);
747 break;
748
749 case PIO_KEYMAP:
750 case PIO_KEYMAPENT:
751 case PIO_DEADKEYMAP:
752 default:
753 return (genkbd_commonioctl(kbd, cmd, data));
754 }
755
756 return (error);
757}
758
759static int akbd_lock(keyboard_t *kbd, int lock)
760{
761 return (0);
762}
763
764static void akbd_clear_state(keyboard_t *kbd)
765{
766 struct adb_kbd_softc *sc;
767
768 sc = (struct adb_kbd_softc *)(kbd);
769
770 mtx_lock(&sc->sc_mutex);
771
772 sc->buffers = 0;
773 callout_stop(&sc->sc_repeater);
774
775#if defined(AKBD_EMULATE_ATKBD)
776 sc->at_buffered_char[0] = 0;
777 sc->at_buffered_char[1] = 0;
778#endif
779 mtx_unlock(&sc->sc_mutex);
780}
781
782static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
783{
784 return (0);
785}
786
787static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
788{
789 return (0);
790}
791
792static int akbd_poll(keyboard_t *kbd, int on)
793{
794 return (0);
795}
796
797static int
798akbd_modevent(module_t mod, int type, void *data)
799{
800 switch (type) {
801 case MOD_LOAD:
802 kbd_add_driver(&akbd_kbd_driver);
803 break;
804
805 case MOD_UNLOAD:
806 kbd_delete_driver(&akbd_kbd_driver);
807 break;
808
809 default:
810 return (EOPNOTSUPP);
811 }
812
813 return (0);
814}
815
816DEV_MODULE(akbd, akbd_modevent, NULL);
817