/*
 *  Copyright (C) 2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
 */

/*
 * LK keyboard driver for Linux, based on sunkbd.c (C) by Vojtech Pavlik
 */

/*
 * DEC LK201 and LK401 keyboard driver for Linux (primary for DECstations
 * and VAXstations, but can also be used on any standard RS232 with an
 * adaptor).
 *
 * DISCLAIMER: This works for _me_. If you break anything by using the
 * information given below, I will _not_ be liable!
 *
 * RJ10 pinout:		To DE9:		Or DB25:
 *	1 - RxD <---->	Pin 3 (TxD) <->	Pin 2 (TxD)
 *	2 - GND <---->	Pin 5 (GND) <->	Pin 7 (GND)
 *	4 - TxD <---->	Pin 2 (RxD) <->	Pin 3 (RxD)
 *	3 - +12V (from HDD drive connector), DON'T connect to DE9 or DB25!!!
 *
 * Pin numbers for DE9 and DB25 are noted on the plug (quite small:). For
 * RJ10, it's like this:
 *
 *      __=__	Hold the plug in front of you, cable downwards,
 *     /___/|	nose is hidden behind the plug. Now, pin 1 is at
 *    |1234||	the left side, pin 4 at the right and 2 and 3 are
 *    |IIII||	in between, of course:)
 *    |    ||
 *    |____|/
 *      ||	So the adaptor consists of three connected cables
 *      ||	for data transmission (RxD and TxD) and signal ground.
 *		Additionally, you have to get +12V from somewhere.
 * Most easily, you'll get that from a floppy or HDD power connector.
 * It's the yellow cable there (black is ground and red is +5V).
 *
 * The keyboard and all the commands it understands are documented in
 * "VCB02 Video Subsystem - Technical Manual", EK-104AA-TM-001. This
 * document is LK201 specific, but LK401 is mostly compatible. It comes
 * up in LK201 mode and doesn't report any of the additional keys it
 * has. These need to be switched on with the LK_CMD_ENABLE_LK401
 * command. You'll find this document (scanned .pdf file) on MANX,
 * a search engine specific to DEC documentation. Try
 * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
 */

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>

#define DRIVER_DESC	"LK keyboard driver"

MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
MODULE_DESCRIPTION (DRIVER_DESC);
MODULE_LICENSE ("GPL");

/*
 * Known parameters:
 *	bell_volume
 *	keyclick_volume
 *	ctrlclick_volume
 *
 * Please notice that there's not yet an API to set these at runtime.
 */
static int bell_volume = 100; /* % */
module_param (bell_volume, int, 0);
MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%");

static int keyclick_volume = 100; /* % */
module_param (keyclick_volume, int, 0);
MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%");

static int ctrlclick_volume = 100; /* % */
module_param (ctrlclick_volume, int, 0);
MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");

static int lk201_compose_is_alt;
module_param (lk201_compose_is_alt, int, 0);
MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
		"will act as an Alt key");



#undef LKKBD_DEBUG
#ifdef LKKBD_DEBUG
#define DBG(x...) printk (x)
#else
#define DBG(x...) do {} while (0)
#endif

/* LED control */
#define LK_LED_WAIT		0x81
#define LK_LED_COMPOSE		0x82
#define LK_LED_SHIFTLOCK	0x84
#define LK_LED_SCROLLLOCK	0x88
#define LK_CMD_LED_ON		0x13
#define LK_CMD_LED_OFF		0x11

/* Mode control */
#define LK_MODE_DOWN		0x80
#define LK_MODE_AUTODOWN	0x82
#define LK_MODE_UPDOWN		0x86
#define LK_CMD_SET_MODE(mode,div)	((mode) | ((div) << 3))

