Chinaunix首页 | 论坛 | 博客
  • 博客访问: 271814
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-28 21:13:10

/* linux/drivers/char
 *

*

* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include
#include
#include
#include
#include

#define EINT_MAJOR        250 //主设备号 



static int s_tp_openflag = 0;
static int s_pen_status  = PEN_UP;

struct eirq_dev
{
    struct cdev cdev;
    unsigned short count;

};

struct eirq_dev *eirqdev;

static void s3c6410_eirq_setup(void)
{

    *(volatile unsigned long*)INTC_IMR_V |= 0x200; //extern int 8
    *(volatile unsigned long*)INTC_IER_V |= 0x200;  
   
  disable_irq(INTSRC_EXTINT8);

  mdelay(20);
    printk("in the touchpad setup \n");

    enable_irq(INTSRC_EXTINT8);



static void tsevent(void)
{

}


static int s3c6410_tp_irqhandler(int irq, void *dev_id, struct pt_regs *regs)

    disable_irq(INTSRC_EXTINT8); 

    s_pen_status = PEN_UNSURE;

    tpdev->tp_timer.expires = jiffies + PEN_TIMER_DELAY_JUDGE;
    add_timer(&tpdev->tp_timer);

    *(volatile unsigned long*)GPIO_PORTA_INTRCLR_V |= 0x100;                 
    *(volatile unsigned long*)GPIO_PORTA_INTRCLR_V &= 0x0;                 //清除中断  

    //we will turn on the irq in the timer_handler
    return IRQ_HANDLED;
}



static int s3c6410_tp_open(struct inode *inode, struct file *filp)
{
eirqdev->count = 0;

    s3c6410_eirq_setup();
    return 0;
}

static int s3c6410_eirq_release(struct inode *inode, struct file *filp)
{
    return 0;
}

static ssize_t s3c6410_eirq_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{
    unsigned int a = 0;
    a = eirqpdev->count;
    copy_to_user(buf, a, sizeof(a));
    return 0;
}


static  struct file_operations s3c6410_tp_fops = 
{
.owner = THIS_MODULE,
.read  = s3c6410_eirq_read,
.open  = s3c6410_eirq_open,
.release = s3c6410_eirq_release,
};

static int __init s3c6410_eirq_init(void)
    int err,result;

    dev_t devno = MKDEV(EINT_MAJOR, 0);

#ifdef EINT_MAJOR
result = register_chrdev_region(devno, 1, "s3c6410_eirq");//向系统静态申请设备号
#else 
result = alloc_chrdev_region(&devno, 0, 1, "s3c6410_eirq");//向系统动态申请设备号
#endif

    if(result < 0)
        return result;
    eirqdev = kmalloc(sizeof(struct eirq_dev),GFP_KERNEL);
    if (!eirqdev)
    {
        result = -ENOMEM;
        unregister_chrdev_region(devno,1);
        return result;
        }
    memset(eirqdev,0,sizeof(struct eirq_dev));

    //add a irqhandler
    if(request_irq(S3C_EINT(19),s3c6410_eirq_irqhandler,SA_INTERRUPT,"s3c6410_eirq",NULL))
        {
        printk("request eirq irq8 failed!\n");
        unregister_chrdev_region(devno,1);
        kfree(tpdev);
        return -1;
        }
    //init the tpdev device struct
    cdev_init(&eirqdev->cdev, &s3c6410_eirq_fops);
    eirqdev->cdev.owner = THIS_MODULE;
    //just init the timer, not add to the kernel now
    //setup_timer(&tpdev->tp_timer,tp_timer_handler,0);

         //向系统注册该字符设备
    err = cdev_add(&eirqdev->cdev, devno, 1);
    if(err)
        {
        printk("adding err\r\n");
        unregister_chrdev_region(devno,1);
        kfree(tpdev);
        free_irq(INTSRC_EXTINT8,NULL);
        return err;
        }  
    return 0;
}

static void __exit s3c6410_tp_exit(void)
{
cdev_del(&eirqdev->cdev);
kfree(eirqdev);
free_irq(INTSRC_EXTINT8,NULL);
unregister_chrdev_region(MKDEV(EINT_MAJOR, 0),1);
}

module_init(s3c6410_eirq_init);
module_exit(s3c6410_eirq_exit);

MODULE_AUTHOR("Rockie Cheng");
MODULE_LICENSE("GPL");

阅读(9195) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~