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

📄 kbd7312.c

📁 嵌入式下实验的新的驱动设计源代码
💻 C
字号:
#include <linux/config.h>#include <linux/utsname.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/slab.h>#include <linux/timer.h>#include <linux/module.h>#include <linux/init.h>#include <linux/poll.h>#include <asm/irq.h>#include <asm/segment.h>#define KBD_IRQ_NUM		0#define KEYBOARD_MAJOR 	59 static short Ready;static char KeyValue;static DECLARE_WAIT_QUEUE_HEAD(KbdWait);static int col_global;void dly(int n){	int i, j;	for(i = 0; i < 1000; i++)		for(j = 0; j < n; j++)			;}static void KbdInterrupt(int irq, void *dev_id, struct pt_regs *regs){	unsigned char value;		Ready = 0;		value = *(unsigned char *)0xff000000;		if(col_global == 0) {		if(value == 0x1) {			KeyValue = 1;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 1\n", col_global + 1);		} 		if(value & 0x2) {			KeyValue = 5;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 2\n", col_global + 1);		} 		if(value & 0x4) {			KeyValue = 9;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 3\n", col_global + 1);		} 					if(value & 0x8) {			KeyValue = 13;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 4\n", col_global + 1);		} 		dly(1000);	} 	else if (col_global == 1) {		if(value & 0x1) {			KeyValue = 2;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 1\n", col_global + 1);		}		if(value & 0x2) {			KeyValue = 6;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 2\n", col_global + 1);		} 		if(value & 0x4) {			KeyValue = 10;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 3\n", col_global + 1);		}					if(value & 0x8) {			KeyValue = 14;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 4\n", col_global + 1);		} 				dly(1000);	}	else if(col_global == 2) {		if(value & 0x1) {			KeyValue = 3;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 1\n", col_global + 1);		} 		if(value & 0x2) {			KeyValue = 7;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 2\n", col_global + 1);		} 		if(value & 0x4) {			KeyValue = 11;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 3\n", col_global + 1);		} 					if(value & 0x8) {			KeyValue = 15;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 4\n", col_global + 1);		} 			dly(1000);	}	else if(col_global == 3) {		if(value & 0x1) {			KeyValue = 4;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 1\n", col_global + 1);		} 		if(value & 0x2) {			KeyValue = 8;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 2\n", col_global + 1);		} 		if(value & 0x4) {			KeyValue = 12;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 3\n", col_global + 1);		} 					if(value & 0x8) {			KeyValue = 16;			printk("KeyValue = %d\n", KeyValue);//			printk("col = %d, row = 4\n", col_global + 1);		} 		dly(1000);	}#if 0	//test ok		if(value & 0x1) {		printk("col = %d, row = 1\n", col_global + 1);	}	if(value & 0x2) {		printk("col = %d, row = 2\n", col_global + 1);	}	if(value & 0x4) {		printk("col = %d, row = 3\n", col_global + 1);	}				if(value & 0x8) {		printk("col = %d, row = 4\n", col_global + 1);	}	//			printk("value = 0x%02x\n", value);			dly(500);#endif			#if 0		while(1){					again:			printk("\n0x80000100 : 0x%08x\n", *(unsigned char *)0xff000100);			printk("0x80000000 : 0x%08x\n", *(unsigned char *)0xff000000);						printk("n= %d\n", n);			printk("interrupt\n");			value = *(unsigned char *)0xff000000;						if(value & 0x1) {				printk("col = %d, row = 1\n", n + 1);			}			if(value & 0x2) {				printk("col = %d, row = 2\n", n + 1);			}			if(value & 0x4) {				printk("col = %d, row = 3\n", n + 1);			}						if(value & 0x8) {				printk("col = %d, row = 4\n", n + 1);			}//			printk("value = 0x%02x\n", value);			dly(500);			*(unsigned long *)0xff000100 += 1;			*(unsigned long *)0xff001700 |= 0xff;		//clear			n += 1;			if( n == 4) {				*(unsigned long *)0xff000100 -= 4;				n -= 4;				goto scan_exit;			}			goto again;	}#endif						//	*(unsigned long *)0xff001700 |= 0xff;		//clear}static int KbdClose(struct inode * inode, struct file * file){ 	MOD_DEC_USE_COUNT; 	return 0;}static int KbdOpen(struct inode * inode, struct file * file){	MOD_INC_USE_COUNT;		*(unsigned long *)0xff000040 |= 0xfffffffff;        *(unsigned long *)0xff001100 |= 0x000000008;        *(unsigned long *)0xff000100 |= 0x000000009;	enable_irq(16);	return 0;}static int KbdRead(struct file * file, char * buffer, size_t count, loff_t *ppos){        unsigned char *kbuf=kmalloc(16, GFP_KERNEL);	*kbuf = KeyValue;	copy_to_user(buffer, kbuf, 1);	kfree(kbuf);		//copy_to_user(buffer, &KeyValue, sizeof KeyValue);	//Ready = 0;	return sizeof 1;}/* * select for mouse input */static unsigned int KbdSelect(	struct file *file, 	struct poll_table_struct *wait){    	if (Ready)        return 1;	poll_wait(file, &KbdWait, wait);	return 0;}static int KbdIoctl(        struct inode *inode,        struct file *file,        unsigned int cmd,        unsigned long arg){	int flag = 0;	        switch(cmd) {		case 0:			for(col_global = 0; col_global < 4; col_global++){				if(col_global == 0 ) {									*(unsigned long *)0xff000100 &= ~0xf;					*(unsigned long *)0xff000100 |= 0x8;					dly(1000);				}				else if( col_global == 1) {					*(unsigned long *)0xff000100 &= ~0xf;					*(unsigned long *)0xff000100 |= 0x9;					dly(1000);				}					else if( col_global == 2) {					*(unsigned long *)0xff000100 &= ~0xf;					*(unsigned long *)0xff000100 |= 0xa;					dly(1000);				}					else if( col_global == 3) {					*(unsigned long *)0xff000100 &= ~0xf;					*(unsigned long *)0xff000100 |= 0xb;					dly(1000);				}				}			break;		case 2:			if( flag == 0) {				*(unsigned long *)0xff000100 += 1;				flag = 1;			} else if (flag == 1){				*(unsigned long *)0xff000100 -= 1;				flag = 0;			}			break;		case 1:			{			unsigned char value;			int n = 0;					while(1){					again://			printk("0x80000100 : 0x%08x\n", *(unsigned char *)0xff000100);//			printk("0x80000000 : 0x%08x\n", *(unsigned char *)0xff000000);			//			printk("n= %d\n", n);			value = *(unsigned char *)0xff000000;						if(value & 0x1) {				printk("col = %d, row = 1\n", n + 1);			}			if(value & 0x2) {				printk("col = %d, row = 2\n", n + 1);			}			if(value & 0x4) {				printk("col = %d, row = 3\n", n + 1);			}						if(value & 0x8) {				printk("col = %d, row = 4\n", n + 1);			}//			printk("value = 0x%02x\n", value);			dly(500);			*(unsigned long *)0xff000100 += 1;			n += 1;			if( n == 4) {				*(unsigned long *)0xff000100 -= 4;				n -= 4;				break;			}			goto again;		}// end for			break;			} //end case 0				        default:                return -EINVAL;        }	return 1;}struct file_operations Kbd_fops = {	read:	KbdRead,	poll:	KbdSelect, 	/* select */	open:	KbdOpen,	ioctl:	KbdIoctl,	release:	KbdClose,};int keyboard_init(void){        int     rc;        Ready = 0;        rc = register_chrdev(KEYBOARD_MAJOR, "ep7312-keyboard", &Kbd_fops);        if (rc < 0) {                printk(KERN_WARNING "Keyboard: can't get Major %d\n",                        KEYBOARD_MAJOR);                return rc;         }        printk("Keyboard Driver Support\n");	*(unsigned long *)0xff000040 |= 0xfffffffff;	*(unsigned long *)0xff001100 |= 0x000000008;	*(unsigned long *)0xff000100 |= 0x000000009;			if ( request_irq(16, KbdInterrupt, 0, "mykbd", NULL) ) {		printk("Keyboard: Cannot register interrupt.\n");		return -EBUSY;	}	return 0;}void keyboard_cleanup(void){         free_irq(16, NULL);	      unregister_chrdev(KEYBOARD_MAJOR, "ep7312-keyboard");     return;}	module_init(keyboard_init);module_exit(keyboard_cleanup);

⌨️ 快捷键说明

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