// SPDX-License-Identifier: GPL-2.0
/*
 * drivers/macintosh/adbhid.c
 *
 * ADB HID driver for Power Macintosh computers.
 *
 * Adapted from drivers/macintosh/mac_keyb.c by Franz Sirl.
 * drivers/macintosh/mac_keyb.c was Copyright (C) 1996 Paul Mackerras
 * with considerable contributions from Ben Herrenschmidt and others.
 *
 * Copyright (C) 2000 Franz Sirl.
 *
 * Adapted to ADB changes and support for more devices by
 * Benjamin Herrenschmidt. Adapted from code in MkLinux
 * and reworked.
 * 
 * Supported devices:
 *
 * - Standard 1 button mouse
 * - All standard Apple Extended protocol (handler ID 4)
 * - mouseman and trackman mice & trackballs 
 * - PowerBook Trackpad (default setup: enable tapping)
 * - MicroSpeed mouse & trackball (needs testing)
 * - CH Products Trackball Pro (needs testing)
 * - Contour Design (Contour Mouse)
 * - Hunter digital (NoHandsMouse)
 * - Kensignton TurboMouse 5 (needs testing)
 * - Mouse Systems A3 mice and trackballs <aidan@kublai.com>
 * - MacAlly 2-buttons mouse (needs testing) <pochini@denise.shiny.it>
 *
 * To do:
 *
 * Improve Kensington support.
 * Split mouse/kbd
 * Move to syfs
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/input.h>

#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>

#include <asm/machdep.h>
#ifdef CONFIG_PPC_PMAC
#include <asm/backlight.h>
#include <asm/pmac_feature.h>
#endif

MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>");

static int restore_capslock_events;
module_param(restore_capslock_events, int, 0644);
MODULE_PARM_DESC(restore_capslock_events,
	"Produce keypress events for capslock on both keyup and keydown.");

#define KEYB_KEYREG	0	/* register # for key up/down data */
#define KEYB_LEDREG	2	/* register # for leds on ADB keyboard */
#define MOUSE_DATAREG	0	/* reg# for movement/button codes from mouse */

static int adb_message_handler(struct notifier_block *, unsigned long, void *);
static struct notifier_block adbhid_adb_notifier = {
	.notifier_call	= adb_message_handler,
};

/* Some special keys */
#define ADB_KEY_DEL		0x33
#define ADB_KEY_CMD		0x37
#define ADB_KEY_CAPSLOCK	0x39
#define ADB_KEY_FN		0x3f
#define ADB_KEY_FWDEL		0x75
#define ADB_KEY_POWER_OLD	0x7e
#define ADB_KEY_POWER		0x7f

