输入子系统简单(按键)测试
//input_key.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/types.h>
4 #include <linux/fs.h>
5 #include <linux/mm.h>
6 #include <linux/device.h>
7 #include <linux/errno.h> /* for -EBUSY */
8 #include <linux/ioport.h> /* for request_region */
9 #include <linux/delay.h> /* for loops_per_jiffy */
10 #include <linux/irq.h>
11 #include <linux/wait.h> /* for wait_queue */
12 #include <linux/init.h> /* for __init, module_{init,exit} */
13 #include <linux/poll.h> /* for POLLIN, etc. */
14 #include <linux/interrupt.h>
15 #include <linux/irqreturn.h>
16 #include <linux/input.h>
17
18 #include <mach/regs-clock.h>
19 #include <mach/regs-gpio.h>
20 #include <mach/hardware.h>
21 //#include <mach/irq.h>
22 #include <mach/map.h>
23 #include <mach/gpio-bank-n.h>
24
25 #include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
26 #include <asm/uaccess.h> /* for get_user, etc. */
27 #include <asm/irq.h>
28 #include <asm/gpio.h>
29 #include <plat/gpio-cfg.h>
30
31 struct pin_desc {
32 int irq;
33 int pin;
34 char *name;
35 char key_val;
36 }
37
38 static struct pin_desc buttons_pin[4] = {
39 {IRQ_EINT(0), 0, "K10", KEY_LEFTSHIFT},
40 {IRQ_EINT(1), 1, "K7", KEY_S},
41 {IRQ_EINT(2), 2, "K4", KEY_L},
42 {IRQ_EINT(3), 3, "K1", KEY_ENTER},
43 };
44
45 static volatile char key_values[] = {'0', '0', '0', '0'};
46
47 //所有的输入事件设备 内核都用这个统一个数据结构来描述
48 static struct input_dev *buttons_input;
49
50 static irqreturn_t buttons_interrupt(int irq, void *dev_id)
51 {
52 struct pin_desc *pin_desc = (struct pin_desc *)dev_id;
53 // 根据发生的按键动作发送事件
54 int down;
55 int number;
56 unsigned tmp;
57 udelay(0);
58 number = pin_desc->pin;
59 switch(number) {
60 case 0: case 1: case 2: case 3:
61 tmp = readl(S3C64XX_GPNDAT);
62 down = !(tmp & (1<<number)); //按下 1 down 0 松开 0 down 1
63 break;
64 default:
65 down = 0;
66 }
67
68 //报告输入事件用的接口(内核提供了底层输入设备驱动所需的api)
69 // type: EV_KEY
70 // 最后一个参数: 1-按下, 0-松开
71 input_event(buttons_input, EV_KEY, pin_desc->key_val, down); //报告指定type code 的输入事件
72 input_sync(buttons_input); //报告同步事件
73
74 return IRQ_HANDLED;
75 }
76
77 static int buttons_init(void)
78 {
79 int error;
80 int i;
81
82 // 1. 分配一个input_dev(输入设备)
83 buttons_input = input_allocate_device();
84 if (!buttons_input)
85 return -ENOMEM;
86
87 // 2. 设置input_dev
88 // 2.1 能产生 哪类 事件
89 buttons_input->evbit[0] = BIT(EV_KEY);
90
91 // 2.2 能产生 哪些 事件
92 __set_bit(KEY_L, buttons_input->keybit);
93 __set_bit(KEY_S, buttons_input->keybit);
94 __set_bit(KEY_ENTER, buttons_input->keybit);
95 __set_bit(KEY_LEFTSHIFT, buttons_input->keybit);
96
97 // 2.3 其他信息(厂家/产品ID)// 可以不设置
98 buttons_input->name = "6410_keys";
99 buttons_input->phys = "6410_keys";
100 buttons_input->dev.parent = NULL;
101
102 buttons_input->id.bustype = BUS_HOST;
103 buttons_input->id.vendor = 0x0001;
104 buttons_input->id.product = 0x0001;
105 buttons_input->id.version = 0x0100;
106
107 // 3.驱动 注册input_dev设备 进输入子系统
108 error = input_register_device(buttons_input);
109 if (error) {
110 input_free_device(buttons_input);
111 return -1;
112 }
113
114 // 2. 把K10的引脚配置为中断引脚并且设置触发方式 注册中断
115 for (i = 0; i < sizeof(buttons_pin)/sizeof(buttons_pin[0]); i++){
116 request_irq(buttons_pin[i].irq, buttons_interrupt,IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, buttons_pin[i].name, (void *)&buttons_pin[i]);
117 }
118 return 0;
119 }
120
121
122 static void buttons_exit(void)
123 {
124 int i;
125
126 for (i = 0; i < sizeof(buttons_pin)/sizeof(buttons_pin[0]); i++){
127 free_irq(buttons_pin[i].irq, (void *)&buttons_pin[i]);
128 }
129
130 input_unregister_device(buttons_input);
131 input_free_device(buttons_input);
132
133 }
134
135 module_init(buttons_init);
136 module_exit(buttons_exit);
137
138 MODULE_LICENSE("GPL");
测试应用程序:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/ioctl.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <sys/select.h>
9 #include <sys/time.h>
10 #include <errno.h>
11 #include <linux/input.h>
12
13 int main(void)
14 {
15 int buttons_fd;
16 int key_value,i=0, count;
17
18 struct input_event ev_key;
19 buttons_fd = open("/dev/input/event1", O_RDWR);
20
21 if (buttons_fd < 0) {
22 perror("open device buttons!!");
23 exit(1);
24 }
25
26 for (;;) {
27 count = read(buttons_fd, &ev_key, sizeof(struct input_event));
28
29 for(i = 0; i < (int)count/sizeof(struct input_event); i++)
30 if(EV_KEY == ev_key.type)
31 printf("type:%d,code:%d,value:%d\n", ev_key.type, ev_key.code, ev_key.value);
32
33 if(EV_SYN == ev_key.type)
34 printf("syn event\n\n");
35
36 }
37 close(buttons_fd);
38 return 0;
39 }
ubuntu的抓图功能用不了,只能复制终端的打印上来:
[root@FriendlyARM plg]# lsmod
[root@FriendlyARM plg]# ls
app_glo_signal input_key.ko led_misc_cfgpin.ko
app_key_signal key_test led_misc_test
button_input_app led_cdev_test misc_key.ko
buttons_test led_driver_cdev.ko misc_key_async.ko
driver.ko led_key_app
globalfifo.ko led_misc.ko
[root@FriendlyARM plg]# ls -l /dev/input
crw-rw---- 1 root root 13, 64 Oct 3 2000 event0
crw-rw---- 1 root root 13, 63 Oct 3 2000 mice
crw-rw---- 1 root root 13, 32 Oct 3 2000 mouse0
crw-rw---- 1 root root 10, 185 Oct 3 2000 ts-if
[root@FriendlyARM plg]# insmod input_key.ko
input: 6410_keys as /class/input/input2
[root@FriendlyARM plg]# ls -l /dev/input
crw-rw---- 1 root root 13, 64 Oct 3 2000 event0
crw-rw---- 1 root root 13, 65 Oct 2 22:51 event1
crw-rw---- 1 root root 13, 63 Oct 3 2000 mice
crw-rw---- 1 root root 13, 32 Oct 3 2000 mouse0
crw-rw---- 1 root root 10, 185 Oct 3 2000 ts-if
[root@FriendlyARM plg]#
[root@FriendlyARM plg]# ./button_input_app
type:1,code:42,value:1
syn event
type:1,code:42,value:0
syn event
type:1,code:31,value:1
syn event
type:1,code:31,value:0
syn event
type:1,code:38,value:1
syn event
type:1,code:38,value:0
syn event
type:1,code:28,value:1
syn event
type:1,code:28,value:0
syn event