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

📄 keyb.c

📁 键盘设备驱动,只需修改代码里的功能码和系统码即可使用
💻 C
📖 第 1 页 / 共 3 页
字号:
	      }	      return 0;	  } 	} else	  *keycode = scancode;	  	handle_keyboard(*keycode);  //yhwang add	 	return 1;}void command(unsigned char cmd){	int key;	outportb(PORT_PSDAT,cmd);	if(debug>0)		printk("cmd[%x]\n",cmd);	while(1) {		key = inportb(PORT_PSTAT);		if(debug>0)			printk("PORT_PSTAT[%x]\n",key);		if((key&0x2)==0)			break;	}	key = inportb(PORT_PSTAT);	outportb(PORT_PSCON,0x80);}void pscon(unsigned char cmd){	outportb(PORT_PSCON,cmd);}void delay(int i){	do {		int j =1000;	// ori		do {			asm volatile ("nop");		} while (--j>=0);	} while (--i>=0);}void init_kbd(void);void init_kbd(){	pscon(0x6c);	command(0xff);}void pollingKeyboard(void){	int i;	int stat;	for(i=0;i<10;i++) {		stat = inportb(PORT_PSTAT);		if ((stat&0x0a)==0x0a) {			int in_key;			in_key = inportb(PORT_PSDAT);			handle_at_scancode(in_key);			if(debug>0)				printk("kbd(%d)[%x] ",i,in_key);       			outportb(PORT_PSCON,0x80);		}		}}#ifdef SUPPORT_IRextern int read_ir(void);extern void init_ir(void);extern int ir_flag;void polling_ir(void){	int i;	int data;	int keyb;	for(i=0;i<1;i++) {		data = read_ir();		if(data>=0) {					if(ir_flag)			{				printk("!!!!!!!!!!!! you used hangzhou_ir  !!!!!!!!!!!!!!\n");				keyb = ir_map_hansuntech[data];			}			else			{				printk("!!!!!!!!!!!! you used other_ir  !!!!!!!!!!!!!!\n");				keyb= ir_map[data];			}				//keyb= ir_map[data];			if(debug>0)			//	printk("!!!!!!!ir(%d)[%x]->[%x] ",i, data, keyb);         //*****huang modify			switch(keyb) {			case R_UP:			case R_DOWN:			case R_LEFT:			case R_RGHT:/*				handle_at_scancode(0xe0);				handle_at_scancode(keyb);*/				handle_at_scancode(0xe0);				handle_at_scancode(0xf0);				handle_at_scancode(keyb);			default:				handle_at_scancode(keyb);				handle_at_scancode(0xf0);				handle_at_scancode(keyb);				break;			}		}	}}#endif //SUPPORT_IRstruct timer_list keyboard_timer;  static void dvd_keyboard_timeup(unsigned long data){	if(use_keyb)		pollingKeyboard();#ifdef SUPPORT_IR	if(use_ir)		polling_ir();#endif	mod_timer(&keyboard_timer, jiffies + SCANHZ);   }                                        static void  dvd_keyboard_starttimer(void){	printk("dvd_keyboard_starttimer\n");	init_timer(&keyboard_timer);	keyboard_timer.function = dvd_keyboard_timeup;	keyboard_timer.data = 0;	keyboard_timer.expires = jiffies + SCANHZ;	add_timer(&keyboard_timer);}/* *	PS/2 Auxiliary Device */static spinlock_t controller_lock = SPIN_LOCK_UNLOCKED; static struct aux_queue *queue;	/* Mouse data buffer. */static int aux_count;static inline void handle_keyboard(unsigned char scancode){	static unsigned char prev_code;	int head;	prev_code = scancode;	add_mouse_randomness(scancode);	if (aux_count) {		head = queue->head;		queue->buf[head] = scancode;		head = (head + 1) & (AUX_BUF_SIZE-1);		if (head != queue->tail) {			queue->head = head;			kill_fasync(&queue->fasync, SIGIO, POLL_IN);			wake_up_interruptible(&queue->proc_list);		}	}}static unsigned char get_from_queue(void){	unsigned char result;	unsigned long flags;	spin_lock_irqsave(&controller_lock, flags);	result = queue->buf[queue->tail];	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);	spin_unlock_irqrestore(&controller_lock, flags);	return result;}static inline int queue_empty(void){	return queue->head == queue->tail;}static int fasync_aux(int fd, struct file *filp, int on){	int retval;	retval = fasync_helper(fd, filp, on, &queue->fasync);	if (retval < 0)		return retval;	return 0;}/* * Random magic cookie for the aux device */#define AUX_DEV ((void *)queue)static int release_aux(struct inode * inode, struct file * file){	lock_kernel();	fasync_aux(-1, file, 0);	if (--aux_count) {		unlock_kernel();		return 0;	}	del_timer(&keyboard_timer);	unlock_kernel();	return 0;}/* * Install interrupt handler. * Enable auxiliary device. */static int open_aux(struct inode * inode, struct file * file){	if (aux_count++) {		return 0;	}	queue->head = queue->tail = 0;		/* Flush input queue */	dvd_keyboard_starttimer();	return 0;}/* * Put bytes from input queue to buffer. */static ssize_t read_aux(struct file * file, char * buffer,			size_t count, loff_t *ppos){	DECLARE_WAITQUEUE(wait, current);	ssize_t i = count;	unsigned char c;	if (queue_empty()) {		if (file->f_flags & O_NONBLOCK)			return -EAGAIN;		add_wait_queue(&queue->proc_list, &wait);repeat:		set_current_state(TASK_INTERRUPTIBLE);		if (queue_empty() && !signal_pending(current)) {			schedule();			goto repeat;		}		current->state = TASK_RUNNING;		remove_wait_queue(&queue->proc_list, &wait);	}	while (i > 0 && !queue_empty()) {		c = get_from_queue();		put_user(c, buffer++);		i--;	}	if (count-i) {		file->f_dentry->d_inode->i_atime = CURRENT_TIME;		return count-i;	}	if (signal_pending(current))		return -ERESTARTSYS;	return 0;}/* * Write to the aux device. */#if 0static ssize_t write_aux(struct file * file, const char * buffer,			 size_t count, loff_t *ppos){	ssize_t retval = 0;	if (count) {		ssize_t written = 0;		if (count > 32)			count = 32; /* Limit to 32 bytes. */		do {			char c;			get_user(c, buffer++);			aux_write_dev(c);			written++;		} while (--count);		retval = -EIO;		if (written) {			retval = written;			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;		}	}	return retval;}#endifstatic int set_ir_map(int keymap){	switch(keymap) {		case 1:			ir_map = ir_map_coship;			printk("INFO: sp_keyb: ir_map = ir_map_coship\n");			break;		default:			ir_map = ir_map_sunplus;			printk("INFO: sp_keyb: ir_map = ir_map_sunplus(2008/8/8)\n");			break;	}	return 0;}/* No kernel lock held - fine */static unsigned int aux_poll(struct file *file, poll_table * wait){	poll_wait(file, &queue->proc_list, wait);	if (!queue_empty())		return POLLIN | POLLRDNORM;	return 0;}struct file_operations psaux_fops = {	read:		read_aux,//	write:		write_aux,	poll:		aux_poll,	open:		open_aux,	release:	release_aux,	fasync:		fasync_aux,};/* * Initialize driver. */static struct miscdevice psaux_mouse = {	/*PSMOUSE_MINOR*/2, "psaux1", &psaux_fops};int __init psaux_init(void){	int retval;	printk("Sunplus DVD PS/2 Keyboard Driver Initial\n");//	printk("INFO: sp_keyb v0.1c(2003.11.28)\n");//	printk("INFO: sp_keyb v0.1d(2003.12.30)[SUNPLUS IR]\n");//	printk("INFO: sp_keyb v0.1d(2004.01.02)[SUNPLUS IR]\n");//	printk("INFO: sp_keyb v0.1e(2004.01.02)[debug, ir_type]\n");	if ((retval = misc_register(&psaux_mouse)))		return retval;	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);	if (queue == NULL) {		printk(KERN_ERR "psaux_init(): out of memory\n");		misc_deregister(&psaux_mouse);		return -ENOMEM;	}	memset(queue, 0, sizeof(*queue));	queue->head = queue->tail = 0;	init_waitqueue_head(&queue->proc_list);	set_ir_map(ir_type);	init_kbd();#ifdef SUPPORT_IR	init_ir();#endif	return 0;}#ifdef CONFIG_PROC_FS#include <linux/proc_fs.h>#define	DRVNAME	"sp_keyb"#define	PROCNAME "driver/" DRVNAME//char sp_keyb_version[]="sp_keyb: v0.1(2004.01.19)";char sp_keyb_version[]="sp_keyb: v0.2a(2008.02.23) use_keyb use_ir time_tick";static int sp_keyb_read_proc(char *buf, char **start, off_t offset,			   int len, int *eof, void *private){	int clen=0;	clen += sprintf(buf + clen, "%s\n", sp_keyb_version);	*start = buf + offset;	if (clen > offset)		clen -= offset;	else		clen = 0;	return clen < len ? clen : len;}#endif	//CONFIG_PROC_FSstatic int init_module(void){#ifdef CONFIG_PROC_FS	create_proc_read_entry(PROCNAME, 0, 0, sp_keyb_read_proc, NULL);#endif	return psaux_init();	}static void cleanup_module(void){	#ifdef CONFIG_PROC_FS	remove_proc_entry(PROCNAME, NULL);#endif	del_timer(&keyboard_timer); //yhwang for testing 	misc_deregister(&psaux_mouse);	printk("cleanup_module\n");	return;}MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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