static const u16 adb_to_linux_keycodes[128] = {
	/* 0x00 */ KEY_A, 		/*  30 */
	/* 0x01 */ KEY_S, 		/*  31 */
	/* 0x02 */ KEY_D,		/*  32 */
	/* 0x03 */ KEY_F,		/*  33 */
	/* 0x04 */ KEY_H,		/*  35 */
	/* 0x05 */ KEY_G,		/*  34 */
	/* 0x06 */ KEY_Z,		/*  44 */
	/* 0x07 */ KEY_X,		/*  45 */
	/* 0x08 */ KEY_C,		/*  46 */
	/* 0x09 */ KEY_V,		/*  47 */
	/* 0x0a */ KEY_102ND,		/*  86 */
	/* 0x0b */ KEY_B,		/*  48 */
	/* 0x0c */ KEY_Q,		/*  16 */
	/* 0x0d */ KEY_W,		/*  17 */
	/* 0x0e */ KEY_E,		/*  18 */
	/* 0x0f */ KEY_R,		/*  19 */
	/* 0x10 */ KEY_Y,		/*  21 */
	/* 0x11 */ KEY_T,		/*  20 */
	/* 0x12 */ KEY_1,		/*   2 */
	/* 0x13 */ KEY_2,		/*   3 */
	/* 0x14 */ KEY_3,		/*   4 */
	/* 0x15 */ KEY_4,		/*   5 */
	/* 0x16 */ KEY_6,		/*   7 */
	/* 0x17 */ KEY_5,		/*   6 */
	/* 0x18 */ KEY_EQUAL,		/*  13 */
	/* 0x19 */ KEY_9,		/*  10 */
	/* 0x1a */ KEY_7,		/*   8 */
	/* 0x1b */ KEY_MINUS,		/*  12 */
	/* 0x1c */ KEY_8,		/*   9 */
	/* 0x1d */ KEY_0,		/*  11 */
	/* 0x1e */ KEY_RIGHTBRACE,	/*  27 */
	/* 0x1f */ KEY_O,		/*  24 */
	/* 0x20 */ KEY_U,		/*  22 */
	/* 0x21 */ KEY_LEFTBRACE,	/*  26 */
	/* 0x22 */ KEY_I,		/*  23 */
	/* 0x23 */ KEY_P,		/*  25 */
	/* 0x24 */ KEY_ENTER,		/*  28 */
	/* 0x25 */ KEY_L,		/*  38 */
	/* 0x26 */ KEY_J,		/*  36 */
	/* 0x27 */ KEY_APOSTROPHE,	/*  40 */
	/* 0x28 */ KEY_K,		/*  37 */
	/* 0x29 */ KEY_SEMICOLON,	/*  39 */
	/* 0x2a */ KEY_BACKSLASH,	/*  43 */
	/* 0x2b */ KEY_COMMA,		/*  51 */
	/* 0x2c */ KEY_SLASH,		/*  53 */
	/* 0x2d */ KEY_N,		/*  49 */
	/* 0x2e */ KEY_M,		/*  50 */
	/* 0x2f */ KEY_DOT,		/*  52 */
	/* 0x30 */ KEY_TAB,		/*  15 */
	/* 0x31 */ KEY_SPACE,		/*  57 */
	/* 0x32 */ KEY_GRAVE,		/*  41 */
	/* 0x33 */ KEY_BACKSPACE,	/*  14 */
	/* 0x34 */ KEY_KPENTER,		/*  96 */
	/* 0x35 */ KEY_ESC,		/*   1 */
	/* 0x36 */ KEY_LEFTCTRL,	/*  29 */
	/* 0x37 */ KEY_LEFTMETA,	/* 125 */
	/* 0x38 */ KEY_LEFTSHIFT,	/*  42 */
	/* 0x39 */ KEY_CAPSLOCK,	/*  58 */
	/* 0x3a */ KEY_LEFTALT,		/*  56 */
	/* 0x3b */ KEY_LEFT,		/* 105 */
	/* 0x3c */ KEY_RIGHT,		/* 106 */
	/* 0x3d */ KEY_DOWN,		/* 108 */
	/* 0x3e */ KEY_UP,		/* 103 */
	/* 0x3f */ KEY_FN,		/* 0x1d0 */
	/* 0x40 */ 0,
	/* 0x41 */ KEY_KPDOT,		/*  83 */
	/* 0x42 */ 0,
	/* 0x43 */ KEY_KPASTERISK,	/*  55 */
	/* 0x44 */ 0,
	/* 0x45 */ KEY_KPPLUS,		/*  78 */
	/* 0x46 */ 0,
	/* 0x47 */ KEY_NUMLOCK,		/*  69 */
	/* 0x48 */ 0,
	/* 0x49 */ 0,
	/* 0x4a */ 0,
	/* 0x4b */ KEY_KPSLASH,		/*  98 */
	/* 0x4c */ KEY_KPENTER,		/*  96 */
	/* 0x4d */ 0,
	/* 0x4e */ KEY_KPMINUS,		/*  74 */
	/* 0x4f */ 0,
	/* 0x50 */ 0,
	/* 0x51 */ KEY_KPEQUAL,		/* 117 */
	/* 0x52 */ KEY_KP0,		/*  82 */
	/* 0x53 */ KEY_KP1,		/*  79 */
	/* 0x54 */ KEY_KP2,		/*  80 */
	/* 0x55 */ KEY_KP3,		/*  81 */
	/* 0x56 */ KEY_KP4,		/*  75 */
	/* 0x57 */ KEY_KP5,		/*  76 */
	/* 0x58 */ KEY_KP6,		/*  77 */
	/* 0x59 */ KEY_KP7,		/*  71 */
	/* 0x5a */ 0,
	/* 0x5b */ KEY_KP8,		/*  72 */
	/* 0x5c */ KEY_KP9,		/*  73 */
	/* 0x5d */ KEY_YEN,		/* 124 */
	/* 0x5e */ KEY_RO,		/*  89 */
	/* 0x5f */ KEY_KPCOMMA,		/* 121 */
	/* 0x60 */ KEY_F5,		/*  63 */
	/* 0x61 */ KEY_F6,		/*  64 */
	/* 0x62 */ KEY_F7,		/*  65 */
	/* 0x63 */ KEY_F3,		/*  61 */
	/* 0x64 */ KEY_F8,		/*  66 */
	/* 0x65 */ KEY_F9,		/*  67 */
	/* 0x66 */ KEY_HANJA,		/* 123 */
	/* 0x67 */ KEY_F11,		/*  87 */
	/* 0x68 */ KEY_HANGEUL,		/* 122 */
	/* 0x69 */ KEY_SYSRQ,		/*  99 */
	/* 0x6a */ 0,
	/* 0x6b */ KEY_SCROLLLOCK,	/*  70 */
	/* 0x6c */ 0,
	/* 0x6d */ KEY_F10,		/*  68 */
	/* 0x6e */ KEY_COMPOSE,		/* 127 */
	/* 0x6f */ KEY_F12,		/*  88 */
	/* 0x70 */ 0,
	/* 0x71 */ KEY_PAUSE,		/* 119 */
	/* 0x72 */ KEY_INSERT,		/* 110 */
	/* 0x73 */ KEY_HOME,		/* 102 */
	/* 0x74 */ KEY_PAGEUP,		/* 104 */
	/* 0x75 */ KEY_DELETE,		/* 111 */
	/* 0x76 */ KEY_F4,		/*  62 */
	/* 0x77 */ KEY_END,		/* 107 */
	/* 0x78 */ KEY_F2,		/*  60 */
	/* 0x79 */ KEY_PAGEDOWN,	/* 109 */
	/* 0x7a */ KEY_F1,		/*  59 */
	/* 0x7b */ KEY_RIGHTSHIFT,	/*  54 */
	/* 0x7c */ KEY_RIGHTALT,	/* 100 */
	/* 0x7d */ KEY_RIGHTCTRL,	/*  97 */
	/* 0x7e */ KEY_RIGHTMETA,	/* 126 */
	/* 0x7f */ KEY_POWER,		/* 116 */
};