/* Misc commands */
#define LK_CMD_ENABLE_KEYCLICK	0x1b
#define LK_CMD_DISABLE_KEYCLICK	0x99
#define LK_CMD_DISABLE_BELL	0xa1
#define LK_CMD_SOUND_BELL	0xa7
#define LK_CMD_ENABLE_BELL	0x23
#define LK_CMD_DISABLE_CTRCLICK	0xb9
#define LK_CMD_ENABLE_CTRCLICK	0xbb
#define LK_CMD_SET_DEFAULTS	0xd3
#define LK_CMD_POWERCYCLE_RESET	0xfd
#define LK_CMD_ENABLE_LK401	0xe9
#define LK_CMD_REQUEST_ID	0xab

/* Misc responses from keyboard */
#define LK_STUCK_KEY		0x3d
#define LK_SELFTEST_FAILED	0x3e
#define LK_ALL_KEYS_UP		0xb3
#define LK_METRONOME		0xb4
#define LK_OUTPUT_ERROR		0xb5
#define LK_INPUT_ERROR		0xb6
#define LK_KBD_LOCKED		0xb7
#define LK_KBD_TEST_MODE_ACK	0xb8
#define LK_PREFIX_KEY_DOWN	0xb9
#define LK_MODE_CHANGE_ACK	0xba
#define LK_RESPONSE_RESERVED	0xbb

#define LK_NUM_KEYCODES		256
#define LK_NUM_IGNORE_BYTES	6
typedef u_int16_t lk_keycode_t;



static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
	[0x56] = KEY_F1,
	[0x57] = KEY_F2,
	[0x58] = KEY_F3,
	[0x59] = KEY_F4,
	[0x5a] = KEY_F5,
	[0x64] = KEY_F6,
	[0x65] = KEY_F7,
	[0x66] = KEY_F8,
	[0x67] = KEY_F9,
	[0x68] = KEY_F10,
	[0x71] = KEY_F11,
	[0x72] = KEY_F12,
	[0x73] = KEY_F13,
	[0x74] = KEY_F14,
	[0x7c] = KEY_F15,
	[0x7d] = KEY_F16,
	[0x80] = KEY_F17,
	[0x81] = KEY_F18,
	[0x82] = KEY_F19,
	[0x83] = KEY_F20,
	[0x8a] = KEY_FIND,
	[0x8b] = KEY_INSERT,
	[0x8c] = KEY_DELETE,
	[0x8d] = KEY_SELECT,
	[0x8e] = KEY_PAGEUP,
	[0x8f] = KEY_PAGEDOWN,
	[0x92] = KEY_KP0,
	[0x94] = KEY_KPDOT,
	[0x95] = KEY_KPENTER,
	[0x96] = KEY_KP1,
	[0x97] = KEY_KP2,
	[0x98] = KEY_KP3,
	[0x99] = KEY_KP4,
	[0x9a] = KEY_KP5,
	[0x9b] = KEY_KP6,
	[0x9c] = KEY_KPCOMMA,
	[0x9d] = KEY_KP7,
	[0x9e] = KEY_KP8,
	[0x9f] = KEY_KP9,
	[0xa0] = KEY_KPMINUS,
	[0xa1] = KEY_PROG1,
	[0xa2] = KEY_PROG2,
	[0xa3] = KEY_PROG3,
	[0xa4] = KEY_PROG4,
	[0xa7] = KEY_LEFT,
	[0xa8] = KEY_RIGHT,
	[0xa9] = KEY_DOWN,
	[0xaa] = KEY_UP,
	[0xab] = KEY_RIGHTSHIFT,
	[0xac] = KEY_LEFTALT,
	[0xad] = KEY_COMPOSE, /* Right Compose, that is. */
	[0xae] = KEY_LEFTSHIFT, /* Same as KEY_RIGHTSHIFT on LK201 */
	[0xaf] = KEY_LEFTCTRL,
	[0xb0] = KEY_CAPSLOCK,
	[0xb1] = KEY_COMPOSE, /* Left Compose, that is. */
	[0xb2] = KEY_RIGHTALT,
	[0xbc] = KEY_BACKSPACE,
	[0xbd] = KEY_ENTER,
	[0xbe] = KEY_TAB,
	[0xbf] = KEY_ESC,
	[0xc0] = KEY_1,
	[0xc1] = KEY_Q,
	[0xc2] = KEY_A,
	[0xc3] = KEY_Z,
	[0xc5] = KEY_2,
	[0xc6] = KEY_W,
	[0xc7] = KEY_S,
	[0xc8] = KEY_X,
	[0xc9] = KEY_102ND,
	[0xcb] = KEY_3,
	[0xcc] = KEY_E,
	[0xcd] = KEY_D,
	[0xce] = KEY_C,
	[0xd0] = KEY_4,
	[0xd1] = KEY_R,
	[0xd2] = KEY_F,
	[0xd3] = KEY_V,
	[0xd4] = KEY_SPACE,
	[0xd6] = KEY_5,
	[0xd7] = KEY_T,
	[0xd8] = KEY_G,
	[0xd9] = KEY_B,
	[0xdb] = KEY_6,
	[0xdc] = KEY_Y,
	[0xdd] = KEY_H,
	[0xde] = KEY_N,
	[0xe0] = KEY_7,
	[0xe1] = KEY_U,
	[0xe2] = KEY_J,
	[0xe3] = KEY_M,
	[0xe5] = KEY_8,
	[0xe6] = KEY_I,
	[0xe7] = KEY_K,
	[0xe8] = KEY_COMMA,
	[0xea] = KEY_9,
	[0xeb] = KEY_O,
	[0xec] = KEY_L,
	[0xed] = KEY_DOT,
	[0xef] = KEY_0,
	[0xf0] = KEY_P,
	[0xf2] = KEY_SEMICOLON,
	[0xf3] = KEY_SLASH,
	[0xf5] = KEY_EQUAL,
	[0xf6] = KEY_RIGHTBRACE,
	[0xf7] = KEY_BACKSLASH,
	[0xf9] = KEY_MINUS,
	[0xfa] = KEY_LEFTBRACE,
	[0xfb] = KEY_APOSTROPHE,
};

