1.代码input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变。input_subsys.drv.c 1 #include <linux/module. ...
1.代码
input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变。
input_subsys.drv.c
1 #include <linux/module.h> 2 #include <linux/version.h> 3 4 #include <linux/init.h> 5 #include <linux/fs.h> 6 #include <linux/interrupt.h> 7 #include <linux/irq.h> 8 #include <linux/sched.h> 9 #include <linux/pm.h> 10 #include <linux/sysctl.h> 11 #include <linux/proc_fs.h> 12 #include <linux/delay.h> 13 #include <linux/platform_device.h> 14 #include <linux/input.h> 15 #include <linux/irq.h> 16 17 #include <asm/gpio.h> 18 #include <asm/io.h> 19 #include <asm/arch/regs-gpio.h> 20 21 22 struct pin_desc{ 23 int irq; 24 char *name; 25 unsigned int pin; 26 unsigned int key_val; 27 }; 28 29 struct pin_desc pins_desc[4] = { 30 {IRQ_EINT0, "S2", S3C2410_GPF0, KEY_L}, 31 {IRQ_EINT2, "S3", S3C2410_GPF2, KEY_S}, 32 {IRQ_EINT11, "S4", S3C2410_GPG3, KEY_ENTER}, 33 {IRQ_EINT19, "S5", S3C2410_GPG11, KEY_LEFTSHIFT}, 34 }; 35 36 static struct input_dev *input_subsys_dev; 37 static struct pin_desc *irq_pd; 38 static struct timer_list buttons_timer; 39 40 static irqreturn_t buttons_irq(int irq, void *dev_id) 41 { 42 /* [cgw]: 按键IO发生边沿中断时重新设置定时间隔 43 * 用于按键消抖 44 */ 45 irq_pd = (struct pin_desc *)dev_id; 46 buttons_timer.data = irq_pd->pin; 47 mod_timer(&buttons_timer, jiffies+USER_HZ/10); 48 return IRQ_RETVAL(IRQ_HANDLED); 49 } 50 51 static void buttons_timer_function(unsigned long data) 52 { 53 struct pin_desc * pindesc = irq_pd; 54 unsigned int pinval; 55 56 if (!pindesc) 57 return; 58 59 /* [cgw]: 获取按键IO状态 */ 60 pinval = s3c2410_gpio_getpin((unsigned int)data); 61 62 /* [cgw]: 根据按键IO状态上报按键事件 */ 63 if (pinval) 64 { 65 /* [cgw]: 上报按键弹起 */ 66 input_report_key(input_subsys_dev, pindesc->key_val, 0); 67 //input_sync(input_subsys_dev); 68 } 69 else 70 { 71 /* [cgw]: 上报按键按下 */ 72 input_report_key(input_subsys_dev, pindesc->key_val, 1); 73 //input_sync(input_subsys_dev); 74 } 75 76 //printk("timer occur!\n"); 77 } 78 79 80 static int event_handler(struct input_dev *dev, unsigned int type, unsigned int code, int value) 81 { 82 #if 0 83 /* [cgw]: 根据应用程序下发的LED控制事件 84 * 亮灭LED 85 */ 86 //if (code == SND_BELL) { 87 if (code == LED_MUTE) { 88 if (value == 0xAA) { 89 /* [cgw]: 点亮 */ 90 s3c2410_gpio_setpin(S3C2410_GPF4, 0); 91 } else if (value == 0xEE) { 92 /* [cgw]: 熄灭 */ 93 s3c2410_gpio_setpin(S3C2410_GPF4, 1); 94 } 95 96 return 0; 97 } 98 #endif 99 100 switch (type) {101 case EV_REP:102 return 0;103 //break;104 105 case EV_LED:106 if (code == LED_MUTE) {107 if (value == 0xAA) {108 /* [cgw]: 点亮 */109 s3c2410_gpio_setpin(S3C2410_GPF4, 0);110 } else if (value == 0xEE) {111 /* [cgw]: 熄灭 */112 s3c2410_gpio_setpin(S3C2410_GPF4, 1);113 }114 115 return 0;116 }117 //break;118 119 case EV_SND:120 return 0;121 //break;122 }123 124 return -1;125 }126 127 int input_subsys_open(struct input_dev *dev)128 { 129 int i, retval;130 131 /* [cgw]: 设置按键IO为中断输入 */132 s3c2410_gpio_cfgpin(S3C2410_GPF0, S3C2410_GPF0_EINT0);133 s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);134 s3c2410_gpio_cfgpin(S3C2410_GPG3, S3C2410_GPG3_EINT11);135 s3c2410_gpio_cfgpin(S3C2410_GPG11, S3C2410_GPG11_EINT19);136 137 /* [cgw]: 设置LED IO为输出,初始为熄灭LED */138 s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);139 s3c2410_gpio_setpin(S3C2410_GPF4, 1);140 141 s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);142 s3c2410_gpio_setpin(S3C2410_GPF5, 1);143 144 s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);145 s3c2410_gpio_setpin(S3C2410_GPF5, 1);146 147 /* [cgw]: 为按键IO分配中断线 */148 for (i = 0; i < 4; i++)149 {150 retval = request_irq(pins_desc[i].irq, buttons_irq, IRQT_BOTHEDGE, pins_desc[i].name, &pins_desc[i]);151 }152 153 printk("input subsys open!\n");154 //printk("USER_HZ: %d\n", USER_HZ);155 156 return 0;157 }158 159 160 161 static int input_subsys_init(void)162 {163 /* [cgw]: 分配一个输入设备 */164 input_subsys_dev = input_allocate_device();165 input_subsys_dev->name = "input_subsys_dev";166 167 /* [cgw]: 设置支持的事件类型 */168 set_bit(EV_KEY, input_subsys_dev->evbit);169 set_bit(EV_REP, input_subsys_dev->evbit);170 171 set_bit(EV_LED, input_subsys_dev->evbit);172 //set_bit(EV_SND, input_subsys_dev->evbit);173 174 /* [cgw]: 设置支持的事件码 */175 set_bit(KEY_L, input_subsys_dev->keybit);176 set_bit(KEY_S, input_subsys_dev->keybit);177 set_bit(KEY_ENTER, input_subsys_dev->keybit);178 set_bit(KEY_LEFTSHIFT, input_subsys_dev->keybit);179 180 set_bit(LED_MUTE, input_subsys_dev->ledbit);181 //set_bit(SND_BELL, input_subsys_dev->sndbit);182 183 /* [cgw]: 分配输入设备的open方法 */184 input_subsys_dev->open = input_subsys_open;185 /* [cgw]: 分配输入设备的event方法,用户在应用程序write()时 */186 input_subsys_dev->event = event_handler;187 188 /* [cgw]: 注册输入设备 */189 input_register_device(input_subsys_dev);190 191 //input_subsys_dev->rep[REP_DELAY] = 250;192 //input_subsys_dev->rep[REP_PERIOD] = 100;193 194 /* [cgw]: 初始化定时器,用于按键消抖 */195 init_timer(&buttons_timer);196 buttons_timer.function = buttons_timer_function;197 add_timer(&buttons_timer);198 199 printk("input subsys init!\n");200 201 return 0;202 }203 204 static void input_subsys_exit(void)205 {206 int i;207 208 /* [cgw]: 释放按键IO中断 */209 for (i = 0; i < 4; i++)210 {211 free_irq(pins_desc[i].irq, &pins_desc[i]);212 }213 214 /* [cgw]: 删除定时器 */215 del_timer(&buttons_timer);216 /* [cgw]: 注销输入设备 */217 input_unregister_device(input_subsys_dev);218 /* [cgw]: 释放输入设备内存空间 */219 input_free_device(input_subsys_dev); 220 }221 222 module_init(input_subsys_init);223 224 module_exit(input_subsys_exit);225 226 MODULE_LICENSE("GPL");
原标题:linux输入子系统(input subsystem)之evdev.c事件处理过程
关键词:linux
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。