OK335xs2按键驱动程序

来源:互联网 发布:阿里云的销售好累啊 编辑:程序博客网 时间:2024/06/04 19:17

OK335xs2按键驱动程序,给予输入子系统编写。





#include <linux/module.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>


/* GPIO0~3 寄存器基地址 */
#define GPIO0_BASE 0x44E07000
#define GPIO1_BASE 0x4804C000
#define GPIO2_BASE 0x481AC000
#define GPIO3_BASE 0x481AE000


//寄存器偏移量
#define GPIO_EOI_OFFSET      0x20
#define GPIO_OE_OFFSET       0x134
#define GPIO_DATAIN_OFFSET   0x138
#define GPIO_DATAOUT_OFFSET  0x13c
#define GPIO_CTRL_OFFSET     0x130




#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))


/*  按键数量 */
#define KEY_NUM 2


volatile unsigned long * GPIO1_oe;
volatile unsigned long * GPIO1_data_in;




/* 定义基本的按键描述 */
struct pin_desc{
int irq;
char *name;
unsigned int pin;
unsigned int key_val;
};
/* 两个按键的描述 */
struct pin_desc pins_desc[4] = {
{OMAP_GPIO_IRQ(GPIO_TO_PIN(1, 22)),  "K1", GPIO_TO_PIN(1, 22),   KEY_1},
{OMAP_GPIO_IRQ(GPIO_TO_PIN(1, 20)),  "K2", GPIO_TO_PIN(1, 20),   KEY_2},
};


static struct input_dev *buttons_dev;
static struct pin_desc  *irq_pd;
static struct timer_list buttons_timer;
/* 按键中断处理函数 */
static irqreturn_t buttons_irq(int irq, void *dev_id)
{
/* 10ms后启动定时器 */
irq_pd = (struct pin_desc *)dev_id;
mod_timer(&buttons_timer, jiffies+HZ/100);
return IRQ_RETVAL(IRQ_HANDLED);
}
/* 定时器处理函数 */
static void buttons_timer_function(unsigned long data)
{
struct pin_desc * pindesc = irq_pd;
unsigned int pinval;


if (!pindesc)
return;



pinval = gpio_get_value(pindesc->pin);




if (pinval)
{
/* 松开 : 最后一个参数: 0-松开, 1-按下 */
input_event(buttons_dev, EV_KEY, pindesc->key_val, 0);
input_sync(buttons_dev);


//printk("up\v");
}
else
{
/* 按下 */
input_event(buttons_dev, EV_KEY, pindesc->key_val, 1);
input_sync(buttons_dev);
//printk("down\v");
}
}


static int buttons_init(void)
{
int i;

/* 1. 分配一个input_dev结构体 */
buttons_dev = input_allocate_device();;


/* 2. 设置 */
/* 2.1 能产生哪类事件 */
set_bit(EV_KEY, buttons_dev->evbit);
set_bit(EV_REP, buttons_dev->evbit);

/* 2.2 能产生这类操作里的哪些事件: L,S,ENTER,LEFTSHIT */
set_bit(KEY_1, buttons_dev->keybit);
set_bit(KEY_2, buttons_dev->keybit);

/* 3. 注册 */
input_register_device(buttons_dev);

/* 4. 硬件相关的操作 */
init_timer(&buttons_timer);
buttons_timer.function = buttons_timer_function;
add_timer(&buttons_timer);


    GPIO1_oe = ioremap(GPIO1_BASE + GPIO_OE_OFFSET,4);
    GPIO1_data_in = ioremap(GPIO1_BASE + GPIO_DATAIN_OFFSET,4);


    /* 将gpio1_22 gpio1_20配置为输入 */
    *GPIO1_oe = (1<<20 | 1<<22);

for (i = 0; i < KEY_NUM; i++)
{
request_irq(pins_desc[i].irq, buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, pins_desc[i].name, &pins_desc[i]);
}

return 0;
}


static void buttons_exit(void)
{
int i;
for (i = 0; i < KEY_NUM; i++)
{
free_irq(pins_desc[i].irq, &pins_desc[i]);
}


del_timer(&buttons_timer);
input_unregister_device(buttons_dev);
input_free_device(buttons_dev);


iounmap(GPIO1_oe);
iounmap(GPIO1_data_in);
}


module_init(buttons_init);
module_exit(buttons_exit);


MODULE_LICENSE("GPL");
测试程序如下:

#include <stdio.h>
#include <stdlib.h> //system
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <linux/input.h>






int main(int argc,char **argv)
{
   int fd; 
  
   struct input_event t;
   
   fd = open("/dev/input/event0",O_RDWR|O_NONBLOCK);


   if(fd < 0)
   {
       perror("open device event0 fail");
       exit(1);
   }
   /* 读按键 */
   while(1)
   {
    if(read(fd,&t,sizeof(t)) == sizeof(t)) {


if(t.type==EV_KEY)
{
if(t.value==0 || t.value==1)
{
                switch(t.code)
{


case KEY_1:
                     
 if(t.value)
  printf("key1 down\n");
 else
  printf("key1 up\n");
                         
break;




   case KEY_2:
                          if(t.value)
  printf("key2 down\n");
 else
  printf("key2 up\n");


break;
         
                  default:
    break;
                }


}
}
    }
   }




  close(fd);


}








0 0