Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1553818
  • 博文数量: 239
  • 博客积分: 1760
  • 博客等级: 上尉
  • 技术积分: 1595
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-08 23:53
文章分类

全部博文(239)

文章存档

2016年(1)

2015年(28)

2014年(53)

2013年(42)

2012年(50)

2011年(65)

分类: LINUX

2012-04-02 02:28:40

问: 为何要基于input子系统??
答: 因为linux下所有GUI都可以接收input子系统的消息。写基于GUI的程序时可以用GUI实现的按键机制,而不是单片机的思维,一个死循环来处理用户输入。

不扯淡了,一切尽在源码中!

硬件平台: s3c2440
软件平台: linux-3.1.6 + qt-4.7.4

此驱动源码以GPL协议开放.

点击(此处)折叠或打开

  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. #include <mach/regs-gpio.h>
  8. #include <linux/gpio.h>
  9. #include <linux/irq.h>


  10. #define DHOLE2440_KBD "dhole2440kbd"
  11. #define DHOLE2440_KBD_IRQ_NUM (6)
  12. #define KBD_NONE (0xff)

  13. #define KBD_UP (0)
  14. #define KBD_DOWN (1)

  15. typedef struct _dhole2440_key{
  16.     unsigned int gpio;/*对应gpio口*/
  17.     unsigned int irq;/*对应中断*/
  18.     int n_key;/*键值*/
  19. }dhole2440_key;

  20. struct dhole2440_kbd{
  21.     dhole2440_key keys[DHOLE2440_KBD_IRQ_NUM];
  22.     struct timer_list key_timer; /*按键去抖定时器*/
  23.     unsigned int key_status; /*按键状态*/
  24.     struct input_dev *input;
  25. };

  26. struct dhole2440_kbd *p_dhole2440_kbd;


  27. struct dhole2440_kbd *get_kbd(void)
  28. {
  29.     printk("get_kbd p_dhole2440_kbd=%x\n", (unsigned int)p_dhole2440_kbd);
  30.     return p_dhole2440_kbd;
  31. }

  32. void set_kbd(struct dhole2440_kbd *p_kbd)
  33. {
  34.     p_dhole2440_kbd = p_kbd;

  35.     printk("set_kbd p_kbd=%x, p_dhole2440_kbd=%x\n",
  36.         (unsigned int)p_kbd, (unsigned int)p_dhole2440_kbd);
  37. }

  38. static irqreturn_t dhole2440_kbd_handler(int irq, void *p_date)
  39. {
  40.     unsigned int n_key = 0;
  41.     struct dhole2440_kbd *p_kbd = p_date;
  42.     unsigned int key_state = 0;
  43.     int i;

  44.     for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  45.     {
  46.         if( irq == p_kbd->keys[i].irq )
  47.         {
  48.             key_state = s3c2410_gpio_getpin(p_kbd->keys[i].gpio);
  49.             n_key = p_kbd->keys[i].n_key;
  50.             break;
  51.         }
  52.     }

  53.     printk("dhole2440_kbd_handler n_key=%d, key_state=%d\n", n_key, key_state);

  54.     input_report_key(p_kbd->input, n_key, !key_state);/*1表示按下*/
  55.     input_sync(p_kbd->input);

  56.     return IRQ_HANDLED;
  57. }


  58. static void kbd_free_irqs(void)
  59. {
  60.     struct dhole2440_kbd *p_kbd = get_kbd();
  61.     int i;

  62.     printk("kbd_free_irqs p_kbd=%x\n", (unsigned int)p_kbd);
  63.    
  64.     for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  65.         free_irq(p_kbd->keys[i].irq, p_kbd);
  66. }

  67. static int kbd_req_irqs(void)
  68. {
  69.     int n_ret;
  70.     int i;
  71.     struct dhole2440_kbd *p_kbd = get_kbd();

  72.     printk("kbd_req_irqs p_kbd=%x\n", (unsigned int)p_kbd);

  73.     for(i = 0; i < DHOLE2440_KBD_IRQ_NUM; i++)
  74.     {
  75.         n_ret = request_irq(p_kbd->keys[i].irq, dhole2440_kbd_handler, IRQ_TYPE_EDGE_BOTH, DHOLE2440_KBD, p_kbd);
  76.         if(n_ret)
  77.         {
  78.             printk("%d: could not register interrupt\n", p_kbd->keys[i].irq);
  79.             goto fail;
  80.         }
  81.     }

  82.     return n_ret;

  83. fail:
  84.     /*因为上面申请失败的那个没有成功,所以也不要释放*/
  85.     for(i--; i >= 0; i--)
  86.     {
  87.         disable_irq(p_kbd->keys[i].irq);
  88.         free_irq(p_kbd->keys[i].irq, p_kbd);
  89.     }

  90.     return n_ret;
  91. }

  92. static void dhole2440_init_kbd_data(struct dhole2440_kbd *p_kbd)
  93. {
  94.     printk("dhole2440_init_kbd_data p_kbd=%x\n", (unsigned int)p_kbd);

  95.     p_kbd->keys[0].gpio = S3C2410_GPG(11);
  96.     p_kbd->keys[1].gpio = S3C2410_GPG(7);
  97.     p_kbd->keys[2].gpio = S3C2410_GPG(6);
  98.     p_kbd->keys[3].gpio = S3C2410_GPG(5);
  99.     p_kbd->keys[4].gpio = S3C2410_GPG(3);
  100.     p_kbd->keys[5].gpio = S3C2410_GPG(0);

  101.     p_kbd->keys[0].irq = IRQ_EINT19;
  102.     p_kbd->keys[1].irq = IRQ_EINT15;
  103.     p_kbd->keys[2].irq = IRQ_EINT14;
  104.     p_kbd->keys[3].irq = IRQ_EINT13;
  105.     p_kbd->keys[4].irq = IRQ_EINT11;
  106.     p_kbd->keys[5].irq = IRQ_EINT8;

  107.     p_kbd->keys[0].n_key = KEY_0;
  108.     p_kbd->keys[1].n_key = KEY_1;
  109.     p_kbd->keys[2].n_key = KEY_2;
  110.     p_kbd->keys[3].n_key = KEY_3;
  111.     p_kbd->keys[4].n_key = KEY_ESC;
  112.     p_kbd->keys[5].n_key = KEY_ENTER;
  113. }

  114. static int __devinit dhole2440_keys_probe(struct platform_device *pdev)
  115. {
  116.     int err = -ENOMEM;
  117.     struct dhole2440_kbd *p_dhole2440_keys = NULL;
  118.     struct input_dev *input_dev = NULL;

  119.     printk("dhole2440_keys_probe entry!\n");

  120.     p_dhole2440_keys = kmalloc(sizeof(struct dhole2440_kbd), GFP_KERNEL);
  121.     if( !p_dhole2440_keys )
  122.     {
  123.         printk("dhole2440_keys_probe kmalloc error!\n");
  124.         return err;
  125.     }
  126.     printk("dhole2440_keys_probe p_dhole2440_keys=%x\n", (unsigned int)p_dhole2440_keys);

  127.     dhole2440_init_kbd_data(p_dhole2440_keys);

  128.     input_dev = input_allocate_device();
  129.     if (!input_dev)
  130.     {
  131.         printk("dhole2440_keys_probe input_allocate_device error!\n");
  132.         goto fail;
  133.     }

  134.     p_dhole2440_keys->input = input_dev;

  135.     platform_set_drvdata(pdev, p_dhole2440_keys);
  136.     input_dev->name = pdev->name;
  137.     input_dev->phys = DHOLE2440_KBD"/input0";
  138.     input_dev->id.bustype = BUS_HOST;
  139.     input_dev->dev.parent = &pdev->dev;
  140.     input_dev->id.vendor = 0x0001;
  141.     input_dev->id.product = 0x0001;
  142.     input_dev->id.version = 0x0100;

  143.     __set_bit(EV_KEY, input_dev->evbit);
  144.     __set_bit(KEY_0, input_dev->keybit);
  145.     __set_bit(KEY_1, input_dev->keybit);
  146.     __set_bit(KEY_2, input_dev->keybit);
  147.     __set_bit(KEY_3, input_dev->keybit);
  148.     __set_bit(KEY_ESC, input_dev->keybit);
  149.     __set_bit(KEY_ENTER, input_dev->keybit);
  150.     input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);

  151.     err = input_register_device(input_dev);
  152.     if( err )
  153.     {
  154.         printk("dhole2440_keys_probe input_register_device error!\n");
  155.         goto fail_allocate;
  156.     }

  157.     set_kbd(p_dhole2440_keys);

  158.     err = kbd_req_irqs();
  159.     if( err )
  160.     {
  161.         printk("dhole2440_keys_probe kbd_req_irqs error!\n");
  162.         goto fail_register;
  163.     }

  164.     printk("dhole2440_keys_probe sucess!\n");

  165.     return 0;

  166. fail_register:
  167.     input_unregister_device(input_dev);
  168.     goto fail;
  169. fail_allocate:
  170.     input_free_device(input_dev);
  171. fail:
  172.     kfree(p_dhole2440_keys);

  173.     return err;
  174. }

  175. static int __devexit dhole2440_keys_remove(struct platform_device *pdev)
  176. {
  177.     struct dhole2440_kbd *p_dhole2440_keys = platform_get_drvdata(pdev);

  178.     printk("dhole2440_keys_remove entry!\n");

  179.     kbd_free_irqs();

  180.     input_unregister_device(p_dhole2440_keys->input);
  181.     kfree(p_dhole2440_keys);

  182.     printk("dhole2440_keys_remove sucess!\n");

  183.     return 0;
  184. }

  185. static void dhole2440_keys_release(struct device *dev)
  186. {
  187.     dev = dev;
  188. }


  189. static struct platform_driver dhole2440_keys_device_driver = {
  190.     .probe = dhole2440_keys_probe,
  191.     .remove = __devexit_p(dhole2440_keys_remove),
  192.     .driver = {
  193.         .name = DHOLE2440_KBD,
  194.         .owner = THIS_MODULE,
  195.     }
  196. };

  197. static struct platform_device dhole2440_device_kbd = {
  198.     .name = DHOLE2440_KBD,
  199.     .id = -1,
  200.     .dev = {
  201.         .release = dhole2440_keys_release,
  202.     }
  203. };

  204. static int __init dhole2440_keys_init(void)
  205. {
  206.     int n_ret;
  207.     n_ret = platform_driver_register(&dhole2440_keys_device_driver);

  208.     printk("dhole2440_keys_init 1 n_ret=%d jiffies=%lu,HZ=%d\n", n_ret, jiffies, HZ);
  209.     if( n_ret )
  210.         return n_ret;

  211.     n_ret = platform_device_register(&dhole2440_device_kbd);

  212.     printk("dhole2440_keys_init 2 n_ret=%d\n", n_ret);
  213.     if( n_ret )
  214.         goto fail;

  215.     return n_ret;

  216. fail:
  217.     platform_driver_unregister(&dhole2440_keys_device_driver);

  218.     return n_ret;
  219. }

  220. static void __exit dhole2440_keys_exit(void)
  221. {
  222.     printk("dhole2440_keys_exit\n");

  223.     platform_device_unregister(&dhole2440_device_kbd);

  224.     platform_driver_unregister(&dhole2440_keys_device_driver);
  225. }

  226. module_init(dhole2440_keys_init);
  227. module_exit(dhole2440_keys_exit);

  228. MODULE_DESCRIPTION("dhole2440 keyboard input events driver");
  229. MODULE_AUTHOR("liuzhiping ");
  230. MODULE_LICENSE("GPL");
  231. MODULE_ALIAS("platform:dhole2440 keyboard driver");

qt环境变量配置
export set QWS_KEYBOARD="LinuxInput:/dev/input/event1"
"event1"可能是event0,因驱动加载的先后顺序而不同。

以上驱动在给出的软硬件平台达到预期效果->"把键盘融入整个linux生态系统".
代码没整理,而且没实现去抖动。各位就将就这看。
期间参考了很多网上大牛的博客,在此一并感谢!!
又一个小土丘被我征服了,很有成就感,该执行下一步计划了!
但是还得先睡觉。
阅读(8122) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~