首页 > 代码库 > 06day01input_driver

06day01input_driver

  1 /*  2 输入子系统:  3 把按键的驱动,添加到输入子系统中,可以通过按键来输入对应的字符  4   5 内核中  include/linux/input.h   6 驱动中主要填充 input_dev 这个结构体  7 name 名称  phys  uniq  input_id  设置对应的节点信息  8   9  10 */ 11 #include <linux/module.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14  15 #include <linux/input.h> 16 #include <linux/bitops.h> 17 #include <linux/interrupt.h> //request_irq 18 #include <mach/irqs.h> //IRQ_EINT 19 #include <linux/gpio.h>  //gpio_request 20 #include <mach/gpio.h>  //EXYNOS4_GPX3 21 /* 22 用四个按键模拟键盘  把案件值 直接输出标准输出 23  24 可以将开发板上的系统当前终端输入重定向为标准输入 25  26 exec 0 < /dev/tty1 27 */ 28  29  30 #define DEVNAME "ldm" 31  32 // 33 struct ldm_info 34 { 35     struct input_dev * pdev; 36 }; 37  38 struct ldm_info ldm; 39  40 struct  key_info 41 { 42     char * name; 43     int code; 44     int irqno; 45     int gpio_num; 46 }; 47  48 //l s enter   backspace 49 struct key_info keyinfo[] = { 50     {"KEY_L", KEY_L, IRQ_EINT(26), EXYNOS4_GPX3(2)}, 51     {"KEY_S", KEY_S, IRQ_EINT(27), EXYNOS4_GPX3(3)}, 52     {"KEY_ENTER", KEY_ENTER, IRQ_EINT(28), EXYNOS4_GPX3(4)}, 53     {"KEY_BACKSPACE", KEY_BACKSPACE, IRQ_EINT(29), EXYNOS4_GPX3(5)},   54 }; 55  56 //中断处理函数 57 static irqreturn_t key_handler(int irqno, void * arg) 58 { 59     struct key_info *key = (struct key_info *)arg; 60     //产生了中断,在合适时候,发送input_event事件 61  62     int key_stat = gpio_get_value(key->gpio_num); 63  64     //发送事件  发送按键的按键值 和 按键的状态 65     input_report_key(ldm.pdev,  key->code,  !key_stat); 66     //发送结束事件 67     input_sync(ldm.pdev); 68  69     return IRQ_HANDLED; 70 } 71  72 static int test_init(void) 73 { 74     int ret = 0; 75     int i = 0; 76     int j = 0; 77     printk("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__); 78  79     //1.创建input_dev 的对象  input_allocate_device(); 80     //如果仅仅申请了空间,没有注册 即调用input_allocate_device 81     //那么需要调用input_free_device 函数来释放空间 82     //一旦注册成功,则不需要调用input_free_device来释放空间 83     ldm.pdev = input_allocate_device(); 84     if(!ldm.pdev) { 85         printk("input_allocate_device  failed\n"); 86         ret = -ENOMEM; 87         goto err_input_allocate_device; 88     } 89  90     //2.填充input_dev 这个结构体 91     ////////////相关的信息///////////////////////// 92     ldm.pdev->name = "my test input device"; 93     ldm.pdev->phys = "key"; 94     ldm.pdev->uniq = "candle"; 95     ldm.pdev->id.bustype = 0x1234; 96     ldm.pdev->id.vendor = 0x2222; 97     ldm.pdev->id.product =  0xabcd; 98     ldm.pdev->id.version =  0x3433; 99     ///////////////////////////////////////////////////////100 101     //这个设备支持哪些事件?102     //本设备支持的事件的类型,通过set_bit函数来指定位置103     //所有的位置,都可以通过宏来设置104     set_bit(EV_KEY,   ldm.pdev->evbit); //支持按键类型的事件105     set_bit(EV_REP, ldm.pdev->evbit);//支持连发106 107     //针对不同的事件,处理什么样的数据?108     //eint26~29   GPX3_2 ~5109     //这个设备支持的按键的键值110     111     for(i=0; i< ARRAY_SIZE(keyinfo);i++) {112         set_bit(keyinfo[i].code, ldm.pdev->keybit);113     }114 115     //注册设备对象116     ret = input_register_device(ldm.pdev);117     if(ret < 0) {118         printk("input_register_device  failed\n");119         goto  err_input_register_device;120     }121 122     //注册中断,按下和抬起的时候都要去触发123     for(i=0;i < ARRAY_SIZE(keyinfo);i++) {124         ret = request_irq(keyinfo[i].irqno, key_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, DEVNAME, keyinfo + i );125         if(ret < 0) {126             printk("request_irq  failed\n");127             goto err_request_irq;128         }129     }130 131     //注册GPIO管脚132     //int j = 0;133     for(j=0; j < ARRAY_SIZE(keyinfo);j++) {134         ret = gpio_request(keyinfo[j].gpio_num, keyinfo[j].name);135         if(ret < 0) {136             printk("gpio_request  failed\n");137             goto err_gpio_request;138         }139     }140 141 142     return 0;143 144 err_gpio_request:145     for(j = j - 1;j>=0;j--) {146         gpio_free(keyinfo[j].gpio_num);147     }148 err_request_irq:149     for(i=i-1;i>=0;i--) {150         free_irq(keyinfo[i].irqno, keyinfo + i); 151         //把之前注册成功的中断号释放掉152     }153     input_unregister_device(ldm.pdev);154     return ret;155 err_input_register_device:156     input_free_device(ldm.pdev);157 err_input_allocate_device:158     return ret;159 }160 161 static  void test_exit(void)162 {163     int i = ARRAY_SIZE(keyinfo);164     printk("%s:%s:%d\n", __FILE__, __FUNCTION__, __LINE__);165     166 167     for(i=i-1; i>=0;i--) {168         gpio_free(keyinfo[i].gpio_num);169         free_irq(keyinfo[i].irqno, keyinfo + i);170     }171 172     input_unregister_device(ldm.pdev);173 }174 175 176 module_init(test_init);177 module_exit(test_exit);178 MODULE_LICENSE("GPL");

 

06day01input_driver