keyboard-input-platform1-按键驱动代码实现

一个简单的按键驱动,涉及到的知识点有:GPIO配置,input输入子系统,platform平台总线,中断,kobject(sysfs)。

由于内核中已经有了gpio_keys.c函数,简单的实现独立式按键驱动功能,应该还是挺简单,按键所接端口为中断引脚。如果是矩阵按键呢?相应代码的改动应该较大,未研究。

按键驱动属于input输入子系统,同时按键驱动也是挂在platform平台总线上。

编写platform驱动要完成三方面的工作:
1.platform_device的编写
2.platform_driver的编写
3.设备资源和数据的定义

对于platform_device的编写又有两方法:
1.在BSP板文件中实现定义,在板文件中将platform_device被归纳为一个数组,最终通过platform_add_devices()函数统一注册。

这个函数内部其实调用了platform_device_register()单个注册平台设备。

2.第二种是为platform_device单独编写内核模块然后加载到内核中。

同理其中对于resource的定义也有两种方法:
1.在板文件中定义
2.在platform_device所处的内核模块代码中编写

我这边采用第一种方法。

Linux 内核下的 drivers/input/keyboard/gpio_keys.c实现了一个体系结构无关的GPIO按键驱动,如下:

static struct platform_driver gpio_keys_device_driver = {
	.probe		= gpio_keys_probe,
	.remove		= __devexit_p(gpio_keys_remove),
	.driver		= {
		.name	= "gpio-keys",
		.owner	= THIS_MODULE,
		.pm	= &gpio_keys_pm_ops,
		.of_match_table = gpio_keys_of_match,
	}
};

使用此按键驱动,只需在arch/arm/板级文件中定义相关的数据即可。

找到对应的板级文件,如Board-xxxx-gpiomux.c ,只需要做两件事。

1、增加GPIO的配置

msm_gpiomux_install(function_key_configs,ARRAY_SIZE(function_key_configs));    //完成GPIO的配置
static struct msm_gpiomux_config function_key_configs[] __initdata = {
	{
		.gpio      = 10,	
		.settings = {
			[GPIOMUX_SUSPENDED] = &function_buttons_cfg,
	                     },
	},
};

static struct gpiomux_setting function_buttons_cfg = {
	.func = GPIOMUX_FUNC_GPIO,
	.drv = GPIOMUX_DRV_2MA,
	.pull = GPIOMUX_PULL_UP,
};
其中ARRAY_SIZE这个宏,是求设备结构体中设备的个数。
2、按键的platform_device的编写
platform_add_devices(function_devices,ARRAY_SIZE(function_devices));//注册平台设备
static struct platform_device *function_devices[] __initdata = {
	&function_buttons_device,
};
static struct platform_device function_buttons_device = {
	.name		= "gpio-keys",
	.id		= -1,
	.dev		= {
		.platform_data	= &function_buttons_data,
	},
};
static struct gpio_keys_platform_data function_buttons_data = {
	.buttons	= function_buttons,//设备名
	.nbuttons	= ARRAY_SIZE(function_buttons),
};
static struct gpio_keys_button function_buttons [ ] = 
{
	{
		.gpio = GPIO_NUM_WPS_BUTTON,
		.code = KEY_WPS_BUTTON,
		.desc = "WPS Button" ,
		.active_low	= 1,
	},
};
这样就可以了,在终端里就发现有这两个节点:

/sys/bus/platform/devices/gpio-keys
/sys/devices/platform/gpio-keys

同时在文件系统dev目录下有event设备节点,对gpio-keys按键的访问可以通过event来完成。

应用层程序:

 fd = open("/dev/input/event0", O_RDONLY);//打开按键文件节点
 repeat_param[0]=500;//ms重复按键第一次间隔
 repeat_param[1]=66;//ms重复按键后续间隔
 ret = ioctl(fd,EVIOCSREP,(int *)repeat_param);//设置重复按键参数,当然这些参数也可以在驱动里设置
while(1) {ret = read(fd,&buf,sizeof(struct input_event));}//数据保存在buf
code = buf.code;
key_state = buf.value;
	switch(code)
       {
          case KEY_DOWN:
              code = '1';
              break;
          case KEY_ENTER:
              code = '2';
              break;
          case KEY_HOME:
              code = '3';
              break;
          case KEY_POWER:
              code = '4';
              break;
          default:
              code = 0;
              break;
       }
     close(fd);
     printf("Key test finished.\n"); 
     return 0;

基本完成了,应用层程序可以按照应用层要求增加相应代码,如进程通信等。

另外关于平台文件说明:

common文件夹下的文件就是与平台无关的文件;与平台相关的文件又分为CPU级相关的文件和与板级相关的文件:
arch目录下的文件就是与CPU级相关的文件,而board、drivers、include等文件夹下的文件都是与板级相关的文件。

我们在移植的过程中,需要修改的文件也就是这些与平台相关的文件。对于开发板,如2440,多修改板级文件,对于公司开发的新产品,多修改arch目录下的文件就是与CPU级相关的文件。有时CPU级相关的文件和与板级相关的文件都称混称为板级文件。

另active_low = 1,还是active_low =0,要根据硬件的连接,如果按下按键为高电平那么active_low =0,如果按下按键为低电平那么active_low =1.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值