linux-bk/drivers/macintosh/adbhid.c
<<
>>
Prefs
   1/*
   2 * drivers/input/adbhid.c
   3 *
   4 * ADB HID driver for Power Macintosh computers.
   5 *
   6 * Adapted from drivers/macintosh/mac_keyb.c by Franz Sirl.
   7 * drivers/macintosh/mac_keyb.c was Copyright (C) 1996 Paul Mackerras
   8 * with considerable contributions from Ben Herrenschmidt and others.
   9 *
  10 * Copyright (C) 2000 Franz Sirl.
  11 *
  12 * Adapted to ADB changes and support for more devices by
  13 * Benjamin Herrenschmidt. Adapted from code in MkLinux
  14 * and reworked.
  15 * 
  16 * Supported devices:
  17 *
  18 * - Standard 1 button mouse
  19 * - All standard Apple Extended protocol (handler ID 4)
  20 * - mouseman and trackman mice & trackballs 
  21 * - PowerBook Trackpad (default setup: enable tapping)
  22 * - MicroSpeed mouse & trackball (needs testing)
  23 * - CH Products Trackball Pro (needs testing)
  24 * - Contour Design (Contour Mouse)
  25 * - Hunter digital (NoHandsMouse)
  26 * - Kensignton TurboMouse 5 (needs testing)
  27 * - Mouse Systems A3 mice and trackballs <aidan@kublai.com>
  28 * - MacAlly 2-buttons mouse (needs testing) <pochini@denise.shiny.it>
  29 *
  30 * To do:
  31 *
  32 * Improve Kensington support.
  33 * Split mouse/kbd
  34 * Move to syfs
  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       /* register # for key up/down data */
  60#define KEYB_LEDREG     2       /* register # for leds on ADB keyboard */
  61#define MOUSE_DATAREG   0       /* reg# for movement/button codes from mouse */
  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/* Some special keys */
  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        /* 0x00 */ KEY_A,               /*  30 */
  79        /* 0x01 */ KEY_S,               /*  31 */
  80        /* 0x02 */ KEY_D,               /*  32 */
  81        /* 0x03 */ KEY_F,               /*  33 */
  82        /* 0x04 */ KEY_H,               /*  35 */
  83        /* 0x05 */ KEY_G,               /*  34 */
  84        /* 0x06 */ KEY_Z,               /*  44 */
  85        /* 0x07 */ KEY_X,               /*  45 */
  86        /* 0x08 */ KEY_C,               /*  46 */
  87        /* 0x09 */ KEY_V,               /*  47 */
  88        /* 0x0a */ KEY_102ND,           /*  86 */
  89        /* 0x0b */ KEY_B,               /*  48 */
  90        /* 0x0c */ KEY_Q,               /*  16 */
  91        /* 0x0d */ KEY_W,               /*  17 */
  92        /* 0x0e */ KEY_E,               /*  18 */
  93        /* 0x0f */ KEY_R,               /*  19 */
  94        /* 0x10 */ KEY_Y,               /*  21 */
  95        /* 0x11 */ KEY_T,               /*  20 */
  96        /* 0x12 */ KEY_1,               /*   2 */
  97        /* 0x13 */ KEY_2,               /*   3 */
  98        /* 0x14 */ KEY_3,               /*   4 */
  99        /* 0x15 */ KEY_4,               /*   5 */
 100        /* 0x16 */ KEY_6,               /*   7 */
 101        /* 0x17 */ KEY_5,               /*   6 */
 102        /* 0x18 */ KEY_EQUAL,           /*  13 */
 103        /* 0x19 */ KEY_9,               /*  10 */
 104        /* 0x1a */ KEY_7,               /*   8 */
 105        /* 0x1b */ KEY_MINUS,           /*  12 */
 106        /* 0x1c */ KEY_8,               /*   9 */
 107        /* 0x1d */ KEY_0,               /*  11 */
 108        /* 0x1e */ KEY_RIGHTBRACE,      /*  27 */
 109        /* 0x1f */ KEY_O,               /*  24 */
 110        /* 0x20 */ KEY_U,               /*  22 */
 111        /* 0x21 */ KEY_LEFTBRACE,       /*  26 */
 112        /* 0x22 */ KEY_I,               /*  23 */
 113        /* 0x23 */ KEY_P,               /*  25 */
 114        /* 0x24 */ KEY_ENTER,           /*  28 */
 115        /* 0x25 */ KEY_L,               /*  38 */
 116        /* 0x26 */ KEY_J,               /*  36 */
 117        /* 0x27 */ KEY_APOSTROPHE,      /*  40 */
 118        /* 0x28 */ KEY_K,               /*  37 */
 119        /* 0x29 */ KEY_SEMICOLON,       /*  39 */
 120        /* 0x2a */ KEY_BACKSLASH,       /*  43 */
 121        /* 0x2b */ KEY_COMMA,           /*  51 */
 122        /* 0x2c */ KEY_SLASH,           /*  53 */
 123        /* 0x2d */ KEY_N,               /*  49 */
 124        /* 0x2e */ KEY_M,               /*  50 */
 125        /* 0x2f */ KEY_DOT,             /*  52 */
 126        /* 0x30 */ KEY_TAB,             /*  15 */
 127        /* 0x31 */ KEY_SPACE,           /*  57 */
 128        /* 0x32 */ KEY_GRAVE,           /*  41 */
 129        /* 0x33 */ KEY_BACKSPACE,       /*  14 */
 130        /* 0x34 */ KEY_KPENTER,         /*  96 */
 131        /* 0x35 */ KEY_ESC,             /*   1 */
 132        /* 0x36 */ KEY_LEFTCTRL,        /*  29 */
 133        /* 0x37 */ KEY_LEFTMETA,        /* 125 */
 134        /* 0x38 */ KEY_LEFTSHIFT,       /*  42 */
 135        /* 0x39 */ KEY_CAPSLOCK,        /*  58 */
 136        /* 0x3a */ KEY_LEFTALT,         /*  56 */
 137        /* 0x3b */ KEY_LEFT,            /* 105 */
 138        /* 0x3c */ KEY_RIGHT,           /* 106 */
 139        /* 0x3d */ KEY_DOWN,            /* 108 */
 140        /* 0x3e */ KEY_UP,              /* 103 */
 141        /* 0x3f */ 0,
 142        /* 0x40 */ 0,
 143        /* 0x41 */ KEY_KPDOT,           /*  83 */
 144        /* 0x42 */ 0,
 145        /* 0x43 */ KEY_KPASTERISK,      /*  55 */
 146        /* 0x44 */ 0,
 147        /* 0x45 */ KEY_KPPLUS,          /*  78 */
 148        /* 0x46 */ 0,
 149        /* 0x47 */ KEY_NUMLOCK,         /*  69 */
 150        /* 0x48 */ 0,
 151        /* 0x49 */ 0,
 152        /* 0x4a */ 0,
 153        /* 0x4b */ KEY_KPSLASH,         /*  98 */
 154        /* 0x4c */ KEY_KPENTER,         /*  96 */
 155        /* 0x4d */ 0,
 156        /* 0x4e */ KEY_KPMINUS,         /*  74 */
 157        /* 0x4f */ 0,
 158        /* 0x50 */ 0,
 159        /* 0x51 */ KEY_KPEQUAL,         /* 117 */
 160        /* 0x52 */ KEY_KP0,             /*  82 */
 161        /* 0x53 */ KEY_KP1,             /*  79 */
 162        /* 0x54 */ KEY_KP2,             /*  80 */
 163        /* 0x55 */ KEY_KP3,             /*  81 */
 164        /* 0x56 */ KEY_KP4,             /*  75 */
 165        /* 0x57 */ KEY_KP5,             /*  76 */
 166        /* 0x58 */ KEY_KP6,             /*  77 */
 167        /* 0x59 */ KEY_KP7,             /*  71 */
 168        /* 0x5a */ 0,
 169        /* 0x5b */ KEY_KP8,             /*  72 */
 170        /* 0x5c */ KEY_KP9,             /*  73 */
 171        /* 0x5d */ KEY_YEN,             /* 124 */
 172        /* 0x5e */ KEY_RO,              /*  89 */
 173        /* 0x5f */ KEY_KPCOMMA,         /* 121 */
 174        /* 0x60 */ KEY_F5,              /*  63 */
 175        /* 0x61 */ KEY_F6,              /*  64 */
 176        /* 0x62 */ KEY_F7,              /*  65 */
 177        /* 0x63 */ KEY_F3,              /*  61 */
 178        /* 0x64 */ KEY_F8,              /*  66 */
 179        /* 0x65 */ KEY_F9,              /*  67 */
 180        /* 0x66 */ KEY_HANJA,           /* 123 */
 181        /* 0x67 */ KEY_F11,             /*  87 */
 182        /* 0x68 */ KEY_HANGUEL,         /* 122 */
 183        /* 0x69 */ KEY_SYSRQ,           /*  99 */
 184        /* 0x6a */ 0,
 185        /* 0x6b */ KEY_SCROLLLOCK,      /*  70 */
 186        /* 0x6c */ 0,
 187        /* 0x6d */ KEY_F10,             /*  68 */
 188        /* 0x6e */ KEY_COMPOSE,         /* 127 */
 189        /* 0x6f */ KEY_F12,             /*  88 */
 190        /* 0x70 */ 0,
 191        /* 0x71 */ KEY_PAUSE,           /* 119 */
 192        /* 0x72 */ KEY_INSERT,          /* 110 */
 193        /* 0x73 */ KEY_HOME,            /* 102 */
 194        /* 0x74 */ KEY_PAGEUP,          /* 104 */
 195        /* 0x75 */ KEY_DELETE,          /* 111 */
 196        /* 0x76 */ KEY_F4,              /*  62 */
 197        /* 0x77 */ KEY_END,             /* 107 */
 198        /* 0x78 */ KEY_F2,              /*  60 */
 199        /* 0x79 */ KEY_PAGEDOWN,        /* 109 */
 200        /* 0x7a */ KEY_F1,              /*  59 */
 201        /* 0x7b */ KEY_RIGHTSHIFT,      /*  54 */
 202        /* 0x7c */ KEY_RIGHTALT,        /* 100 */
 203        /* 0x7d */ KEY_RIGHTCTRL,       /*  97 */
 204        /* 0x7e */ KEY_RIGHTMETA,       /* 126 */
 205        /* 0x7f */ KEY_POWER,           /* 116 */
 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/* Exported to via-pmu.c */
 243int disable_kernel_backlight = 0;
 244#endif /* CONFIG_PMAC_BACKLIGHT */
 245
 246/* Kind of keyboard, see Apple technote 1152  */
 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/* Kind of mouse  */
 253#define ADBMOUSE_STANDARD_100   0       /* Standard 100cpi mouse (handler 1) */
 254#define ADBMOUSE_STANDARD_200   1       /* Standard 200cpi mouse (handler 2) */
 255#define ADBMOUSE_EXTENDED       2       /* Apple Extended mouse (handler 4) */
 256#define ADBMOUSE_TRACKBALL      3       /* TrackBall (handler 4) */
 257#define ADBMOUSE_TRACKPAD       4       /* Apple's PowerBook trackpad (handler 4) */
 258#define ADBMOUSE_TURBOMOUSE5    5       /* Turbomouse 5 (previously req. mousehack) */
 259#define ADBMOUSE_MICROSPEED     6       /* Microspeed mouse (&trackball ?), MacPoint */
 260#define ADBMOUSE_TRACKBALLPRO   7       /* Trackball Pro (special buttons) */
 261#define ADBMOUSE_MS_A3          8       /* Mouse systems A3 trackball (handler 3) */
 262#define ADBMOUSE_MACALLY2       9       /* MacAlly 2-button mouse */
 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        /* first check this is from register 0 */
 276        if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
 277                return;         /* ignore it */
 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: /* Generate down/up events for CapsLock everytime. */
 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: /* Power key on PBook 3400 needs remapping */
 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                /* Fn + Command will produce a bogus "power" keycode */
 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                /* Keep track of the Fn key state */
 324                if (up_flag) {
 325                        ahid->flags &= ~FLAG_FN_KEY_PRESSED;
 326                        /* Emulate Fn+delete = forward delete */
 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                /* Swallow the key press */
 335                return;
 336        case ADB_KEY_DEL:
 337                /* Emulate Fn+delete = forward delete */
 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 /* CONFIG_PPC_PMAC */
 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    Handler 1 -- 100cpi original Apple mouse protocol.
 372    Handler 2 -- 200cpi original Apple mouse protocol.
 373
 374    For Apple's standard one-button mouse protocol the data array will
 375    contain the following values:
 376
 377                BITS    COMMENTS
 378    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
 379    data[1] = bxxx xxxx First button and x-axis motion.
 380    data[2] = byyy yyyy Second button and y-axis motion.
 381
 382    Handler 4 -- Apple Extended mouse protocol.
 383
 384    For Apple's 3-button mouse protocol the data array will contain the
 385    following values:
 386
 387                BITS    COMMENTS
 388    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
 389    data[1] = bxxx xxxx Left button and x-axis motion.
 390    data[2] = byyy yyyy Second button and y-axis motion.
 391    data[3] = byyy bxxx Third button and fourth button.  Y is additional
 392              high bits of y-axis motion.  XY is additional
 393              high bits of x-axis motion.
 394
 395    MacAlly 2-button mouse protocol.
 396
 397    For MacAlly 2-button mouse protocol the data array will contain the
 398    following values:
 399
 400                BITS    COMMENTS
 401    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
 402    data[1] = bxxx xxxx Left button and x-axis motion.
 403    data[2] = byyy yyyy Right button and y-axis motion.
 404    data[3] = ???? ???? unknown
 405    data[4] = ???? ???? unknown
 406
 407  */
 408
 409        /* If it's a trackpad, we alias the second button to the first.
 410           NOTE: Apple sends an ADB flush command to the trackpad when
 411                 the first (the real) button is released. We could do
 412                 this here using async flush requests.
 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;  /* Right button is mapped as button 3 */
 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: /* Adjustable keyboard button device */
 475          {
 476                int down = (data[1] == (data[1] & 0xf));
 477
 478                switch (data[1] & 0x0f) {
 479                case 0x0:       /* microphone */
 480                        input_report_key(&adbhid[id]->input, KEY_SOUND, down);
 481                        break;
 482
 483                case 0x1:       /* mute */
 484                        input_report_key(&adbhid[id]->input, KEY_MUTE, down);
 485                        break;
 486
 487                case 0x2:       /* volume decrease */
 488                        input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
 489                        break;
 490
 491                case 0x3:       /* volume increase */
 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: /* Powerbook button device */
 504          {
 505                int down = (data[1] == (data[1] & 0xf));
 506#ifdef CONFIG_PMAC_BACKLIGHT
 507                int backlight = get_backlight_level();
 508#endif
 509                /*
 510                 * XXX: Where is the contrast control for the passive?
 511                 *  -- Cort
 512                 */
 513
 514                switch (data[1] & 0x0f) {
 515                case 0x8:       /* mute */
 516                        input_report_key(&adbhid[id]->input, KEY_MUTE, down);
 517                        break;
 518
 519                case 0x7:       /* volume decrease */
 520                        input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
 521                        break;
 522
 523                case 0x6:       /* volume increase */
 524                        input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
 525                        break;
 526
 527                case 0xb:       /* eject */
 528                        input_report_key(&adbhid[id]->input, KEY_EJECTCD, down);
 529                        break;
 530
 531                case 0xa:       /* brightness decrease */
 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 /* CONFIG_PMAC_BACKLIGHT */
 542                        input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
 543                        break;
 544
 545                case 0x9:       /* brightness increase */
 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 /* CONFIG_PMAC_BACKLIGHT */
 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 * Event callback from the input module. Events that change the state of
 620 * the hardware are processed here.
 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                /* Stop the repeat timer. Autopoll is already off at this point */
 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                /* Stop pending led requests */
 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: /* Adjustable keyboard button device */
 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: /* Powerbook button device */
 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                /* else fall through */
 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                /* HACK WARNING!! This should go away as soon there is an utility
 799                 * to control that for event devices.
 800                 */
 801                adbhid[id]->input.rep[REP_DELAY] = 500;   /* input layer default: 250 */
 802                adbhid[id]->input.rep[REP_PERIOD] = 66; /* input layer default: 33 */
 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                /* turn off all leds */
 859                adb_request(&req, NULL, ADBREQ_SYNC, 3,
 860                            ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);
 861
 862                /* Enable full feature set of the keyboard
 863                   ->get it to send separate codes for left and right shift,
 864                   control, option keys */
 865#if 0           /* handler 5 doesn't send separate codes for R modifiers */
 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        /* Try to switch all mice to handler 4, or 2 for three-button
 889           mode and full resolution. */
 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                         * Register 1 is usually used for device
 937                         * identification.  Here, we try to identify
 938                         * a known device and call the appropriate
 939                         * init function.
 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, /*r1_buffer[6],*/
1027                    r1_buffer[7]);
1028
1029            /* Without this flush, the trackpad may be locked up */
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        /* This will initialize mice using the Microspeed, MacPoint and
1112           other compatible firmware. Bit 12 enables extended protocol.
1113           
1114           Register 1 Listen (4 Bytes)
1115            0 -  3     Button is mouse (set also for double clicking!!!)
1116            4 -  7     Button is locking (affects change speed also)
1117            8 - 11     Button changes speed
1118           12          1 = Extended mouse mode, 0 = normal mouse mode
1119           13 - 15     unused 0
1120           16 - 23     normal speed
1121           24 - 31     changed speed
1122
1123       Register 1 talk holds version and product identification information.
1124       Register 1 Talk (4 Bytes):
1125            0 -  7     Product code
1126            8 - 23     undefined, reserved
1127           24 - 31     Version number
1128        
1129       Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max.
1130 */
1131        adb_request(&req, NULL, ADBREQ_SYNC, 5,
1132        ADB_WRITEREG(id,1),
1133            0x20,       /* alt speed = 0x20 (rather slow) */
1134            0x00,       /* norm speed = 0x00 (fastest) */
1135            0x10,       /* extended protocol, no speed change */
1136            0x07);      /* all buttons enabled as mouse buttons, no locking */
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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.