参考:
Documentation/devicetree/bindings/gpio/gpio_keys.txt
要让按键支持控制台,需要配置
/etc/inittab
,在开一个
tty
tty2::askfirst:-/bin/sh
编译内核,运行测试
drivers/input/keyboard/gpio_keys.c
查看 TQ210 原理图
在 mach-smdkv210.c 中添加头文件<linux/gpio_keys.h>
定义 keys 的平台设备
/* gpio keys (add by JerryGou) */
static struct gpio_keys_button buttons[] = {
[0] = {
.code = KEY_UP,
.gpio = S5PV210_GPH0(0),
.active_low = 1,
.desc = "up",
.type = EV_KEY,
.debounce_interval = 50, //表示抖动延时 50ms
},
[1] = {
.code = KEY_DOWN,
.gpio = S5PV210_GPH0(1),
.active_low = 1,
.desc = "down",
.type = EV_KEY,
.debounce_interval = 50,
},
[2] = {
.code = KEY_LEFT,
.gpio = S5PV210_GPH0(2),
.active_low = 1,
.desc = "left",
.type = EV_KEY,
.debounce_interval = 50,
},
[3] = {
.code = KEY_RIGHT,
.gpio = S5PV210_GPH0(3),
.active_low = 1,
.desc = "right",
.type = EV_KEY,
.debounce_interval = 50,
},
[4] = {
.code = KEY_ENTER,
.gpio = S5PV210_GPH0(4),
.active_low = 1,
.desc = "enter",
.type = EV_KEY,
.debounce_interval = 50,
},
};
static struct gpio_keys_platform_data tq210_keys_pdata = {
.buttons = buttons,
.nbuttons = ARRAY_SIZE(buttons),
.rep = 1, //表示允许重复输入
};
static struct platform_device tq210_keys = {
.name = "gpio-keys",
.dev = {
.platform_data = &tq210_keys_pdata,
},
.id = -1,
};
其中 debounce_interval 表示抖动延时 50ms, rep=1 表示允许重复输入。
配置内核
Device Drivers ---> Input device support ---> [*] Keyboards ---> <*> GPIO Buttons |
tty2::askfirst:-/bin/sh
编译内核,运行测试
成功注册 gpio_keys,设备文件为/dev/input/event1
现在按 Enter 键(key5), LCD 效果如下
用户空间程序测试效果:
用户空间测试程序 key_input.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/fcntl.h>
#include <string.h>
#include <signal.h>
int fd = -1;
struct input_event ev;
void sig_handle(int sig)
{
int rc = -1;
rc = read(fd, &ev, sizeof(struct input_event));
if (rc < 0)
{
perror("read");
return;
}
if (EV_KEY == ev.type)
{
if (1 == ev.value)
printf("key %d, value:%d\n", ev.code, ev.value);
else
printf("key %d, value:%d\n", ev.code, ev.value);
}
}
int main(int argc, char *argv[])
{
size_t rb;
int version;
char name[20];
int oflags = 0;
if (argc != 2)
{
fprintf(stderr, "Usage:%s /dev/eventx\n", argv[0]);
exit(1);
}
if ((fd = open(argv[1], O_RDONLY)) < 0)
{
perror("open error");
exit(1);
}
#if 0
if (ioctl(fd, EVIOCGNAME(sizeof(name)-1), name) < 0)
{
perror("getname error");
exit(1);
}
printf("name=%s\n", name);
if (ioctl(fd, EVIOCGVERSION, &version) < 0)
{
perror("getversion error");
exit(1);
}
printf("version=0x%x\n", version);
while(1)
{
rb = read(fd, &ev, sizeof(struct input_event));
if (rb < (int)sizeof(struct input_event))
{
perror("read error");
exit(1);
}
if (EV_KEY == ev.type)
{
if (1 == ev.value)
printf("key %d is pressed\n", ev.code);
else
printf("key %d is releassed\n", ev.code);
}
}
#else
signal(SIGIO, sig_handle);
fcntl(fd, F_SETOWN, getpid());
oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, oflags | FASYNC);
while (1)
sleep(1);
#endif
close(fd);
return 0;
}