#define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do {		\
	if (test_bit (LED, (LK)->dev->led))			\
		VAR_ON |= BITS;					\
	else							\
		VAR_OFF |= BITS;				\
	} while (0)

/*
 * Per-keyboard data
 */
struct lkkbd {
	lk_keycode_t keycode[LK_NUM_KEYCODES];
	int ignore_bytes;
	unsigned char id[LK_NUM_IGNORE_BYTES];
	struct input_dev *dev;
	struct serio *serio;
	struct work_struct tq;
	char name[64];
	char phys[32];
	char type;
	int bell_volume;
	int keyclick_volume;
	int ctrlclick_volume;
};

#ifdef LKKBD_DEBUG
/*
 * Responses from the keyboard and mapping back to their names.
 */
static struct {
	unsigned char value;
	unsigned char *name;
} lk_response[] = {
#define RESPONSE(x) { .value = (x), .name = #x, }
	RESPONSE (LK_STUCK_KEY),
	RESPONSE (LK_SELFTEST_FAILED),
	RESPONSE (LK_ALL_KEYS_UP),
	RESPONSE (LK_METRONOME),
	RESPONSE (LK_OUTPUT_ERROR),
	RESPONSE (LK_INPUT_ERROR),
	RESPONSE (LK_KBD_LOCKED),
	RESPONSE (LK_KBD_TEST_MODE_ACK),
	RESPONSE (LK_PREFIX_KEY_DOWN),
	RESPONSE (LK_MODE_CHANGE_ACK),
	RESPONSE (LK_RESPONSE_RESERVED),
#undef RESPONSE
};

