cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lkkbd.c (17602B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (C) 2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
      4 */
      5
      6/*
      7 * LK keyboard driver for Linux, based on sunkbd.c (C) by Vojtech Pavlik
      8 */
      9
     10/*
     11 * DEC LK201 and LK401 keyboard driver for Linux (primary for DECstations
     12 * and VAXstations, but can also be used on any standard RS232 with an
     13 * adaptor).
     14 *
     15 * DISCLAIMER: This works for _me_. If you break anything by using the
     16 * information given below, I will _not_ be liable!
     17 *
     18 * RJ10 pinout:		To DE9:		Or DB25:
     19 *	1 - RxD <---->	Pin 3 (TxD) <->	Pin 2 (TxD)
     20 *	2 - GND <---->	Pin 5 (GND) <->	Pin 7 (GND)
     21 *	4 - TxD <---->	Pin 2 (RxD) <->	Pin 3 (RxD)
     22 *	3 - +12V (from HDD drive connector), DON'T connect to DE9 or DB25!!!
     23 *
     24 * Pin numbers for DE9 and DB25 are noted on the plug (quite small:). For
     25 * RJ10, it's like this:
     26 *
     27 *      __=__	Hold the plug in front of you, cable downwards,
     28 *     /___/|	nose is hidden behind the plug. Now, pin 1 is at
     29 *    |1234||	the left side, pin 4 at the right and 2 and 3 are
     30 *    |IIII||	in between, of course:)
     31 *    |    ||
     32 *    |____|/
     33 *      ||	So the adaptor consists of three connected cables
     34 *      ||	for data transmission (RxD and TxD) and signal ground.
     35 *		Additionally, you have to get +12V from somewhere.
     36 * Most easily, you'll get that from a floppy or HDD power connector.
     37 * It's the yellow cable there (black is ground and red is +5V).
     38 *
     39 * The keyboard and all the commands it understands are documented in
     40 * "VCB02 Video Subsystem - Technical Manual", EK-104AA-TM-001. This
     41 * document is LK201 specific, but LK401 is mostly compatible. It comes
     42 * up in LK201 mode and doesn't report any of the additional keys it
     43 * has. These need to be switched on with the LK_CMD_ENABLE_LK401
     44 * command. You'll find this document (scanned .pdf file) on MANX,
     45 * a search engine specific to DEC documentation. Try
     46 * http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
     47 */
     48
     49/*
     50 */
     51
     52#include <linux/delay.h>
     53#include <linux/slab.h>
     54#include <linux/module.h>
     55#include <linux/interrupt.h>
     56#include <linux/input.h>
     57#include <linux/serio.h>
     58#include <linux/workqueue.h>
     59
     60#define DRIVER_DESC	"LK keyboard driver"
     61
     62MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
     63MODULE_DESCRIPTION(DRIVER_DESC);
     64MODULE_LICENSE("GPL");
     65
     66/*
     67 * Known parameters:
     68 *	bell_volume
     69 *	keyclick_volume
     70 *	ctrlclick_volume
     71 *
     72 * Please notice that there's not yet an API to set these at runtime.
     73 */
     74static int bell_volume = 100; /* % */
     75module_param(bell_volume, int, 0);
     76MODULE_PARM_DESC(bell_volume, "Bell volume (in %). default is 100%");
     77
     78static int keyclick_volume = 100; /* % */
     79module_param(keyclick_volume, int, 0);
     80MODULE_PARM_DESC(keyclick_volume, "Keyclick volume (in %), default is 100%");
     81
     82static int ctrlclick_volume = 100; /* % */
     83module_param(ctrlclick_volume, int, 0);
     84MODULE_PARM_DESC(ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
     85
     86static int lk201_compose_is_alt;
     87module_param(lk201_compose_is_alt, int, 0);
     88MODULE_PARM_DESC(lk201_compose_is_alt,
     89		 "If set non-zero, LK201' Compose key will act as an Alt key");
     90
     91
     92
     93#undef LKKBD_DEBUG
     94#ifdef LKKBD_DEBUG
     95#define DBG(x...) printk(x)
     96#else
     97#define DBG(x...) do {} while (0)
     98#endif
     99
    100/* LED control */
    101#define LK_LED_WAIT		0x81
    102#define LK_LED_COMPOSE		0x82
    103#define LK_LED_SHIFTLOCK	0x84
    104#define LK_LED_SCROLLLOCK	0x88
    105#define LK_CMD_LED_ON		0x13
    106#define LK_CMD_LED_OFF		0x11
    107
    108/* Mode control */
    109#define LK_MODE_DOWN		0x80
    110#define LK_MODE_AUTODOWN	0x82
    111#define LK_MODE_UPDOWN		0x86
    112#define LK_CMD_SET_MODE(mode, div)	((mode) | ((div) << 3))
    113
    114/* Misc commands */
    115#define LK_CMD_ENABLE_KEYCLICK	0x1b
    116#define LK_CMD_DISABLE_KEYCLICK	0x99
    117#define LK_CMD_DISABLE_BELL	0xa1
    118#define LK_CMD_SOUND_BELL	0xa7
    119#define LK_CMD_ENABLE_BELL	0x23
    120#define LK_CMD_DISABLE_CTRCLICK	0xb9
    121#define LK_CMD_ENABLE_CTRCLICK	0xbb
    122#define LK_CMD_SET_DEFAULTS	0xd3
    123#define LK_CMD_POWERCYCLE_RESET	0xfd
    124#define LK_CMD_ENABLE_LK401	0xe9
    125#define LK_CMD_REQUEST_ID	0xab
    126
    127/* Misc responses from keyboard */
    128#define LK_STUCK_KEY		0x3d
    129#define LK_SELFTEST_FAILED	0x3e
    130#define LK_ALL_KEYS_UP		0xb3
    131#define LK_METRONOME		0xb4
    132#define LK_OUTPUT_ERROR		0xb5
    133#define LK_INPUT_ERROR		0xb6
    134#define LK_KBD_LOCKED		0xb7
    135#define LK_KBD_TEST_MODE_ACK	0xb8
    136#define LK_PREFIX_KEY_DOWN	0xb9
    137#define LK_MODE_CHANGE_ACK	0xba
    138#define LK_RESPONSE_RESERVED	0xbb
    139
    140#define LK_NUM_KEYCODES		256
    141#define LK_NUM_IGNORE_BYTES	6
    142
    143static unsigned short lkkbd_keycode[LK_NUM_KEYCODES] = {
    144	[0x56] = KEY_F1,
    145	[0x57] = KEY_F2,
    146	[0x58] = KEY_F3,
    147	[0x59] = KEY_F4,
    148	[0x5a] = KEY_F5,
    149	[0x64] = KEY_F6,
    150	[0x65] = KEY_F7,
    151	[0x66] = KEY_F8,
    152	[0x67] = KEY_F9,
    153	[0x68] = KEY_F10,
    154	[0x71] = KEY_F11,
    155	[0x72] = KEY_F12,
    156	[0x73] = KEY_F13,
    157	[0x74] = KEY_F14,
    158	[0x7c] = KEY_F15,
    159	[0x7d] = KEY_F16,
    160	[0x80] = KEY_F17,
    161	[0x81] = KEY_F18,
    162	[0x82] = KEY_F19,
    163	[0x83] = KEY_F20,
    164	[0x8a] = KEY_FIND,
    165	[0x8b] = KEY_INSERT,
    166	[0x8c] = KEY_DELETE,
    167	[0x8d] = KEY_SELECT,
    168	[0x8e] = KEY_PAGEUP,
    169	[0x8f] = KEY_PAGEDOWN,
    170	[0x92] = KEY_KP0,
    171	[0x94] = KEY_KPDOT,
    172	[0x95] = KEY_KPENTER,
    173	[0x96] = KEY_KP1,
    174	[0x97] = KEY_KP2,
    175	[0x98] = KEY_KP3,
    176	[0x99] = KEY_KP4,
    177	[0x9a] = KEY_KP5,
    178	[0x9b] = KEY_KP6,
    179	[0x9c] = KEY_KPCOMMA,
    180	[0x9d] = KEY_KP7,
    181	[0x9e] = KEY_KP8,
    182	[0x9f] = KEY_KP9,
    183	[0xa0] = KEY_KPMINUS,
    184	[0xa1] = KEY_PROG1,
    185	[0xa2] = KEY_PROG2,
    186	[0xa3] = KEY_PROG3,
    187	[0xa4] = KEY_PROG4,
    188	[0xa7] = KEY_LEFT,
    189	[0xa8] = KEY_RIGHT,
    190	[0xa9] = KEY_DOWN,
    191	[0xaa] = KEY_UP,
    192	[0xab] = KEY_RIGHTSHIFT,
    193	[0xac] = KEY_LEFTALT,
    194	[0xad] = KEY_COMPOSE, /* Right Compose, that is. */
    195	[0xae] = KEY_LEFTSHIFT, /* Same as KEY_RIGHTSHIFT on LK201 */
    196	[0xaf] = KEY_LEFTCTRL,
    197	[0xb0] = KEY_CAPSLOCK,
    198	[0xb1] = KEY_COMPOSE, /* Left Compose, that is. */
    199	[0xb2] = KEY_RIGHTALT,
    200	[0xbc] = KEY_BACKSPACE,
    201	[0xbd] = KEY_ENTER,
    202	[0xbe] = KEY_TAB,
    203	[0xbf] = KEY_ESC,
    204	[0xc0] = KEY_1,
    205	[0xc1] = KEY_Q,
    206	[0xc2] = KEY_A,
    207	[0xc3] = KEY_Z,
    208	[0xc5] = KEY_2,
    209	[0xc6] = KEY_W,
    210	[0xc7] = KEY_S,
    211	[0xc8] = KEY_X,
    212	[0xc9] = KEY_102ND,
    213	[0xcb] = KEY_3,
    214	[0xcc] = KEY_E,
    215	[0xcd] = KEY_D,
    216	[0xce] = KEY_C,
    217	[0xd0] = KEY_4,
    218	[0xd1] = KEY_R,
    219	[0xd2] = KEY_F,
    220	[0xd3] = KEY_V,
    221	[0xd4] = KEY_SPACE,
    222	[0xd6] = KEY_5,
    223	[0xd7] = KEY_T,
    224	[0xd8] = KEY_G,
    225	[0xd9] = KEY_B,
    226	[0xdb] = KEY_6,
    227	[0xdc] = KEY_Y,
    228	[0xdd] = KEY_H,
    229	[0xde] = KEY_N,
    230	[0xe0] = KEY_7,
    231	[0xe1] = KEY_U,
    232	[0xe2] = KEY_J,
    233	[0xe3] = KEY_M,
    234	[0xe5] = KEY_8,
    235	[0xe6] = KEY_I,
    236	[0xe7] = KEY_K,
    237	[0xe8] = KEY_COMMA,
    238	[0xea] = KEY_9,
    239	[0xeb] = KEY_O,
    240	[0xec] = KEY_L,
    241	[0xed] = KEY_DOT,
    242	[0xef] = KEY_0,
    243	[0xf0] = KEY_P,
    244	[0xf2] = KEY_SEMICOLON,
    245	[0xf3] = KEY_SLASH,
    246	[0xf5] = KEY_EQUAL,
    247	[0xf6] = KEY_RIGHTBRACE,
    248	[0xf7] = KEY_BACKSLASH,
    249	[0xf9] = KEY_MINUS,
    250	[0xfa] = KEY_LEFTBRACE,
    251	[0xfb] = KEY_APOSTROPHE,
    252};
    253
    254#define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do {		\
    255	if (test_bit(LED, (LK)->dev->led))			\
    256		VAR_ON |= BITS;					\
    257	else							\
    258		VAR_OFF |= BITS;				\
    259	} while (0)
    260
    261/*
    262 * Per-keyboard data
    263 */
    264struct lkkbd {
    265	unsigned short keycode[LK_NUM_KEYCODES];
    266	int ignore_bytes;
    267	unsigned char id[LK_NUM_IGNORE_BYTES];
    268	struct input_dev *dev;
    269	struct serio *serio;
    270	struct work_struct tq;
    271	char name[64];
    272	char phys[32];
    273	char type;
    274	int bell_volume;
    275	int keyclick_volume;
    276	int ctrlclick_volume;
    277};
    278
    279#ifdef LKKBD_DEBUG
    280/*
    281 * Responses from the keyboard and mapping back to their names.
    282 */
    283static struct {
    284	unsigned char value;
    285	unsigned char *name;
    286} lk_response[] = {
    287#define RESPONSE(x) { .value = (x), .name = #x, }
    288	RESPONSE(LK_STUCK_KEY),
    289	RESPONSE(LK_SELFTEST_FAILED),
    290	RESPONSE(LK_ALL_KEYS_UP),
    291	RESPONSE(LK_METRONOME),
    292	RESPONSE(LK_OUTPUT_ERROR),
    293	RESPONSE(LK_INPUT_ERROR),
    294	RESPONSE(LK_KBD_LOCKED),
    295	RESPONSE(LK_KBD_TEST_MODE_ACK),
    296	RESPONSE(LK_PREFIX_KEY_DOWN),
    297	RESPONSE(LK_MODE_CHANGE_ACK),
    298	RESPONSE(LK_RESPONSE_RESERVED),
    299#undef RESPONSE
    300};
    301
    302static unsigned char *response_name(unsigned char value)
    303{
    304	int i;
    305
    306	for (i = 0; i < ARRAY_SIZE(lk_response); i++)
    307		if (lk_response[i].value == value)
    308			return lk_response[i].name;
    309
    310	return "<unknown>";
    311}
    312#endif /* LKKBD_DEBUG */
    313
    314/*
    315 * Calculate volume parameter byte for a given volume.
    316 */
    317static unsigned char volume_to_hw(int volume_percent)
    318{
    319	unsigned char ret = 0;
    320
    321	if (volume_percent < 0)
    322		volume_percent = 0;
    323	if (volume_percent > 100)
    324		volume_percent = 100;
    325
    326	if (volume_percent >= 0)
    327		ret = 7;
    328	if (volume_percent >= 13)	/* 12.5 */
    329		ret = 6;
    330	if (volume_percent >= 25)
    331		ret = 5;
    332	if (volume_percent >= 38)	/* 37.5 */
    333		ret = 4;
    334	if (volume_percent >= 50)
    335		ret = 3;
    336	if (volume_percent >= 63)	/* 62.5 */
    337		ret = 2;		/* This is the default volume */
    338	if (volume_percent >= 75)
    339		ret = 1;
    340	if (volume_percent >= 88)	/* 87.5 */
    341		ret = 0;
    342
    343	ret |= 0x80;
    344
    345	return ret;
    346}
    347
    348static void lkkbd_detection_done(struct lkkbd *lk)
    349{
    350	int i;
    351
    352	/*
    353	 * Reset setting for Compose key. Let Compose be KEY_COMPOSE.
    354	 */
    355	lk->keycode[0xb1] = KEY_COMPOSE;
    356
    357	/*
    358	 * Print keyboard name and modify Compose=Alt on user's request.
    359	 */
    360	switch (lk->id[4]) {
    361	case 1:
    362		strlcpy(lk->name, "DEC LK201 keyboard", sizeof(lk->name));
    363
    364		if (lk201_compose_is_alt)
    365			lk->keycode[0xb1] = KEY_LEFTALT;
    366		break;
    367
    368	case 2:
    369		strlcpy(lk->name, "DEC LK401 keyboard", sizeof(lk->name));
    370		break;
    371
    372	default:
    373		strlcpy(lk->name, "Unknown DEC keyboard", sizeof(lk->name));
    374		printk(KERN_ERR
    375			"lkkbd: keyboard on %s is unknown, please report to "
    376			"Jan-Benedict Glaw <jbglaw@lug-owl.de>\n", lk->phys);
    377		printk(KERN_ERR "lkkbd: keyboard ID'ed as:");
    378		for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
    379			printk(" 0x%02x", lk->id[i]);
    380		printk("\n");
    381		break;
    382	}
    383
    384	printk(KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
    385		lk->phys, lk->name);
    386
    387	/*
    388	 * Report errors during keyboard boot-up.
    389	 */
    390	switch (lk->id[2]) {
    391	case 0x00:
    392		/* All okay */
    393		break;
    394
    395	case LK_STUCK_KEY:
    396		printk(KERN_ERR "lkkbd: Stuck key on keyboard at %s\n",
    397			lk->phys);
    398		break;
    399
    400	case LK_SELFTEST_FAILED:
    401		printk(KERN_ERR
    402			"lkkbd: Selftest failed on keyboard at %s, "
    403			"keyboard may not work properly\n", lk->phys);
    404		break;
    405
    406	default:
    407		printk(KERN_ERR
    408			"lkkbd: Unknown error %02x on keyboard at %s\n",
    409			lk->id[2], lk->phys);
    410		break;
    411	}
    412
    413	/*
    414	 * Try to hint user if there's a stuck key.
    415	 */
    416	if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0)
    417		printk(KERN_ERR
    418			"Scancode of stuck key is 0x%02x, keycode is 0x%04x\n",
    419			lk->id[3], lk->keycode[lk->id[3]]);
    420}
    421
    422/*
    423 * lkkbd_interrupt() is called by the low level driver when a character
    424 * is received.
    425 */
    426static irqreturn_t lkkbd_interrupt(struct serio *serio,
    427				   unsigned char data, unsigned int flags)
    428{
    429	struct lkkbd *lk = serio_get_drvdata(serio);
    430	struct input_dev *input_dev = lk->dev;
    431	unsigned int keycode;
    432	int i;
    433
    434	DBG(KERN_INFO "Got byte 0x%02x\n", data);
    435
    436	if (lk->ignore_bytes > 0) {
    437		DBG(KERN_INFO "Ignoring a byte on %s\n", lk->name);
    438		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
    439
    440		if (lk->ignore_bytes == 0)
    441			lkkbd_detection_done(lk);
    442
    443		return IRQ_HANDLED;
    444	}
    445
    446	switch (data) {
    447	case LK_ALL_KEYS_UP:
    448		for (i = 0; i < ARRAY_SIZE(lkkbd_keycode); i++)
    449			input_report_key(input_dev, lk->keycode[i], 0);
    450		input_sync(input_dev);
    451		break;
    452
    453	case 0x01:
    454		DBG(KERN_INFO "Got 0x01, scheduling re-initialization\n");
    455		lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
    456		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
    457		schedule_work(&lk->tq);
    458		break;
    459
    460	case LK_METRONOME:
    461	case LK_OUTPUT_ERROR:
    462	case LK_INPUT_ERROR:
    463	case LK_KBD_LOCKED:
    464	case LK_KBD_TEST_MODE_ACK:
    465	case LK_PREFIX_KEY_DOWN:
    466	case LK_MODE_CHANGE_ACK:
    467	case LK_RESPONSE_RESERVED:
    468		DBG(KERN_INFO "Got %s and don't know how to handle...\n",
    469			response_name(data));
    470		break;
    471
    472	default:
    473		keycode = lk->keycode[data];
    474		if (keycode != KEY_RESERVED) {
    475			input_report_key(input_dev, keycode,
    476					 !test_bit(keycode, input_dev->key));
    477			input_sync(input_dev);
    478		} else {
    479			printk(KERN_WARNING
    480				"%s: Unknown key with scancode 0x%02x on %s.\n",
    481				__FILE__, data, lk->name);
    482		}
    483	}
    484
    485	return IRQ_HANDLED;
    486}
    487
    488static void lkkbd_toggle_leds(struct lkkbd *lk)
    489{
    490	struct serio *serio = lk->serio;
    491	unsigned char leds_on = 0;
    492	unsigned char leds_off = 0;
    493
    494	CHECK_LED(lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
    495	CHECK_LED(lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
    496	CHECK_LED(lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
    497	CHECK_LED(lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
    498	if (leds_on != 0) {
    499		serio_write(serio, LK_CMD_LED_ON);
    500		serio_write(serio, leds_on);
    501	}
    502	if (leds_off != 0) {
    503		serio_write(serio, LK_CMD_LED_OFF);
    504		serio_write(serio, leds_off);
    505	}
    506}
    507
    508static void lkkbd_toggle_keyclick(struct lkkbd *lk, bool on)
    509{
    510	struct serio *serio = lk->serio;
    511
    512	if (on) {
    513		DBG("%s: Activating key clicks\n", __func__);
    514		serio_write(serio, LK_CMD_ENABLE_KEYCLICK);
    515		serio_write(serio, volume_to_hw(lk->keyclick_volume));
    516		serio_write(serio, LK_CMD_ENABLE_CTRCLICK);
    517		serio_write(serio, volume_to_hw(lk->ctrlclick_volume));
    518	} else {
    519		DBG("%s: Deactivating key clicks\n", __func__);
    520		serio_write(serio, LK_CMD_DISABLE_KEYCLICK);
    521		serio_write(serio, LK_CMD_DISABLE_CTRCLICK);
    522	}
    523
    524}
    525
    526/*
    527 * lkkbd_event() handles events from the input module.
    528 */
    529static int lkkbd_event(struct input_dev *dev,
    530			unsigned int type, unsigned int code, int value)
    531{
    532	struct lkkbd *lk = input_get_drvdata(dev);
    533
    534	switch (type) {
    535	case EV_LED:
    536		lkkbd_toggle_leds(lk);
    537		return 0;
    538
    539	case EV_SND:
    540		switch (code) {
    541		case SND_CLICK:
    542			lkkbd_toggle_keyclick(lk, value);
    543			return 0;
    544
    545		case SND_BELL:
    546			if (value != 0)
    547				serio_write(lk->serio, LK_CMD_SOUND_BELL);
    548
    549			return 0;
    550		}
    551
    552		break;
    553
    554	default:
    555		printk(KERN_ERR "%s(): Got unknown type %d, code %d, value %d\n",
    556			__func__, type, code, value);
    557	}
    558
    559	return -1;
    560}
    561
    562/*
    563 * lkkbd_reinit() sets leds and beeps to a state the computer remembers they
    564 * were in.
    565 */
    566static void lkkbd_reinit(struct work_struct *work)
    567{
    568	struct lkkbd *lk = container_of(work, struct lkkbd, tq);
    569	int division;
    570
    571	/* Ask for ID */
    572	serio_write(lk->serio, LK_CMD_REQUEST_ID);
    573
    574	/* Reset parameters */
    575	serio_write(lk->serio, LK_CMD_SET_DEFAULTS);
    576
    577	/* Set LEDs */
    578	lkkbd_toggle_leds(lk);
    579
    580	/*
    581	 * Try to activate extended LK401 mode. This command will
    582	 * only work with a LK401 keyboard and grants access to
    583	 * LAlt, RAlt, RCompose and RShift.
    584	 */
    585	serio_write(lk->serio, LK_CMD_ENABLE_LK401);
    586
    587	/* Set all keys to UPDOWN mode */
    588	for (division = 1; division <= 14; division++)
    589		serio_write(lk->serio,
    590			    LK_CMD_SET_MODE(LK_MODE_UPDOWN, division));
    591
    592	/* Enable bell and set volume */
    593	serio_write(lk->serio, LK_CMD_ENABLE_BELL);
    594	serio_write(lk->serio, volume_to_hw(lk->bell_volume));
    595
    596	/* Enable/disable keyclick (and possibly set volume) */
    597	lkkbd_toggle_keyclick(lk, test_bit(SND_CLICK, lk->dev->snd));
    598
    599	/* Sound the bell if needed */
    600	if (test_bit(SND_BELL, lk->dev->snd))
    601		serio_write(lk->serio, LK_CMD_SOUND_BELL);
    602}
    603
    604/*
    605 * lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
    606 */
    607static int lkkbd_connect(struct serio *serio, struct serio_driver *drv)
    608{
    609	struct lkkbd *lk;
    610	struct input_dev *input_dev;
    611	int i;
    612	int err;
    613
    614	lk = kzalloc(sizeof(struct lkkbd), GFP_KERNEL);
    615	input_dev = input_allocate_device();
    616	if (!lk || !input_dev) {
    617		err = -ENOMEM;
    618		goto fail1;
    619	}
    620
    621	lk->serio = serio;
    622	lk->dev = input_dev;
    623	INIT_WORK(&lk->tq, lkkbd_reinit);
    624	lk->bell_volume = bell_volume;
    625	lk->keyclick_volume = keyclick_volume;
    626	lk->ctrlclick_volume = ctrlclick_volume;
    627	memcpy(lk->keycode, lkkbd_keycode, sizeof(lk->keycode));
    628
    629	strlcpy(lk->name, "DEC LK keyboard", sizeof(lk->name));
    630	snprintf(lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
    631
    632	input_dev->name = lk->name;
    633	input_dev->phys = lk->phys;
    634	input_dev->id.bustype = BUS_RS232;
    635	input_dev->id.vendor = SERIO_LKKBD;
    636	input_dev->id.product = 0;
    637	input_dev->id.version = 0x0100;
    638	input_dev->dev.parent = &serio->dev;
    639	input_dev->event = lkkbd_event;
    640
    641	input_set_drvdata(input_dev, lk);
    642
    643	__set_bit(EV_KEY, input_dev->evbit);
    644	__set_bit(EV_LED, input_dev->evbit);
    645	__set_bit(EV_SND, input_dev->evbit);
    646	__set_bit(EV_REP, input_dev->evbit);
    647	__set_bit(LED_CAPSL, input_dev->ledbit);
    648	__set_bit(LED_SLEEP, input_dev->ledbit);
    649	__set_bit(LED_COMPOSE, input_dev->ledbit);
    650	__set_bit(LED_SCROLLL, input_dev->ledbit);
    651	__set_bit(SND_BELL, input_dev->sndbit);
    652	__set_bit(SND_CLICK, input_dev->sndbit);
    653
    654	input_dev->keycode = lk->keycode;
    655	input_dev->keycodesize = sizeof(lk->keycode[0]);
    656	input_dev->keycodemax = ARRAY_SIZE(lk->keycode);
    657
    658	for (i = 0; i < LK_NUM_KEYCODES; i++)
    659		__set_bit(lk->keycode[i], input_dev->keybit);
    660	__clear_bit(KEY_RESERVED, input_dev->keybit);
    661
    662	serio_set_drvdata(serio, lk);
    663
    664	err = serio_open(serio, drv);
    665	if (err)
    666		goto fail2;
    667
    668	err = input_register_device(lk->dev);
    669	if (err)
    670		goto fail3;
    671
    672	serio_write(lk->serio, LK_CMD_POWERCYCLE_RESET);
    673
    674	return 0;
    675
    676 fail3:	serio_close(serio);
    677 fail2:	serio_set_drvdata(serio, NULL);
    678 fail1:	input_free_device(input_dev);
    679	kfree(lk);
    680	return err;
    681}
    682
    683/*
    684 * lkkbd_disconnect() unregisters and closes behind us.
    685 */
    686static void lkkbd_disconnect(struct serio *serio)
    687{
    688	struct lkkbd *lk = serio_get_drvdata(serio);
    689
    690	input_get_device(lk->dev);
    691	input_unregister_device(lk->dev);
    692	serio_close(serio);
    693	serio_set_drvdata(serio, NULL);
    694	input_put_device(lk->dev);
    695	kfree(lk);
    696}
    697
    698static const struct serio_device_id lkkbd_serio_ids[] = {
    699	{
    700		.type	= SERIO_RS232,
    701		.proto	= SERIO_LKKBD,
    702		.id	= SERIO_ANY,
    703		.extra	= SERIO_ANY,
    704	},
    705	{ 0 }
    706};
    707
    708MODULE_DEVICE_TABLE(serio, lkkbd_serio_ids);
    709
    710static struct serio_driver lkkbd_drv = {
    711	.driver		= {
    712		.name	= "lkkbd",
    713	},
    714	.description	= DRIVER_DESC,
    715	.id_table	= lkkbd_serio_ids,
    716	.connect	= lkkbd_connect,
    717	.disconnect	= lkkbd_disconnect,
    718	.interrupt	= lkkbd_interrupt,
    719};
    720
    721module_serio_driver(lkkbd_drv);