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

来源:互联网 发布:网络用语♀是什么意思 编辑:程序博客网 时间:2024/05/22 06:20

一个简单的按键驱动,涉及到的知识点有: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));}//数据保存在bufcode = 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.


0 0