📄 s3c2410ps.c
字号:
//printk("PS2_SEND_OK\n"); } else { lastps2sendstatus0 = PS2_SEND_FAILED; //printk("PS2_SEND_FAILED\n"); } wake_up_interruptible(&s3c2410fcrps2_device->proc_list); ps0status = PSSTATUS_WAITREV; break; } restore_flags(flags);} /************************************************************************* 功能:Time interrupt handle 参数: 返回值:0 OK -1 err **************************************************************************/static void s3c2410_time_isr_PS2(unsigned long data){ //TCNT1H = 0xcf;TCNT1L = 0x3c; //update time //printk("input time interrupt!\n"); set_timer_irq(&key_timer,1); switch(ps0status) { case PSSTATUS_SendPDCLK: PS2_DATA_OUT(); //pull down ps/2 data GPB4 PS2_DATA_CLR; Release_PS2CLK0(); //delay(40); ps0status = PSSTATUS_SendWTCLK; break; case PSSTATUS_SendWTCLK: //wait user ack timeout Stop_Time1(); lastps2sendstatus0 = PS2_SEND_FAILED; ReleasePS20Data(); ps0status = PSSTATUS_WAITREV; break; }}static void init_ps_timer(struct timer_list *timer){ init_timer(timer); timer->function = (void *) s3c2410_time_isr_PS2; }/************************************************************************* 功能:set and enable timer irq to now + delay ticks 参数: 返回值:NO **************************************************************************/void set_timer_irq(struct timer_list *timer,int delay) { del_timer(timer); timer->expires = jiffies + delay; add_timer(timer); }/************************************************************************* 功能:release_key_timer 参数: 返回值:NO **************************************************************************/static void release_key_timer(struct timer_list *timer) { del_timer(timer);}/************************************************************************* 功能:parse st2 参数: 返回值:0 OK -1 err **************************************************************************/static void SetSend_PS20(unsigned char data){ ps2_senddata0 = data; ps0status = PSSTATUS_SendPDCLK; paritysum = 0; PULLDOWN_PS2CLK0(); //int time enable time interrupt set_timer_irq(&key_timer,1); }/************************************************************************* 功能:parse st2 参数: 返回值:0 OK -1 err **************************************************************************/static void release_ps2_device(void) { disable_irq(IRQ_PS2);}/****************************************************************************XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX System function XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX *****************************************************************************//************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static int PS2_open(struct inode *inode, struct file *filp){ if(device_open) return -EBUSY; MOD_INC_USE_COUNT; device_open++; s3c2410fcrps2_device = (S3C2410fcrps2 *)kmalloc(sizeof(S3C2410fcrps2),GFP_KERNEL); if ( s3c2410fcrps2_device == NULL ) return -ENOMEM; memset(s3c2410fcrps2_device,0,sizeof(*s3c2410fcrps2_device)); s3c2410fcrps2_device->head = s3c2410fcrps2_device->tail = 0; init_waitqueue_head(&s3c2410fcrps2_device->proc_list); ps0status = PSSTATUS_WAITREV; /*success open*/ printk("PS/2_driver open!\n"); return 0;}/************************************************************************* 功能:ps2_poll 参数: 返回值:-1: error 0: OK **************************************************************************/static unsigned int ps2_poll (struct file *flip,struct poll_table_struct *wait){ poll_wait(flip,&s3c2410fcrps2_device->proc_list,wait); if (new_ps2_state) return POLLIN | POLLRDNORM; return 0;}/************************************************************************* 功能:ps2_fasync 参数: 返回值:-1: error 0: OK **************************************************************************/static int ps2_fasync(int inode,struct file *flip,int mode){ return fasync_helper(inode,flip,mode,&s3c2410fcrps2_device->fasync_queue);}/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static int PS2_release(struct inode *inode,struct file *filp) { MOD_DEC_USE_COUNT; printk("PS/2_driver close!\n"); device_open--; ps2_fasync(inode,filp,(int)0); release_ps2_device(); kfree(s3c2410fcrps2_device); return 0; }/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static ssize_t PS2_read(struct file *filp,char * buff,size_t count, loff_t * f_pos){ int i,flag; unsigned char ch; while (!new_ps2_state) { if (filp->f_flags & O_NONBLOCK) return -EAGAIN; interruptible_sleep_on(&s3c2410fcrps2_device->proc_list); if(signal_pending(current)) return -ERESTARTSYS; }/* while */ i = count; while ((i>0) && !queue_empty()) { ch = get_char_from_queue(); flag = put_user(ch,buff++); if (flag != 0) return -EFAULT; /* put failed return number >0 */ i--; } i = count - i; if (queue_empty()) new_ps2_state = 0; else new_ps2_state = 1; //printk(" %d numbers has been read\n",i); return i; /* return the number that has been read */ }/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static ssize_t PS2_write(struct file *file,char *buff, size_t len,loff_t *offset) /* the buffer to fill with data */ { int i = 0,flag,j = 0; unsigned char ch; while( ps0status != PSSTATUS_WAITREV ) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; interruptible_sleep_on(&s3c2410fcrps2_device->proc_list); if(signal_pending(current)) return -ERESTARTSYS; } for( i = len; i > 0; i-- ) { flag = get_user(ch, buff++); if( flag != 0 ) return -EFAULT; SetSend_PS20( ch ); interruptible_sleep_on(&s3c2410fcrps2_device->proc_list); if(lastps2sendstatus0 == PS2_SEND_OK) j++; } //i = len - i; //printk(" %d numbers %x has been writen\n",i,ch); if(j > 0)return j; else return -1; }/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static int PS2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, // the command to the ioctl unsigned long arg) // the parameter to it { return 0;}/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static struct file_operations PS2_fops = { owner: THIS_MODULE, read: PS2_read, ioctl: PS2_ioctl, poll: ps2_poll, open: PS2_open, write: PS2_write, release: PS2_release, fasync: ps2_fasync, };/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/static int __init PS2_init(void){ int ret; ret = register_chrdev(0, DEVICE_NAME,&PS2_fops); if(ret < 0) { printk(DEVICE_NAME": Unable to get major\n"); } else printk("%s: Device register with name: %s and number: %d %d\n", __file__, DEVICE_NAME, ret, FSRTC_MINOR); DbPs2Major = ret; #ifdef CONFIG_DEVFS_FS devfs_PS2_dir = devfs_mk_dir(NULL,"PS2",NULL); devfs_PS2raw = devfs_register(devfs_PS2_dir,"0raw", DEVFS_FL_DEFAULT,DbPs2Major,PS2_MINOR, S_IFCHR|S_IRUSR|S_IWUSR,&PS2_fops,NULL); #endif set_external_irq(IRQ_PS2, EXT_FALLING_EDGE, GPIO_PULLUP_EN);//EXT_FALLING_EDGE disable_irq(IRQ_PS2); ret = request_irq(IRQ_PS2, &s3c2410_exint_isr_PS2, SA_INTERRUPT, "PS2", NULL); disable_irq(IRQ_PS2); if(ret) { printk("Request IRQ %d for PS2 interface failure. ret = %d\n",IRQ_PS2, ret); return ret; } else { printk("IRQ %d has been attached to s3c2410 PS/2 !\n",IRQ_PS2); } PULLDOWN_PS2CLK0(); init_ps_timer(&key_timer); printk(DEVICE_NAME" initialized\n"); return 0;}/************************************************************************* 功能: 参数: 返回值:-1: error 0: OK **************************************************************************/void __exit PS2_cleanup(void){ free_irq(IRQ_PS2,NULL); #ifdef CONFIG_DEVFS_FS devfs_unregister(devfs_PS2raw); devfs_unregister(devfs_PS2_dir);#endif unregister_chrdev(DbPs2Major,DEVICE_NAME); printk("Ps/2 driver is cleanup!\n"); return ;}module_init(PS2_init);module_exit(PS2_cleanup);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -