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