📄 s3c2410ts.c
字号:
tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF); spin_unlock_irq(&(tsdev.lock)); return sizeof(TS_RET);}static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){ TS_RET ts_ret;retry: if (tsdev.head != tsdev.tail) { int count; count = tsRead(&ts_ret); if (count) copy_to_user(buffer, (char *)&ts_ret, count); return count; } else { if (filp->f_flags & O_NONBLOCK) return -EAGAIN; interruptible_sleep_on(&(tsdev.wq)); if (signal_pending(current)) return -ERESTARTSYS; goto retry; } return sizeof(TS_RET);}#ifdef USE_ASYNCstatic int s3c2410_ts_fasync(int fd, struct file *filp, int mode) { return fasync_helper(fd, filp, mode, &(tsdev.aq));}#endifstatic unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait){ poll_wait(filp, &(tsdev.wq), wait); return (tsdev.head == tsdev.tail) ? 0 : (POLLIN | POLLRDNORM); }static inline void start_ts_adc(void){ adc_state = 0; mode_x_axis(); start_adc_x();}static inline void s3c2410_get_XY(void){ if (adc_state == 0) { adc_state = 1; disable_ts_adc(); y = __raw_readl(S3C2410_ADCDAT1) & 0x3ff; mode_y_axis(); start_adc_y(); } else if (adc_state == 1) { adc_state = 0; disable_ts_adc(); x = __raw_readl(S3C2410_ADCDAT0) & 0x3ff; DPRINTK("PEN DOWN: x: %08d, y: %08d\n", x, y); wait_up_int(); tsdev.penStatus = PEN_DOWN; tsEvent(); }}static irqreturn_t s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg){#if 0 DPRINTK("Occured Touch Screen Interrupt\n"); DPRINTK("SUBSRCPND = 0x%08lx\n", SUBSRCPND);#endif //printk(KERN_ERR "Occured Touch Screen Interrupt in s3c2410_isr_adc!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); spin_lock_irq(&(tsdev.lock)); if (tsdev.penStatus == PEN_UP) {//printk(KERN_ERR "hi,i'm s3c2410_isr_adc!"); s3c2410_get_XY();}#ifdef HOOK_FOR_DRAG else s3c2410_get_XY();#endif spin_unlock_irq(&(tsdev.lock)); return IRQ_HANDLED;}static irqreturn_t s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg){#if 0 DPRINTK("Occured Touch Screen Interrupt\n"); DPRINTK("SUBSRCPND = 0x%08lx\n", SUBSRCPND);#endif//printk(KERN_ERR "Occured Touch Screen Interrupt in s3c2410_isr_tc!!!!!!!!!!!!!!!!!!!!!\n"); spin_lock_irq(&(tsdev.lock)); if (tsdev.penStatus == PEN_UP) { //printk(KERN_ERR "hi,i'm s3c2410_isr_tc_p1!\n"); ts_r_idx = 0; //add by hzh ts_r_beg = 5; start_ts_adc(); } else { tsdev.penStatus = PEN_UP; //printk(KERN_ERR "hi,i'm s3c2410_isr_tc_p2!\n"); DPRINTK("PEN UP: x: %08d, y: %08d\n", x, y); //printk(KERN_ERR "PEN UP: x: %08d, y: %08d\n", x, y); wait_down_int(); tsEvent(); } spin_unlock_irq(&(tsdev.lock)); return IRQ_HANDLED;}#ifdef HOOK_FOR_DRAGstatic void ts_timer_handler(unsigned long data){ spin_lock_irq(&(tsdev.lock)); if (tsdev.penStatus == PEN_DOWN) { start_ts_adc(); } spin_unlock_irq(&(tsdev.lock));}#endifstatic int s3c2410_ts_open(struct inode *inode, struct file *filp){ tsdev.head = tsdev.tail = 0; tsdev.penStatus = PEN_UP;#ifdef HOOK_FOR_DRAG init_timer(&ts_timer); ts_timer.function = ts_timer_handler;#endif tsEvent = tsEvent_raw; init_waitqueue_head(&(tsdev.wq)); //MOD_INC_USE_COUNT; return 0;}static int s3c2410_ts_release(struct inode *inode, struct file *filp){#ifdef HOOK_FOR_DRAG del_timer(&ts_timer);#endif //MOD_DEC_USE_COUNT; return 0;}static struct file_operations s3c2410_fops = { owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read, release: s3c2410_ts_release,#ifdef USE_ASYNC fasync: s3c2410_ts_fasync,#endif poll: s3c2410_ts_poll,};void tsEvent_dummy(void) {}#ifdef CONFIG_PMstatic int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) { switch (req) { case PM_SUSPEND: tsEvent = tsEvent_dummy; break; case PM_RESUME: tsEvent = tsEvent_raw; wait_down_int(); break; } return 0;}#endifstatic struct clk *adc_clock;static int __init s3c2410ts_probe(struct device *dev){ int ret; tsEvent = tsEvent_dummy; //printk(KERN_ERR "hello,just junp in s3c2410ts_probe!!!!!!!!!!!!!!\n"); ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops); if (ret < 0) { printk(DEVICE_NAME " can't get major number\n"); return ret; } printk(KERN_ERR "success get major number!!!!!!\n"); tsMajor = ret; printk("%s device driver MAJOR:%d\n", DEVICE_NAME, tsMajor); //fla input ts clk! adc_clock = clk_get(NULL, "adc"); if (!adc_clock) { //printk(KERN_ERR "failed to get adc clock source\n"); return -ENOENT; } clk_use(adc_clock); clk_enable(adc_clock); printk(KERN_ERR "success to get adc clock source!\n"); base_addr = ioremap(S3C2410_PA_ADC,0x20); printk(KERN_ERR "base_addr = %#p\n",base_addr); //printk(KERN_ERR "hi,new adctsc = 0x%08x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__raw_readl(S3C2410_ADCTSC)); //writel((readl(S3C2410_ADCTSC)&0x00000000)|0x00000053,S3C2410_ADCTSC); //writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\ // S3C2410_ADCCON); __raw_writel(WAIT4INT(0), S3C2410_ADCTSC); //printk(KERN_ERR "hi,the newer0 adctsc = 0x%08x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__raw_readl(S3C2410_ADCTSC)); /* set gpio to XP, YM, YP and YM */// set_gpio_ctrl(GPIO_YPON); // set_gpio_ctrl(GPIO_YMON);// set_gpio_ctrl(GPIO_XPON); //set_gpio_ctrl(GPIO_XMON); //__raw_writel(__raw_readl(S3C2410_GPGCON)|(0xff<<24), S3C2410_GPGCON); FLA MASK __raw_writel(30000, S3C2410_ADCDLY); //added by hzh 30000--20000 /* Enable touch interrupt */ ret = request_irq(IRQ_ADC, s3c2410_isr_adc, SA_INTERRUPT, DEVICE_NAME, s3c2410_isr_adc); if (ret) goto adc_failed; ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT, //IRQ_TC--->IRQ_TIMER0 DEVICE_NAME, s3c2410_isr_tc); if (ret) goto tc_failed; /* Wait for touch screen interrupts */ printk(KERN_ERR "line %d passed!\n",__LINE__); wait_down_int(); //fla mask! //printk(KERN_ERR "hi,the newer1 adctsc = 0x%08x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__raw_readl(S3C2410_ADCTSC));__raw_writel(0x12345678,S3C2410_ADCCON);//printk(KERN_ERR "hi,the new adccon = 0x%08x!!!!!!!\n",__raw_readl(S3C2410_ADCCON));#ifdef CONFIG_DEVFS_FS devfs_mk_dir("touchscreen"); devfs_mk_cdev(MKDEV(tsMajor, TSRAW_MINOR), S_IFCHR|S_IRUGO|S_IWUSR, "touchscreen/%d", 0);#endif#ifdef CONFIG_PM#if 0 tsdev.pm_dev = pm_register(PM_GP_DEV, PM_USER_INPUT, s3c2410_ts_pm_callback);#endif tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT, s3c2410_ts_pm_callback);#endif //printk(DEVICE_NAME " hello,success initialized!!!!!!!!!!!!!!!!!!\n"); return 0; tc_failed: {printk(KERN_ERR "tc failed!!!!!!!!!!!!!\n"); free_irq(IRQ_ADC, s3c2410_isr_adc);} adc_failed: {printk(KERN_ERR "adc failed!!!!!!!!!!!!!\n"); return ret;}}static struct device_driver s3c2410ts_driver = { .name = DEVICE_NAME, .bus = &platform_bus_type, .probe = s3c2410ts_probe,#ifdef CONFIG_PM .suspend = s3c2410ts_suspend, .resume = s3c2410ts_resume,#endif};static int __init s3c2410ts_init(void){ int ret; printk("in s3c2410ts init()\n"); ret = driver_register(&s3c2410ts_driver); if(ret) printk("register %s driver failed, return code is %d\n", DEVICE_NAME, ret); else printk(KERN_ERR "register %s driver success, return code is %d\n", DEVICE_NAME, ret); return ret;}static void __exit s3c2410ts_exit(void){#ifdef CONFIG_DEVFS_FS devfs_remove("touchscreen/%d", 0); devfs_remove("touchscreen");#endif unregister_chrdev(tsMajor, DEVICE_NAME);#ifdef CONFIG_PM pm_unregister(tsdev.pm_dev);#endif free_irq(IRQ_ADC, s3c2410_isr_adc); free_irq(IRQ_TC, s3c2410_isr_tc); driver_unregister(&s3c2410ts_driver);}module_init(s3c2410ts_init);module_exit(s3c2410ts_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -