⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lkkbd.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
		case 1:			sprintf (lk->name, "DEC LK201 keyboard");			if (lk201_compose_is_alt)				lk->keycode[0xb1] = KEY_LEFTALT;			break;		case 2:			sprintf (lk->name, "DEC LK401 keyboard");			break;		default:			sprintf (lk->name, "Unknown DEC keyboard");			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_tlkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,		struct pt_regs *regs){	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:			input_regs (lk->dev, regs);			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) {				input_regs (lk->dev, regs);				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 intlkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,		int value){	struct lkkbd *lk = dev->private;	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", __FUNCTION__);						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", __FUNCTION__);						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",					__FUNCTION__, type, code, value);	}	return -1;}/* * lkkbd_reinit() sets leds and beeps to a state the computer remembers they * were in. */static voidlkkbd_reinit (void *data){	struct lkkbd *lk = data;	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 intlkkbd_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 fail;	}	lk->serio = serio;	lk->dev = input_dev;	INIT_WORK (&lk->tq, lkkbd_reinit, lk);	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->cdev.dev = &serio->dev;	input_dev->event = lkkbd_event;	input_dev->private = 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 fail;	input_register_device (lk->dev);	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);	return 0; fail:	serio_set_drvdata (serio, NULL);	input_free_device (input_dev);	kfree (lk);	return err;}/* * lkkbd_disconnect() unregisters and closes behind us. */static voidlkkbd_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 __initlkkbd_init (void){	serio_register_driver(&lkkbd_drv);	return 0;}static void __exitlkkbd_exit (void){	serio_unregister_driver(&lkkbd_drv);}module_init (lkkbd_init);module_exit (lkkbd_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -