📄 keyb.c
字号:
} 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 + -