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

📄 edb7211_keyb.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
字号:
/* * drivers/char/edb7211_keyb.c * * Copyright (C) 2000 Blue Mug, Inc.  All Rights Reserved. * * EDB7211 Keyboard driver for ARM Linux. * * The EP7211 keyboard hardware only supports generating interrupts for 64 keys. * The EBD7211's keyboard has 84 keys. Therefore we need to poll for keys, * instead of waiting for interrupts. * * In a real-world hardware situation, this would be a bad thing. It would * kill power management. */#include <linux/config.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/ptrace.h>#include <linux/signal.h>#include <linux/timer.h>#include <linux/tqueue.h>#include <linux/random.h>#include <linux/ctype.h>#include <linux/init.h>#include <linux/kbd_ll.h>#include <linux/kbd_kern.h>#include <linux/delay.h>#include <asm/bitops.h>#include <asm/keyboard.h>#include <asm/irq.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/system.h>/* * The number of jiffies between keyboard scans. */#define KEYBOARD_SCAN_INTERVAL	5/* * Values for the keyboard column scan control register. */#define KBSC_HI	    0x0	    /*   All driven high */#define KBSC_LO	    0x1	    /*   All driven low */#define KBSC_X	    0x2	    /*   All high impedance */#define KBSC_COL0   0x8	    /*   Column 0 high, others high impedance */#define KBSC_COL1   0x9	    /*   Column 1 high, others high impedance */#define KBSC_COL2   0xa	    /*   Column 2 high, others high impedance */#define KBSC_COL3   0xb	    /*   Column 3 high, others high impedance */#define KBSC_COL4   0xc	    /*   Column 4 high, others high impedance */#define KBSC_COL5   0xd	    /*   Column 5 high, others high impedance */#define KBSC_COL6   0xe	    /*   Column 6 high, others high impedance */#define KBSC_COL7   0xf	    /*   Column 7 high, others high impedance *//* XXX: Figure out what these values should be... *//* Simple translation table for the SysRq keys */#ifdef CONFIG_MAGIC_SYSRQunsigned char edb7211_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 */#endif/*  * Row/column to scancode mappings. * * This table maps row/column keyboard matrix positions to XT scancodes. *  * The port A rows come first, followed by the extended rows. */static unsigned char colrow_2_scancode[128] = {/*  Column:   Row       0     1     2     3     4     5     6     7   *//* A0 */  0x01, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x40, 0x41,/* A1 */  0x02, 0x07, 0x06, 0x05, 0x04, 0x03, 0x08, 0x09,/* A2 */  0x0f, 0x14, 0x13, 0x12, 0x11, 0x10, 0x15, 0x16,/* A3 */  0x3a, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x23, 0x24,/* A4 */  0x29, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x31, 0x32,/* A5 */  0x39, 0x35, 0x6F, 0x52, 0x00, 0x6B, 0x34, 0x33,/* A6 */  0x6A, 0x27, 0x28, 0x00, 0x1c, 0x6D, 0x26, 0x25,/* A7 */  0x67, 0x19, 0x1a, 0x1b, 0x2b, 0x68, 0x18, 0x17,/* E0 */  0x6C, 0x0c, 0x0d, 0x0e, 0x00, 0x66, 0x0b, 0x0a,/* E1 */  0x69, 0x44, 0x45, 0x37, 0x46, 0x77, 0x43, 0x42,/* E2 */  0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* E3 */  0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* E4 */  0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* E5 */  0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* E6 */  0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,/* E7 */  0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};/* * A bitfield array which contains the state of the keyboard after the last * scan. A bit set in this array corresponds to a key down. Only the lower * 16 bits of each array element are used. */static unsigned long previous_keys[8];static unsigned long keys[8];/* This will be set to a non-zero value if a key was found to be pressed * in the last scan. */static int key_is_pressed;static struct tq_struct kbd_process_task;static struct timer_list edb7211_kbd_timer;/* * External methods. */void edb7211_kbd_init_hw(void);/*  * Internal methods. */static int edb7211_kbd_scan_matrix(u_long* keys);static void edb7211_kbd_timeout(unsigned long data);static void edb7211_kbd_process(void* data);/* * Translate a raw keycode to an XT keyboard scancode. */static intedb7211_translate(unsigned char scancode, unsigned char *keycode,		  char raw_mode){	*keycode = colrow_2_scancode[scancode & 0x7f];	return 1;}/* * Scan the keyboard matrix; for each key that is pressed, set the * corresponding bit in the bitfield array. * * The parameter is expected to be an array of 8 32-bit values. Only the lower * 16 bits of each value is used. Each value contains the row bits for the * corresponding column. */static intedb7211_kbd_scan_matrix(u_long* keys){	int column, row, key_pressed;	unsigned char port_a_data, ext_port_data;	key_pressed = 0;	/* Drive all the columns low. */	clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_LO, 		SYSCON1);	for (column = 0; column < 8; column++) {		/* Drive the column high. */		clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | 			    (KBSC_COL0 + column), SYSCON1);		/* Read port A and the extended port. */		port_a_data = clps_readb(PADR) & 0xff;		ext_port_data = __raw_readb(EP7211_VIRT_EXTKBD) & 0xff;		/* Drive all columns tri-state. */		clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_X, 			SYSCON1);		/* Look at each column in port A. */		for (row=0; row < 8; row++) {			/* If the row's bit is set, set the bit in the bitfield.			 * Otherwise, clear it. 			 */			if (port_a_data & (1 << row)) {				keys[column] |= (1 << row); 				key_pressed = 1;			} else {				keys[column] &= ~(1 << row); 			}		}		/* Look at each column in the extended port. */		for (row=0; row < 8; row++) {			/* If the row's bit is set, set the bit in the bitfield.			 * Otherwise, clear it. 			 */			if (ext_port_data & (1 << row)) {				keys[column] |= (1 << (row + 8)); 				key_pressed = 1;			} else {				keys[column] &= ~(1 << (row + 8)); 			}		}		/* 		 * Short delay: The example code for the EDB7211 runs an empty		 * loop 256 times. At this rate, there were some spurious keys		 * generated. I doubled the delay to let the column drives 		 * settle some. 		 */		for (row=0; row < 512; row++) { }	}	/* If we could use interrupts, we would drive all columns high so 	 * that interrupts will be generated on key presses. But we can't,	 * so we leave all columns floating. 	 */	clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_X, 		SYSCON1);	return key_pressed;}/*  * XXX: This is really ugly; this needs to be reworked to have less levels of *   	indentation. */static voidedb7211_kbd_timeout(unsigned long data){	/* Schedule the next timer event. */	edb7211_kbd_timer.expires = jiffies + KEYBOARD_SCAN_INTERVAL;	add_timer(&edb7211_kbd_timer);	if (edb7211_kbd_scan_matrix(keys) || key_is_pressed) {		queue_task(&kbd_process_task, &tq_timer);	} else {		key_is_pressed = 0;	}}/* * Process the keys that have been pressed.  */static voidedb7211_kbd_process(void* data){	int i;	/* First check if any keys have been released. */	if (key_is_pressed) {		for (i=0; i < 8; i++) {			if (previous_keys[i]) {				int row;				for (row=0; row < 16; row++) {					if ((previous_keys[i] & (1 << row)) &&						!(keys[i] & (1 << row))) {						/* Generate the up event. */						handle_scancode(								(row<<3)+i, 0);					}				}			}		}	}	key_is_pressed = 0;	/* Now scan the keys and send press events. */	for (i=0; i < 8; i++) {		if (keys[i]) {			int row;			for (row=0; row < 16; row++) {				if (keys[i] & (1 << row)) {					if (previous_keys[i] & (1 << row)) {						/* Generate the hold event. */						handle_scancode((row<<3)+i, 1);					} else {						/* Generate the down event. */						handle_scancode((row<<3)+i, 1);					}					key_is_pressed = 1;				}			}		}	}	/* Update the state variables. */	memcpy(previous_keys, keys, 8 * sizeof(unsigned long));}static char edb7211_unexpected_up(unsigned char scancode){	return 0200;}static void edb7211_leds(unsigned char leds){}/* * Initialize the keyboard hardware. Set the column drives low and * start the timer. */void __initedb7211_kbd_init_hw(void){	k_translate	= edb7211_translate;	k_unexpected_up	= edb7211_unexpected_up;	k_leds		= edb7211_leds;	/* 	 * If we had the ability to use interrupts, we would want to drive all	 * columns high. But we have more keys than can generate interrupts, so	 * we leave them floating.	 */	clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_X, 		SYSCON1);	/* Initialize the matrix processing task. */	kbd_process_task.routine = edb7211_kbd_process;	kbd_process_task.data = NULL;	/* Setup the timer to poll the keyboard. */	init_timer(&edb7211_kbd_timer);	edb7211_kbd_timer.function = edb7211_kbd_timeout;	edb7211_kbd_timer.data = (unsigned long)NULL;	edb7211_kbd_timer.expires = jiffies + KEYBOARD_SCAN_INTERVAL;	add_timer(&edb7211_kbd_timer); }

⌨️ 快捷键说明

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