struct adbhid {
	struct input_dev *input;
	int id;
	int default_id;
	int original_handler_id;
	int current_handler_id;
	int mouse_kind;
	u16 *keycode;
	char name[64];
	char phys[32];
	int flags;
};

#define FLAG_FN_KEY_PRESSED		0x00000001
#define FLAG_POWER_FROM_FN		0x00000002
#define FLAG_EMU_FWDEL_DOWN		0x00000004
#define FLAG_CAPSLOCK_TRANSLATE		0x00000008
#define FLAG_CAPSLOCK_DOWN		0x00000010
#define FLAG_CAPSLOCK_IGNORE_NEXT	0x00000020
#define FLAG_POWER_KEY_PRESSED		0x00000040

static struct adbhid *adbhid[16];

static void adbhid_probe(void);

static void adbhid_input_keycode(int, int, int);

static void init_trackpad(int id);
static void init_trackball(int id);
static void init_turbomouse(int id);
static void init_microspeed(int id);
static void init_ms_a3(int id);

static struct adb_ids keyboard_ids;
static struct adb_ids mouse_ids;
static struct adb_ids buttons_ids;

/* Kind of keyboard, see Apple technote 1152  */
#define ADB_KEYBOARD_UNKNOWN	0
#define ADB_KEYBOARD_ANSI	0x0100
#define ADB_KEYBOARD_ISO	0x0200
#define ADB_KEYBOARD_JIS	0x0300

/* Kind of mouse  */
#define ADBMOUSE_STANDARD_100	0	/* Standard 100cpi mouse (handler 1) */
#define ADBMOUSE_STANDARD_200	1	/* Standard 200cpi mouse (handler 2) */
#define ADBMOUSE_EXTENDED	2	/* Apple Extended mouse (handler 4) */
#define ADBMOUSE_TRACKBALL	3	/* TrackBall (handler 4) */
#define ADBMOUSE_TRACKPAD       4	/* Apple's PowerBook trackpad (handler 4) */
#define ADBMOUSE_TURBOMOUSE5    5	/* Turbomouse 5 (previously req. mousehack) */
#define ADBMOUSE_MICROSPEED	6	/* Microspeed mouse (&trackball ?), MacPoint */
#define ADBMOUSE_TRACKBALLPRO	7	/* Trackball Pro (special buttons) */
#define ADBMOUSE_MS_A3		8	/* Mouse systems A3 trackball (handler 3) */
#define ADBMOUSE_MACALLY2	9	/* MacAlly 2-button mouse */

static void
adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
{
	int id = (data[0] >> 4) & 0x0f;

	if (!adbhid[id]) {
		pr_err("ADB HID on ID %d not yet registered, packet %#02x, %#02x, %#02x, %#02x\n",
		       id, data[0], data[1], data[2], data[3]);
		return;
	}

	/* first check this is from register 0 */
	if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
		return;		/* ignore it */
	adbhid_input_keycode(id, data[1], 0);
	if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
		adbhid_input_keycode(id, data[2], 0);
}

static void
adbhid_input_keycode(int id, int scancode, int repeat)
{
	struct adbhid *ahid = adbhid[id];
	int keycode, up_flag, key;

	keycode = scancode & 0x7f;
	up_flag = scancode & 0x80;

	if (restore_capslock_events) {
		if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
			/* Key pressed, turning on the CapsLock LED.
			 * The next 0xff will be interpreted as a release. */
			if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
				/* Throw away this key event if it happens
				 * just after resume. */
				ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
				return;
			} else {
				ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
					| FLAG_CAPSLOCK_DOWN;
			}
		} else if (scancode == 0xff &&
			   !(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
			/* Scancode 0xff usually signifies that the capslock
			 * key was either pressed or released, or that the
			 * power button was released. */
			if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
				keycode = ADB_KEY_CAPSLOCK;
				if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
					/* Key released */
					up_flag = 1;
					ahid->flags &= ~FLAG_CAPSLOCK_DOWN;
				} else {
					/* Key pressed */
					up_flag = 0;
					ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE;
				}
			} else {
				pr_info("Spurious caps lock event (scancode 0xff).\n");
			}
		}
	}

	switch (keycode) {
	case ADB_KEY_CAPSLOCK:
		if (!restore_capslock_events) {
			/* Generate down/up events for CapsLock every time. */
			input_report_key(ahid->input, KEY_CAPSLOCK, 1);
			input_sync(ahid->input);
			input_report_key(ahid->input, KEY_CAPSLOCK, 0);
			input_sync(ahid->input);
			return;
		}
		break;
#ifdef CONFIG_PPC_PMAC
	case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */
		switch(pmac_call_feature(PMAC_FTR_GET_MB_INFO,
			NULL, PMAC_MB_INFO_MODEL, 0)) {
		case PMAC_TYPE_COMET:
		case PMAC_TYPE_HOOPER:
		case PMAC_TYPE_KANGA:
			keycode = ADB_KEY_POWER;
		}
		break;
	case ADB_KEY_POWER:
		/* Keep track of the power key state */
		if (up_flag)
			ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
		else
			ahid->flags |= FLAG_POWER_KEY_PRESSED;

		/* Fn + Command will produce a bogus "power" keycode */
		if (ahid->flags & FLAG_FN_KEY_PRESSED) {
			keycode = ADB_KEY_CMD;
			if (up_flag)
				ahid->flags &= ~FLAG_POWER_FROM_FN;
			else
				ahid->flags |= FLAG_POWER_FROM_FN;
		} else if (ahid->flags & FLAG_POWER_FROM_FN) {
			keycode = ADB_KEY_CMD;
			ahid->flags &= ~FLAG_POWER_FROM_FN;
		}
		break;
	case ADB_KEY_FN:
		/* Keep track of the Fn key state */
		if (up_flag) {
			ahid->flags &= ~FLAG_FN_KEY_PRESSED;
			/* Emulate Fn+delete = forward delete */
			if (ahid->flags & FLAG_EMU_FWDEL_DOWN) {
				ahid->flags &= ~FLAG_EMU_FWDEL_DOWN;
				keycode = ADB_KEY_FWDEL;
				break;
			}
		} else
			ahid->flags |= FLAG_FN_KEY_PRESSED;
		break;
	case ADB_KEY_DEL:
		/* Emulate Fn+delete = forward delete */
		if (ahid->flags & FLAG_FN_KEY_PRESSED) {
			keycode = ADB_KEY_FWDEL;
			if (up_flag)
				ahid->flags &= ~FLAG_EMU_FWDEL_DOWN;
			else
				ahid->flags |= FLAG_EMU_FWDEL_DOWN;
		}
		break;
#endif /* CONFIG_PPC_PMAC */
	}

	key = adbhid[id]->keycode[keycode];
	if (key) {
		input_report_key(adbhid[id]->input, key, !up_flag);
		input_sync(adbhid[id]->input);
	} else
		pr_info("Unhandled ADB key (scancode %#02x) %s.\n", keycode,
			up_flag ? "released" : "pressed");

}

