Linux 输入子系统驱动程序范例

<按键驱动程序>
#include <stdio.h>
#include <fcntl.h>
#include <linux/input.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char** argv)
{
   int fd;
   int count;
   int i = 0;
   int j = 0;
   struct input_event key2;
   //在根文件系统用cat /proc/bus/input/devices查看是event几
   fd = open("/dev/event1", O_RDWR);
 
   if (fd < 0)
   {
       perror("open");
       return -1;
   }
   while (1)
   {
       lseek(fd, 0, SEEK_SET);
       count = read(fd, &key2, sizeof(struct input_event)); 
       if(count != sizeof(struct input_event))
       {
           perror("read");
       }
       if(EV_KEY == key2.type)
       {
           printf("\r\ni = %d, type:%d, code:%d, value:%d\r\n", i, key2.type,                key2.code, key2.value);
           if (key2.value)
           {
               i++;
               printf("***********the k2 down %d times***********\r\n", i);    
           }
       else
       {
           printf("****************the k2 up*****************\r\n"); 
       }
   } 
 
   if(EV_SYN == key2.type)
   {
       printf("syn event\r\n");
       if (++j == 2)
       {
           j = 0;
           printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\n");
       }
   }
}
   close(fd);
   return 0;
}
 
驱动程序:inputk2_drv.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <asm/gpio.h>
#include <linux/timer.h>
 
static struct input_dev *button_dev;//定义输入设备
struct timer_list my_timer;//定义定时器结构体timer_list
//定义定时器超时处理函数
void timer_func(unsigned long data)
{
int key_value = gpio_get_value(S5PV210_GPH2(0));
//上报事件给input核心层
input_report_key(button_dev, KEY_A, !key_value);//按下为1
//告诉input子系统上报已经完成
input_sync(button_dev);
//printk("[%d][%s], data=[%lu]\r\n", __LINE__, __FUNCTION__, data);
}
static irqreturn_t button_interrupt(int irq, void *dev_id)
{
//the value of timeout is decided by the n of "jiffies + n" 
//timeout = n*(1000/HZ) ms(HZ=256 in this project)
//the empirical value of timeout ≈ 10~100ms
mod_timer(&my_timer, jiffies + 5);//timeout≈5*4=20ms
return IRQ_HANDLED;
}
static int __init button_init(void)
{
int ret;
ret = gpio_request(S5PV210_GPH2(0), "key2");
   if (ret)
   {
       printk(KERN_ERR "gpio_request Failed to register device\r\n");
       goto error1;
   }
 
   //为新输入设备分配内存并初始化
   button_dev = input_allocate_device();
   if (!button_dev) 
   {
       printk(KERN_ERR "can't allocate input mem!\r\n");
       goto error2;
   }
 
   button_dev->name = "gec_input";
   button_dev->id.bustype = 0x1;
   button_dev->id.product = 0x2;
   button_dev->id.vendor = 0x3;
   button_dev->id.version = 0x4;
   button_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);//set_bit(EV_KEY,button_dev-    >evbit[BIT_WORD(EV_KEY)])
   button_dev->keybit[BIT_WORD(KEY_A)] = BIT_MASK(KEY_A);//set_bit(KEY_A, button_dev-      >keybit[BIT_WORD(KEY_A)])
   //注册一个输入设备
   ret = input_register_device(button_dev);
   if (ret) 
   {
       printk(KERN_ERR "Failed to register device\r\n");
       goto error3;
   }
   //申请中断注册中断处理函数
   ret = request_irq(IRQ_EINT(16), button_interrupt,\
   IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING | IRQF_DISABLED, "button", NULL);
   if (ret) 
   {
       printk(KERN_ERR "Can't request irq %d\r\n", IRQ_EINT(16));
       goto error4;
   }
 
   //定时器
   init_timer(&my_timer);//初始化定时器
   my_timer.function = timer_func;//注册定时器超时处理函数
   return 0;
   error4:
   free_irq(IRQ_EINT(16), NULL);//释放分配给已定中断的内存
   input_unregister_device(button_dev);
   error3:
   input_free_device(button_dev);
   error2:
   ret = -ENOMEM;
   error1:
   gpio_free(S5PV210_GPH2(0));
 
   return ret;
}
 
