Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7688270
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2011-02-24 11:16:05

  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/init.h>
  5. #include <linux/delay.h>
  6. #include <linux/poll.h>
  7. #include <linux/irq.h>
  8. #include <asm/irq.h>
  9. #include <linux/interrupt.h>
  10. #include <asm/uaccess.h>
  11. #include <mach/regs-gpio.h>
  12. #include <mach/hardware.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/cdev.h>
  15. #include <linux/miscdevice.h>

  16. #define DEVICE_NAME "buttons"

  17. //#define DEBUG

  18. struct button_irq_desc {
  19.     int irq;
  20.     int pin;
  21.     int pin_setting;
  22.     int number;
  23.     char *name;    
  24. };

  25. #if !defined (CONFIG_QQ2440_BUTTONS)
  26. static struct button_irq_desc button_irqs [] = {
  27.     {IRQ_EINT8 , S3C2410_GPG0 , S3C2410_GPG0_EINT8 , 0, "KEY0"},
  28.     {IRQ_EINT11, S3C2410_GPG3 , S3C2410_GPG3_EINT11 , 1, "KEY1"},
  29.     {IRQ_EINT13, S3C2410_GPG5 , S3C2410_GPG5_EINT13 , 2, "KEY2"},
  30.     {IRQ_EINT14, S3C2410_GPG6 , S3C2410_GPG6_EINT14 , 3, "KEY3"},
  31.     {IRQ_EINT15, S3C2410_GPG7 , S3C2410_GPG7_EINT15 , 4, "KEY4"},
  32.     {IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG11_EINT19, 5, "KEY5"},
  33. };
  34. #else /* means QQ */
  35. static struct button_irq_desc button_irqs [] = {
  36.     {IRQ_EINT19, S3C2410_GPG11, S3C2410_GPG11_EINT19, 0, "KEY0"},
  37.     {IRQ_EINT11, S3C2410_GPG3, S3C2410_GPG3_EINT11, 1, "KEY1"},
  38.     {IRQ_EINT2, S3C2410_GPF2, S3C2410_GPF2_EINT2, 2, "KEY2"},
  39.     {IRQ_EINT0, S3C2410_GPF0, S3C2410_GPF0_EINT0, 3, "KEY3"},
  40.     { -1, -1, -1, 4, "KEY4"},
  41.     { -1, -1, -1, 5, "KEY5"},
  42. };
  43. #endif
  44. //static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};

  45. static int key_values = 0;

  46. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

  47. static volatile int ev_press = 0;


  48. static irqreturn_t buttons_interrupt(int irq, void *dev_id)
  49. {
  50.     struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
  51.     int down;
  52.     // udelay(0);

  53.     
  54.     /*上升沿触发,GPIO DAT 应该为非0 的数*/
  55.     down = !s3c2410_gpio_getpin(button_irqs->pin);
  56.     if (!down) {
  57.     //printk("rising\n");

  58.     key_values = button_irqs->number;
  59.         ev_press = 1;
  60.         wake_up_interruptible(&button_waitq);
  61.     }
  62.    else {
  63.     //printk("falling\n");

  64.     ev_press = 0;
  65.     return 0;
  66.    }
  67.     return IRQ_RETVAL(IRQ_HANDLED);
  68. }


  69. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
  70. {
  71.     int i;
  72.     int err = 0;
  73.     
  74.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
  75.         if (button_irqs[i].irq < 0) {
  76.             continue;
  77.         }

  78.      /* 设置中断触发方式 IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH ;我们这里设置为上升沿触发*/
  79.         //err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,

  80.         // button_irqs[i].name, (void *)&button_irqs[i]);

  81.         err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_RISING,
  82.                           button_irqs[i].name, (void *)&button_irqs[i]);
  83.         if (err)
  84.             break;
  85.     }

  86.     if (err) {
  87.         i--;
  88.         for (; i >= 0; i--) {
  89.             if (button_irqs[i].irq < 0) {
  90.             continue;
  91.             }
  92.             disable_irq(button_irqs[i].irq);
  93.                 free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
  94.         }
  95.         return -EBUSY;
  96.     }

  97.     ev_press = 0;
  98.     
  99.     return 0;
  100. }


  101. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)
  102. {
  103.     int i;
  104.     
  105.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
  106.     if (button_irqs[i].irq < 0) {
  107.      continue;
  108.     }
  109.     free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
  110.     }

  111.     return 0;
  112. }


  113. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
  114. {
  115.     unsigned long err;
  116.     //int i=0;

  117.     if (!ev_press) {
  118.         if (filp->f_flags & O_NONBLOCK)
  119.             return -EAGAIN;
  120.         else
  121.             wait_event_interruptible(button_waitq, ev_press);
  122.     }
  123.     if(count != sizeof key_values)
  124.     return -EINVAL;
  125.     ev_press = 0;
  126.     err = copy_to_user(buff, &key_values, sizeof(key_values));
  127.     return sizeof(key_values);
  128. }

  129. static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
  130. {
  131.     unsigned int mask = 0;
  132.     poll_wait(file, &button_waitq, wait);
  133.     if (ev_press)
  134.         mask |= POLLIN | POLLRDNORM;
  135.     return mask;
  136. }


  137. static struct file_operations dev_fops = {
  138.     .owner = THIS_MODULE,
  139.     .open = s3c24xx_buttons_open,
  140.     .release = s3c24xx_buttons_close,
  141.     .read = s3c24xx_buttons_read,
  142.     .poll = s3c24xx_buttons_poll,
  143. };

  144. static struct miscdevice misc = {
  145.     .minor = MISC_DYNAMIC_MINOR,
  146.     .name = DEVICE_NAME,
  147.     .fops = &dev_fops,
  148. };

  149. static int __init dev_init(void)
  150. {
  151.     int ret;

  152.     ret = misc_register(&misc);
  153. #ifdef DEBUG
  154.     printk("debug test\n");//ykz

  155. #endif
  156.     printk (DEVICE_NAME"\tinitialized\n");

  157.     return ret;
  158. }

  159. static void __exit dev_exit(void)
  160. {
  161.     misc_deregister(&misc);
  162. }

  163. module_init(dev_init);
  164. module_exit(dev_exit);
  165. MODULE_LICENSE("GPL");
  166. MODULE_AUTHOR("FriendlyARM Inc.");
阅读(1140) | 评论(0) | 转发(2) |
0

上一篇:SDK-H264 应用程序

下一篇:mp3播放处理程序

给主人留下些什么吧!~~