static void
adbhid_mouse_input(unsigned char *data, int nb, int autopoll)
{
	int id = (data[0] >> 4) & 0x0f;

	if (!adbhid[id]) {
		pr_err("ADB HID on ID %d not yet registered\n", id);
		return;
	}

  /*
    Handler 1 -- 100cpi original Apple mouse protocol.
    Handler 2 -- 200cpi original Apple mouse protocol.

    For Apple's standard one-button mouse protocol the data array will
    contain the following values:

                BITS    COMMENTS
    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
    data[1] = bxxx xxxx First button and x-axis motion.
    data[2] = byyy yyyy Second button and y-axis motion.

    Handler 4 -- Apple Extended mouse protocol.

    For Apple's 3-button mouse protocol the data array will contain the
    following values:

		BITS    COMMENTS
    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
    data[1] = bxxx xxxx Left button and x-axis motion.
    data[2] = byyy yyyy Second button and y-axis motion.
    data[3] = byyy bxxx Third button and fourth button.  Y is additional
	      high bits of y-axis motion.  XY is additional
	      high bits of x-axis motion.

    MacAlly 2-button mouse protocol.

    For MacAlly 2-button mouse protocol the data array will contain the
    following values:

		BITS    COMMENTS
    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
    data[1] = bxxx xxxx Left button and x-axis motion.
    data[2] = byyy yyyy Right button and y-axis motion.
    data[3] = ???? ???? unknown
    data[4] = ???? ???? unknown

  */

	/* If it's a trackpad, we alias the second button to the first.
	   NOTE: Apple sends an ADB flush command to the trackpad when
	         the first (the real) button is released. We could do
		 this here using async flush requests.
	*/
	switch (adbhid[id]->mouse_kind)
	{
	    case ADBMOUSE_TRACKPAD:
		data[1] = (data[1] & 0x7f) | ((data[1] & data[2]) & 0x80);
		data[2] = data[2] | 0x80;
		break;
	    case ADBMOUSE_MICROSPEED:
		data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
		data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
		data[3] = (data[3] & 0x77) | ((data[3] & 0x04) << 5)
			| (data[3] & 0x08);
		break;
	    case ADBMOUSE_TRACKBALLPRO:
		data[1] = (data[1] & 0x7f) | (((data[3] & 0x04) << 5)
			& ((data[3] & 0x08) << 4));
		data[2] = (data[2] & 0x7f) | ((data[3] & 0x01) << 7);
		data[3] = (data[3] & 0x77) | ((data[3] & 0x02) << 6);
		break;
	    case ADBMOUSE_MS_A3:
		data[1] = (data[1] & 0x7f) | ((data[3] & 0x01) << 7);
		data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
		data[3] = ((data[3] & 0x04) << 5);
		break;
            case ADBMOUSE_MACALLY2:
		data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
		data[2] |= 0x80;  /* Right button is mapped as button 3 */
		nb=4;
                break;
	}

	input_report_key(adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
	input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));

	if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD)
		input_report_key(adbhid[id]->input, BTN_RIGHT,  !((data[3] >> 7) & 1));

	input_report_rel(adbhid[id]->input, REL_X,
			 ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
	input_report_rel(adbhid[id]->input, REL_Y,
			 ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));

	input_sync(adbhid[id]->input);
}

