Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434067
  • 博文数量: 247
  • 博客积分: 185
  • 博客等级: 入伍新兵
  • 技术积分: 1005
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-10 10:39
文章分类

全部博文(247)

文章存档

2015年(3)

2014年(21)

2013年(53)

2012年(170)

分类:

2012-09-17 23:56:27

Linux 内核下的 drivers/input/keyboard/gpio_keys.c实现了一个体系结构无关的GPIO按键驱动,使用此按键驱动,只需在arch/arm/mach-s3c2410/mach-smdk2410.c中定义相关的数据即可。驱动的实现非常简单,但是较适合于实现独立式按键驱动,且按键所接端口为中断引脚,如本书硬件平台矩阵按键对应的EINT0EINT2EINT11EINT19中断对应的引脚。如果是矩阵按键,相应代码的改动较大,不宜提倡。

假设在S3C2410开发平台上, 使用GPG3GPG11GPF0GPF2实现了DOWNENTERHOMEPOWER四个按键,该法实现驱动程序首先在头文件位置键入以下头文件:

#include

#include

#include //S3C2410各个端口定义

然后在mach-smdk2410.c中键入按键的定义信息:

static struct gpio_keys_button s3c2410_buttons [ ] = {

{

.gpio = S3C2410_GPG3,

.code = KEY_DOWN,

.desc = "Down" ,

.active_low = 1,

},

{

.gpio = S3C2410_GPG11,

.code = KEY_ENTER,

.desc = "Enter " ,

.active_low = 1,

},

{

.gpio = S3C2410_GPF0,

.code = KEY_HOME,

.desc = "Home" ,

.active_low = 1,

},

{

.gpio = S3C2410_GPF2,

.code = KEY_POWER,

.desc = "Power " ,

.active_low = 1,

},

};

static struct gpio_keys_platform_data s3c2410_button_data = {

.buttons = s3c2410_buttons,

.nbuttons = ARRAY_SIZE(s3c2410_buttons) ,

};

static struct platform_device s3c2410_device_button = {

     .name = "gpio-keys",

     .id =-1,

     .dev = {

     .platform_data = &s3c2410_button_data,

}

};

其中

n   gpio是连接按键的IO管脚。

n   code是这个按键上报的键值, input.h中定义。

n   desc是按键的name

n   active_low1是表示低电平触发。

将“&s3c2410_device_button,”语句填入 struct platform_device *s3c2410_devices[]数组,作为该数组的一个成员。

static struct platform_device *smdk2410_devices[] __initdata = {

     &s3c_device_usb,

     &s3c_device_lcd,

     &s3c_device_wdt,

     &s3c_device_i2c,

     &s3c_device_iis,

     &s3c_device_rtc,

     &s3c_device_ts,

     &s3c2410_device_button,};

编译内核时选择:

Device Drivers >

Input device support >

[*] Keyboards

<*> GPIO Buttons

如果要修改按键对应的GPIO和键值,只需要简单的修改s3c2410_buttons[]数组中的内容。

这样在内核的启动过程中,会发现如下的提示:

input: gpio-keys as /class/input/input0

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

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char **argv)

{

     int key_state;

     int fd;

     int ret;

     int code;

     struct input_event buf;

     int repeat_param[2];

     fd = open("/dev/input/event0", O_RDONLY);

     if (fd < 0)

     {

         printf("Open gpio-keys failed.\n");

         return -1;

  }

  else

  {

     printf("Open gpio-keys success.\n");

  }

     repeat_param[0]=500;//ms重复按键第一次间隔

     repeat_param[1]=66;//ms重复按键后续间隔

     ret = ioctl(fd,EVIOCSREP,(int *)repeat_param);//设置重复按键参数

     if(ret != 0)

         {

                   printf("set repeat_param fail!\n");

         }

     else

         {

                printf("set repeat_param ok.\n");

         }

     while(1)

     {

         ret = read(fd,&buf,sizeof(struct input_event));

         if(ret <= 0)

              {

                   printf("read fail!\n");

                   return -1;

              }

             

       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;

       }

       if(code!=0)

          {

           printf("Key_%c state= %d.\n",code,key_state);

         }

     }

     close(fd);

     printf("Key test finished.\n"); 

     return 0;

}

上述按键驱动涉及到Linux内核的platform设备驱动模型相关知识,读者可自行参考相关内容。
阅读(659) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~