This source file includes following definitions.
- akbdmatch
- akbdattach
- akbd_adbcomplete
- getleds
- setleds
- blinkleds
- akbd_enable
- akbd_set_leds
- akbd_ioctl
- akbd_rawrepeat
- akbd_processevent
- akbd_capslockwrapper
- akbd_input
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/param.h>
35 #include <sys/timeout.h>
36 #include <sys/kernel.h>
37 #include <sys/device.h>
38 #include <sys/systm.h>
39
40 #include <dev/wscons/wsconsio.h>
41 #include <dev/wscons/wskbdvar.h>
42 #include <dev/wscons/wsksymdef.h>
43 #include <dev/wscons/wsksymvar.h>
44
45 #include <machine/autoconf.h>
46 #include <machine/cpu.h>
47
48 #include <dev/adb/adb.h>
49 #include <dev/adb/akbdmap.h>
50 #include <dev/adb/akbdvar.h>
51
52 #ifdef WSDISPLAY_COMPAT_RAWKBD
53 #define KEYBOARD_ARRAY
54 #endif
55 #include <dev/adb/keyboard.h>
56
57
58
59
60 int akbdmatch(struct device *, void *, void *);
61 void akbdattach(struct device *, struct device *, void *);
62
63
64 struct cfattach akbd_ca = {
65 sizeof(struct akbd_softc), akbdmatch, akbdattach
66 };
67 struct cfdriver akbd_cd = {
68 NULL, "akbd", DV_DULL
69 };
70
71 int akbd_enable(void *, int);
72 void akbd_set_leds(void *, int);
73 int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
74
75
76 struct wskbd_accessops akbd_accessops = {
77 akbd_enable,
78 akbd_set_leds,
79 akbd_ioctl,
80 };
81
82 struct wskbd_mapdata akbd_keymapdata = {
83 akbd_keydesctab,
84 #ifdef AKBD_LAYOUT
85 AKBD_LAYOUT,
86 #else
87 KB_US,
88 #endif
89 };
90
91 void akbd_adbcomplete(caddr_t, caddr_t, int);
92 void akbd_capslockwrapper(struct akbd_softc *, int);
93 void akbd_input(struct akbd_softc *, int);
94 void akbd_processevent(struct akbd_softc *, adb_event_t *);
95 void akbd_rawrepeat(void *v);
96 #ifdef notyet
97 u_char getleds(int);
98 int setleds(struct akbd_softc *, u_char);
99 void blinkleds(struct akbd_softc *);
100 #endif
101
102 int
103 akbdmatch(struct device *parent, void *vcf, void *aux)
104 {
105 struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
106
107 if (aa_args->origaddr == ADBADDR_KBD)
108 return (1);
109 else
110 return (0);
111 }
112
113 void
114 akbdattach(struct device *parent, struct device *self, void *aux)
115 {
116 ADBSetInfoBlock adbinfo;
117 struct akbd_softc *sc = (struct akbd_softc *)self;
118 struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
119 int error, kbd_done;
120 short cmd;
121 u_char buffer[9];
122 struct wskbddev_attach_args a;
123 static int akbd_console_initted;
124 int wskbd_eligible = 1;
125
126 sc->origaddr = aa_args->origaddr;
127 sc->adbaddr = aa_args->adbaddr;
128 sc->handler_id = aa_args->handler_id;
129
130 sc->sc_leds = (u_int8_t)0x00;
131 sc->sc_caps = 0;
132
133 adbinfo.siServiceRtPtr = (Ptr)akbd_adbcomplete;
134 adbinfo.siDataAreaAddr = (caddr_t)sc;
135
136 printf(": ");
137 switch (sc->handler_id) {
138 case ADB_STDKBD:
139 printf("standard keyboard\n");
140 break;
141 case ADB_ISOKBD:
142 printf("standard keyboard (ISO layout)\n");
143 break;
144 case ADB_EXTKBD:
145 cmd = ADBTALK(sc->adbaddr, 1);
146 kbd_done =
147 (adb_op_sync((Ptr)buffer, cmd) == 0);
148
149
150 if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
151 printf("Mouseman (non-EMP) pseudo keyboard\n");
152 adbinfo.siServiceRtPtr = (Ptr)0;
153 adbinfo.siDataAreaAddr = (Ptr)0;
154 wskbd_eligible = 0;
155 } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
156 printf("Trackman (non-EMP) pseudo keyboard\n");
157 adbinfo.siServiceRtPtr = (Ptr)0;
158 adbinfo.siDataAreaAddr = (Ptr)0;
159 wskbd_eligible = 0;
160 } else {
161 printf("extended keyboard\n");
162 #ifdef notyet
163 blinkleds(sc);
164 #endif
165 }
166 break;
167 case ADB_EXTISOKBD:
168 printf("extended keyboard (ISO layout)\n");
169 #ifdef notyet
170 blinkleds(sc);
171 #endif
172 break;
173 case ADB_KBDII:
174 printf("keyboard II\n");
175 break;
176 case ADB_ISOKBDII:
177 printf("keyboard II (ISO layout)\n");
178 break;
179 case ADB_PBKBD:
180 printf("PowerBook keyboard\n");
181 break;
182 case ADB_PBISOKBD:
183 printf("PowerBook keyboard (ISO layout)\n");
184 break;
185 case ADB_ADJKPD:
186 printf("adjustable keypad\n");
187 wskbd_eligible = 0;
188 break;
189 case ADB_ADJKBD:
190 printf("adjustable keyboard\n");
191 break;
192 case ADB_ADJISOKBD:
193 printf("adjustable keyboard (ISO layout)\n");
194 break;
195 case ADB_ADJJAPKBD:
196 printf("adjustable keyboard (Japanese layout)\n");
197 break;
198 case ADB_PBEXTISOKBD:
199 printf("PowerBook extended keyboard (ISO layout)\n");
200 break;
201 case ADB_PBEXTJAPKBD:
202 printf("PowerBook extended keyboard (Japanese layout)\n");
203 break;
204 case ADB_JPKBDII:
205 printf("keyboard II (Japanese layout)\n");
206 break;
207 case ADB_PBEXTKBD:
208 printf("PowerBook extended keyboard\n");
209 break;
210 case ADB_DESIGNKBD:
211 printf("extended keyboard\n");
212 #ifdef notyet
213 blinkleds(sc);
214 #endif
215 break;
216 case ADB_PBJPKBD:
217 printf("PowerBook keyboard (Japanese layout)\n");
218 break;
219 case ADB_PBG3JPKBD:
220 printf("PowerBook G3 keyboard (Japanese layout)\n");
221 break;
222 case ADB_PBG4KBD:
223 printf("PowerBook G4 keyboard (Inverted T)\n");
224 break;
225 case ADB_IBITISOKBD:
226 printf("iBook keyboard with inverted T (ISO layout)\n");
227 break;
228 default:
229 printf("mapped device (%d)\n", sc->handler_id);
230 #if 0
231 wskbd_eligible = 0;
232 #endif
233 break;
234 }
235 error = set_adb_info(&adbinfo, sc->adbaddr);
236 #ifdef ADB_DEBUG
237 if (adb_debug)
238 printf("akbd: returned %d from set_adb_info\n", error);
239 #endif
240
241 #ifdef WSDISPLAY_COMPAT_RAWKBD
242 timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc);
243 #endif
244
245 if (akbd_is_console() && wskbd_eligible)
246 a.console = (++akbd_console_initted == 1);
247 else
248 a.console = 0;
249 a.keymap = &akbd_keymapdata;
250 a.accessops = &akbd_accessops;
251 a.accesscookie = sc;
252
253 sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
254 }
255
256
257
258
259
260
261 void
262 akbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
263 {
264 adb_event_t event;
265 struct akbd_softc *sc;
266 int adbaddr;
267 #ifdef ADB_DEBUG
268 int i;
269
270 if (adb_debug)
271 printf("adb: transaction completion\n");
272 #endif
273
274 adbaddr = ADB_CMDADDR(adb_command);
275 sc = (struct akbd_softc *)data_area;
276
277 event.byte_count = buffer[0];
278 memcpy(event.bytes, buffer + 1, event.byte_count);
279
280 #ifdef ADB_DEBUG
281 if (adb_debug) {
282 printf("akbd: from %d at %d (org %d) %d:", adbaddr,
283 sc->handler_id, sc->origaddr, buffer[0]);
284 for (i = 1; i <= buffer[0]; i++)
285 printf(" %x", buffer[i]);
286 printf("\n");
287 }
288 #endif
289
290 if (sc->sc_wskbddev != NULL)
291 akbd_processevent(sc, &event);
292 }
293
294 #ifdef notyet
295
296
297
298 u_char
299 getleds(int addr)
300 {
301 short cmd;
302 u_char buffer[9], leds;
303
304 leds = 0x00;
305 buffer[0] = 0;
306
307 cmd = ADBTALK(addr, 2);
308 if (adb_op_sync((Ptr)buffer, cmd) == 0 &&
309 buffer[0] > 0)
310 leds = ~(buffer[2]) & 0x07;
311
312 return (leds);
313 }
314
315
316
317
318
319
320
321 int
322 setleds(struct akbd_softc *sc, u_char leds)
323 {
324 int addr;
325 short cmd;
326 u_char buffer[9];
327
328 addr = sc->adbaddr;
329 buffer[0] = 0;
330
331 cmd = ADBTALK(addr, 2);
332 if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
333 return (EIO);
334
335 leds = ~leds & 0x07;
336 buffer[2] &= 0xf8;
337 buffer[2] |= leds;
338
339 cmd = ADBLISTEN(addr, 2);
340 adb_op_sync((Ptr)buffer, cmd);
341
342
343 cmd = ADBTALK(addr, 2);
344 if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
345 return (EIO);
346
347 if ((buffer[2] & 0xf8) != leds)
348 return (EIO);
349 else
350 return (0);
351 }
352
353
354
355
356 void
357 blinkleds(struct akbd_softc *sc)
358 {
359 u_char origleds;
360
361 origleds = getleds(sc->adbaddr);
362 setleds(sc, LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK);
363 delay(400000);
364 setleds(sc, origleds);
365
366 if (origleds & LED_NUMLOCK)
367 sc->sc_leds |= WSKBD_LED_NUM;
368 if (origleds & LED_CAPSLOCK)
369 sc->sc_leds |= WSKBD_LED_CAPS;
370 if (origleds & LED_SCROLL_LOCK)
371 sc->sc_leds |= WSKBD_LED_SCROLL;
372 }
373 #endif
374
375 int
376 akbd_enable(void *v, int on)
377 {
378 return 0;
379 }
380
381 void
382 akbd_set_leds(void *v, int on)
383 {
384 #ifdef notyet
385 struct akbd_softc *sc = v;
386 int leds;
387
388 if (sc->sc_extended) {
389 if (sc->sc_leds == on)
390 return;
391
392 leds = 0;
393 if (on & WSKBD_LED_NUM)
394 leds |= LED_NUMLOCK;
395 if (on & WSKBD_LED_CAPS)
396 leds |= LED_CAPSLOCK;
397 if (on & WSKBD_LED_SCROLL)
398 leds |= LED_SCROLL_LOCK;
399
400 setleds(sc, leds);
401 }
402 #endif
403 }
404
405 int
406 akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
407 {
408 struct akbd_softc *sc = v;
409
410 switch (cmd) {
411
412 case WSKBDIO_GTYPE:
413 *(int *)data = WSKBD_TYPE_ADB;
414 return 0;
415 case WSKBDIO_SETLEDS:
416 akbd_set_leds(v, *(int *)data);
417 return 0;
418 case WSKBDIO_GETLEDS:
419 *(int *)data = sc->sc_leds;
420 return 0;
421 #ifdef WSDISPLAY_COMPAT_RAWKBD
422 case WSKBDIO_SETMODE:
423 sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
424 timeout_del(&sc->sc_rawrepeat_ch);
425 return (0);
426 #endif
427
428 #ifdef mac68k
429 case WSKBDIO_BELL:
430 case WSKBDIO_COMPLEXBELL:
431 #define d ((struct wskbd_bell_data *)data)
432 mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume);
433 #undef d
434 return (0);
435 #endif
436
437 default:
438 return (-1);
439 }
440 }
441
442 #ifdef WSDISPLAY_COMPAT_RAWKBD
443 void
444 akbd_rawrepeat(void *v)
445 {
446 struct akbd_softc *sc = v;
447 int s;
448
449 s = spltty();
450 wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
451 splx(s);
452 timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
453 }
454 #endif
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476 #define CL_DOWN_ADB 0x01
477 #define CL_DOWN_LOGICAL 0x02
478 #define CL_DOWN_RESET 0x04
479
480
481
482
483 void
484 akbd_processevent(struct akbd_softc *sc, adb_event_t *event)
485 {
486 switch (event->byte_count) {
487 case 1:
488 akbd_capslockwrapper(sc, event->bytes[0]);
489 break;
490 case 2:
491
492
493
494
495 if (event->bytes[0] == event->bytes[1] &&
496 ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
497 if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
498 SET(sc->sc_caps, CL_DOWN_RESET);
499 else {
500 if (ISSET(sc->sc_caps, CL_DOWN_RESET))
501 CLR(sc->sc_caps, CL_DOWN_RESET);
502 else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {
503 akbd_input(sc, ISSET(sc->sc_caps,
504 CL_DOWN_LOGICAL) ?
505 ADBK_KEYDOWN(ADBK_CAPSLOCK) :
506 ADBK_KEYUP(ADBK_CAPSLOCK));
507 sc->sc_caps ^= CL_DOWN_LOGICAL;
508 }
509 }
510 } else {
511 akbd_capslockwrapper(sc, event->bytes[0]);
512 akbd_capslockwrapper(sc, event->bytes[1]);
513 }
514 break;
515 default:
516 #ifdef DIAGNOSTIC
517 printf("%s: unexpected message length %d\n",
518 sc->sc_dev.dv_xname, event->byte_count);
519 #endif
520 break;
521 }
522
523 }
524
525 void
526 akbd_capslockwrapper(struct akbd_softc *sc, int key)
527 {
528 if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK)
529 sc->sc_caps ^= CL_DOWN_ADB;
530
531 if (key != 0xff)
532 akbd_input(sc, key);
533 }
534
535 int adb_polledkey;
536 void
537 akbd_input(struct akbd_softc *sc, int key)
538 {
539 int press, val;
540 int type;
541
542 press = ADBK_PRESS(key);
543 val = ADBK_KEYVAL(key);
544
545 type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
546
547 if (adb_polling) {
548 adb_polledkey = key;
549 #ifdef WSDISPLAY_COMPAT_RAWKBD
550 } else if (sc->sc_rawkbd) {
551 char cbuf[MAXKEYS *2];
552 int c, j, s;
553 int npress;
554
555 j = npress = 0;
556
557 c = keyboard[val];
558 if (c == 0) {
559 return;
560 }
561 if (c & 0x80)
562 cbuf[j++] = 0xe0;
563 cbuf[j] = c & 0x7f;
564 if (type == WSCONS_EVENT_KEY_UP) {
565 cbuf[j] |= 0x80;
566 } else {
567
568 if (c & 0x80)
569 sc->sc_rep[npress++] = 0xe0;
570 sc->sc_rep[npress++] = c & 0x7f;
571 }
572 j++;
573 s = spltty();
574 wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
575 splx(s);
576 timeout_del(&sc->sc_rawrepeat_ch);
577 sc->sc_nrep = npress;
578 if (npress != 0)
579 timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
580 #endif
581 } else {
582 wskbd_input(sc->sc_wskbddev, type, val);
583 }
584 }