static void
adbhid_buttons_input(unsigned char *data, int nb, int autopoll)
{
	int id = (data[0] >> 4) & 0x0f;

	if (!adbhid[id]) {
		pr_err("ADB HID on ID %d not yet registered\n", id);
		return;
	}

	switch (adbhid[id]->original_handler_id) {
	default:
	case 0x02: /* Adjustable keyboard button device */
	  {
		int down = (data[1] == (data[1] & 0xf));

		switch (data[1] & 0x0f) {
		case 0x0:	/* microphone */
			input_report_key(adbhid[id]->input, KEY_SOUND, down);
			break;

		case 0x1:	/* mute */
			input_report_key(adbhid[id]->input, KEY_MUTE, down);
			break;

		case 0x2:	/* volume decrease */
			input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
			break;

		case 0x3:	/* volume increase */
			input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
			break;

		default:
			pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
				data[0], data[1], data[2], data[3]);
			break;
		}
	  }
	  break;

	case 0x1f: /* Powerbook button device */
	  {
		int down = (data[1] == (data[1] & 0xf));

		/*
		 * XXX: Where is the contrast control for the passive?
		 *  -- Cort
		 */

		switch (data[1] & 0x0f) {
		case 0x8:	/* mute */
			input_report_key(adbhid[id]->input, KEY_MUTE, down);
			break;

		case 0x7:	/* volume decrease */
			input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
			break;

		case 0x6:	/* volume increase */
			input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
			break;

		case 0xb:	/* eject */
			input_report_key(adbhid[id]->input, KEY_EJECTCD, down);
			break;

		case 0xa:	/* brightness decrease */
#ifdef CONFIG_PMAC_BACKLIGHT
			if (down)
				pmac_backlight_key_down();
#endif
			input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
			break;

		case 0x9:	/* brightness increase */
#ifdef CONFIG_PMAC_BACKLIGHT
			if (down)
				pmac_backlight_key_up();
#endif
			input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);
			break;

		case 0xc:	/* videomode switch */
			input_report_key(adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
			break;

		case 0xd:	/* keyboard illumination toggle */
			input_report_key(adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
			break;

		case 0xe:	/* keyboard illumination decrease */
			input_report_key(adbhid[id]->input, KEY_KBDILLUMDOWN, down);
			break;

		case 0xf:
			switch (data[1]) {
			case 0x8f:
			case 0x0f:
				/* keyboard illumination increase */
				input_report_key(adbhid[id]->input, KEY_KBDILLUMUP, down);
				break;

			case 0x7f:
			case 0xff:
				/* keypad overlay toogle */
				break;

			default:
				pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
					data[0], data[1], data[2], data[3]);
				break;
			}
			break;
		default:
			pr_info("Unhandled ADB_MISC event %02x, %02x, %02x, %02x\n",
				data[0], data[1], data[2], data[3]);
			break;
		}
	  }
	  break;
	}

	input_sync(adbhid[id]->input);
}

static struct adb_request led_request;
static int leds_pending[16];
static int leds_req_pending;
static int pending_devs[16];
static int pending_led_start;
static int pending_led_end;
static DEFINE_SPINLOCK(leds_lock);

static void leds_done(struct adb_request *req)
{
	int leds = 0, device = 0, pending = 0;
	unsigned long flags;

	spin_lock_irqsave(&leds_lock, flags);

	if (pending_led_start != pending_led_end) {
		device = pending_devs[pending_led_start];
		leds = leds_pending[device] & 0xff;
		leds_pending[device] = 0;
		pending_led_start++;
		pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
		pending = leds_req_pending;
	} else
		leds_req_pending = 0;
	spin_unlock_irqrestore(&leds_lock, flags);
	if (pending)
		adb_request(&led_request, leds_done, 0, 3,
			    ADB_WRITEREG(device, KEYB_LEDREG), 0xff, ~leds);
}

static void real_leds(unsigned char leds, int device)
{
	unsigned long flags;

	spin_lock_irqsave(&leds_lock, flags);
	if (!leds_req_pending) {
		leds_req_pending = 1;
		spin_unlock_irqrestore(&leds_lock, flags);	       
		adb_request(&led_request, leds_done, 0, 3,
			    ADB_WRITEREG(device, KEYB_LEDREG), 0xff, ~leds);
		return;
	} else {
		if (!(leds_pending[device] & 0x100)) {
			pending_devs[pending_led_end] = device;
			pending_led_end++;
			pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
		}
		leds_pending[device] = leds | 0x100;
	}
	spin_unlock_irqrestore(&leds_lock, flags);	       
}

/*
 * Event callback from the input module. Events that change the state of
 * the hardware are processed here.
 */
static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
	struct adbhid *adbhid = input_get_drvdata(dev);
	unsigned char leds;

	switch (type) {
	case EV_LED:
		leds =  (test_bit(LED_SCROLLL, dev->led) ? 4 : 0) |
			(test_bit(LED_NUML,    dev->led) ? 1 : 0) |
			(test_bit(LED_CAPSL,   dev->led) ? 2 : 0);
		real_leds(leds, adbhid->id);
		return 0;
	}

	return -1;
}

static void
adbhid_kbd_capslock_remember(void)
{
	struct adbhid *ahid;
	int i;

	for (i = 1; i < 16; i++) {
		ahid = adbhid[i];

		if (ahid && ahid->id == ADB_KEYBOARD)
			if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
				ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
	}
}

