首页 > 代码库 > 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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。