S3C2440 Linux驱动移植——按键

时间:2021-10-01 23:35:13

开发板:TQ2440

内核版本:2.6.32

1. 硬件链接图

   四个输入引脚:

                            EINT0-----( GPF0  )----INPUT---K4

                            EINT2-----( GPF2  )----INPUT---K3

                            EINT4-----( GPF4  )----INPUT---K2

                            EINT1-----( GPF1  )----INPUT---K1

2. 相关的数据结构

移植所需要的数据结构位于include/linux/gpio_keys.h中。

#ifndef _GPIO_KEYS_H
#define _GPIO_KEYS_H

struct gpio_keys_button {
/* Configuration parameters */
int code; /* input event code (KEY_*, SW_*) */
int gpio;
int active_low;
char *desc;
int type; /* input event type (EV_KEY, EV_SW) */
int wakeup; /* configure the button as a wake-up source */
int debounce_interval; /* debounce ticks interval in msecs */
};

struct gpio_keys_platform_data {
struct gpio_keys_button *buttons;
int nbuttons;
unsigned int rep:1; /* enable input subsystem auto repeat */
};

#endif

从名字上我们可以看出:gpio_keys_platform_data 结构体将作为平台设备的数据。

其中buttons字段指向gpio_keys_button结构体,nbuttons表示有多少个gpio_keys_button结构体。

每个gpio_keys_button结构体表示一个按键,在我的板子上,有四个按键,将会定义一个有4个元素的gpio_keys_button数组,buttons字段将指向该数组,同是,nubuttons字段将为4。

gpio_keys_button 结构体中,gpio字段表示按键所使用IO端口。desc字段为该按键的描述。debounce_interval字段表示软件去抖的时间,单位为ms。

type字段表示输入事件的类型。active_low表示低电平有效。开发板上的按键在按下时为低电平,松开时为高电平,active_low置0(不太确定)


3. 移植代码

这里,我将所有代码均添加在arch/arm/mach-s3c2440/mach-smdk2440.c中。

3.1 添加头文件

#include <linux/gpio_keys.h>    //added by yj423 for buttons driver
#include <linux/input.h> //added by yj423 for buttons driver
#include <mach/gpio-nrs.h> //added by yj423 for buttons driver

3.2 添加gpio_keys_button和gpio_keys_platform_data结构体

/*buttons driver, added by yj423*/
static struct gpio_keys_button s3c_buttons[] =
{
{
.gpio = S3C2410_GPF(1),
.code = KEY_UP,
.desc = "UP(K1)",
.active_low = 0,
},
{
.gpio = S3C2410_GPF(4),
.code = KEY_DOWN,
.desc = "DOWN(K2)",
.active_low = 0,
},
{
.gpio = S3C2410_GPF(2),
.code = KEY_LEFT,
.desc = "LEFT(K3)",
.active_low = 0,
},
{
.gpio = S3C2410_GPF(0),
.code = KEY_RIGHT,
.desc = "RIGHT(K4)",
.active_low = 0,
},
};

static struct gpio_keys_platform_data buttons_platdata =
{
.buttons = s3c_buttons,
.nbuttons = ARRAY_SIZE(s3c_buttons),
};

3. 3 将gpio_keys_platform_data添加到平台设备中

static struct platform_device s3c_device_buttons= {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.resource = NULL,
.dev = {。
.platform_data = &buttons_platdata,
}
};

需要注意的是,根据platform总线的匹配函数,这里的name字段必须和文件drivers/input/keyboard/gpio_keys.c中的 gpio_keys_device_driver.driver.name的值一致,即为gpio-keys

3.4 将按键的平台设备注册到内核中

在smdk2440_devices数组中增加s3c_device_buttons,如下:

static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_dm9000, //added by yj423
&s3c_device_ds18b20,//added by yj423
&s3c_device_buttons, //added by yj423
};

4. 配置内核

在添加完代码以后,开始配置内核。需要配置两个模块,在这里我将它们编译进了内核,你也可以选择编译为模块。

S3C2440 Linux驱动移植——按键

S3C2440 Linux驱动移植——按键


编译结束后,将内核烧入flash中,启动内核。如果你发现/dev/event0的存在,恭喜你,移植成功了。

5. 测试

测试程序如下:

 

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/io.h>

#include <linux/input.h>



int main(int argc, char **argv)
{
int fd, ret;
char *str;

struct input_event button_event;

fd = open("/dev/event0", O_RDWR);
if(fd< 0 ){
printf("open wrong\n");
return -1;
}

while(1)
{
ret = read(fd, &button_event, sizeof(button_event));
if(ret < sizeof(button_event)){
printf("incomplete read\n");
return -1;
}
switch(button_event.type){
case EV_KEY:
str = "key";
break;
case EV_SYN:
str = "syn";
break;
default:
break;
}
printf("type = %s, code = %d\n", str, button_event.code);
}

close(fd);
}


测试结果如下:

[root@yj423 yj423]#./key
type = key, code = 103
type = syn, code = 0
type = key, code = 103
type = syn, code = 0
type = key, code = 108
type = syn, code = 0
type = key, code = 108
type = syn, code = 0
type = key, code = 105
type = syn, code = 0
type = key, code = 105
type = syn, code = 0
type = key, code = 106
type = syn, code = 0
type = key, code = 106
type = syn, code = 0

结果对应着上、下、左和右。

 

 

2012.12.1  添加测试程序和测试结果。