static int
adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
{
	switch (code) {
	case ADB_MSG_PRE_RESET:
	case ADB_MSG_POWERDOWN:
		/* Stop the repeat timer. Autopoll is already off at this point */
		{
			int i;
			for (i = 1; i < 16; i++) {
				if (adbhid[i])
					del_timer_sync(&adbhid[i]->input->timer);
			}
		}

		/* Stop pending led requests */
		while (leds_req_pending)
			adb_poll();

		/* After resume, and if the capslock LED is on, the PMU will
		 * send a "capslock down" key event. This confuses the
		 * restore_capslock_events logic. Remember if the capslock
		 * LED was on before suspend so the unwanted key event can
		 * be ignored after resume. */
		if (restore_capslock_events)
			adbhid_kbd_capslock_remember();

		break;

	case ADB_MSG_POST_RESET:
		adbhid_probe();
		break;
	}
	return NOTIFY_DONE;
}

static int
adbhid_input_register(int id, int default_id, int original_handler_id,
		      int current_handler_id, int mouse_kind)
{
	struct adbhid *hid;
	struct input_dev *input_dev;
	int err;
	int i;
	char *keyboard_type;

	if (adbhid[id]) {
		pr_err("Trying to reregister ADB HID on ID %d\n", id);
		return -EEXIST;
	}

	adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!hid || !input_dev) {
		err = -ENOMEM;
		goto fail;
	}

	sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);

	hid->input = input_dev;
	hid->id = default_id;
	hid->original_handler_id = original_handler_id;
	hid->current_handler_id = current_handler_id;
	hid->mouse_kind = mouse_kind;
	hid->flags = 0;
	input_set_drvdata(input_dev, hid);
	input_dev->name = hid->name;
	input_dev->phys = hid->phys;
	input_dev->id.bustype = BUS_ADB;
	input_dev->id.vendor = 0x0001;
	input_dev->id.product = (id << 12) | (default_id << 8) | original_handler_id;
	input_dev->id.version = 0x0100;

	switch (default_id) {
	case ADB_KEYBOARD:
		hid->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL);
		if (!hid->keycode) {
			err = -ENOMEM;
			goto fail;
		}

		sprintf(hid->name, "ADB keyboard");

		memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));

		switch (original_handler_id) {
		default:
			keyboard_type = "<unknown>";
			input_dev->id.version = ADB_KEYBOARD_UNKNOWN;
			break;

		case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
		case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
		case 0xC0: case 0xC3: case 0xC6:
			keyboard_type = "ANSI";
			input_dev->id.version = ADB_KEYBOARD_ANSI;
			break;

		case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
		case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
		case 0xC4: case 0xC7:
			keyboard_type = "ISO, swapping keys";
			input_dev->id.version = ADB_KEYBOARD_ISO;
			i = hid->keycode[10];
			hid->keycode[10] = hid->keycode[50];
			hid->keycode[50] = i;
			break;

		case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
		case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
			keyboard_type = "JIS";
			input_dev->id.version = ADB_KEYBOARD_JIS;
			break;
		}
		pr_info("Detected ADB keyboard, type %s.\n", keyboard_type);

		for (i = 0; i < 128; i++)
			if (hid->keycode[i])
				set_bit(hid->keycode[i], input_dev->keybit);

		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
			BIT_MASK(EV_REP);
		input_dev->ledbit[0] = BIT_MASK(LED_SCROLLL) |
			BIT_MASK(LED_CAPSL) | BIT_MASK(LED_NUML);
		input_dev->event = adbhid_kbd_event;
		input_dev->keycodemax = KEY_FN;
		input_dev->keycodesize = sizeof(hid->keycode[0]);
		break;

	case ADB_MOUSE:
		sprintf(hid->name, "ADB mouse");

		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
		input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
			BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
		input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
		break;

	case ADB_MISC:
		switch (original_handler_id) {
		case 0x02: /* Adjustable keyboard button device */
			sprintf(hid->name, "ADB adjustable keyboard buttons");
			input_dev->evbit[0] = BIT_MASK(EV_KEY) |
				BIT_MASK(EV_REP);
			set_bit(KEY_SOUND, input_dev->keybit);
			set_bit(KEY_MUTE, input_dev->keybit);
			set_bit(KEY_VOLUMEUP, input_dev->keybit);
			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
			break;
		case 0x1f: /* Powerbook button device */
			sprintf(hid->name, "ADB Powerbook buttons");
			input_dev->evbit[0] = BIT_MASK(EV_KEY) |
				BIT_MASK(EV_REP);
			set_bit(KEY_MUTE, input_dev->keybit);
			set_bit(KEY_VOLUMEUP, input_dev->keybit);
			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
			set_bit(KEY_BRIGHTNESSUP, input_dev->keybit);
			set_bit(KEY_BRIGHTNESSDOWN, input_dev->keybit);
			set_bit(KEY_EJECTCD, input_dev->keybit);
			set_bit(KEY_SWITCHVIDEOMODE, input_dev->keybit);
			set_bit(KEY_KBDILLUMTOGGLE, input_dev->keybit);
			set_bit(KEY_KBDILLUMDOWN, input_dev->keybit);
			set_bit(KEY_KBDILLUMUP, input_dev->keybit);
			break;
		}
		if (hid->name[0])
			break;
		fallthrough;

	default:
		pr_info("Trying to register unknown ADB device to input layer.\n");
		err = -ENODEV;
		goto fail;
	}

	input_dev->keycode = hid->keycode;

	err = input_register_device(input_dev);
	if (err)
		goto fail;

	if (default_id == ADB_KEYBOARD) {
		/* HACK WARNING!! This should go away as soon there is an utility
		 * to control that for event devices.
		 */
		input_dev->rep[REP_DELAY] = 500;   /* input layer default: 250 */
		input_dev->rep[REP_PERIOD] = 66; /* input layer default: 33 */
	}

	return 0;

 fail:	input_free_device(input_dev);
	if (hid) {
		kfree(hid->keycode);
		kfree(hid);
	}
	adbhid[id] = NULL;
	return err;
}

