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

📄 newtonkbd.c

📁 键盘驱动
💻 C
字号:
/* *  Copyright (c) 2000 Justin Cormack *//* * Newton keyboard driver for Linux *//* * 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 * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <j.cormack@doc.ic.ac.uk>, or by paper mail: * Justin Cormack, 68 Dartmouth Park Road, London NW5 1SN, UK. */#include <linux/slab.h>#include <linux/module.h>#include <linux/input.h>#include <linux/init.h>#include <linux/serio.h>#define DRIVER_DESC	"Newton keyboard driver"MODULE_AUTHOR("Justin Cormack <j.cormack@doc.ic.ac.uk>");MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");#define NKBD_KEY	0x7f#define NKBD_PRESS	0x80static unsigned char nkbd_keycode[128] = {	KEY_A, KEY_S, KEY_D, KEY_F, KEY_H, KEY_G, KEY_Z, KEY_X,	KEY_C, KEY_V, 0, KEY_B, KEY_Q, KEY_W, KEY_E, KEY_R,	KEY_Y, KEY_T, KEY_1, KEY_2, KEY_3, KEY_4, KEY_6, KEY_5,	KEY_EQUAL, KEY_9, KEY_7, KEY_MINUS, KEY_8, KEY_0, KEY_RIGHTBRACE, KEY_O,	KEY_U, KEY_LEFTBRACE, KEY_I, KEY_P, KEY_ENTER, KEY_L, KEY_J, KEY_APOSTROPHE,	KEY_K, KEY_SEMICOLON, KEY_BACKSLASH, KEY_COMMA, KEY_SLASH, KEY_N, KEY_M, KEY_DOT,	KEY_TAB, KEY_SPACE, KEY_GRAVE, KEY_DELETE, 0, 0, 0, KEY_LEFTMETA,	KEY_LEFTSHIFT, KEY_CAPSLOCK, KEY_LEFTALT, KEY_LEFTCTRL, KEY_RIGHTSHIFT, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0};static char *nkbd_name = "Newton Keyboard";struct nkbd {	unsigned char keycode[128];	struct input_dev dev;	struct serio *serio;	char phys[32];};static irqreturn_t nkbd_interrupt(struct serio *serio,		unsigned char data, unsigned int flags, struct pt_regs *regs){	struct nkbd *nkbd = serio_get_drvdata(serio);	/* invalid scan codes are probably the init sequence, so we ignore them */	if (nkbd->keycode[data & NKBD_KEY]) {		input_regs(&nkbd->dev, regs);		input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);		input_sync(&nkbd->dev);	}	else if (data == 0xe7) /* end of init sequence */		printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);	return IRQ_HANDLED;}static int nkbd_connect(struct serio *serio, struct serio_driver *drv){	struct nkbd *nkbd;	int i;	int err;	if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))		return -ENOMEM;	memset(nkbd, 0, sizeof(struct nkbd));	nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);	nkbd->serio = serio;	init_input_dev(&nkbd->dev);	nkbd->dev.keycode = nkbd->keycode;	nkbd->dev.keycodesize = sizeof(unsigned char);	nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);	nkbd->dev.private = nkbd;	serio_set_drvdata(serio, nkbd);	err = serio_open(serio, drv);	if (err) {		serio_set_drvdata(serio, NULL);		kfree(nkbd);		return err;	}	memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));	for (i = 0; i < 128; i++)		set_bit(nkbd->keycode[i], nkbd->dev.keybit);	clear_bit(0, nkbd->dev.keybit);	sprintf(nkbd->phys, "%s/input0", serio->phys);	nkbd->dev.name = nkbd_name;	nkbd->dev.phys = nkbd->phys;	nkbd->dev.id.bustype = BUS_RS232;	nkbd->dev.id.vendor = SERIO_NEWTON;	nkbd->dev.id.product = 0x0001;	nkbd->dev.id.version = 0x0100;	nkbd->dev.dev = &serio->dev;	input_register_device(&nkbd->dev);	printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);	return 0;}static void nkbd_disconnect(struct serio *serio){	struct nkbd *nkbd = serio_get_drvdata(serio);	input_unregister_device(&nkbd->dev);	serio_close(serio);	serio_set_drvdata(serio, NULL);	kfree(nkbd);}static struct serio_device_id nkbd_serio_ids[] = {	{		.type	= SERIO_RS232,		.proto	= SERIO_NEWTON,		.id	= SERIO_ANY,		.extra	= SERIO_ANY,	},	{ 0 }};MODULE_DEVICE_TABLE(serio, nkbd_serio_ids);static struct serio_driver nkbd_drv = {	.driver		= {		.name	= "newtonkbd",	},	.description	= DRIVER_DESC,	.id_table	= nkbd_serio_ids,	.interrupt	= nkbd_interrupt,	.connect	= nkbd_connect,	.disconnect	= nkbd_disconnect,};static int __init nkbd_init(void){	serio_register_driver(&nkbd_drv);	return 0;}static void __exit nkbd_exit(void){	serio_unregister_driver(&nkbd_drv);}module_init(nkbd_init);module_exit(nkbd_exit);

⌨️ 快捷键说明

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