static unsigned char *
response_name (unsigned char value)
{
	int i;

	for (i = 0; i < ARRAY_SIZE (lk_response); i++)
		if (lk_response[i].value == value)
			return lk_response[i].name;

	return "<unknown>";
}
#endif /* LKKBD_DEBUG */

/*
 * Calculate volume parameter byte for a given volume.
 */
static unsigned char
volume_to_hw (int volume_percent)
{
	unsigned char ret = 0;

	if (volume_percent < 0)
		volume_percent = 0;
	if (volume_percent > 100)
		volume_percent = 100;

	if (volume_percent >= 0)
		ret = 7;
	if (volume_percent >= 13)	/* 12.5 */
		ret = 6;
	if (volume_percent >= 25)
		ret = 5;
	if (volume_percent >= 38)	/* 37.5 */
		ret = 4;
	if (volume_percent >= 50)
		ret = 3;
	if (volume_percent >= 63)	/* 62.5 */
		ret = 2;		/* This is the default volume */
	if (volume_percent >= 75)
		ret = 1;
	if (volume_percent >= 88)	/* 87.5 */
		ret = 0;

	ret |= 0x80;

	return ret;
}

static void
lkkbd_detection_done (struct lkkbd *lk)
{
	int i;

	/*
	 * Reset setting for Compose key. Let Compose be KEY_COMPOSE.
	 */
	lk->keycode[0xb1] = KEY_COMPOSE;

	/*
	 * Print keyboard name and modify Compose=Alt on user's request.
	 */
	switch (lk->id[4]) {
		case 1:
			strlcpy (lk->name, "DEC LK201 keyboard",
				 sizeof (lk->name));

			if (lk201_compose_is_alt)
				lk->keycode[0xb1] = KEY_LEFTALT;
			break;

		case 2:
			strlcpy (lk->name, "DEC LK401 keyboard",
				 sizeof (lk->name));
			break;

		default:
			strlcpy (lk->name, "Unknown DEC keyboard",
				 sizeof (lk->name));
			printk (KERN_ERR "lkkbd: keyboard on %s is unknown, "
					"please report to Jan-Benedict Glaw "
					"<jbglaw@lug-owl.de>\n", lk->phys);
			printk (KERN_ERR "lkkbd: keyboard ID'ed as:");
			for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
				printk (" 0x%02x", lk->id[i]);
			printk ("\n");
			break;
	}
	printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
			lk->phys, lk->name);

	/*
	 * Report errors during keyboard boot-up.
	 */
	switch (lk->id[2]) {
		case 0x00:
			/* All okay */
			break;

		case LK_STUCK_KEY:
			printk (KERN_ERR "lkkbd: Stuck key on keyboard at "
					"%s\n", lk->phys);
			break;

		case LK_SELFTEST_FAILED:
			printk (KERN_ERR "lkkbd: Selftest failed on keyboard "
					"at %s, keyboard may not work "
					"properly\n", lk->phys);
			break;

		default:
			printk (KERN_ERR "lkkbd: Unknown error %02x on "
					"keyboard at %s\n", lk->id[2],
					lk->phys);
			break;
	}

	/*
	 * Try to hint user if there's a stuck key.
	 */
	if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0)
		printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode "
				"is 0x%04x\n", lk->id[3],
				lk->keycode[lk->id[3]]);

	return;
}

/*
 * lkkbd_interrupt() is called by the low level driver when a character
 * is received.
 */
