• Button驱动


    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.   
    17. #include <linux/gpio.h>  
    18. #include <linux/sched.h>  
    19.   
    20. #define DEVICE_NAME     "buttons_liu"  
    21.   
    22.   
    23. //#define DEBUG   
    24. struct button_irq_desc {  
    25.     int irq;  
    26.     int pin;  
    27.     int pin_setting;  
    28.     int number;  
    29.     char *name;   
    30. };  
    31.   
    32. static struct button_irq_desc button_irqs [] = {  
    33.     {IRQ_EINT8 , S3C2410_GPG0 ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},  
    34.     {IRQ_EINT11, S3C2410_GPG3 ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},  
    35.     {IRQ_EINT13, S3C2410_GPG5 ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},  
    36.     {IRQ_EINT14, S3C2410_GPG6 ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},  
    37.     {IRQ_EINT15, S3C2410_GPG7 ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},  
    38.     {IRQ_EINT19, S3C2410_GPG11,  S3C2410_GPG11_EINT19, 5, "KEY5"},  
    39. };  

    40. //static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};  
    41. static int key_values = 0;  
    42.   
    43. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);  
    44.   
    45. static volatile int ev_press = 0;  
    46.   
    47.   
    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);  //按下down = 1 = !0 //松开down = 0 = !1  
    56.     if (!down) {   
    57.     //printk("rising ");  
    58.     key_values = button_irqs->number;  
    59.         ev_press = 1;                          //表示中断发生了  
    60.         wake_up_interruptible(&button_waitq);  
    61.     }  
    62.    else {  
    63.     //printk("falling ");  
    64.     ev_press = 0;  
    65.     return 0;                        // irqrequest_t,可能返回两个特殊的值:IRQ_NONE和IRQ_HANDLED.  
    66.    }                                 // 当中断处理程序检测到一个中断时,但该中断对应的设备并不是在注册处理函数期间指定的产生源时,返回IRQ_NONE;  
    67.     return IRQ_RETVAL(IRQ_HANDLED);  // 当中断处理程序被正确调用,且确实是它所对应的设备产生了中断时,返回IRQ_HANDLED    
    68. }  
    69.   
    70.   
    71. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)  
    72. {  
    73.     int i;  
    74.     int err = 0;  
    75.       
    76.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {  
    77.     if (button_irqs[i].irq < 0) {  
    78.         continue;  
    79.     }  
    80.   
    81.     /* 设置中断触发方式 IRQ_TYPE_EDGE_FALLING,IRQ_TYPE_EDGE_RISING,IRQ_TYPE_EDGE_BOTH ;我们这里设置为上升沿触发*/  
    82.         //err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,   
    83.         //                  button_irqs[i].name, (void *)&button_irqs[i]);  
    84.         err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_RISING,   
    85.                           button_irqs[i].name, (void *)&button_irqs[i]);  
    86.         if (err)  
    87.             break;               //request_irq 返回0表示成功。  
    88.     }  
    89.   
    90.     if (err) {  
    91.         i--;  
    92.         for (; i >= 0; i--) {  
    93.         if (button_irqs[i].irq < 0) {  
    94.         continue;  
    95.         }  
    96.         disable_irq(button_irqs[i].irq);  
    97.             free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);  
    98.         }  
    99.         return -EBUSY;  
    100.     }  
    101.   
    102.     ev_press = 0;  
    103.       
    104.     return 0;  
    105. }  
    106.   
    107.   
    108. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)  
    109. {  
    110.     int i;  
    111.       
    112.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {  
    113.     if (button_irqs[i].irq < 0) {  
    114.         continue;  
    115.     }  
    116.     free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);  
    117.     }  
    118.   
    119.     return 0;  
    120. }  
    121.   
    122.   
    123. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)  
    124. {  
    125.     unsigned long err;  
    126.     //int i=0;  
    127.     if (!ev_press) {  
    128.     if (filp->f_flags & O_NONBLOCK)  
    129.         return -EAGAIN;  
    130.     else  
    131.         wait_event_interruptible(button_waitq, ev_press);  
    132.     }  
    133.     if(count != sizeof key_values)  
    134.     return -EINVAL;  
    135.     ev_press = 0;  
    136.     err = copy_to_user(buff, &key_values, sizeof(key_values));  
    137.     return sizeof(key_values);  
    138. }  
    139.   
    140. static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)  
    141. {  
    142.     unsigned int mask = 0;  
    143.     poll_wait(file, &button_waitq, wait);  
    144.     if (ev_press)  
    145.         mask |= POLLIN | POLLRDNORM;  
    146.     return mask;  
    147. }  
    148.   
    149.   
    150. static struct file_operations dev_fops = {  
    151.     .owner   =   THIS_MODULE,  
    152.     .open    =   s3c24xx_buttons_open,  
    153.     .release =   s3c24xx_buttons_close,   
    154.     .read    =   s3c24xx_buttons_read,  
    155.     .poll    =   s3c24xx_buttons_poll,  
    156. };  
    157.   
    158. static struct miscdevice misc = {  
    159.     .minor = MISC_DYNAMIC_MINOR,  
    160.     .name = DEVICE_NAME,  
    161.     .fops = &dev_fops,  
    162. };  
    163.   
    164. static int __init dev_init(void)  
    165. {  
    166.     int ret;  
    167.   
    168.     ret = misc_register(&misc);  
    169. #ifdef DEBUG  
    170.     printk("debug test ");//ykz  
    171. #endif  
    172.     printk (DEVICE_NAME" initialized ");  
    173.   
    174.     return ret;  
    175. }  
    176.   
    177. static void __exit dev_exit(void)  
    178. {  
    179.     misc_deregister(&misc);  
    180. }  
    181.   
    182. module_init(dev_init);  
    183. module_exit(dev_exit);  
    184. MODULE_LICENSE("GPL");  
    185. MODULE_AUTHOR("FriendlyARM Inc.");

     request_irq(unsignedintirq,   irq_handler_thandler,     unsignedlongflags,     constchar*name,      void*dev)

     发生对应于第 1个参数 irq 的中断时,则调用第 2 个参数handler 为要注册的中断服务函数(也就是把 handler() 中断服务函数注册到内核中 )。

     第 3 个参数 flags 指定了快速中断或中断共享等中断处理属性

     第 4 个参数 name,通常是设备驱动程序的名称

     第 5 个参数 dev_id 中断名称 可作为共享中断时的中断区别参数,也可以用来指定中断服务函数需要参考的数据地址。建议将设备结构指针作为dev_id参数

  • 相关阅读:
    DOM event beforeload
    有关点击付费的十大失误-转载
    DOM 事件DOMContentLoaded
    Git 系列之四:Git 进阶功能转载
    Qt webkit中单独编译JavaScriptCore
    搜索知识与技巧集锦转载
    webkit中DOM 事件有多少
    Git 系列之三:Windows 下 Git 配置与使用指南转载
    简历:第一章:技术亮点如何写
    实战:第十三章:工作中熬夜加班学到的
  • 原文地址:https://www.cnblogs.com/liuchengchuxiao/p/4111368.html
Copyright © 2020-2023  润新知