驱动之输入子系统

  1 #include <linux/module.h>
  2 #include <linux/kernel.h>
  3 #include <linux/fs.h>
  4 #include <linux/init.h>
  5 #include <linux/delay.h>
  6 #include <linux/irq.h>
  7 #include <asm/uaccess.h>
  8 #include <asm/irq.h>
  9 #include <asm/io.h>
 10 #include <linux/cdev.h>
 11 #include <linux/device.h>
 12 #include <linux/interrupt.h>
 13 #include <linux/input.h>
 14 #include <linux/bitmap.h>
 15 #include <asm/gpio.h>
 16 
 17 static struct input_dev *key_dev;
 18 static struct timer_list key_time;
 19 
 20 struct input_inode {
 21             char *name;
 22             unsigned int irq_type;
 23             unsigned int pin;
 24             int key_val;
 25 };
 26 
 27 static struct input_inode *irq_pd;
 28 
 29 static struct input_inode key[] = {
 30                  [0] = {
 31                          "L",
 32                         IRQ_EINT0,
 33                         S3C2410_GPF(0),
 34                         KEY_L},
 35                  [1] = {
 36                         "S",
 37                         IRQ_EINT2,
 38                         S3C2410_GPF(2),
 39                         KEY_S},
 40                  [2] = {
 41                         "ENTER",
 42                         IRQ_EINT11,
 43                         S3C2410_GPG(3),
 44                         KEY_ENTER},
 45 };
 46 
 47 //dev_id就是request_irq的最后一个参数,通过它可以知道是哪个中断发生了
 48 static irqreturn_t key_irq(int irq, void *dev_id)
 49 {
 50      irq_pd = (struct input_inode *)dev_id;
 51      mod_timer(&key_time,jiffies + HZ/100); //延迟10ms,延迟过程中断仍然可以被触发
 52       
 53       return IRQ_HANDLED;
 54 }
 55 
 56 //input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
 57 static void key_time_function(unsigned long data)
 58 {
 59     unsigned int pinval;
 60 
 61     if (!irq_pd)
 62         return;   //返回值为 void 的函数也可以使用return
 63     
 64     pinval = s3c2410_gpio_getpin(irq_pd->pin);
 65 
 66     if (pinval)
 67     {
 68         /* 松开 : 最后一个参数: 0-松开, 1-按下 */
 69          input_report_key(key_dev,irq_pd->key_val, 0);
 70         //input_event(key_dev, EV_KEY, irq_pd->key_val, 0);
 71         input_sync(key_dev);
 72     }
 73     else
 74     {
 75         /* 按下 */
 76         input_report_key(key_dev,irq_pd->key_val, 1);
 77         //input_event(key_dev, EV_KEY, irq_pd->key_val, 1);
 78         input_sync(key_dev);
 79     }
 80 }
 81 
 82 static int input_key_init(void)
 83 {
 84     int error;
 85     int i;
 86     /*分配结构体*/
 87      key_dev = input_allocate_device();
 88     /*设置*/
 89     /*1.哪类事件*/
 90     set_bit(EV_KEY,key_dev->evbit);
 91     set_bit(EV_REP,key_dev->evbit);
 92     /*2. 哪些具体事件*/
 93     set_bit(KEY_L,key_dev->keybit);
 94     set_bit(KEY_S,key_dev->keybit);
 95     set_bit(KEY_ENTER,key_dev->keybit);
 96 
 97     /*中断*/
 98     for(i = 0; i < 3; i++){
 99        error = request_irq(key[i].irq_type,key_irq,IRQ_TYPE_EDGE_BOTH,key[i].name,&key[i]);
100        if(error){
101           printk("couldn't get irq!\n");
102               return -1;
103        }
104     }
105     
106     init_timer(&key_time);
107     key_time.function = key_time_function;
108     add_timer(&key_time);
109     
110     /*注册*/
111     error = input_register_device(key_dev);
112     if(error){
113        printk("input_register_device error!\n");
114        return -1;
115     }
116     
117     return 0;
118 }
119 
120 static void input_key_exit(void)
121 {
122       int i;
123       input_unregister_device(key_dev);
124       del_timer(&key_time);
125       for(i = 0; i < 3; i++){
126          free_irq(key[i].irq_type,&key[i]);
127       }
128       input_free_device(key_dev);
129 }
130 
131 module_init(input_key_init);
132 module_exit(input_key_exit);
133 
134 MODULE_LICENSE("GPL");
135 MODULE_AUTHOR("[email protected]");

猜你喜欢

转载自www.cnblogs.com/zhu-g5may/p/9314834.html
今日推荐