您的位置:首页 > 运维架构 > Linux

S3C2440 Linux驱动移植——按键

2012-10-22 20:06 477 查看
开发板: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. 配置内核

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





编译结束后,将内核烧入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 添加测试程序和测试结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: