歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

mini2440 MP3播放器

按鍵平台驅動:

platfrom_device.c:

  1. #include <linux/device.h>  
  2. #include <linux/string.h>  
  3. #include <linux/platform_device.h>  
  4. #include <linux/module.h>  
  5. #include <linux/kernel.h>  
  6. #include <linux/fs.h>  
  7. #include <linux/init.h>  
  8. #include <linux/delay.h>  
  9. #include <linux/poll.h>  
  10. #include <linux/irq.h>  
  11. #include <asm/irq.h>  
  12. #include <linux/interrupt.h>  
  13. #include <asm/uaccess.h>  
  14. #include <mach/regs-gpio.h>  
  15. #include <mach/hardware.h>  
  16. #include <linux/cdev.h>  
  17. #include <linux/miscdevice.h>  
  18. #include <linux/sched.h>  
  19. #include <linux/gpio.h>   
  20.   
  21. static struct resource key_resource[]=  
  22. {  
  23.     [0] = {  
  24.         .start = IRQ_EINT8,  
  25.         .end = IRQ_EINT8,  
  26.         .flags = IORESOURCE_IRQ,  
  27.     },  
  28.     [1] = {  
  29.         .start = IRQ_EINT11,  
  30.         .end = IRQ_EINT11,  
  31.         .flags = IORESOURCE_IRQ,  
  32.     },  
  33.     [2]= {  
  34.         .start = IRQ_EINT13,  
  35.         .end = IRQ_EINT13,  
  36.         .flags = IORESOURCE_IRQ,  
  37.     },  
  38.     [3] = {  
  39.         .start = IRQ_EINT14,  
  40.                 .end = IRQ_EINT14,  
  41.         .flags = IORESOURCE_IRQ,  
  42.     },  
  43.     [4] = {  
  44.         .start = IRQ_EINT15,  
  45.         .end = IRQ_EINT15,  
  46.         .flags = IORESOURCE_IRQ,  
  47.     },  
  48.     [5] = {  
  49.         .start = IRQ_EINT19,  
  50.         .end = IRQ_EINT19,  
  51.         .flags = IORESOURCE_IRQ,  
  52.     },  
  53. };  
  54.   
  55. struct platform_device *my_buttons_dev;  
  56.   
  57. static int __init platform_dev_init(void)  
  58. {  
  59.     int ret;  
  60.   
  61.     my_buttons_dev = platform_device_alloc("my_buttons", -1);  
  62.   
  63.     platform_device_add_resources(my_buttons_dev,key_resource,6);//添加資源一定要用該函數,不能使用對platform_device->resource幅值   
  64.                                                                 //否則會導致platform_device_unregister調用失敗,內核異常。   
  65.   
  66.     ret = platform_device_add(my_buttons_dev);  
  67.   
  68.     if(ret)  
  69.         platform_device_put(my_buttons_dev);  
  70.   
  71.     return ret;  
  72. }  
  73.   
  74. static void __exit platform_dev_exit(void)  
  75. {  
  76.     platform_device_unregister(my_buttons_dev);  
  77. }  
  78.   
  79. module_init(platform_dev_init);  
  80. module_exit(platform_dev_exit);  
  81.   
  82. MODULE_AUTHOR("Z-YP");  
  83. MODULE_LICENSE("GPL");  

platfrom_derver.c:

  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. #include <linux/sched.h>  
  17. #include <linux/gpio.h>  
  18.  
  19. #define DEVICE_NAME     "my_buttons"   
  20.   
  21. struct button_irq_desc {  
  22.     int irq;  
  23.     int pin;  
  24.     int pin_setting;  
  25.     int number;  
  26.     char *name;   
  27. };  
  28.   
  29. static struct button_irq_desc button_irqs [] = {  
  30.     {IRQ_EINT8 , S3C2410_GPG(0) ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},  
  31.     {IRQ_EINT11, S3C2410_GPG(3) ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},  
  32.     {IRQ_EINT13, S3C2410_GPG(5) ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},  
  33.     {IRQ_EINT14, S3C2410_GPG(6) ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},  
  34.     {IRQ_EINT15, S3C2410_GPG(7) ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},  
  35.     {IRQ_EINT19, S3C2410_GPG(11),  S3C2410_GPG11_EINT19, 5, "KEY5"},  
  36. };  
  37. static volatile char key_values [] = {'0''0''0''0''0''0'};  
  38.   
  39. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);  
  40.   
  41. static volatile int ev_press = 0;  
  42.   
  43.   
  44. static irqreturn_t buttons_interrupt(int irq, void *dev_id)  
  45. {  
  46.     struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;  
  47.     int down;  
  48.   
  49.     // udelay(0);   
  50.     down = !s3c2410_gpio_getpin(button_irqs->pin);  
  51.   
  52.     if (down != (key_values[button_irqs->number] & 1)) { // Changed   
  53.   
  54.     key_values[button_irqs->number] = '0' + down;      
  55.         ev_press = 1;  
  56.         wake_up_interruptible(&button_waitq);  
  57.     }  
  58.       
  59.     return IRQ_RETVAL(IRQ_HANDLED);  
  60. }  
  61.   
  62.   
  63. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)  
  64. {  
  65.     int i;  
  66.     int err = 0;  
  67.       
  68.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {  
  69.     if (button_irqs[i].irq < 0) {  
  70.         continue;  
  71.     }  
  72.         err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,   
  73.                           button_irqs[i].name, (void *)&button_irqs[i]);  
  74.         if (err)  
  75.             break;  
  76.     }  
  77.   
  78.     if (err) {  
  79.         i--;  
  80.         for (; i >= 0; i--) {  
  81.         if (button_irqs[i].irq < 0) {  
  82.         continue;  
  83.         }  
  84.         disable_irq(button_irqs[i].irq);  
  85.             free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);  
  86.         }  
  87.         return -EBUSY;  
  88.     }  
  89.   
  90.     ev_press = 1;  
  91.       
  92.     return 0;  
  93. }  
  94.   
  95.   
  96. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)  
  97. {  
  98.     int i;  
  99.       
  100.     for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {  
  101.     if (button_irqs[i].irq < 0) {  
  102.         continue;  
  103.     }  
  104.     free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);  
  105.     }  
  106.   
  107.     return 0;  
  108. }  
  109.   
  110.   
  111. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)  
  112. {  
  113.     unsigned long err;  
  114.   
  115.     if (!ev_press) {  
  116.     if (filp->f_flags & O_NONBLOCK)  
  117.         return -EAGAIN;  
  118.     else  
  119.         wait_event_interruptible(button_waitq, ev_press);  
  120.     }  
  121.       
  122.     ev_press = 0;  
  123.   
  124.     err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));  
  125.   
  126.     return err ? -EFAULT : min(sizeof(key_values), count);  
  127. }  
  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.   
  138.   
  139. static struct file_operations dev_fops = {  
  140.     .owner   =   THIS_MODULE,  
  141.     .open    =   s3c24xx_buttons_open,  
  142.     .release =   s3c24xx_buttons_close,   
  143.     .read    =   s3c24xx_buttons_read,  
  144.     .poll    =   s3c24xx_buttons_poll,  
  145. };  
  146.   
  147. static struct miscdevice misc = {  
  148.     .minor = MISC_DYNAMIC_MINOR,  
  149.     .name = "my_buttons",  
  150.     .fops = &dev_fops,  
  151. };  
  152.  
  153. #if 1   
  154. static int my_plat_probe(struct platform_device *dev)  
  155. {  
  156.     int ret,i;  
  157.     struct resource *plat_resource;  
  158.     struct platform_device *pdev = dev;  
  159.   
  160.     //printk("----");   
  161.     for(i = 0;i < 6;i++)  
  162.     {  
  163.         plat_resource = platform_get_resource(pdev,IORESOURCE_IRQ,i);  
  164.     if(plat_resource == NULL)  
  165.     {  
  166.         return -ENOENT;  
  167.     }  
  168.     button_irqs[i].irq = plat_resource->start;  
  169.     }  
  170.     ret = misc_register(&misc);  
  171.     if(ret)  
  172.     {  
  173.         return ret;  
  174.     }  
  175.     return 0;  
  176. }  
  177. #endif   
  178. static int my_plat_remove(struct platform_device *dev)  
  179. {  
  180.     printk("my platfrom device has removed.");  
  181.     misc_deregister(&misc);  
  182.     return 0;  
  183. }  
  184.   
  185. struct platform_driver my_buttons_drv = {  
  186.     .probe = my_plat_probe,  
  187.     .remove = my_plat_remove,  
  188.     .driver = {  
  189.         .owner = THIS_MODULE,  
  190.     .name = "my_buttons",  
  191.     },  
  192. };  
  193.   
  194. static int __init platform_drv_init(void)  
  195. {  
  196.     int ret;  
  197.     ret = platform_driver_register(&my_buttons_drv);  
  198.     printk (DEVICE_NAME"\tinitialized\n");  
  199.     return ret;  
  200. }  
  201.   
  202. static void __exit platform_drv_exit(void)  
  203. {  
  204.     platform_driver_unregister(&my_buttons_drv);  
  205. }  
  206.   
  207. module_init(platform_drv_init);  
  208. module_exit(platform_drv_exit);  
  209. MODULE_LICENSE("GPL");  
  210. MODULE_AUTHOR("Z-YP");  
Copyright © Linux教程網 All Rights Reserved