日期:2014-05-16  浏览次数:20667 次

s3c2440触摸屏驱动
刚开始学习驱动,测试的时候发现第一次打开没问题,但第2次打开却没反应了.
大家帮忙看看可能是什么原因
下面是部分代码:
C/C++ code
static int s3c2410_ts_open(struct inode *inode, struct file *filp)
{
    TS_DEV *devp;
    
    devp = container_of(inode->i_cdev, TS_DEV, cdev);
    
    filp->private_data = devp;
    
    /* 创建等待队列和环形缓冲区 */
    
    devp->head = devp->tail = 0;
    devp->penStatus = PEN_UP;
    init_waitqueue_head(&(devp->wq));
    
    /* 注册中断 */
    
    if (request_irq(IRQ_ADC, stylus_action, IRQF_SHARED,    /* 共享中断 */ 
        "s3c2410_action", &(devp->cdev))) {
        printk(KERN_ERR "Could not allocate ts IRQ_ADC\n");
        return -EIO;
    }
    if (request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM,
        "s3c241_updown", &(devp->cdev))) {
        printk(KERN_ERR "Could not allocate ts IRQ_TC\n");
        return -EIO;    
    }
    
    DPRINTK("ts opened\n");
    
    return 0;
}
static int s3c2410_ts_release(struct inode *inode, struct file *filp)
{
    TS_DEV *devp = filp->private_data;
    
    disable_irq(IRQ_ADC);
    disable_irq(IRQ_TC);
    free_irq(IRQ_TC,&(devp->cdev));
    free_irq(IRQ_ADC,&(devp->cdev));
    
    DPRINTK("ts released\n");
    
    return 0;
}
static int __init s3c2410_ts_init(void)
{
    int ret;
    adc_clock = clk_get(NULL, "adc");
    if (!adc_clock) {
        printk(KERN_ERR "Faild to get adc clock source\n");
        return -ENOENT;
    }
    clk_enable(adc_clock);
    
    base_addr = ioremap(S3C2410_PA_ADC, 0x20);
    if (base_addr == NULL) {
        printk(KERN_ERR "Fiald to remap register block\n");
        return -ENOMEM;
    }
    
    /* Config GPIOs */
    s3c2410_ts_connect();
    
    iowrite32(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),\
             base_addr+S3C2410_ADCCON);
    iowrite32(0xffff,  base_addr+S3C2410_ADCDLY);
    iowrite32(WAIT4INT(0), base_addr+S3C2410_ADCTSC);
    
    /* Register char device */
    
    if (alloc_chrdev_region(&tsdev_number, 0, 1, DEVICE_NAME) < 0) {
        printk(KERN_DEBUG "Can not register device\n");
        return -1;
    }
    
    tsdev_class = class_create(THIS_MODULE, DEVICE_NAME);
    
    tsdev = kmalloc(sizeof(TS_DEV), GFP_KERNEL);
    if (!tsdev) {
        printk(KERN_ERR "Bad kmalloc\n");
        return -ENOMEM;
    }
    
    cdev_init(&tsdev->cdev, &tsdev_fops);
    tsdev->cdev.owner = THIS_MODULE;
    
    ret = cdev_add(&tsdev->cdev, tsdev_number, 1);
    if (ret) {
        printk(KERN_ERR "Bad cdev\n");
        return ret;
    }
    
    device_create(tsdev_class, NULL, tsdev_number, 0, "my-ts");
    
    DPRINTK("Loading Module my-ts Success..\n");
    
    return 0;
}
static void __exit s3c2410_ts_exit(void)
{
    if (adc_clock) {
        clk_disable(adc_clock);
        clk_put(adc_clock);
        adc_clock = 0;
    }
    
    /* Unregister devce */
    
    unregister_chrdev_region(tsdev_number, 1);
    device_destroy(tsdev_class, tsdev_number);
    cdev_del(&tsdev->cdev);
    kfree(tsdev);
    class_destroy(tsdev_class); 
    
    iounmap(base_addr);
    
    DPRINTK("Unloading Module my-ts Success..\n");
}

在重新加载模块后第一次打开发现它在打开ADC转换中断后不再相应ADC转换中断
iowrite32(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);
iowrite32(ioread32(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, 
  base_addr+S3C2410_ADCCON);
同样第2次打开,触摸屏中断IRQ_TC和ADC中断IRQ_ADC都不响应
只有重启系统后第一次打开没任何问题
打开设备后系统中断如下:
[root@FriendlyARM driver]# cat /proc/interrupts 
  CPU0
 30: 25085 s3c S3C2410 Timer Tick
 32: 0 s3c s3c241