?? ps2_kbd_mouse.c
字號:
do{ ack=0; mega8_PS20_Send(data); mega8_PS20_WaitData(&ack, KBD_TIMEOUT); if(KBD_REPLY_RESEND==ack){ sleep(HZ/5); continue; } if(KBD_REPLY_ACK==ack) break; }while(retries-->0); PS20_CLR_WAITING(); } else if(ps2n==1){ //for ps2-1 PS21_SET_WAITING(); do{ ack=0; mega8_PS21_Send(data); mega8_PS21_WaitData(&ack, KBD_TIMEOUT); if(KBD_REPLY_RESEND==ack){ sleep(HZ/5); continue; } if(KBD_REPLY_ACK==ack) break; }while(retries-->0); PS21_CLR_WAITING(); } spin_unlock_irqrestore(&ps_controller_lock[ps2n], flags); if(retries==-1){ printk("ps/2 port=%d send failed!, ack=0x%x, data=0x%x\n", ps2n, ack,data); return -1; } sleep(HZ/5); return 0;}typedef struct{ wait_queue_head_t wait; unsigned char data; int exit;}KbdLedCtrl;static KbdLedCtrl ledctrl;static inline void Ps2_Set_KeyboardLed(int ps2n, unsigned char led){ PS2DPRINTK("begin set led done\n"); if ((send_data(ps2n, KBD_CMD_SET_LEDS)<0 || send_data(ps2n, led)<0)) { PS2DPRINTK("Set led failed!\n"); send_data(ps2n, KBD_CMD_ENABLE); /* re-enable kbd if any errors */ } PS2DPRINTK("Set led done\n");}static int Ps2_Kbdled_sendthread(void* ps2n){ init_waitqueue_head(&ledctrl.wait); ledctrl.exit=0; for(;;){ interruptible_sleep_on(&ledctrl.wait); if(ledctrl.exit==1){ //stop this thread PS2DPRINTK("Ps2_Kbdled_sendthread release!\n"); return 0; } sleep(HZ/5); Ps2_Set_KeyboardLed((int)ps2n, ledctrl.data); } return 0;}static void Ps2_Kbd_leds(unsigned char leds){ PS2DPRINTK("Set led = 0x%x\n", leds); ledctrl.data=leds; wake_up_interruptible(&ledctrl.wait);}static ps2_handle_event __init Ps2_kbd_init_hw(int ps2n){ int i; static int once=0; if(once){ printk("I2c-PS/2: can't support two keyboard\n"); return NULL; } once++; //initialization keyboard map memset(Sc2_Sc1_Map, 0, sizeof(Sc2_Sc1_Map)); memset(Sc2_Sc1_MapE0, 0, sizeof(Sc2_Sc1_MapE0)); for(i=0; i<sizeof(Make_Sc2Sc1_Map)/sizeof(*Make_Sc2Sc1_Map); i++){ Sc2_Sc1_Map[Make_Sc2Sc1_Map[i].Scancode2]=Make_Sc2Sc1_Map[i].Scancode1; } for(i=0; i<sizeof(Make_Sc2Sc1_MapE0)/sizeof(*Make_Sc2Sc1_MapE0); i++){ Sc2_Sc1_MapE0[Make_Sc2Sc1_MapE0[i].Scancode2]=Make_Sc2Sc1_MapE0[i].Scancode1; } kernel_thread(Ps2_Kbdled_sendthread, (void*)ps2n, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); k_setkeycode = Ps2_Kbd_setkeycode; k_getkeycode = Ps2_Kbd_getkeycode; k_translate = Ps2_Kbd_translate; k_unexpected_up = Ps2_Kbd_unexpected_up; k_leds = Ps2_Kbd_leds;#ifdef CONFIG_MAGIC_SYSRQ k_sysrq_xlate = Ps2_Kbd_sysrq_xlate; k_sysrq_key = 0x54;#endif //sync keyboard led Ps2_Set_KeyboardLed(ps2n, getledstate()); return handle_PS2kbd_event;}static void Ps2_kbd_release(void){ ledctrl.exit=1; wake_up_interruptible(&ledctrl.wait); sleep(HZ/2);}//////////////////////////////////PS/2 mouse//////////////////////////////////* * PS/2 Auxiliary Device */static int __init psaux_init(void);#define AUX_RECONNECT1 0xaa /* scancode1 when ps2 device is plugged (back) in */#define AUX_RECONNECT2 0x00 /* scancode2 when ps2 device is plugged (back) in */ static struct aux_queue *queue; /* Mouse data buffer. */static int aux_count;static int ps2port;#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)#define MAX_RETRIES 60 /* some aux operations take long time*/static inline void handle_mouse_event(int ps2n, unsigned char scancode){ add_mouse_randomness((__u32)scancode); if (aux_count) { int head = queue->head; queue->buf[head] = scancode; head = (head + 1) & (AUX_BUF_SIZE - 1); if (head != queue->tail) { queue->head = head; if (queue->fasync) kill_fasync(&queue->fasync, SIGIO, POLL_IN); wake_up_interruptible(&queue->proc_list); } }}static inline void handle_PS2mouse_event(int ps2n, unsigned char data){ handle_mouse_event(ps2n, data);}/* * Send a byte to the mouse. */static void aux_write_dev(int ps2n, int val){ unsigned long flags; DPRINTK("aux write: val=0x%x",val); spin_lock_irqsave(&ps_controller_lock[ps2n], flags); if(ps2n==0) mega8_PS20_Send(val); else if(ps2n==1) //for ps2-1 mega8_PS21_Send(val); sleep(HZ/5); spin_unlock_irqrestore(&ps_controller_lock[ps2n], flags);}/* * Send a byte to the mouse & handle returned ack */static void aux_write_ack(int ps2n, unsigned char val){ unsigned char data; unsigned long flags; spin_lock_irqsave(&ps_controller_lock[ps2n], flags); if(ps2n==0){ PS20_SET_WAITING(); mega8_PS20_Send(val); mega8_PS20_WaitData(&data, MOUSE_TIMEOUT); PS20_CLR_WAITING(); } else if(ps2n==1){ //for ps2-1 PS21_SET_WAITING(); mega8_PS21_Send(val); mega8_PS21_WaitData(&data, MOUSE_TIMEOUT); PS21_CLR_WAITING(); } spin_unlock_irqrestore(&ps_controller_lock[ps2n], flags);}static unsigned char get_from_queue(int ps2n){ unsigned char result; unsigned long flags; spin_lock_irqsave(&ps_controller_lock[ps2n], flags); result = queue->buf[queue->tail]; queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE - 1); spin_unlock_irqrestore(&ps_controller_lock[ps2n], 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){ fasync_aux(-1, file, 0); if (--aux_count) return 0; aux_write_ack(ps2port, AUX_DISABLE_DEV); /* Disable aux device */ if(ps2port==0) mega8_device_release (DTYPE_PS2_0); //release ps2 else if(ps2port==1) mega8_device_release (DTYPE_PS2_1); //release ps2 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 */ if(ps2port==0) mega8_device_request(DTYPE_PS2_0); //release ps2 else if(ps2port==1) mega8_device_request(DTYPE_PS2_1); //release ps2 /* Enable the auxiliary port on controller. */ aux_write_ack(ps2port, AUX_ENABLE_DEV); /* Enable aux device */ return 0;}/* * Put bytes from input queue to buffer. */static ssize_tread_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(ps2port); 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.static 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(ps2port, c); written++; } while (--count); retval = -EIO; if (written) { retval = written; file->f_dentry->d_inode->i_mtime = CURRENT_TIME; } } return retval;}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, "psaux", &psaux_fops,};static int __init psaux_init(void){ aux_count=0; misc_register(&psaux_mouse); queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); memset(queue, 0, sizeof(*queue)); queue->head = queue->tail = 0; init_waitqueue_head(&queue->proc_list); aux_write_ack(ps2port, AUX_SET_SAMPLE); aux_write_ack(ps2port, 50); /* 100 samples/sec */ aux_write_ack(ps2port, AUX_SET_RES); aux_write_ack(ps2port, 3); /* 8 counts per mm */ aux_write_ack(ps2port, AUX_SET_SCALE11); /* 2:1 scaling */ return 0;}static ps2_handle_event __init Ps2_Mouse_init_hw(int ps2n){ static int once=0; if(once){ printk("I2c-PS/2: can't support two Mouse\n"); return NULL; } once++; ps2port=ps2n; psaux_init(); if(ps2n==0) mega8_device_release (DTYPE_PS2_0); //open port when open mouse device else if(ps2n==1) mega8_device_release (DTYPE_PS2_1); //open port when open mouse device else return NULL; return handle_PS2mouse_event;}////////////////////////////////for PS/2 port0 ///////////////////////////////////////////////////////////////////for PS/2 port0 end////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -