linux 输入子系统驱动程序

来源:互联网 发布:mac ntfs 新建文件夹 编辑:程序博客网 时间:2024/06/05 17:23

一,过程概述

1. 分配一个struct input_dev

        key_input_dev = input_allocate_device();

2. 设置 input_dev 支持的事件 Event types 主要有按键事件 EV_KEY 重复事件 EV_REP

        set_bit(EV_KEY, key_input_dev->evbit);

3. 设置 input_dev 里按键事件 EV_KEY 支持的按键 如    l    键     KEY_L

        set_bit(KEY_L, key_input_dev->keybit);

4. 注册 input_dev

      input_register_device(key_input_dev)

5. 注册完之后还要向我们的  key_input_dev 发送消息

     input_event(key_input_dev, EV_KEY, desc->number, 0);

     input_sync(key_input_dev);

二. 实例代码

#include <linux/module.h>//MODULE_LICENSE,MODULE_AUTHOR  #include <linux/init.h>//module_init/module_exit  #include <linux/fs.h>//file_operations  #include <linux/cdev.h>//cdev  #include <linux/wait.h>//wait_event_interruptible(wait_queue_head_t q,int condition) wake_up_interruptible(struct wait_queue **q)  #include <linux/sched.h>//request_irq,free_irq  #include <linux/irq.h>//IRQ_TYPE_EDGE_FALLING  #include <linux/interrupt.h>//request_irq,free_irq  #include <linux/device.h>//class device  #include <linux/poll.h>#include <linux/input.h>#include <asm/uaccess.h>//copy_to_user  #include <asm/io.h>//ioread32,iowrite32 #include <mach/map.h>//定义了S3C64XX_VA_GPIO  #include <mach/regs-gpio.h>//定义了gpio-bank-n中使用的S3C64XX_GPN_BASE  #include <mach/gpio-bank-n.h>//定义了GPNCON  #include <mach/gpio-bank-l.h>//定义了GPNCON #include "s3c6410.h"typedef struct {      int irq;      int number;      char *name; char pin;} key_irq_desc_t; volatile unsigned long *gpndat;volatile unsigned long *gpncon;static key_irq_desc_t key_irqs [] = {      {IRQ_EINT(0), KEY_L,  "KEY0", 0},      {IRQ_EINT(1), KEY_S,  "KEY1", 1},      {IRQ_EINT(2), KEY_ENTER,     "KEY2", 2},      {IRQ_EINT(3), KEY_LEFTSHIFT, "KEY3", 3},}; static struct input_dev *key_input_dev;static struct timer_list key_timer;static key_irq_desc_t *key_desc  = NULL;static void key_timer_function(unsigned long data){key_irq_desc_t *desc = (key_irq_desc_t*)key_desc;int pin_val = 0;if(!desc)return;pin_val = *gpndat & (1<<(desc->pin)) ? 1 : 0;if(pin_val){input_event(key_input_dev, EV_KEY, desc->number, 0);}else{input_event(key_input_dev, EV_KEY, desc->number, 1);}input_sync(key_input_dev);printk(KERN_INFO"pin_val %d pin %d\n", pin_val, desc->pin);}static irqreturn_t keys_drv_irq(int irq, void* dev_id){key_desc = (key_irq_desc_t*)dev_id;mod_timer(&key_timer, jiffies+HZ/100);return IRQ_HANDLED;}static int key_drv_input_init(void){int i = 0;key_input_dev = input_allocate_device();if(!key_input_dev)return -EFAULT;set_bit(EV_KEY, key_input_dev->evbit);set_bit(EV_REP, key_input_dev->evbit);set_bit(KEY_L, key_input_dev->keybit);set_bit(KEY_S, key_input_dev->keybit);set_bit(KEY_ENTER, key_input_dev->keybit);set_bit(KEY_LEFTSHIFT, key_input_dev->keybit);if(input_register_device(key_input_dev))return -EFAULT;init_timer(&key_timer);key_timer.function = key_timer_function;add_timer(&key_timer);for (i = 0; i < sizeof(key_irqs)/sizeof(key_irq_desc_t); i++) {if(request_irq(key_irqs[i].irq, keys_drv_irq, IRQ_TYPE_EDGE_BOTH, key_irqs[i].name, (void*)&key_irqs[i])){return -EFAULT;}}gpncon = (volatile unsigned long *)ioremap(ELFIN_GPIO_BASE+GPNCON_OFFSET, 12);gpndat  = gpncon+1;printk(KERN_DEBUG"key_drv_input_init\n");return 0;}static void key_drv_input_exit(void){int i = 0; iounmap(gpncon);for (i = 0; i < sizeof(key_irqs)/sizeof(key_irq_desc_t); i++) {free_irq(key_irqs[i].irq, (void*)&key_irqs[i]);}del_timer(&key_timer);input_unregister_device(key_input_dev);input_free_device(key_input_dev);printk(KERN_DEBUG"key_drv_input_exit\n");}module_init(key_drv_input_init);module_exit(key_drv_input_exit);MODULE_LICENSE("GPL");