static void adbhid_input_unregister(int id)
{
	input_unregister_device(adbhid[id]->input);
	kfree(adbhid[id]->keycode);
	kfree(adbhid[id]);
	adbhid[id] = NULL;
}


static u16
adbhid_input_reregister(int id, int default_id, int org_handler_id,
			int cur_handler_id, int mk)
{
	if (adbhid[id]) {
		if (adbhid[id]->input->id.product !=
		    ((id << 12)|(default_id << 8)|org_handler_id)) {
			adbhid_input_unregister(id);
			adbhid_input_register(id, default_id, org_handler_id,
					      cur_handler_id, mk);
		}
	} else
		adbhid_input_register(id, default_id, org_handler_id,
				      cur_handler_id, mk);
	return 1<<id;
}

static void
adbhid_input_devcleanup(u16 exist)
{
	int i;
	for(i=1; i<16; i++)
		if (adbhid[i] && !(exist&(1<<i)))
			adbhid_input_unregister(i);
}

static void
adbhid_probe(void)
{
	struct adb_request req;
	int i, default_id, org_handler_id, cur_handler_id;
	u16 reg = 0;

	adb_register(ADB_MOUSE, 0, &mouse_ids, adbhid_mouse_input);
	adb_register(ADB_KEYBOARD, 0, &keyboard_ids, adbhid_keyboard_input);
	adb_register(ADB_MISC, 0, &buttons_ids, adbhid_buttons_input);

	for (i = 0; i < keyboard_ids.nids; i++) {
		int id = keyboard_ids.id[i];

		adb_get_infos(id, &default_id, &org_handler_id);

		/* turn off all leds */
		adb_request(&req, NULL, ADBREQ_SYNC, 3,
			    ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);

		/* Enable full feature set of the keyboard
		   ->get it to send separate codes for left and right shift,
		   control, option keys */
#if 0		/* handler 5 doesn't send separate codes for R modifiers */
		if (!adb_try_handler_change(id, 5))
#endif
		adb_try_handler_change(id, 3);

		adb_get_infos(id, &default_id, &cur_handler_id);
		printk(KERN_DEBUG "ADB keyboard at %d has handler 0x%X\n",
		       id, cur_handler_id);
		reg |= adbhid_input_reregister(id, default_id, org_handler_id,
					       cur_handler_id, 0);
	}

	for (i = 0; i < buttons_ids.nids; i++) {
		int id = buttons_ids.id[i];

		adb_get_infos(id, &default_id, &org_handler_id);
		reg |= adbhid_input_reregister(id, default_id, org_handler_id,
					       org_handler_id, 0);
	}

	/* Try to switch all mice to handler 4, or 2 for three-button
	   mode and full resolution. */
	for (i = 0; i < mouse_ids.nids; i++) {
		int id = mouse_ids.id[i];
		int mouse_kind;
		char *desc = "standard";

		adb_get_infos(id, &default_id, &org_handler_id);

		if (adb_try_handler_change(id, 4)) {
			mouse_kind = ADBMOUSE_EXTENDED;
		}
		else if (adb_try_handler_change(id, 0x2F)) {
			mouse_kind = ADBMOUSE_MICROSPEED;
		}
		else if (adb_try_handler_change(id, 0x42)) {
			mouse_kind = ADBMOUSE_TRACKBALLPRO;
		}
		else if (adb_try_handler_change(id, 0x66)) {
			mouse_kind = ADBMOUSE_MICROSPEED;
		}
		else if (adb_try_handler_change(id, 0x5F)) {
			mouse_kind = ADBMOUSE_MICROSPEED;
		}
		else if (adb_try_handler_change(id, 3)) {
			mouse_kind = ADBMOUSE_MS_A3;
		}
		else if (adb_try_handler_change(id, 2)) {
			mouse_kind = ADBMOUSE_STANDARD_200;
		}
		else {
			mouse_kind = ADBMOUSE_STANDARD_100;
		}

		if ((mouse_kind == ADBMOUSE_TRACKBALLPRO)
		    || (mouse_kind == ADBMOUSE_MICROSPEED)) {
			desc = "Microspeed/MacPoint or compatible";
			init_microspeed(id);
		} else if (mouse_kind == ADBMOUSE_MS_A3) {
			desc = "Mouse Systems A3 Mouse or compatible";
			init_ms_a3(id);
		} else if (mouse_kind ==  ADBMOUSE_EXTENDED) {
			desc = "extended";
			/*
			 * Register 1 is usually used for device
			 * identification.  Here, we try to identify
			 * a known device and call the appropriate
			 * init function.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    ADB_READREG(id, 1));

			if ((req.reply_len) &&
			    (req.reply[1] == 0x9a) && ((req.reply[2] == 0x21)
			    	|| (req.reply[2] == 0x20))) {
				mouse_kind = ADBMOUSE_TRACKBALL;
				desc = "trackman/mouseman";
				init_trackball(id);
			}
			else if ((req.reply_len >= 4) &&
			    (req.reply[1] == 0x74) && (req.reply[2] == 0x70) &&
			    (req.reply[3] == 0x61) && (req.reply[4] == 0x64)) {
				mouse_kind = ADBMOUSE_TRACKPAD;
				desc = "trackpad";
				init_trackpad(id);
			}
			else if ((req.reply_len >= 4) &&
			    (req.reply[1] == 0x4b) && (req.reply[2] == 0x4d) &&
			    (req.reply[3] == 0x4c) && (req.reply[4] == 0x31)) {
				mouse_kind = ADBMOUSE_TURBOMOUSE5;
				desc = "TurboMouse 5";
				init_turbomouse(id);
			}
			else if ((req.reply_len == 9) &&
			    (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
			    (req.reply[3] == 0x49) && (req.reply[4] == 0x54)) {
				if (adb_try_handler_change(id, 0x42)) {
					mouse_kind = ADBMOUSE_MACALLY2;
					desc = "MacAlly 2-button";
				}
			}
		}

		adb_get_infos(id, &default_id, &cur_handler_id);
		printk(KERN_DEBUG "ADB mouse (%s) at %d has handler 0x%X\n",
		       desc, id, cur_handler_id);
		reg |= adbhid_input_reregister(id, default_id, org_handler_id,
					       cur_handler_id, mouse_kind);
	}
	adbhid_input_devcleanup(reg);
}

static void 
init_trackpad(int id)
{
	struct adb_request req;
	unsigned char r1_buffer[8];

	adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
		    ADB_READREG(id,1));
	if (req.reply_len < 8)
		pr_err("%s: bad length for reg. 1\n", __func__);
	else
	{
	    memcpy(r1_buffer, &req.reply[1], 8);

	    adb_request(&req, NULL, ADBREQ_SYNC, 9,
	        ADB_WRITEREG(id,1),
	            r1_buffer[0],
	            r1_buffer[1],
	            r1_buffer[2],
	            r1_buffer[3],
	            r1_buffer[4],
	            r1_buffer[5],
	            0x0d,
	            r1_buffer[7]);

            adb_request(&req, NULL, ADBREQ_SYNC, 9,
	        ADB_WRITEREG(id,2),
	    	    0x99,
	    	    0x94,
	    	    0x19,
	    	    0xff,
	    	    0xb2,
	    	    0x8a,
	    	    0x1b,
	    	    0x50);

	    adb_request(&req, NULL, ADBREQ_SYNC, 9,
	        ADB_WRITEREG(id,1),
	            r1_buffer[0],
	            r1_buffer[1],
	            r1_buffer[2],
	            r1_buffer[3],
	            r1_buffer[4],
	            r1_buffer[5],
	            0x03, /*r1_buffer[6],*/
	            r1_buffer[7]);

	    /* Without this flush, the trackpad may be locked up */
	    adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
        }
}