static irqreturn_t
lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags)
{
	struct lkkbd *lk = serio_get_drvdata (serio);
	int i;

	DBG (KERN_INFO "Got byte 0x%02x\n", data);

	if (lk->ignore_bytes > 0) {
		DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;

		if (lk->ignore_bytes == 0)
			lkkbd_detection_done (lk);

		return IRQ_HANDLED;
	}

	switch (data) {
		case LK_ALL_KEYS_UP:
			for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
				if (lk->keycode[i] != KEY_RESERVED)
					input_report_key (lk->dev, lk->keycode[i], 0);
			input_sync (lk->dev);
			break;

		case 0x01:
			DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
			lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
			lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
			schedule_work (&lk->tq);
			break;

		case LK_METRONOME:
		case LK_OUTPUT_ERROR:
		case LK_INPUT_ERROR:
		case LK_KBD_LOCKED:
		case LK_KBD_TEST_MODE_ACK:
		case LK_PREFIX_KEY_DOWN:
		case LK_MODE_CHANGE_ACK:
		case LK_RESPONSE_RESERVED:
			DBG (KERN_INFO "Got %s and don't know how to handle...\n",
					response_name (data));
			break;

		default:
			if (lk->keycode[data] != KEY_RESERVED) {
				if (!test_bit (lk->keycode[data], lk->dev->key))
					input_report_key (lk->dev, lk->keycode[data], 1);
				else
					input_report_key (lk->dev, lk->keycode[data], 0);
				input_sync (lk->dev);
                        } else
                                printk (KERN_WARNING "%s: Unknown key with "
						"scancode 0x%02x on %s.\n",
						__FILE__, data, lk->name);
	}

	return IRQ_HANDLED;
}

/*
 * lkkbd_event() handles events from the input module.
 */
static int
lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
		int value)
{
	struct lkkbd *lk = input_get_drvdata (dev);
	unsigned char leds_on = 0;
	unsigned char leds_off = 0;

	switch (type) {
		case EV_LED:
			CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
			CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
			CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
			CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
			if (leds_on != 0) {
				lk->serio->write (lk->serio, LK_CMD_LED_ON);
				lk->serio->write (lk->serio, leds_on);
			}
			if (leds_off != 0) {
				lk->serio->write (lk->serio, LK_CMD_LED_OFF);
				lk->serio->write (lk->serio, leds_off);
			}
			return 0;

		case EV_SND:
			switch (code) {
				case SND_CLICK:
					if (value == 0) {
						DBG ("%s: Deactivating key clicks\n", __func__);
						lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
						lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
					} else {
						DBG ("%s: Activating key clicks\n", __func__);
						lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
						lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
						lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
						lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
					}
					return 0;

				case SND_BELL:
					if (value != 0)
						lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);

					return 0;
			}
			break;

		default:
			printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
					__func__, type, code, value);
	}

	return -1;
}

/*
 * lkkbd_reinit() sets leds and beeps to a state the computer remembers they
 * were in.
 */
static void
lkkbd_reinit (struct work_struct *work)
{
	struct lkkbd *lk = container_of(work, struct lkkbd, tq);
	int division;
	unsigned char leds_on = 0;
	unsigned char leds_off = 0;

	/* Ask for ID */
	lk->serio->write (lk->serio, LK_CMD_REQUEST_ID);

	/* Reset parameters */
	lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);

	/* Set LEDs */
	CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
	CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
	CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
	CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
	if (leds_on != 0) {
		lk->serio->write (lk->serio, LK_CMD_LED_ON);
		lk->serio->write (lk->serio, leds_on);
	}
	if (leds_off != 0) {
		lk->serio->write (lk->serio, LK_CMD_LED_OFF);
		lk->serio->write (lk->serio, leds_off);
	}

	/*
	 * Try to activate extended LK401 mode. This command will
	 * only work with a LK401 keyboard and grants access to
	 * LAlt, RAlt, RCompose and RShift.
	 */
	lk->serio->write (lk->serio, LK_CMD_ENABLE_LK401);

	/* Set all keys to UPDOWN mode */
	for (division = 1; division <= 14; division++)
		lk->serio->write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
					division));

	/* Enable bell and set volume */
	lk->serio->write (lk->serio, LK_CMD_ENABLE_BELL);
	lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));

	/* Enable/disable keyclick (and possibly set volume) */
	if (test_bit (SND_CLICK, lk->dev->snd)) {
		lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
		lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
		lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
		lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
	} else {
		lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
		lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
	}

	/* Sound the bell if needed */
	if (test_bit (SND_BELL, lk->dev->snd))
		lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
}

