Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/adb/adb_kbd.c
39562 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
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
28
#include <sys/param.h>
29
#include <sys/systm.h>
30
#include <sys/lock.h>
31
#include <sys/module.h>
32
#include <sys/mutex.h>
33
#include <sys/bus.h>
34
#include <sys/conf.h>
35
#include <sys/kbio.h>
36
#include <sys/condvar.h>
37
#include <sys/callout.h>
38
#include <sys/kernel.h>
39
#include <sys/sysctl.h>
40
41
#include <machine/bus.h>
42
43
#include "opt_kbd.h"
44
#include <dev/kbd/kbdreg.h>
45
#include <dev/kbd/kbdtables.h>
46
#include <dev/ofw/openfirm.h>
47
#include <dev/ofw/ofw_bus.h>
48
49
#include <vm/vm.h>
50
#include <vm/pmap.h>
51
52
#include "adb.h"
53
54
#define KBD_DRIVER_NAME "akbd"
55
56
#define AKBD_EMULATE_ATKBD 1
57
58
static int adb_kbd_probe(device_t dev);
59
static int adb_kbd_attach(device_t dev);
60
static int adb_kbd_detach(device_t dev);
61
static void akbd_repeat(void *xsc);
62
static int adb_fn_keys(SYSCTL_HANDLER_ARGS);
63
64
static u_int adb_kbd_receive_packet(device_t dev, u_char status,
65
u_char command, u_char reg, int len, u_char *data);
66
67
struct adb_kbd_softc {
68
keyboard_t sc_kbd;
69
70
device_t sc_dev;
71
struct mtx sc_mutex;
72
struct cv sc_cv;
73
74
int sc_mode;
75
int sc_state;
76
77
int have_led_control;
78
79
uint8_t buffer[8];
80
#ifdef AKBD_EMULATE_ATKBD
81
uint8_t at_buffered_char[2];
82
#endif
83
volatile int buffers;
84
85
struct callout sc_repeater;
86
int sc_repeatstart;
87
int sc_repeatcontinue;
88
uint8_t last_press;
89
};
90
91
static device_method_t adb_kbd_methods[] = {
92
/* Device interface */
93
DEVMETHOD(device_probe, adb_kbd_probe),
94
DEVMETHOD(device_attach, adb_kbd_attach),
95
DEVMETHOD(device_detach, adb_kbd_detach),
96
DEVMETHOD(device_shutdown, bus_generic_shutdown),
97
DEVMETHOD(device_suspend, bus_generic_suspend),
98
DEVMETHOD(device_resume, bus_generic_resume),
99
100
/* ADB interface */
101
DEVMETHOD(adb_receive_packet, adb_kbd_receive_packet),
102
{ 0, 0 }
103
};
104
105
static driver_t adb_kbd_driver = {
106
"akbd",
107
adb_kbd_methods,
108
sizeof(struct adb_kbd_softc),
109
};
110
111
DRIVER_MODULE(akbd, adb, adb_kbd_driver, 0, 0);
112
113
#ifdef AKBD_EMULATE_ATKBD
114
115
#define SCAN_PRESS 0x000
116
#define SCAN_RELEASE 0x080
117
#define SCAN_PREFIX_E0 0x100
118
#define SCAN_PREFIX_E1 0x200
119
#define SCAN_PREFIX_CTL 0x400
120
#define SCAN_PREFIX_SHIFT 0x800
121
#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
122
SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
123
124
static const uint8_t adb_to_at_scancode_map[128] = { 30, 31, 32, 33, 35, 34,
125
44, 45, 46, 47, 0, 48, 16, 17, 18, 19, 21, 20, 2, 3, 4, 5, 7, 6, 13,
126
10, 8, 12, 9, 11, 27, 24, 22, 26, 23, 25, 28, 38, 36, 40, 37, 39, 43,
127
51, 53, 49, 50, 52, 15, 57, 41, 14, 0, 1, 29, 0, 42, 58, 56, 97, 98,
128
100, 95, 0, 0, 83, 0, 55, 0, 78, 0, 69, 0, 0, 0, 91, 89, 0, 74, 13, 0,
129
0, 82, 79, 80, 81, 75, 76, 77, 71, 0, 72, 73, 0, 0, 0, 63, 64, 65, 61,
130
66, 67, 0, 87, 0, 105, 0, 70, 0, 68, 0, 88, 0, 107, 102, 94, 96, 103,
131
62, 99, 60, 101, 59, 54, 93, 90, 0, 0 };
132
133
static int
134
keycode2scancode(int keycode, int shift, int up)
135
{
136
static const int scan[] = {
137
/* KP enter, right ctrl, KP divide */
138
0x1c , 0x1d , 0x35 ,
139
/* print screen */
140
0x37 | SCAN_PREFIX_SHIFT,
141
/* right alt, home, up, page up, left, right, end */
142
0x38, 0x47, 0x48, 0x49, 0x4b, 0x4d, 0x4f,
143
/* down, page down, insert, delete */
144
0x50, 0x51, 0x52, 0x53,
145
/* pause/break (see also below) */
146
0x46,
147
/*
148
* MS: left window, right window, menu
149
* also Sun: left meta, right meta, compose
150
*/
151
0x5b, 0x5c, 0x5d,
152
/* Sun type 6 USB */
153
/* help, stop, again, props, undo, front, copy */
154
0x68, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63,
155
/* open, paste, find, cut, audiomute, audiolower, audioraise */
156
0x64, 0x65, 0x66, 0x67, 0x25, 0x1f, 0x1e,
157
/* power */
158
0x20
159
};
160
int scancode;
161
162
scancode = keycode;
163
if ((keycode >= 89) && (keycode < 89 + nitems(scan)))
164
scancode = scan[keycode - 89] | SCAN_PREFIX_E0;
165
/* pause/break */
166
if ((keycode == 104) && !(shift & CTLS))
167
scancode = 0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL;
168
if (shift & SHIFTS)
169
scancode &= ~SCAN_PREFIX_SHIFT;
170
return (scancode | (up ? SCAN_RELEASE : SCAN_PRESS));
171
}
172
#endif
173
174
/* keyboard driver declaration */
175
static int akbd_configure(int flags);
176
static kbd_probe_t akbd_probe;
177
static kbd_init_t akbd_init;
178
static kbd_term_t akbd_term;
179
static kbd_intr_t akbd_interrupt;
180
static kbd_test_if_t akbd_test_if;
181
static kbd_enable_t akbd_enable;
182
static kbd_disable_t akbd_disable;
183
static kbd_read_t akbd_read;
184
static kbd_check_t akbd_check;
185
static kbd_read_char_t akbd_read_char;
186
static kbd_check_char_t akbd_check_char;
187
static kbd_ioctl_t akbd_ioctl;
188
static kbd_lock_t akbd_lock;
189
static kbd_clear_state_t akbd_clear_state;
190
static kbd_get_state_t akbd_get_state;
191
static kbd_set_state_t akbd_set_state;
192
static kbd_poll_mode_t akbd_poll;
193
194
keyboard_switch_t akbdsw = {
195
.probe = akbd_probe,
196
.init = akbd_init,
197
.term = akbd_term,
198
.intr = akbd_interrupt,
199
.test_if = akbd_test_if,
200
.enable = akbd_enable,
201
.disable = akbd_disable,
202
.read = akbd_read,
203
.check = akbd_check,
204
.read_char = akbd_read_char,
205
.check_char = akbd_check_char,
206
.ioctl = akbd_ioctl,
207
.lock = akbd_lock,
208
.clear_state = akbd_clear_state,
209
.get_state = akbd_get_state,
210
.set_state = akbd_set_state,
211
.poll = akbd_poll,
212
};
213
214
KEYBOARD_DRIVER(akbd, akbdsw, akbd_configure);
215
216
static int
217
adb_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
271
static int
272
ms_to_ticks(int ms)
273
{
274
if (hz > 1000)
275
return ms*(hz/1000);
276
277
return ms/(1000/hz);
278
}
279
280
static int
281
adb_kbd_attach(device_t dev)
282
{
283
struct adb_kbd_softc *sc;
284
keyboard_switch_t *sw;
285
uint32_t fkeys;
286
phandle_t handle;
287
288
sw = kbd_get_switch(KBD_DRIVER_NAME);
289
if (sw == NULL) {
290
return ENXIO;
291
}
292
293
sc = device_get_softc(dev);
294
sc->sc_dev = dev;
295
sc->sc_mode = K_RAW;
296
sc->sc_state = 0;
297
sc->have_led_control = 0;
298
sc->buffers = 0;
299
300
/* Try stepping forward to the extended keyboard protocol */
301
adb_set_device_handler(dev,3);
302
303
mtx_init(&sc->sc_mutex, KBD_DRIVER_NAME, NULL, MTX_DEF);
304
cv_init(&sc->sc_cv,KBD_DRIVER_NAME);
305
callout_init(&sc->sc_repeater, 0);
306
307
#ifdef AKBD_EMULATE_ATKBD
308
kbd_init_struct(&sc->sc_kbd, KBD_DRIVER_NAME, KB_101, 0, 0, 0, 0);
309
kbd_set_maps(&sc->sc_kbd, &key_map, &accent_map, fkey_tab,
310
sizeof(fkey_tab) / sizeof(fkey_tab[0]));
311
#else
312
#error ADB raw mode not implemented
313
#endif
314
315
KBD_FOUND_DEVICE(&sc->sc_kbd);
316
KBD_PROBE_DONE(&sc->sc_kbd);
317
KBD_INIT_DONE(&sc->sc_kbd);
318
KBD_CONFIG_DONE(&sc->sc_kbd);
319
320
(*sw->enable)(&sc->sc_kbd);
321
322
kbd_register(&sc->sc_kbd);
323
324
#ifdef KBD_INSTALL_CDEV
325
if (kbd_attach(&sc->sc_kbd)) {
326
adb_kbd_detach(dev);
327
return ENXIO;
328
}
329
#endif
330
331
/* Check if we can read out the LED state from
332
this keyboard by reading the key state register */
333
if (adb_read_register(dev, 2, NULL) == 2)
334
sc->have_led_control = 1;
335
336
adb_set_autopoll(dev,1);
337
338
handle = OF_finddevice("mac-io/via-pmu/adb/keyboard");
339
if (handle != -1 && OF_getprop(handle, "AAPL,has-embedded-fn-keys",
340
&fkeys, sizeof(fkeys)) != -1) {
341
static const char *key_names[] = {"F1", "F2", "F3", "F4", "F5",
342
"F6", "F7", "F8", "F9", "F10", "F11", "F12"};
343
struct sysctl_ctx_list *ctx;
344
struct sysctl_oid *tree;
345
int i;
346
347
if (bootverbose)
348
device_printf(dev, "Keyboard has embedded Fn keys\n");
349
350
for (i = 0; i < 12; i++) {
351
uint32_t keyval;
352
char buf[3];
353
if (OF_getprop(handle, key_names[i], &keyval,
354
sizeof(keyval)) < 0)
355
continue;
356
buf[0] = 1;
357
buf[1] = i+1;
358
buf[2] = keyval;
359
adb_write_register(dev, 0, 3, buf);
360
}
361
adb_write_register(dev, 1, 2, &(uint16_t){0});
362
363
ctx = device_get_sysctl_ctx(dev);
364
tree = device_get_sysctl_tree(dev);
365
366
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
367
"fn_keys_function_as_primary",
368
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, sc,
369
0, adb_fn_keys, "I",
370
"Set the Fn keys to be their F-key type as default");
371
}
372
373
return (0);
374
}
375
376
static int
377
adb_kbd_detach(device_t dev)
378
{
379
struct adb_kbd_softc *sc;
380
keyboard_t *kbd;
381
382
sc = device_get_softc(dev);
383
384
adb_set_autopoll(dev,0);
385
callout_stop(&sc->sc_repeater);
386
387
mtx_lock(&sc->sc_mutex);
388
389
kbd = kbd_get_keyboard(kbd_find_keyboard(KBD_DRIVER_NAME,
390
device_get_unit(dev)));
391
392
kbdd_disable(kbd);
393
394
#ifdef KBD_INSTALL_CDEV
395
kbd_detach(kbd);
396
#endif
397
398
kbdd_term(kbd);
399
400
mtx_unlock(&sc->sc_mutex);
401
402
mtx_destroy(&sc->sc_mutex);
403
cv_destroy(&sc->sc_cv);
404
405
return (0);
406
}
407
408
static u_int
409
adb_kbd_receive_packet(device_t dev, u_char status,
410
u_char command, u_char reg, int len, u_char *data)
411
{
412
struct adb_kbd_softc *sc;
413
414
sc = device_get_softc(dev);
415
416
if (command != ADB_COMMAND_TALK)
417
return 0;
418
419
if (reg != 0 || len != 2)
420
return (0);
421
422
mtx_lock(&sc->sc_mutex);
423
/* 0x7f is always the power button */
424
if (data[0] == 0x7f) {
425
devctl_notify("PMU", "Button", "pressed", NULL);
426
mtx_unlock(&sc->sc_mutex);
427
return (0);
428
} else if (data[0] == 0xff) {
429
mtx_unlock(&sc->sc_mutex);
430
return (0); /* Ignore power button release. */
431
}
432
if ((data[0] & 0x7f) == 57 && sc->buffers < 7) {
433
/* Fake the down/up cycle for caps lock */
434
sc->buffer[sc->buffers++] = data[0] & 0x7f;
435
sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7);
436
} else {
437
sc->buffer[sc->buffers++] = data[0];
438
}
439
if (sc->buffer[sc->buffers-1] < 0xff)
440
sc->last_press = sc->buffer[sc->buffers-1];
441
442
if ((data[1] & 0x7f) == 57 && sc->buffers < 7) {
443
/* Fake the down/up cycle for caps lock */
444
sc->buffer[sc->buffers++] = data[1] & 0x7f;
445
sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7);
446
} else {
447
sc->buffer[sc->buffers++] = data[1];
448
}
449
450
if (sc->buffer[sc->buffers-1] < 0xff)
451
sc->last_press = sc->buffer[sc->buffers-1];
452
453
/* Stop any existing key repeating */
454
callout_stop(&sc->sc_repeater);
455
456
/* Schedule a repeat callback on keydown */
457
if (!(sc->last_press & (1 << 7))) {
458
callout_reset(&sc->sc_repeater,
459
ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc);
460
}
461
mtx_unlock(&sc->sc_mutex);
462
463
cv_broadcast(&sc->sc_cv);
464
465
if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) {
466
sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
467
KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
468
}
469
470
return (0);
471
}
472
473
static void
474
akbd_repeat(void *xsc) {
475
struct adb_kbd_softc *sc = xsc;
476
int notify_kbd = 0;
477
478
/* Fake an up/down key repeat so long as we have the
479
free buffers */
480
mtx_lock(&sc->sc_mutex);
481
if (sc->buffers < 7) {
482
sc->buffer[sc->buffers++] = sc->last_press | (1 << 7);
483
sc->buffer[sc->buffers++] = sc->last_press;
484
485
notify_kbd = 1;
486
}
487
mtx_unlock(&sc->sc_mutex);
488
489
if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd)
490
&& KBD_IS_BUSY(&sc->sc_kbd)) {
491
sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd,
492
KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg);
493
}
494
495
/* Reschedule the callout */
496
callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2),
497
akbd_repeat, sc);
498
}
499
500
static int
501
akbd_configure(int flags)
502
{
503
return 0;
504
}
505
506
static int
507
akbd_probe(int unit, void *arg, int flags)
508
{
509
return 0;
510
}
511
512
static int
513
akbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
514
{
515
return 0;
516
}
517
518
static int
519
akbd_term(keyboard_t *kbd)
520
{
521
return 0;
522
}
523
524
static int
525
akbd_interrupt(keyboard_t *kbd, void *arg)
526
{
527
return 0;
528
}
529
530
static int
531
akbd_test_if(keyboard_t *kbd)
532
{
533
return 0;
534
}
535
536
static int
537
akbd_enable(keyboard_t *kbd)
538
{
539
KBD_ACTIVATE(kbd);
540
return (0);
541
}
542
543
static int
544
akbd_disable(keyboard_t *kbd)
545
{
546
struct adb_kbd_softc *sc;
547
sc = (struct adb_kbd_softc *)(kbd);
548
549
callout_stop(&sc->sc_repeater);
550
KBD_DEACTIVATE(kbd);
551
return (0);
552
}
553
554
static int
555
akbd_read(keyboard_t *kbd, int wait)
556
{
557
return (0);
558
}
559
560
static int
561
akbd_check(keyboard_t *kbd)
562
{
563
struct adb_kbd_softc *sc;
564
565
if (!KBD_IS_ACTIVE(kbd))
566
return (FALSE);
567
568
sc = (struct adb_kbd_softc *)(kbd);
569
570
mtx_lock(&sc->sc_mutex);
571
#ifdef AKBD_EMULATE_ATKBD
572
if (sc->at_buffered_char[0]) {
573
mtx_unlock(&sc->sc_mutex);
574
return (TRUE);
575
}
576
#endif
577
578
if (sc->buffers > 0) {
579
mtx_unlock(&sc->sc_mutex);
580
return (TRUE);
581
}
582
mtx_unlock(&sc->sc_mutex);
583
584
return (FALSE);
585
}
586
587
static u_int
588
akbd_read_char(keyboard_t *kbd, int wait)
589
{
590
struct adb_kbd_softc *sc;
591
uint16_t key;
592
uint8_t adb_code;
593
int i;
594
595
sc = (struct adb_kbd_softc *)(kbd);
596
597
mtx_lock(&sc->sc_mutex);
598
599
#if defined(AKBD_EMULATE_ATKBD)
600
if (sc->sc_mode == K_RAW && sc->at_buffered_char[0]) {
601
key = sc->at_buffered_char[0];
602
if (key & SCAN_PREFIX) {
603
sc->at_buffered_char[0] = key & ~SCAN_PREFIX;
604
key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
605
} else {
606
sc->at_buffered_char[0] = sc->at_buffered_char[1];
607
sc->at_buffered_char[1] = 0;
608
}
609
610
mtx_unlock(&sc->sc_mutex);
611
612
return (key);
613
}
614
#endif
615
616
if (!sc->buffers && wait)
617
cv_wait(&sc->sc_cv,&sc->sc_mutex);
618
619
if (!sc->buffers) {
620
mtx_unlock(&sc->sc_mutex);
621
return (NOKEY);
622
}
623
624
adb_code = sc->buffer[0];
625
626
for (i = 1; i < sc->buffers; i++)
627
sc->buffer[i-1] = sc->buffer[i];
628
629
sc->buffers--;
630
631
#ifdef AKBD_EMULATE_ATKBD
632
key = adb_to_at_scancode_map[adb_code & 0x7f];
633
if (sc->sc_mode == K_CODE) {
634
/* Add the key-release bit */
635
key |= adb_code & 0x80;
636
} else if (sc->sc_mode == K_RAW) {
637
/*
638
* In the raw case, we have to emulate the gross
639
* variable-length AT keyboard thing. Since this code
640
* is copied from sunkbd, which is the same code
641
* as ukbd, it might be nice to have this centralized.
642
*/
643
644
key = keycode2scancode(key,
645
0, adb_code & 0x80);
646
647
if (key & SCAN_PREFIX) {
648
if (key & SCAN_PREFIX_CTL) {
649
sc->at_buffered_char[0] =
650
0x1d | (key & SCAN_RELEASE);
651
sc->at_buffered_char[1] =
652
key & ~SCAN_PREFIX;
653
} else if (key & SCAN_PREFIX_SHIFT) {
654
sc->at_buffered_char[0] =
655
0x2a | (key & SCAN_RELEASE);
656
sc->at_buffered_char[1] =
657
key & ~SCAN_PREFIX_SHIFT;
658
} else {
659
sc->at_buffered_char[0] =
660
key & ~SCAN_PREFIX;
661
sc->at_buffered_char[1] = 0;
662
}
663
664
key = (key & SCAN_PREFIX_E0) ? 0xe0 : 0xe1;
665
}
666
}
667
#else
668
key = adb_code;
669
#endif
670
671
mtx_unlock(&sc->sc_mutex);
672
673
return (key);
674
}
675
676
static int
677
akbd_check_char(keyboard_t *kbd)
678
{
679
if (!KBD_IS_ACTIVE(kbd))
680
return (FALSE);
681
682
return (akbd_check(kbd));
683
}
684
685
static int
686
set_typematic(keyboard_t *kbd, int code)
687
{
688
if (code & ~0x7f)
689
return EINVAL;
690
kbd->kb_delay1 = kbdelays[(code >> 5) & 3];
691
kbd->kb_delay2 = kbrates[code & 0x1f];
692
return 0;
693
}
694
695
static int akbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
696
{
697
struct adb_kbd_softc *sc;
698
uint16_t r2;
699
int error;
700
701
sc = (struct adb_kbd_softc *)(kbd);
702
error = 0;
703
704
switch (cmd) {
705
case KDGKBMODE:
706
*(int *)data = sc->sc_mode;
707
break;
708
case KDSKBMODE:
709
switch (*(int *)data) {
710
case K_XLATE:
711
if (sc->sc_mode != K_XLATE) {
712
/* make lock key state and LED state match */
713
sc->sc_state &= ~LOCK_MASK;
714
sc->sc_state |= KBD_LED_VAL(kbd);
715
}
716
/* FALLTHROUGH */
717
case K_RAW:
718
case K_CODE:
719
if (sc->sc_mode != *(int *)data)
720
sc->sc_mode = *(int *)data;
721
break;
722
default:
723
error = EINVAL;
724
break;
725
}
726
727
break;
728
729
case KDGETLED:
730
*(int *)data = KBD_LED_VAL(kbd);
731
break;
732
733
case KDSKBSTATE:
734
if (*(int *)data & ~LOCK_MASK) {
735
error = EINVAL;
736
break;
737
}
738
sc->sc_state &= ~LOCK_MASK;
739
sc->sc_state |= *(int *)data;
740
741
/* FALLTHROUGH */
742
743
case KDSETLED:
744
KBD_LED_VAL(kbd) = *(int *)data;
745
746
if (!sc->have_led_control)
747
break;
748
749
r2 = (~0 & 0x04) | 3;
750
751
if (*(int *)data & NLKED)
752
r2 &= ~1;
753
if (*(int *)data & CLKED)
754
r2 &= ~2;
755
if (*(int *)data & SLKED)
756
r2 &= ~4;
757
758
adb_send_packet(sc->sc_dev,ADB_COMMAND_LISTEN,2,
759
sizeof(uint16_t),(u_char *)&r2);
760
761
break;
762
763
case KDGKBSTATE:
764
*(int *)data = sc->sc_state & LOCK_MASK;
765
break;
766
767
case KDSETREPEAT:
768
if (!KBD_HAS_DEVICE(kbd))
769
return 0;
770
if (((int *)data)[1] < 0)
771
return EINVAL;
772
if (((int *)data)[0] < 0)
773
return EINVAL;
774
else if (((int *)data)[0] == 0) /* fastest possible value */
775
kbd->kb_delay1 = 200;
776
else
777
kbd->kb_delay1 = ((int *)data)[0];
778
kbd->kb_delay2 = ((int *)data)[1];
779
780
break;
781
782
case KDSETRAD:
783
error = set_typematic(kbd, *(int *)data);
784
break;
785
786
case PIO_KEYMAP:
787
case PIO_KEYMAPENT:
788
case PIO_DEADKEYMAP:
789
#ifdef COMPAT_FREEBSD13
790
case OPIO_KEYMAP:
791
case OPIO_DEADKEYMAP:
792
#endif /* COMPAT_FREEBSD13 */
793
default:
794
return (genkbd_commonioctl(kbd, cmd, data));
795
}
796
797
return (error);
798
}
799
800
static int akbd_lock(keyboard_t *kbd, int lock)
801
{
802
return (0);
803
}
804
805
static void akbd_clear_state(keyboard_t *kbd)
806
{
807
struct adb_kbd_softc *sc;
808
809
sc = (struct adb_kbd_softc *)(kbd);
810
811
mtx_lock(&sc->sc_mutex);
812
813
sc->buffers = 0;
814
callout_stop(&sc->sc_repeater);
815
816
#if defined(AKBD_EMULATE_ATKBD)
817
sc->at_buffered_char[0] = 0;
818
sc->at_buffered_char[1] = 0;
819
#endif
820
mtx_unlock(&sc->sc_mutex);
821
}
822
823
static int akbd_get_state(keyboard_t *kbd, void *buf, size_t len)
824
{
825
return (0);
826
}
827
828
static int akbd_set_state(keyboard_t *kbd, void *buf, size_t len)
829
{
830
return (0);
831
}
832
833
static int akbd_poll(keyboard_t *kbd, int on)
834
{
835
return (0);
836
}
837
838
static int
839
akbd_modevent(module_t mod, int type, void *data)
840
{
841
switch (type) {
842
case MOD_LOAD:
843
kbd_add_driver(&akbd_kbd_driver);
844
break;
845
846
case MOD_UNLOAD:
847
kbd_delete_driver(&akbd_kbd_driver);
848
break;
849
850
default:
851
return (EOPNOTSUPP);
852
}
853
854
return (0);
855
}
856
857
static int
858
adb_fn_keys(SYSCTL_HANDLER_ARGS)
859
{
860
struct adb_kbd_softc *sc = arg1;
861
int error;
862
uint16_t is_fn_enabled;
863
unsigned int is_fn_enabled_sysctl;
864
865
adb_read_register(sc->sc_dev, 1, &is_fn_enabled);
866
is_fn_enabled &= 1;
867
is_fn_enabled_sysctl = is_fn_enabled;
868
error = sysctl_handle_int(oidp, &is_fn_enabled_sysctl, 0, req);
869
870
if (error || !req->newptr)
871
return (error);
872
873
is_fn_enabled = is_fn_enabled_sysctl;
874
if (is_fn_enabled != 1 && is_fn_enabled != 0)
875
return (EINVAL);
876
877
adb_write_register(sc->sc_dev, 1, 2, &is_fn_enabled);
878
return (0);
879
}
880
881
DEV_MODULE(akbd, akbd_modevent, NULL);
882
883