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

📄 amba_kmi_keyb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
static void kmi_kbd_intr(struct kmi_info *kmi, u_int val, struct pt_regs *regs){#ifdef CONFIG_AMBA_PS2_RECONNECT	/* Try to detect a hot-plug event on the PS/2 keyboard port */	switch (kmi->hotplug_state) {	case 0:		/* Maybe we lost contact... */		if (val == PS2_I_BAT_OK) {			kmi_send(kmi, PS2_O_SET_SCANSET);			kmi->hotplug_state++;			DEBUG(("%s: Saw 0xAA. Going to hotplug state %d\n", kmi->name, kmi->hotplug_state));		}		break;	case 1:		/* Eat up acknowledge */		if (val == PS2_I_ACK) {			/* Request scan code set: '2' if POR has happend, '1' is false alarm */			kmi_send(kmi, 0);			kmi->hotplug_state++;		}		else {			kmi->hotplug_state = 0;			DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));		}		break;	case 2:		/* Eat up acknowledge */		if (val == PS2_I_ACK)			kmi->hotplug_state++;		else {			kmi->hotplug_state = 0;			DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));		}		break;	case 3:		kmi->hotplug_state = 0;		if (val == 2) {			DEBUG(("%s: POR detected. Scan code is: (%d)\n", kmi->name, val));			kmi->present = 1;			tasklet_schedule(&kmikbd_init_tasklet);			printk(KERN_ERR "%s: reconnected\n", kmi->name);			return;		}		else			DEBUG(("%s: False Alarm...\n", kmi->name));		break;	} /* switch (kmi->hotplug_state) */#endif	if (val == PS2_I_DIAGFAIL) {		printk(KERN_ERR "%s: diagnostic failed\n", kmi->name);		return;	}	/* We are waiting for the keyboard to respond to a kmi_send_and_wait() */	if (kmi->res == KMI_NO_ACK) {		if (val == PS2_I_RESEND) {			if (kmi->resend_count < 5)				__kmi_send(kmi, kmi->last_tx);			else {				printk(KERN_ERR "%s: too many resends\n", kmi->name);				return;			}		}		if (val >= 0xee) {			kmi->res = val;			wake_up(&kmi->wait_q);		}		return;	}#ifdef CONFIG_VT	kbd_pt_regs = regs;	handle_scancode(val, !(val & 0x80));	tasklet_schedule(&keyboard_tasklet);#endif}static void kmi_intr(int nr, void *devid, struct pt_regs *regs){	struct kmi_info *kmi = devid;	u_int status = __raw_readb(KMIIR);	if (status & KMIIR_RXINTR) {		u_int val = __raw_readb(KMIDATA);		if (kmi->rx)			kmi->rx(kmi, val, regs);	}}static int kmi_init_keyboard(struct kmi_info *kmi){	kmikbd_init_tasklet.data = (unsigned long)kmi;	tasklet_enable(&kmikbd_init_tasklet);	return __kmi_init_keyboard(kmi);}/* * Reset interrupt handler */static void __initkmi_reset_intr(struct kmi_info *kmi, u_int val, struct pt_regs *regs){	if (kmi->state == KMI_RESET) {		if (val == PS2_I_ACK)			kmi->state = KMI_RESET_POR;		else {			val = KMI_NO_ACK;			goto finished;		}	} else if (kmi->state == KMI_RESET_POR) {finished:		kmi->res = val;		kmi->state = KMI_RESET_DONE;		kmi->rx = NULL;		wake_up(&kmi->wait_q);	}}/* * Reset the device plugged into this interface */static int __init kmi_reset(struct kmi_info *kmi){	u_int res;	int ret = 0;	kmi->state = KMI_RESET;	kmi->rx = kmi_reset_intr;	res = kmi_send_and_wait(kmi, PS2_O_RESET, HZ);	kmi->rx = NULL;	if (res != PS2_I_BAT_OK) {		printk(KERN_ERR "%s: reset failed; ", kmi->name);		if (kmi->res != KMI_NO_ACK)			printk("code 0x%2.2x\n", kmi->res);		else			printk("no ack\n");		ret = -EINVAL;	}	return ret;}static int __init kmi_init_one_interface(struct kmi_info *kmi){	u_int stat;	int ret = -ENODEV;	init_waitqueue_head(&kmi->wait_q);	printk(KERN_INFO "%s at 0x%8.8x on irq %d (%s)\n", kmi->name,		kmi->base, kmi->irq, kmi_type[kmi->type]);	/*	 * Initialise the KMI interface	 */	__raw_writeb(kmi->divisor, KMICLKDIV);	__raw_writeb(KMICR_EN, KMICR);	/*	 * Check that the data and clock lines are OK.	 */	stat = __raw_readb(KMISTAT);	if ((stat & (KMISTAT_IC|KMISTAT_ID)) != (KMISTAT_IC|KMISTAT_ID)) {		printk(KERN_ERR "%s: %s%s%sline%s stuck low\n", kmi->name,			(stat & KMISTAT_IC) ? "" : "clock ",			(stat & (KMISTAT_IC | KMISTAT_ID)) ? "" : "and ",			(stat & KMISTAT_ID) ? "" : "data ",			(stat & (KMISTAT_IC | KMISTAT_ID)) ? "" : "s");		goto bad;	}	/*	 * Claim the appropriate interrupts	 */	ret = request_irq(kmi->irq, kmi_intr, 0, kmi->name, kmi);	if (ret)		goto bad;	/*	 * Enable the receive interrupt, and reset the device.	 */	__raw_writeb(KMICR_EN | KMICR_RXINTREN, KMICR);	kmi->present = 1;	kmi->present = kmi_reset(kmi) == 0;	switch (kmi->type) {	case KMI_KEYBOARD:		ret = kmi_init_keyboard(kmi);		break;#ifdef CONFIG_KMI_MOUSE	case KMI_MOUSE:		ret = kmi_init_mouse(kmi);		break;#endif	}	return ret;bad:	/*	 * Oh dear, the interface was bad, disable it.	 */	__raw_writeb(0, KMICR);	return ret;}#ifdef CONFIG_VT/* * The fragment between #ifdef above and #endif * CONFIG_VT * * is from the pc_keyb.c driver.  It is not copyrighted under the * above notice.  This code is by various authors; please see * drivers/char/pc_keyb.c for further information. *//* * Translation of escaped scancodes to keycodes. * This is now user-settable. * The keycodes 1-88,96-111,119 are fairly standard, and * should probably not be changed - changing might confuse X. * X also interprets scancode 0x5d (KEY_Begin). * * For 1-88 keycode equals scancode. */#define E0_KPENTER 96#define E0_RCTRL   97#define E0_KPSLASH 98#define E0_PRSCR   99#define E0_RALT    100#define E0_BREAK   101	/* (control-pause) */#define E0_HOME    102#define E0_UP	   103#define E0_PGUP    104#define E0_LEFT    105#define E0_RIGHT   106#define E0_END	   107#define E0_DOWN    108#define E0_PGDN    109#define E0_INS	   110#define E0_DEL	   111#define E1_PAUSE   119/* BTC */#define E0_MACRO   112/* LK450 */#define E0_F13	   113#define E0_F14	   114#define E0_HELP    115#define E0_DO	   116#define E0_F17	   117#define E0_KPMINPLUS 118/* * My OmniKey generates e0 4c for  the "OMNI" key and the * right alt key does nada. [kkoller@nyx10.cs.du.edu] */#define E0_OK	124/* * New microsoft keyboard is rumoured to have * e0 5b (left window button), e0 5c (right window button), * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] * [or: Windows_L, Windows_R, TaskMan] */#define E0_MSLW 125#define E0_MSRW 126#define E0_MSTM 127static u_char e0_keys[128] = {	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,	E0_KPENTER,	E0_RCTRL,	0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		E0_KPSLASH,	0,		E0_PRSCR,	E0_RALT,	0,		0,		0,	0,		E0_F13, 	E0_F14, 	E0_HELP,	E0_DO,		E0_F17, 	0,		0,	0,		0,		E0_BREAK,	E0_HOME,	E0_UP,		E0_PGUP,	0,		E0_LEFT,	E0_OK,		E0_RIGHT,	E0_KPMINPLUS,	E0_END,	E0_DOWN,	E0_PGDN,	E0_INS, 	E0_DEL,	0,		0,		0,		0,	0,		0,		0,		E0_MSLW,	E0_MSRW,	E0_MSTM,	0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		E0_MACRO,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		0,	0,		0,		0,		0};#ifdef CONFIG_MAGIC_SYSRQu_char kmi_kbd_sysrq_xlate[128] =	"\000\0331234567890-=\177\t"			/* 0x00 - 0x0f */	"qwertyuiop[]\r\000as"				/* 0x10 - 0x1f */	"dfghjkl;'`\000\\zxcv"				/* 0x20 - 0x2f */	"bnm,./\000*\000 \000\201\202\203\204\205"	/* 0x30 - 0x3f */	"\206\207\210\211\212\000\000789-456+1" 	/* 0x40 - 0x4f */	"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */	"\r\000/";					/* 0x60 - 0x6f */#endifint kmi_kbd_setkeycode(u_int scancode, u_int keycode){	if (scancode < 128 || scancode > 255 || keycode > 127)		return -EINVAL;	e0_keys[scancode - 128] = keycode;	return 0;}int kmi_kbd_getkeycode(u_int scancode){	if (scancode < 128 || scancode > 255)		return -EINVAL;	return e0_keys[scancode - 128];}	        int kmi_kbd_translate(u_char scancode, u_char *keycode, char raw_mode){	static int prev_scancode = 0;	/* special prefix scancodes.. */	if (scancode == 0xe0 || scancode == 0xe1) {		prev_scancode = scancode;		return 0;	}	/* 0xff is sent by a few keyboards, ignore it.	0x00 is error */	if (scancode == 0x00 || scancode == 0xff) {		prev_scancode = 0;		return 0;	}	scancode &= 0x7f;	if (prev_scancode) {		int old_scancode = prev_scancode;		prev_scancode = 0;		switch (old_scancode) {		case 0xe0:			/*			 * The keyboard maintains its own internal caps lock			 * and num lock status.  In caps lock mode, E0 AA			 * precedes make code and E0 2A follows break code.			 * In numlock mode, E0 2A precedes make code, and			 * E0 AA follows break code.  We do our own book-			 * keeping, so we will just ignore these.			 *			 * For my keyboard there is no caps lock mode, but			 * there are both Shift-L and Shift-R modes. The			 * former mode generates E0 2A / E0 AA pairs, the			 * latter E0 B6 / E0 36 pairs.	So, we should also			 * ignore the latter. - aeb@cwi.nl			 */			if  (scancode == 0x2a || scancode == 0x36)				return 0;			if (e0_keys[scancode])				*keycode = e0_keys[scancode];			else {				if (!raw_mode)					printk(KERN_INFO "kbd: unknown "						"scancode e0 %02x\n",						scancode);				return 0;			}			break;		case 0xe1:			if (scancode == 0x1d)				prev_scancode = 0x100;			else {				if (!raw_mode)					printk(KERN_INFO "kbd: unknown "						"scancode e1 %02x\n",						scancode);				return 0;			}			break;		case 0x100:			if (scancode == 0x45)				*keycode = E1_PAUSE;			else {				if (!raw_mode)					printk(KERN_INFO "kbd: unknown "						"scan code e1 1d %02x\n",						scancode);				return 0;			}			break;		}	} else		*keycode = scancode;	return 1;}char kmi_kbd_unexpected_up(u_char keycode){	return 0x80;}void kmi_kbd_leds(u_char leds){	struct kmi_info *kmi = kmi_keyb;	u_int ret;	if (kmi) {		ret = kmi_send_and_wait(kmi, PS2_O_INDICATORS, HZ);		if (ret != KMI_NO_ACK)			ret = kmi_send_and_wait(kmi, leds, HZ);		if (ret == KMI_NO_ACK)			kmi->present = 0;	}}int __init kmi_kbd_init(void){	int  ret = -ENODEV;	if (kmi_keyb) {		strcpy(kmi_keyb->name, "kmikbd");		ret = kmi_init_one_interface(kmi_keyb);	}	if (ret == 0) {		k_setkeycode	= kmi_kbd_setkeycode;		k_getkeycode	= kmi_kbd_getkeycode;		k_translate	= kmi_kbd_translate;		k_unexpected_up = kmi_kbd_unexpected_up;		k_leds		= kmi_kbd_leds;#ifdef CONFIG_MAGIC_SYSRQ		k_sysrq_xlate	= kmi_kbd_sysrq_xlate;		k_sysrq_key	= 0x54;#endif	}	return ret;}#endif /* CONFIG_VT */int register_kmi(struct kmi_info *kmi){	struct kmi_info **kmip = NULL;	int ret;	if (kmi->type == KMI_KEYBOARD)		kmip = &kmi_keyb;	else if (kmi->type == KMI_MOUSE)		kmip = &kmi_mouse;	ret = -EINVAL;	if (kmip) {		ret = -EBUSY;		if (!*kmip) {			*kmip = kmi;			ret = 0;		}	}	return ret;}#ifdef CONFIG_KMI_MOUSEstatic int __init kmi_init(void){	int  ret = -ENODEV;	if (kmi_mouse) {		strcpy(kmi_mouse->name, "kmimouse");		ret = kmi_init_one_interface(kmi_mouse);	}	return ret;}__initcall(kmi_init);#endif

⌨️ 快捷键说明

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