static void 
init_trackball(int id)
{
	struct adb_request req;

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 00,0x81);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 01,0x81);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 02,0x81);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 03,0x38);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 00,0x81);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 01,0x81);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 02,0x81);

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id,1), 03,0x38);
}

static void
init_turbomouse(int id)
{
	struct adb_request req;

	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));

	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));

	adb_request(&req, NULL, ADBREQ_SYNC, 9,
	ADB_WRITEREG(3,2),
	    0xe7,
	    0x8c,
	    0,
	    0,
	    0,
	    0xff,
	    0xff,
	    0x94);

	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));

	adb_request(&req, NULL, ADBREQ_SYNC, 9,
	ADB_WRITEREG(3,2),
	    0xa5,
	    0x14,
	    0,
	    0,
	    0x69,
	    0xff,
	    0xff,
	    0x27);
}

static void
init_microspeed(int id)
{
	struct adb_request req;

	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));

	/* This will initialize mice using the Microspeed, MacPoint and
	   other compatible firmware. Bit 12 enables extended protocol.
	   
	   Register 1 Listen (4 Bytes)
            0 -  3     Button is mouse (set also for double clicking!!!)
            4 -  7     Button is locking (affects change speed also)
            8 - 11     Button changes speed
           12          1 = Extended mouse mode, 0 = normal mouse mode
           13 - 15     unused 0
           16 - 23     normal speed
           24 - 31     changed speed

       Register 1 talk holds version and product identification information.
       Register 1 Talk (4 Bytes):
            0 -  7     Product code
            8 - 23     undefined, reserved
           24 - 31     Version number
        
       Speed 0 is max. 1 to 255 set speed in increments of 1/256 of max.
 */
	adb_request(&req, NULL, ADBREQ_SYNC, 5,
	ADB_WRITEREG(id,1),
	    0x20,	/* alt speed = 0x20 (rather slow) */
	    0x00,	/* norm speed = 0x00 (fastest) */
	    0x10,	/* extended protocol, no speed change */
	    0x07);	/* all buttons enabled as mouse buttons, no locking */


	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
}

static void
init_ms_a3(int id)
{
	struct adb_request req;

	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	ADB_WRITEREG(id, 0x2),
	    0x00,
	    0x07);
 
 	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
}

static int __init adbhid_init(void)
{
#ifndef CONFIG_MAC
	if (!machine_is(chrp) && !machine_is(powermac))
		return 0;
#endif

	led_request.complete = 1;

	adbhid_probe();

	blocking_notifier_chain_register(&adb_client_list,
			&adbhid_adb_notifier);

	return 0;
}

static void __exit adbhid_exit(void)
{
}
 
module_init(adbhid_init);
module_exit(adbhid_exit);