/*
 * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
 */
static int
lkkbd_connect (struct serio *serio, struct serio_driver *drv)
{
	struct lkkbd *lk;
	struct input_dev *input_dev;
	int i;
	int err;

	lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
	input_dev = input_allocate_device ();
	if (!lk || !input_dev) {
		err = -ENOMEM;
		goto fail1;
	}

	lk->serio = serio;
	lk->dev = input_dev;
	INIT_WORK (&lk->tq, lkkbd_reinit);
	lk->bell_volume = bell_volume;
	lk->keyclick_volume = keyclick_volume;
	lk->ctrlclick_volume = ctrlclick_volume;
	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);

	strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
	snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);

	input_dev->name = lk->name;
	input_dev->phys = lk->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_LKKBD;
	input_dev->id.product = 0;
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = &serio->dev;
	input_dev->event = lkkbd_event;

	input_set_drvdata (input_dev, lk);

	set_bit (EV_KEY, input_dev->evbit);
	set_bit (EV_LED, input_dev->evbit);
	set_bit (EV_SND, input_dev->evbit);
	set_bit (EV_REP, input_dev->evbit);
	set_bit (LED_CAPSL, input_dev->ledbit);
	set_bit (LED_SLEEP, input_dev->ledbit);
	set_bit (LED_COMPOSE, input_dev->ledbit);
	set_bit (LED_SCROLLL, input_dev->ledbit);
	set_bit (SND_BELL, input_dev->sndbit);
	set_bit (SND_CLICK, input_dev->sndbit);

	input_dev->keycode = lk->keycode;
	input_dev->keycodesize = sizeof (lk_keycode_t);
	input_dev->keycodemax = LK_NUM_KEYCODES;
	for (i = 0; i < LK_NUM_KEYCODES; i++)
		set_bit (lk->keycode[i], input_dev->keybit);

	serio_set_drvdata (serio, lk);

	err = serio_open (serio, drv);
	if (err)
		goto fail2;

	err = input_register_device (lk->dev);
	if (err)
		goto fail3;

	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);

	return 0;

 fail3:	serio_close (serio);
 fail2:	serio_set_drvdata (serio, NULL);
 fail1:	input_free_device (input_dev);
	kfree (lk);
	return err;
}

/*
 * lkkbd_disconnect() unregisters and closes behind us.
 */
static void
lkkbd_disconnect (struct serio *serio)
{
	struct lkkbd *lk = serio_get_drvdata (serio);

	input_get_device (lk->dev);
	input_unregister_device (lk->dev);
	serio_close (serio);
	serio_set_drvdata (serio, NULL);
	input_put_device (lk->dev);
	kfree (lk);
}

static struct serio_device_id lkkbd_serio_ids[] = {
	{
		.type	= SERIO_RS232,
		.proto	= SERIO_LKKBD,
		.id	= SERIO_ANY,
		.extra	= SERIO_ANY,
	},
	{ 0 }
};

MODULE_DEVICE_TABLE(serio, lkkbd_serio_ids);

static struct serio_driver lkkbd_drv = {
	.driver		= {
		.name	= "lkkbd",
	},
	.description	= DRIVER_DESC,
	.id_table	= lkkbd_serio_ids,
	.connect	= lkkbd_connect,
	.disconnect	= lkkbd_disconnect,
	.interrupt	= lkkbd_interrupt,
};

/*
 * The functions for insering/removing us as a module.
 */
static int __init
lkkbd_init (void)
{
	return serio_register_driver(&lkkbd_drv);
}

static void __exit
lkkbd_exit (void)
{
	serio_unregister_driver(&lkkbd_drv);
}

module_init (lkkbd_init);
module_exit (lkkbd_exit);

