Linux2.6.32内核下按键作为输入子系统实现

本文详细探讨了在Linux 2.6.32内核版本中如何实现按键作为输入子系统的过程,内容包括相关代码分析及在mini2440开发板上的验证结果。
摘要由CSDN通过智能技术生成
/*驱动部分代码实现如下(根据国嵌代码,做出部分修改)*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <linux/input.h>
#include <linux/gpio.h>

struct input_dev *button_dev;
struct button_irq_desc {
    int irq;
    int pin;
    int pin_setting;
    int number;
    char *name; 
};




static struct button_irq_desc button_irqs [] = {
    {IRQ_EINT8 , S3C2410_GPG(0) ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},  
    {IRQ_EINT11, S3C2410_GPG(3) ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},
    {IRQ_EINT13, S3C2410_GPG(5) ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},
    {IRQ_EINT14, S3C2410_GPG(6) ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},
    {IRQ_EINT15, S3C2410_GPG(7) ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},
    {IRQ_EINT19, S3C2410_GPG(11),  S3C2410_GPG11_EINT19, 5, "KEY5"},
};


static int key_values = 0;


static irqreturn_t buttons_interrupt(int irq, void *dev_id)
{
    struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
    int down;
     udelay(0);
    down = !s3c2410_gpio_getpin(button_irqs->pin);   //down: 1(按下),0(弹起)
   if (!down) { 

/*报告事件*/
key_values = button_irqs->number;
//printk("====>rising key_values=%d\n",key_values);
  if(key_values==0)
  input_report_key(button_dev, KEY_1, 0);
  if(key_values==1)
  input_report_key(button_dev, KEY_2, 0);
  if(key_values==2)
  input_report_key(button_dev, KEY_3, 0);
  if(key_values==3)
  input_report_key(button_dev, KEY_4, 0);
  if(key_values==4)
  input_report_key(button_dev, KEY_5, 0);
  if(key_values==5)
  input_report_key(button_dev, KEY_6, 0);

  input_sync(button_dev);      
    }

     else {

        key_values = button_irqs->number;
        //printk("====>falling key_values=%d\n",key_values);
  if(key_values==0)
        input_report_key(button_dev, KEY_1, 1);
  if(key_values==1)
        input_report_key(button_dev, KEY_2, 1);
  if(key_values==2)
        input_report_key(button_dev, KEY_3, 1);
  if(key_values==3)
        input_report_key(button_dev, KEY_4, 1);
  if(key_values==4)
        input_report_key(button_dev, KEY_5, 1);
  if(key_values==5)
        input_report_key(button_dev, KEY_6, 1);
  input_sync(button_dev);      


     }



    return IRQ_RETVAL(IRQ_HANDLED);
}




static int s3c24xx_request_irq(void)
{
    int i;
    int err = 0;

    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {



if (button_irqs[i].irq < 0) {
continue;
}
  /* IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH */
        err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, 
                          button_irqs[i].name, (void *)&button_irqs[i]);
        if (err)
            break;
    }


    if (err) {
        i--;
        for (; i >= 0; i--) {
   if (button_irqs[i].irq < 0) {
continue;
   }
   disable_irq(button_irqs[i].irq);
            free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
        }
        return -EBUSY;
    }



    return 0;
}




static int __init dev_init(void)
{



  /*request irq*/
  s3c24xx_request_irq();
/* Initialise input stuff */
button_dev = input_allocate_device();
if (!button_dev) {
printk(KERN_ERR "Unable to allocate the input device !!\n");
return -ENOMEM;
}
button_dev->name = "s3c2440_button";
button_dev->id.bustype = BUS_RS232;
  button_dev->id.vendor = 0xDEAD;
  button_dev->id.product = 0xBEEF;
  button_dev->id.version = 0x0100;


button_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT(EV_SYN);
//set_bit(EV_KEY, button_dev->evbit)//支持EV_KEY事件
set_bit(KEY_1,   button_dev->keybit);
set_bit(KEY_2,   button_dev->keybit);
set_bit(KEY_3,   button_dev->keybit);
set_bit(KEY_4,   button_dev->keybit);
set_bit(KEY_5,   button_dev->keybit);
set_bit(KEY_6,   button_dev->keybit);
//printk("KEY_RESERVED=%d ,KEY_1=%d",KEY_RESERVED,KEY_1);
input_register_device(button_dev);   //注册input设备


printk ("initialized\n");


return 0;
}


static void __exit dev_exit(void)
{
   int i;

  for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
if (button_irqs[i].irq < 0) {
   continue;
}
free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
   }


input_unregister_device(button_dev);
}


module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Xie");


/*应用部分代码实现如下(根据国嵌代码,做出部分修改)*/
/*
 *      Buttons Example for Matrix V
 *
 *      Copyright (C) 2004 capbily - friendly-arm
 * capbily@hotmail.com
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <linux/input.h>
int main(void)
{
int buttons_fd;
int key_value,i=0,count;


struct input_event ev_key;
buttons_fd = open("/dev/input/event1", O_RDWR);//查看/dev/input/eventX是什么类型的事件, cat /proc/bus/input/devices
if (buttons_fd < 0) {
perror("open device buttons");
exit(1);
}


for (;;) {
count = read(buttons_fd,&ev_key,sizeof(struct input_event));
// printf("count=%d\n",count);
for(i=0; i<(int)count/sizeof(struct input_event); i++)
if(EV_KEY==ev_key.type)
printf("type:%d,code:%d,value:%d\n", ev_key.type,ev_key.code-1,ev_key.value);
if(EV_SYN==ev_key.type)
printf("syn event\n\n");


}


close(buttons_fd);
return 0;
}

该代码在mini2440开发板上验证过!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值