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
35
36
37
38#include <linux/module.h>
39#include <linux/slab.h>
40#include <linux/init.h>
41#include <linux/notifier.h>
42#include <linux/input.h>
43
44#include <linux/adb.h>
45#include <linux/cuda.h>
46#include <linux/pmu.h>
47
48#include <asm/machdep.h>
49#ifdef CONFIG_PPC_PMAC
50#include <asm/backlight.h>
51#include <asm/pmac_feature.h>
52#endif
53
54MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>");
55
56static int restore_capslock_events;
57module_param(restore_capslock_events, int, 0644);
58MODULE_PARM_DESC(restore_capslock_events,
59 "Produce keypress events for capslock on both keyup and keydown.");
60
61#define KEYB_KEYREG 0
62#define KEYB_LEDREG 2
63#define MOUSE_DATAREG 0
64
65static int adb_message_handler(struct notifier_block *, unsigned long, void *);
66static struct notifier_block adbhid_adb_notifier = {
67 .notifier_call = adb_message_handler,
68};
69
70
71#define ADB_KEY_DEL 0x33
72#define ADB_KEY_CMD 0x37
73#define ADB_KEY_CAPSLOCK 0x39
74#define ADB_KEY_FN 0x3f
75#define ADB_KEY_FWDEL 0x75
76#define ADB_KEY_POWER_OLD 0x7e
77#define ADB_KEY_POWER 0x7f
78
79static const u16 adb_to_linux_keycodes[128] = {
80 KEY_A,
81 KEY_S,
82 KEY_D,
83 KEY_F,
84 KEY_H,
85 KEY_G,
86 KEY_Z,
87 KEY_X,
88 KEY_C,
89 KEY_V,
90 KEY_102ND,
91 KEY_B,
92 KEY_Q,
93 KEY_W,
94 KEY_E,
95 KEY_R,
96 KEY_Y,
97 KEY_T,
98 KEY_1,
99 KEY_2,
100 KEY_3,
101 KEY_4,
102 KEY_6,
103 KEY_5,
104 KEY_EQUAL,
105 KEY_9,
106 KEY_7,
107 KEY_MINUS,
108 KEY_8,
109 KEY_0,
110 KEY_RIGHTBRACE,
111 KEY_O,
112 KEY_U,
113 KEY_LEFTBRACE,
114 KEY_I,
115 KEY_P,
116 KEY_ENTER,
117 KEY_L,
118 KEY_J,
119 KEY_APOSTROPHE,
120 KEY_K,
121 KEY_SEMICOLON,
122 KEY_BACKSLASH,
123 KEY_COMMA,
124 KEY_SLASH,
125 KEY_N,
126 KEY_M,
127 KEY_DOT,
128 KEY_TAB,
129 KEY_SPACE,
130 KEY_GRAVE,
131 KEY_BACKSPACE,
132 KEY_KPENTER,
133 KEY_ESC,
134 KEY_LEFTCTRL,
135 KEY_LEFTMETA,
136 KEY_LEFTSHIFT,
137 KEY_CAPSLOCK,
138 KEY_LEFTALT,
139 KEY_LEFT,
140 KEY_RIGHT,
141 KEY_DOWN,
142 KEY_UP,
143 KEY_FN,
144 0,
145 KEY_KPDOT,
146 0,
147 KEY_KPASTERISK,
148 0,
149 KEY_KPPLUS,
150 0,
151 KEY_NUMLOCK,
152 0,
153 0,
154 0,
155 KEY_KPSLASH,
156 KEY_KPENTER,
157 0,
158 KEY_KPMINUS,
159 0,
160 0,
161 KEY_KPEQUAL,
162 KEY_KP0,
163 KEY_KP1,
164 KEY_KP2,
165 KEY_KP3,
166 KEY_KP4,
167 KEY_KP5,
168 KEY_KP6,
169 KEY_KP7,
170 0,
171 KEY_KP8,
172 KEY_KP9,
173 KEY_YEN,
174 KEY_RO,
175 KEY_KPCOMMA,
176 KEY_F5,
177 KEY_F6,
178 KEY_F7,
179 KEY_F3,
180 KEY_F8,
181 KEY_F9,
182 KEY_HANJA,
183 KEY_F11,
184 KEY_HANGEUL,
185 KEY_SYSRQ,
186 0,
187 KEY_SCROLLLOCK,
188 0,
189 KEY_F10,
190 KEY_COMPOSE,
191 KEY_F12,
192 0,
193 KEY_PAUSE,
194 KEY_INSERT,
195 KEY_HOME,
196 KEY_PAGEUP,
197 KEY_DELETE,
198 KEY_F4,
199 KEY_END,
200 KEY_F2,
201 KEY_PAGEDOWN,
202 KEY_F1,
203 KEY_RIGHTSHIFT,
204 KEY_RIGHTALT,
205 KEY_RIGHTCTRL,
206 KEY_RIGHTMETA,
207 KEY_POWER,
208};
209
210struct adbhid {
211 struct input_dev *input;
212 int id;
213 int default_id;
214 int original_handler_id;
215 int current_handler_id;
216 int mouse_kind;
217 u16 *keycode;
218 char name[64];
219 char phys[32];
220 int flags;
221};
222
223#define FLAG_FN_KEY_PRESSED 0x00000001
224#define FLAG_POWER_FROM_FN 0x00000002
225#define FLAG_EMU_FWDEL_DOWN 0x00000004
226#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
227#define FLAG_CAPSLOCK_DOWN 0x00000010
228#define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020
229#define FLAG_POWER_KEY_PRESSED 0x00000040
230
231static struct adbhid *adbhid[16];
232
233static void adbhid_probe(void);
234
235static void adbhid_input_keycode(int, int, int);
236
237static void init_trackpad(int id);
238static void init_trackball(int id);
239static void init_turbomouse(int id);
240static void init_microspeed(int id);
241static void init_ms_a3(int id);
242
243static struct adb_ids keyboard_ids;
244static struct adb_ids mouse_ids;
245static struct adb_ids buttons_ids;
246
247
248#define ADB_KEYBOARD_UNKNOWN 0
249#define ADB_KEYBOARD_ANSI 0x0100
250#define ADB_KEYBOARD_ISO 0x0200
251#define ADB_KEYBOARD_JIS 0x0300
252
253
254#define ADBMOUSE_STANDARD_100 0
255#define ADBMOUSE_STANDARD_200 1
256#define ADBMOUSE_EXTENDED 2
257#define ADBMOUSE_TRACKBALL 3
258#define ADBMOUSE_TRACKPAD 4
259#define ADBMOUSE_TURBOMOUSE5 5
260#define ADBMOUSE_MICROSPEED 6
261#define ADBMOUSE_TRACKBALLPRO 7
262#define ADBMOUSE_MS_A3 8
263#define ADBMOUSE_MACALLY2 9
264
265static void
266adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
267{
268 int id = (data[0] >> 4) & 0x0f;
269
270 if (!adbhid[id]) {
271 pr_err("ADB HID on ID %d not yet registered, packet %#02x, %#02x, %#02x, %#02x\n",
272 id, data[0], data[1], data[2], data[3]);
273 return;
274 }
275
276
277 if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
278 return;
279 adbhid_input_keycode(id, data[1], 0);
280 if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
281 adbhid_input_keycode(id, data[2], 0);
282}
283
284static void
285adbhid_input_keycode(int id, int scancode, int repeat)
286{
287 struct adbhid *ahid = adbhid[id];
288 int keycode, up_flag, key;
289
290 keycode = scancode & 0x7f;
291 up_flag = scancode & 0x80;
292
293 if (restore_capslock_events) {
294 if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
295
296
297 if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
298
299
300 ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
301 return;
302 } else {
303 ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
304 | FLAG_CAPSLOCK_DOWN;
305 }
306 } else if (scancode == 0xff &&
307 !(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
308
309
310
311 if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
312 keycode = ADB_KEY_CAPSLOCK;
313 if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
314
315 up_flag = 1;
316 ahid->flags &= ~FLAG_CAPSLOCK_DOWN;
317 } else {
318
319 up_flag = 0;
320 ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE;
321 }
322 } else {
323 pr_info("Spurious caps lock event (scancode 0xff).\n");
324 }
325 }
326 }
327
328 switch (keycode) {
329 case ADB_KEY_CAPSLOCK:
330 if (!restore_capslock_events) {
331
332 input_report_key(ahid->input, KEY_CAPSLOCK, 1);
333 input_sync(ahid->input);
334 input_report_key(ahid->input, KEY_CAPSLOCK, 0);
335 input_sync(ahid->input);
336 return;
337 }
338 break;
339#ifdef CONFIG_PPC_PMAC
340 case ADB_KEY_POWER_OLD:
341 switch(pmac_call_feature(PMAC_FTR_GET_MB_INFO,
342 NULL, PMAC_MB_INFO_MODEL, 0)) {
343 case PMAC_TYPE_COMET:
344 case PMAC_TYPE_HOOPER:
345 case PMAC_TYPE_KANGA:
346 keycode = ADB_KEY_POWER;
347 }
348 break;
349 case ADB_KEY_POWER:
350
351 if (up_flag)
352 ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
353 else
354 ahid->flags |= FLAG_POWER_KEY_PRESSED;
355
356
357 if (ahid->flags & FLAG_FN_KEY_PRESSED) {
358 keycode = ADB_KEY_CMD;
359 if (up_flag)
360 ahid->flags &= ~FLAG_POWER_FROM_FN;
361 else
362 ahid->flags |= FLAG_POWER_FROM_FN;
363 } else if (ahid->flags & FLAG_POWER_FROM_FN) {
364 keycode = ADB_KEY_CMD;
365 ahid->flags &= ~FLAG_POWER_FROM_FN;
366 }
367 break;
368 case ADB_KEY_FN:
369
370 if (up_flag) {
371 ahid->flags &= ~FLAG_FN_KEY_PRESSED;
372
373 if (ahid->flags & FLAG_EMU_FWDEL_DOWN) {
374 ahid->flags &= ~FLAG_EMU_FWDEL_DOWN;
375 keycode = ADB_KEY_FWDEL;
376 break;
377 }
378 } else
379 ahid->flags |= FLAG_FN_KEY_PRESSED;
380 break;
381 case ADB_KEY_DEL:
382
383 if (ahid->flags & FLAG_FN_KEY_PRESSED) {
384 keycode = ADB_KEY_FWDEL;
385 if (up_flag)
386 ahid->flags &= ~FLAG_EMU_FWDEL_DOWN;
387 else
388 ahid->flags |= FLAG_EMU_FWDEL_DOWN;
389 }
390 break;
391#endif
392 }
393
394 key = adbhid[id]->keycode[keycode];
395 if (key) {
396 input_report_key(adbhid[id]->input, key, !up_flag);
397 input_sync(adbhid[id]->input);
398 } else
399 pr_info("Unhandled ADB key (scancode %#02x) %s.\n", keycode,
400 up_flag ? "released" : "pressed");
401
402}
403
404static void
405adbhid_mouse_input(unsigned char *data, int nb, int autopoll)
406{
407 int id = (data[0] >> 4) & 0x0f;
408
409 if (!adbhid[id]) {
410 pr_err("ADB HID on ID %d not yet registered\n", id);
411 return;
412 }
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 switch (adbhid[id]->mouse_kind)
459 {
460 case ADBMOUSE_TRACKPAD:
461 data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
462 data[2] = data[2] | 0x80;
463 break;
464 case ADBMOUSE_MICROSPEED:
465 data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
466 data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
467 data[3] = (data[3] & 0x77) | ((data[3] & 0x04) << 5)
468 | (data[3] & 0x08);
469 break;
470 case ADBMOUSE_TRACKBALLPRO:
471 data[1] = (data[1] & 0x7f) | (((data[3] & 0x04) << 5)
472 & ((data[3] & 0x08) << 4));
473 data[2] = (data[2] & 0x7f) | ((data[3] & 0x01) << 7);
474 data[3] = (data[3] & 0x77) | ((data[3] & 0x02) << 6);
475 break;
476 case ADBMOUSE_MS_A3:
477 data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
478 data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
479 data[3] = ((data[3] & 0x04) << 5);
480 break;
481 case ADBMOUSE_MACALLY2:
482 data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
483 data[2] |= 0x80;
484 nb=4;
485 break;
486 }
487
488 input_report_key(adbhid[id]->input, BTN_LEFT, !((data[1] >> 7) & 1));
489 input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
490
491 if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD)
492 input_report_key(adbhid[id]->input, BTN_RIGHT, !((data[3] >> 7) & 1));
493
494 input_report_rel(adbhid[id]->input, REL_X,
495 ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
496 input_report_rel(adbhid[id]->input, REL_Y,
497 ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));
498
499 input_sync(adbhid[id]->input);
500}
501
502static void
503adbhid_buttons_input(unsigned char *data, int nb, int autopoll)
504{
505 int id = (data[0] >> 4) & 0x0f;
506
507 if (!adbhid[id]) {
508 pr_err("ADB HID on ID %d not yet registered\n", id);
509 return;
510 }
511
512 switch (adbhid[id]->original_handler_id) {
513 default:
514 case 0x02:
515 {
516 int down = (data[1] == (data[1] & 0xf));
517
518 switch (data[1] & 0x0f) {
519 case 0x0:
520 input_report_key(adbhid[id]->input, KEY_SOUND, down);
521 break;
522
523 case 0x1:
524 input_report_key(adbhid[id]->input, KEY_MUTE, down);
525 break;
526
527 case 0x2:
528 input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
529 break;
530
531 case 0x3:
532 input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
533 break;
534
535 default:
536 pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
537 data[0], data[1], data[2], data[3]);
538 break;
539 }
540 }
541 break;
542
543 case 0x1f:
544 {
545 int down = (data[1] == (data[1] & 0xf));
546
547
548
549
550
551
552 switch (data[1] & 0x0f) {
553 case 0x8:
554 input_report_key(adbhid[id]->input, KEY_MUTE, down);
555 break;
556
557 case 0x7:
558 input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
559 break;
560
561 case 0x6:
562 input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
563 break;
564
565 case 0xb:
566 input_report_key(adbhid[id]->input, KEY_EJECTCD, down);
567 break;
568
569 case 0xa:
570#ifdef CONFIG_PMAC_BACKLIGHT
571 if (down)
572 pmac_backlight_key_down();
573#endif
574 input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
575 break;
576
577 case 0x9:
578#ifdef CONFIG_PMAC_BACKLIGHT
579 if (down)
580 pmac_backlight_key_up();
581#endif
582 input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);
583 break;
584
585 case 0xc:
586 input_report_key(adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
587 break;
588
589 case 0xd:
590 input_report_key(adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
591 break;
592
593 case 0xe:
594 input_report_key(adbhid[id]->input, KEY_KBDILLUMDOWN, down);
595 break;
596
597 case 0xf:
598 switch (data[1]) {
599 case 0x8f:
600 case 0x0f:
601
602 input_report_key(adbhid[id]->input, KEY_KBDILLUMUP, down);
603 break;
604
605 case 0x7f:
606 case 0xff:
607
608 break;
609
610 default:
611 pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
612 data[0], data[1], data[2], data[3]);
613 break;
614 }
615 break;
616 default:
617 pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
618 data[0], data[1], data[2], data[3]);
619 break;
620 }
621 }
622 break;
623 }
624
625 input_sync(adbhid[id]->input);
626}
627
628static struct adb_request led_request;
629static int leds_pending[16];
630static int leds_req_pending;
631static int pending_devs[16];
632static int pending_led_start;
633static int pending_led_end;
634static DEFINE_SPINLOCK(leds_lock);
635
636static void leds_done(struct adb_request *req)
637{
638 int leds = 0, device = 0, pending = 0;
639 unsigned long flags;
640
641 spin_lock_irqsave(&leds_lock, flags);
642
643 if (pending_led_start != pending_led_end) {
644 device = pending_devs[pending_led_start];
645 leds = leds_pending[device] & 0xff;
646 leds_pending[device] = 0;
647 pending_led_start++;
648 pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
649 pending = leds_req_pending;
650 } else
651 leds_req_pending = 0;
652 spin_unlock_irqrestore(&leds_lock, flags);
653 if (pending)
654 adb_request(&led_request, leds_done, 0, 3,
655 ADB_WRITEREG(device, KEYB_LEDREG), 0xff, ~leds);
656}
657
658static void real_leds(unsigned char leds, int device)
659{
660 unsigned long flags;
661
662 spin_lock_irqsave(&leds_lock, flags);
663 if (!leds_req_pending) {
664 leds_req_pending = 1;
665 spin_unlock_irqrestore(&leds_lock, flags);
666 adb_request(&led_request, leds_done, 0, 3,
667 ADB_WRITEREG(device, KEYB_LEDREG), 0xff, ~leds);
668 return;
669 } else {
670 if (!(leds_pending[device] & 0x100)) {
671 pending_devs[pending_led_end] = device;
672 pending_led_end++;
673 pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
674 }
675 leds_pending[device] = leds | 0x100;
676 }
677 spin_unlock_irqrestore(&leds_lock, flags);
678}
679
680
681
682
683
684static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
685{
686 struct adbhid *adbhid = input_get_drvdata(dev);
687 unsigned char leds;
688
689 switch (type) {
690 case EV_LED:
691 leds = (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) |
692 (test_bit(LED_NUML, dev->led) ? 1 : 0) |
693 (test_bit(LED_CAPSL, dev->led) ? 2 : 0);
694 real_leds(leds, adbhid->id);
695 return 0;
696 }
697
698 return -1;
699}
700
701static void
702adbhid_kbd_capslock_remember(void)
703{
704 struct adbhid *ahid;
705 int i;
706
707 for (i = 1; i < 16; i++) {
708 ahid = adbhid[i];
709
710 if (ahid && ahid->id == ADB_KEYBOARD)
711 if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
712 ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
713 }
714}
715
716static int
717adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
718{
719 switch (code) {
720 case ADB_MSG_PRE_RESET:
721 case ADB_MSG_POWERDOWN:
722
723 {
724 int i;
725 for (i = 1; i < 16; i++) {
726 if (adbhid[i])
727 del_timer_sync(&adbhid[i]->input->timer);
728 }
729 }
730
731
732 while (leds_req_pending)
733 adb_poll();
734
735
736
737
738
739
740 if (restore_capslock_events)
741 adbhid_kbd_capslock_remember();
742
743 break;
744
745 case ADB_MSG_POST_RESET:
746 adbhid_probe();
747 break;
748 }
749 return NOTIFY_DONE;
750}
751
752static int
753adbhid_input_register(int id, int default_id, int original_handler_id,
754 int current_handler_id, int mouse_kind)
755{
756 struct adbhid *hid;
757 struct input_dev *input_dev;
758 int err;
759 int i;
760
761 if (adbhid[id]) {
762 pr_err("Trying to reregister ADB HID on ID %d\n", id);
763 return -EEXIST;
764 }
765
766 adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL);
767 input_dev = input_allocate_device();
768 if (!hid || !input_dev) {
769 err = -ENOMEM;
770 goto fail;
771 }
772
773 sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
774
775 hid->input = input_dev;
776 hid->id = default_id;
777 hid->original_handler_id = original_handler_id;
778 hid->current_handler_id = current_handler_id;
779 hid->mouse_kind = mouse_kind;
780 hid->flags = 0;
781 input_set_drvdata(input_dev, hid);
782 input_dev->name = hid->name;
783 input_dev->phys = hid->phys;
784 input_dev->id.bustype = BUS_ADB;
785 input_dev->id.vendor = 0x0001;
786 input_dev->id.product = (id << 12) | (default_id << 8) | original_handler_id;
787 input_dev->id.version = 0x0100;
788
789 switch (default_id) {
790 case ADB_KEYBOARD:
791 hid->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL);
792 if (!hid->keycode) {
793 err = -ENOMEM;
794 goto fail;
795 }
796
797 sprintf(hid->name, "ADB keyboard");
798
799 memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
800
801 pr_info("Detected ADB keyboard, type ");
802 switch (original_handler_id) {
803 default:
804 pr_cont("<unknown>.\n");
805 input_dev->id.version = ADB_KEYBOARD_UNKNOWN;
806 break;
807
808 case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
809 case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
810 case 0xC0: case 0xC3: case 0xC6:
811 pr_cont("ANSI.\n");
812 input_dev->id.version = ADB_KEYBOARD_ANSI;
813 break;
814
815 case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
816 case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
817 case 0xC4: case 0xC7:
818 pr_cont("ISO, swapping keys.\n");
819 input_dev->id.version = ADB_KEYBOARD_ISO;
820 i = hid->keycode[10];
821 hid->keycode[10] = hid->keycode[50];
822 hid->keycode[50] = i;
823 break;
824
825 case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
826 case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
827 pr_cont("JIS.\n");
828 input_dev->id.version = ADB_KEYBOARD_JIS;
829 break;
830 }
831
832 for (i = 0; i < 128; i++)
833 if (hid->keycode[i])
834 set_bit(hid->keycode[i], input_dev->keybit);
835
836 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
837 BIT_MASK(EV_REP);
838 input_dev->ledbit[0] = BIT_MASK(LED_SCROLLL) |
839 BIT_MASK(LED_CAPSL) | BIT_MASK(LED_NUML);
840 input_dev->event = adbhid_kbd_event;
841 input_dev->keycodemax = KEY_FN;
842 input_dev->keycodesize = sizeof(hid->keycode[0]);
843 break;
844
845 case ADB_MOUSE:
846 sprintf(hid->name, "ADB mouse");
847
848 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
849 input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
850 BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
851 input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
852 break;
853
854 case ADB_MISC:
855 switch (original_handler_id) {
856 case 0x02:
857 sprintf(hid->name, "ADB adjustable keyboard buttons");
858 input_dev->evbit[0] = BIT_MASK(EV_KEY) |
859 BIT_MASK(EV_REP);
860 set_bit(KEY_SOUND, input_dev->keybit);
861 set_bit(KEY_MUTE, input_dev->keybit);
862 set_bit(KEY_VOLUMEUP, input_dev->keybit);
863 set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
864 break;
865 case 0x1f:
866 sprintf(hid->name, "ADB Powerbook buttons");
867 input_dev->evbit[0] = BIT_MASK(EV_KEY) |
868 BIT_MASK(EV_REP);
869 set_bit(KEY_MUTE, input_dev->keybit);
870 set_bit(KEY_VOLUMEUP, input_dev->keybit);
871 set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
872 set_bit(KEY_BRIGHTNESSUP, input_dev->keybit);
873 set_bit(KEY_BRIGHTNESSDOWN, input_dev->keybit);
874 set_bit(KEY_EJECTCD, input_dev->keybit);
875 set_bit(KEY_SWITCHVIDEOMODE, input_dev->keybit);
876 set_bit(KEY_KBDILLUMTOGGLE, input_dev->keybit);
877 set_bit(KEY_KBDILLUMDOWN, input_dev->keybit);
878 set_bit(KEY_KBDILLUMUP, input_dev->keybit);
879 break;
880 }
881 if (hid->name[0])
882 break;
883
884
885 default:
886 pr_info("Trying to register unknown ADB device to input layer.\n");
887 err = -ENODEV;
888 goto fail;
889 }
890
891 input_dev->keycode = hid->keycode;
892
893 err = input_register_device(input_dev);
894 if (err)
895 goto fail;
896
897 if (default_id == ADB_KEYBOARD) {
898
899
900
901 input_dev->rep[REP_DELAY] = 500;
902 input_dev->rep[REP_PERIOD] = 66;
903 }
904
905 return 0;
906
907 fail: input_free_device(input_dev);
908 if (hid) {
909 kfree(hid->keycode);
910 kfree(hid);
911 }
912 adbhid[id] = NULL;
913 return err;
914}
915
916static void adbhid_input_unregister(int id)
917{
918 input_unregister_device(adbhid[id]->input);
919 kfree(adbhid[id]->keycode);
920 kfree(adbhid[id]);
921 adbhid[id] = NULL;
922}
923
924
925static u16
926adbhid_input_reregister(int id, int default_id, int org_handler_id,
927 int cur_handler_id, int mk)
928{
929 if (adbhid[id]) {
930 if (adbhid[id]->input->id.product !=
931 ((id << 12)|(default_id << 8)|org_handler_id)) {
932 adbhid_input_unregister(id);
933 adbhid_input_register(id, default_id, org_handler_id,
934 cur_handler_id, mk);
935 }
936 } else
937 adbhid_input_register(id, default_id, org_handler_id,
938 cur_handler_id, mk);
939 return 1<<id;
940}
941
942static void
943adbhid_input_devcleanup(u16 exist)
944{
945 int i;
946 for(i=1; i<16; i++)
947 if (adbhid[i] && !(exist&(1<<i)))
948 adbhid_input_unregister(i);
949}
950
951static void
952adbhid_probe(void)
953{
954 struct adb_request req;
955 int i, default_id, org_handler_id, cur_handler_id;
956 u16 reg = 0;
957
958 adb_register(ADB_MOUSE, 0, &mouse_ids, adbhid_mouse_input);
959 adb_register(ADB_KEYBOARD, 0, &keyboard_ids, adbhid_keyboard_input);
960 adb_register(ADB_MISC, 0, &buttons_ids, adbhid_buttons_input);
961
962 for (i = 0; i < keyboard_ids.nids; i++) {
963 int id = keyboard_ids.id[i];
964
965 adb_get_infos(id, &default_id, &org_handler_id);
966
967
968 adb_request(&req, NULL, ADBREQ_SYNC, 3,
969 ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);
970
971
972
973
974#if 0
975 if (adb_try_handler_change(id, 5))
976 printk("ADB keyboard at %d, handler set to 5\n", id);
977 else
978#endif
979 if (adb_try_handler_change(id, 3))
980 printk("ADB keyboard at %d, handler set to 3\n", id);
981 else
982 printk("ADB keyboard at %d, handler 1\n", id);
983
984 adb_get_infos(id, &default_id, &cur_handler_id);
985 reg |= adbhid_input_reregister(id, default_id, org_handler_id,
986 cur_handler_id, 0);
987 }
988
989 for (i = 0; i < buttons_ids.nids; i++) {
990 int id = buttons_ids.id[i];
991
992 adb_get_infos(id, &default_id, &org_handler_id);
993 reg |= adbhid_input_reregister(id, default_id, org_handler_id,
994 org_handler_id, 0);
995 }
996
997
998
999 for (i = 0; i < mouse_ids.nids; i++) {
1000 int id = mouse_ids.id[i];
1001 int mouse_kind;
1002
1003 adb_get_infos(id, &default_id, &org_handler_id);
1004
1005 if (adb_try_handler_change(id, 4)) {
1006 printk("ADB mouse at %d, handler set to 4", id);
1007 mouse_kind = ADBMOUSE_EXTENDED;
1008 }
1009 else if (adb_try_handler_change(id, 0x2F)) {
1010 printk("ADB mouse at %d, handler set to 0x2F", id);
1011 mouse_kind = ADBMOUSE_MICROSPEED;
1012 }
1013 else if (adb_try_handler_change(id, 0x42)) {
1014 printk("ADB mouse at %d, handler set to 0x42", id);
1015 mouse_kind = ADBMOUSE_TRACKBALLPRO;
1016 }
1017 else if (adb_try_handler_change(id, 0x66)) {
1018 printk("ADB mouse at %d, handler set to 0x66", id);
1019 mouse_kind = ADBMOUSE_MICROSPEED;
1020 }
1021 else if (adb_try_handler_change(id, 0x5F)) {
1022 printk("ADB mouse at %d, handler set to 0x5F", id);
1023 mouse_kind = ADBMOUSE_MICROSPEED;
1024 }
1025 else if (adb_try_handler_change(id, 3)) {
1026 printk("ADB mouse at %d, handler set to 3", id);
1027 mouse_kind = ADBMOUSE_MS_A3;
1028 }
1029 else if (adb_try_handler_change(id, 2)) {
1030 printk("ADB mouse at %d, handler set to 2", id);
1031 mouse_kind = ADBMOUSE_STANDARD_200;
1032 }
1033 else {
1034 printk("ADB mouse at %d, handler 1", id);
1035 mouse_kind = ADBMOUSE_STANDARD_100;
1036 }
1037
1038 if ((mouse_kind == ADBMOUSE_TRACKBALLPRO)
1039 || (mouse_kind == ADBMOUSE_MICROSPEED)) {
1040 init_microspeed(id);
1041 } else if (mouse_kind == ADBMOUSE_MS_A3) {
1042 init_ms_a3(id);
1043 } else if (mouse_kind == ADBMOUSE_EXTENDED) {
1044
1045
1046
1047
1048
1049
1050 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
1051 ADB_READREG(id, 1));
1052
1053 if ((req.reply_len) &&
1054 (req.reply[1] == 0x9a) && ((req.reply[2] == 0x21)
1055 || (req.reply[2] == 0x20))) {
1056 mouse_kind = ADBMOUSE_TRACKBALL;
1057 init_trackball(id);
1058 }
1059 else if ((req.reply_len >= 4) &&
1060 (req.reply[1] == 0x74) && (req.reply[2] == 0x70) &&
1061 (req.reply[3] == 0x61) && (req.reply[4] == 0x64)) {
1062 mouse_kind = ADBMOUSE_TRACKPAD;
1063 init_trackpad(id);
1064 }
1065 else if ((req.reply_len >= 4) &&
1066 (req.reply[1] == 0x4b) && (req.reply[2] == 0x4d) &&
1067 (req.reply[3] == 0x4c) && (req.reply[4] == 0x31)) {
1068 mouse_kind = ADBMOUSE_TURBOMOUSE5;
1069 init_turbomouse(id);
1070 }
1071 else if ((req.reply_len == 9) &&
1072 (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
1073 (req.reply[3] == 0x49) && (req.reply[4] == 0x54)) {
1074 if (adb_try_handler_change(id, 0x42)) {
1075 pr_cont("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id);
1076 mouse_kind = ADBMOUSE_MACALLY2;
1077 }
1078 }
1079 }
1080 pr_cont("\n");
1081
1082 adb_get_infos(id, &default_id, &cur_handler_id);
1083 reg |= adbhid_input_reregister(id, default_id, org_handler_id,
1084 cur_handler_id, mouse_kind);
1085 }
1086 adbhid_input_devcleanup(reg);
1087}
1088
1089static void
1090init_trackpad(int id)
1091{
1092 struct adb_request req;
1093 unsigned char r1_buffer[8];
1094
1095 pr_cont(" (trackpad)");
1096
1097 adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
1098 ADB_READREG(id,1));
1099 if (req.reply_len < 8)
1100 pr_cont("bad length for reg. 1\n");
1101 else
1102 {
1103 memcpy(r1_buffer, &req.reply[1], 8);
1104
1105 adb_request(&req, NULL, ADBREQ_SYNC, 9,
1106 ADB_WRITEREG(id,1),
1107 r1_buffer[0],
1108 r1_buffer[1],
1109 r1_buffer[2],
1110 r1_buffer[3],
1111 r1_buffer[4],
1112 r1_buffer[5],
1113 0x0d,
1114 r1_buffer[7]);
1115
1116 adb_request(&req, NULL, ADBREQ_SYNC, 9,
1117 ADB_WRITEREG(id,2),
1118 0x99,
1119 0x94,
1120 0x19,
1121 0xff,
1122 0xb2,
1123 0x8a,
1124 0x1b,
1125 0x50);
1126
1127 adb_request(&req, NULL, ADBREQ_SYNC, 9,
1128 ADB_WRITEREG(id,1),
1129 r1_buffer[0],
1130 r1_buffer[1],
1131 r1_buffer[2],
1132 r1_buffer[3],
1133 r1_buffer[4],
1134 r1_buffer[5],
1135 0x03,
1136 r1_buffer[7]);
1137
1138
1139 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1140 }
1141}
1142
1143static void
1144init_trackball(int id)
1145{
1146 struct adb_request req;
1147
1148 pr_cont(" (trackman/mouseman)");
1149
1150 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1151 ADB_WRITEREG(id,1), 00,0x81);
1152
1153 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1154 ADB_WRITEREG(id,1), 01,0x81);
1155
1156 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1157 ADB_WRITEREG(id,1), 02,0x81);
1158
1159 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1160 ADB_WRITEREG(id,1), 03,0x38);
1161
1162 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1163 ADB_WRITEREG(id,1), 00,0x81);
1164
1165 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1166 ADB_WRITEREG(id,1), 01,0x81);
1167
1168 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1169 ADB_WRITEREG(id,1), 02,0x81);
1170
1171 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1172 ADB_WRITEREG(id,1), 03,0x38);
1173}
1174
1175static void
1176init_turbomouse(int id)
1177{
1178 struct adb_request req;
1179
1180 pr_cont(" (TurboMouse 5)");
1181
1182 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1183
1184 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
1185
1186 adb_request(&req, NULL, ADBREQ_SYNC, 9,
1187 ADB_WRITEREG(3,2),
1188 0xe7,
1189 0x8c,
1190 0,
1191 0,
1192 0,
1193 0xff,
1194 0xff,
1195 0x94);
1196
1197 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
1198
1199 adb_request(&req, NULL, ADBREQ_SYNC, 9,
1200 ADB_WRITEREG(3,2),
1201 0xa5,
1202 0x14,
1203 0,
1204 0,
1205 0x69,
1206 0xff,
1207 0xff,
1208 0x27);
1209}
1210
1211static void
1212init_microspeed(int id)
1213{
1214 struct adb_request req;
1215
1216 pr_cont(" (Microspeed/MacPoint or compatible)");
1217
1218 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240 adb_request(&req, NULL, ADBREQ_SYNC, 5,
1241 ADB_WRITEREG(id,1),
1242 0x20,
1243 0x00,
1244 0x10,
1245 0x07);
1246
1247
1248 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1249}
1250
1251static void
1252init_ms_a3(int id)
1253{
1254 struct adb_request req;
1255
1256 pr_cont(" (Mouse Systems A3 Mouse, or compatible)");
1257 adb_request(&req, NULL, ADBREQ_SYNC, 3,
1258 ADB_WRITEREG(id, 0x2),
1259 0x00,
1260 0x07);
1261
1262 adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
1263}
1264
1265static int __init adbhid_init(void)
1266{
1267#ifndef CONFIG_MAC
1268 if (!machine_is(chrp) && !machine_is(powermac))
1269 return 0;
1270#endif
1271
1272 led_request.complete = 1;
1273
1274 adbhid_probe();
1275
1276 blocking_notifier_chain_register(&adb_client_list,
1277 &adbhid_adb_notifier);
1278
1279 return 0;
1280}
1281
1282static void __exit adbhid_exit(void)
1283{
1284}
1285
1286module_init(adbhid_init);
1287module_exit(adbhid_exit);
1288