static void __exit button_exit(void)
{
   gpio_free(S5PV210_GPH2(0)); 
   free_irq(IRQ_EINT(16), NULL);
   input_unregister_device(button_dev);
   del_timer(&my_timer);//删除内核定时器
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_LICENSE("GPL");
Makefile:
obj-m += inputk2_drv.o
PWD ?= shell pwd
KDIR := /opt/03.kernel_transplant/android-kernel-samsung-dev
all:
make -C $(KDIR) M=$(PWD) modules
cp ./inputk2_drv.ko /mini_rootfs/modules
cp ./inputk2_app /mini_rootfs/modules
rm -rf ./*.o
rm -rf ./*.order
rm -rf ./*.symvers
rm -rf ./*.mod.c
rm -rf ./.*.cmd 
rm -rf ./.*.tmp* 
rm -rf ./.tmp_versions
 
<键盘驱动程序>
  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/interrupt.h>
  4. #include <linux/platform_device.h>
  5. #include <linux/input.h>
  6. #include <linux/slab.h>
  7.  
  8. #include <mach/regs-gpio.h>
  9. #include <linux/gpio.h>
  10. #include <linux/irq.h>
  11.  
  12.  
  13. #define DHOLE2440_KBD "dhole2440kbd"
  14. #define DHOLE2440_KBD_IRQ_NUM (6)
  15. #define KBD_NONE (0xff)
  16.  
  17. #define KBD_UP (0)
  18. #define KBD_DOWN (1)
  19.  
  20. typedef struct _dhole2440_key{
  21.     unsigned int gpio;/*对应gpio口*/
  22.     unsigned int irq;/*对应中断*/
  23.     int n_key;/*键值*/
  24. }dhole2440_key;
  25.  
  26. struct dhole2440_kbd{
  27.     dhole2440_key keys[DHOLE2440_KBD_IRQ_NUM];
  28.     struct timer_list key_timer; /*按键去抖定时器*/
  29.     unsigned int key_status; /*按键状态*/
  30.     struct input_dev *input;
  31. };
  32.  
  33. struct dhole2440_kbd *p_dhole2440_kbd;
  34.  
  35.  
  36. struct dhole2440_kbd *get_kbd(void)
  37. {
  38.     printk("get_kbd p_dhole2440_kbd=%x\n", (unsigned int)p_dhole2440_kbd);
  39.     return p_dhole2440_kbd;
  40. }
  41.  
  42. void set_kbd(struct dhole2440_kbd *p_kbd)
  43. {
  44.     p_dhole2440_kbd = p_kbd;
  45.  
  46.     printk("set_kbd p_kbd=%x, p_dhole2440_kbd=%x\n",
  47.         (unsigned int)p_kbd, (unsigned int)p_dhole2440_kbd);
  48. }
  49.  
  50. static irqreturn_t dhole2440_kbd_handler(int irq, void *p_date)
  51. {
  52.     unsigned int n_key = 0;
  53.     struct dhole2440_kbd *p_kbd = p_date;
  54.     unsigned int key_state = 0;
  55.     int i;
  56.  
  57.     for(= 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  58.     {
  59.         if( irq == p_kbd->keys[i].irq )
  60.         {
  61.             key_state = s3c2410_gpio_getpin(p_kbd->keys[i].gpio);
  62.             n_key = p_kbd->keys[i].n_key;
  63.             break;
  64.         }
  65.     }
  66.  
  67.     printk("dhole2440_kbd_handler n_key=%d, key_state=%d\n", n_key, key_state);
  68.  
  69.     input_report_key(p_kbd->input, n_key, !key_state);/*1表示按下*/
  70.     input_sync(p_kbd->input);
  71.  
  72.     return IRQ_HANDLED;
  73. }
  74.  
  75.  
  76. static void kbd_free_irqs(void)
  77. {
  78.     struct dhole2440_kbd *p_kbd = get_kbd();
  79.     int i;
  80.  
  81.     printk("kbd_free_irqs p_kbd=%x\n", (unsigned int)p_kbd);
  82.    
  83.     for(= 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  84.         free_irq(p_kbd->keys[i].irq, p_kbd);
  85. }
  86.  
  87. static int kbd_req_irqs(void)
  88. {
  89.     int n_ret;
  90.     int i;
  91.     struct dhole2440_kbd *p_kbd = get_kbd();
  92.  
  93.     printk("kbd_req_irqs p_kbd=%x\n", (unsigned int)p_kbd);
  94.  
  95.     for(= 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  96.     {
  97.         n_ret = request_irq(p_kbd->keys[i].irq, dhole2440_kbd_handler, IRQ_TYPE_EDGE_BOTH, DHOLE2440_KBD, p_kbd);
  98.         if(n_ret)
  99.         {
  100.             printk("%d: could not register interrupt\n", p_kbd->keys[i].irq);
  101.             goto fail;
  102.         }
  103.     }
  104.  
  105.     return n_ret;
  106.  
  107. fail:
  108.     /*因为上面申请失败的那个没有成功,所以也不要释放*/
  109.     for(i--; i >= 0; i--)
  110.     {
  111.         disable_irq(p_kbd->keys[i].irq);
  112.         free_irq(p_kbd->keys[i].irq, p_kbd);
  113.     }
  114.  
  115.     return n_ret;
  116. }
  117.  
  118. static void dhole2440_init_kbd_data(struct dhole2440_kbd *p_kbd)
  119. {
  120.     printk("dhole2440_init_kbd_data p_kbd=%x\n", (unsigned int)p_kbd);
  121.  
  122.     p_kbd->keys[0].gpio = S3C2410_GPG(11);
  123.     p_kbd->keys[1].gpio = S3C2410_GPG(7);
  124.     p_kbd->keys[2].gpio = S3C2410_GPG(6);
  125.     p_kbd->keys[3].gpio = S3C2410_GPG(5);
  126.     p_kbd->keys[4].gpio = S3C2410_GPG(3);
  127.     p_kbd->keys[5].gpio = S3C2410_GPG(0);
  128.  
  129.     p_kbd->keys[0].irq = IRQ_EINT19;
  130.     p_kbd->keys[1].irq = IRQ_EINT15;
  131.     p_kbd->keys[2].irq = IRQ_EINT14;
  132.     p_kbd->keys[3].irq = IRQ_EINT13;
  133.     p_kbd->keys[4].irq = IRQ_EINT11;
  134.     p_kbd->keys[5].irq = IRQ_EINT8;
  135.  
  136.     p_kbd->keys[0].n_key = KEY_0;
  137.     p_kbd->keys[1].n_key = KEY_1;
  138.     p_kbd->keys[2].n_key = KEY_2;
  139.     p_kbd->keys[3].n_key = KEY_3;
  140.     p_kbd->keys[4].n_key = KEY_ESC;
  141.     p_kbd->keys[5].n_key = KEY_ENTER;
  142. }
  143.  
  144. static int __devinit dhole2440_keys_probe(struct platform_device *pdev)
  145. {
  146.     int err = -ENOMEM;
  147.     struct dhole2440_kbd *p_dhole2440_keys = NULL;
  148.     struct input_dev *input_dev = NULL;
  149.  
  150.     printk("dhole2440_keys_probe entry!\n");
  151.  
  152.     p_dhole2440_keys = kmalloc(sizeof(struct dhole2440_kbd), GFP_KERNEL);
  153.     if( !p_dhole2440_keys )
  154.     {
  155.         printk("dhole2440_keys_probe kmalloc error!\n");
  156.         return err;
  157.     }
  158.     printk("dhole2440_keys_probe p_dhole2440_keys=%x\n", (unsigned int)p_dhole2440_keys);
  159.  
  160.     dhole2440_init_kbd_data(p_dhole2440_keys);
  161.  
  162.     input_dev = input_allocate_device();
  163.     if (!input_dev)
  164.     {
  165.         printk("dhole2440_keys_probe input_allocate_device error!\n");
  166.         goto fail;
  167.     }
  168.  
  169.     p_dhole2440_keys->input = input_dev;
  170.  
  171.     platform_set_drvdata(pdev, p_dhole2440_keys);
  172.     input_dev->name = pdev->name;
  173.     input_dev->phys = DHOLE2440_KBD"/input0";
  174.     input_dev->id.bustype = BUS_HOST;
  175.     input_dev->dev.parent = &pdev->dev;
  176.     input_dev->id.vendor = 0x0001;
  177.     input_dev->id.product = 0x0001;
  178.     input_dev->id.version = 0x0100;
  179.  
  180.     __set_bit(EV_KEY, input_dev->evbit);
  181.     __set_bit(KEY_0, input_dev->keybit);
  182.     __set_bit(KEY_1, input_dev->keybit);
  183.     __set_bit(KEY_2, input_dev->keybit);
  184.     __set_bit(KEY_3, input_dev->keybit);
  185.     __set_bit(KEY_ESC, input_dev->keybit);
  186.     __set_bit(KEY_ENTER, input_dev->keybit);
  187.     input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
  188.  
  189.     err = input_register_device(input_dev);
  190.     if( err )
  191.     {
  192.         printk("dhole2440_keys_probe input_register_device error!\n");
  193.         goto fail_allocate;
  194.     }
  195.  
  196.     set_kbd(p_dhole2440_keys);
  197.  
  198.     err = kbd_req_irqs();
  199.     if( err )
  200.     {
  201.         printk("dhole2440_keys_probe kbd_req_irqs error!\n");
  202.         goto fail_register;
  203.     }
  204.  
  205.     printk("dhole2440_keys_probe sucess!\n");
  206.  
  207.     return 0;
  208.  
  209. fail_register:
  210.     input_unregister_device(input_dev);
  211.     goto fail;
  212. fail_allocate:
  213.     input_free_device(input_dev);
  214. fail:
  215.     kfree(p_dhole2440_keys);
  216.  
  217.     return err;
  218. }
  219.  
  220. static int __devexit dhole2440_keys_remove(struct platform_device *pdev)
  221. {
  222.     struct dhole2440_kbd *p_dhole2440_keys = platform_get_drvdata(pdev);
  223.  
  224.     printk("dhole2440_keys_remove entry!\n");
  225.  
  226.     kbd_free_irqs();
  227.  
  228.     input_unregister_device(p_dhole2440_keys->input);
  229.     kfree(p_dhole2440_keys);
  230.  
  231.     printk("dhole2440_keys_remove sucess!\n");
  232.  
  233.     return 0;
  234. }
  235.  
  236. static void dhole2440_keys_release(struct device *dev)
  237. {
  238.     dev = dev;
  239. }
  240.  
  241.  
  242. static struct platform_driver dhole2440_keys_device_driver = {
  243.     .probe = dhole2440_keys_probe,
  244.     .remove = __devexit_p(dhole2440_keys_remove),
  245.     .driver = {
  246.         .name = DHOLE2440_KBD,
  247.         .owner = THIS_MODULE,
  248.     }
  249. };
  250.  
  251. static struct platform_device dhole2440_device_kbd = {
  252.     .name = DHOLE2440_KBD,
  253.     .id = -1,
  254.     .dev = {
  255.         .release = dhole2440_keys_release,
  256.     }
  257. };
  258.  
  259. static int __init dhole2440_keys_init(void)
  260. {
  261.     int n_ret;
  262.     n_ret = platform_driver_register(&dhole2440_keys_device_driver);
  263.  
  264.     printk("dhole2440_keys_init 1 n_ret=%d jiffies=%lu,HZ=%d\n", n_ret, jiffies, HZ);
  265.     if( n_ret )
  266.         return n_ret;
  267.  
  268.     n_ret = platform_device_register(&dhole2440_device_kbd);
  269.  
  270.     printk("dhole2440_keys_init 2 n_ret=%d\n", n_ret);
  271.     if( n_ret )
  272.         goto fail;
  273.  
  274.     return n_ret;
  275.  
  276. fail:
  277.     platform_driver_unregister(&dhole2440_keys_device_driver);
  278.  
  279.     return n_ret;
  280. }
  281.  
  282. static void __exit dhole2440_keys_exit(void)
  283. {
  284.     printk("dhole2440_keys_exit\n");
  285.  
  286.     platform_device_unregister(&dhole2440_device_kbd);
  287.  
  288.     platform_driver_unregister(&dhole2440_keys_device_driver);
  289. }
  290.  
  291. module_init(dhole2440_keys_init);
  292. module_exit(dhole2440_keys_exit);
  293.  
  294. MODULE_DESCRIPTION("dhole2440 keyboard input events driver");
  295. MODULE_AUTHOR("liuzhiping <lyliuzhiping@yeah.net style="word-wrap: break-word;">");
  296. MODULE_LICENSE("GPL");
  297. MODULE_ALIAS("platform:dhole2440 keyboard driver");
 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

posted @ 2018-03-17 15:20  流浪的Coder  阅读(569)  评论(0编辑  收藏  举报