歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> mini2440 MP3播放器

mini2440 MP3播放器

日期:2017/3/1 10:11:59   编辑:Linux編程

按鍵平台驅動:

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. static struct resource key_resource[]=
  21. {
  22. [0] = {
  23. .start = IRQ_EINT8,
  24. .end = IRQ_EINT8,
  25. .flags = IORESOURCE_IRQ,
  26. },
  27. [1] = {
  28. .start = IRQ_EINT11,
  29. .end = IRQ_EINT11,
  30. .flags = IORESOURCE_IRQ,
  31. },
  32. [2]= {
  33. .start = IRQ_EINT13,
  34. .end = IRQ_EINT13,
  35. .flags = IORESOURCE_IRQ,
  36. },
  37. [3] = {
  38. .start = IRQ_EINT14,
  39. .end = IRQ_EINT14,
  40. .flags = IORESOURCE_IRQ,
  41. },
  42. [4] = {
  43. .start = IRQ_EINT15,
  44. .end = IRQ_EINT15,
  45. .flags = IORESOURCE_IRQ,
  46. },
  47. [5] = {
  48. .start = IRQ_EINT19,
  49. .end = IRQ_EINT19,
  50. .flags = IORESOURCE_IRQ,
  51. },
  52. };
  53. struct platform_device *my_buttons_dev;
  54. static int __init platform_dev_init(void)
  55. {
  56. int ret;
  57. my_buttons_dev = platform_device_alloc("my_buttons", -1);
  58. platform_device_add_resources(my_buttons_dev,key_resource,6);//添加資源一定要用該函數,不能使用對platform_device->resource幅值
  59. //否則會導致platform_device_unregister調用失敗,內核異常。
  60. ret = platform_device_add(my_buttons_dev);
  61. if(ret)
  62. platform_device_put(my_buttons_dev);
  63. return ret;
  64. }
  65. static void __exit platform_dev_exit(void)
  66. {
  67. platform_device_unregister(my_buttons_dev);
  68. }
  69. module_init(platform_dev_init);
  70. module_exit(platform_dev_exit);
  71. MODULE_AUTHOR("Z-YP");
  72. 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. #define DEVICE_NAME "my_buttons"
  19. struct button_irq_desc {
  20. int irq;
  21. int pin;
  22. int pin_setting;
  23. int number;
  24. char *name;
  25. };
  26. static struct button_irq_desc button_irqs [] = {
  27. {IRQ_EINT8 , S3C2410_GPG(0) , S3C2410_GPG0_EINT8 , 0, "KEY0"},
  28. {IRQ_EINT11, S3C2410_GPG(3) , S3C2410_GPG3_EINT11 , 1, "KEY1"},
  29. {IRQ_EINT13, S3C2410_GPG(5) , S3C2410_GPG5_EINT13 , 2, "KEY2"},
  30. {IRQ_EINT14, S3C2410_GPG(6) , S3C2410_GPG6_EINT14 , 3, "KEY3"},
  31. {IRQ_EINT15, S3C2410_GPG(7) , S3C2410_GPG7_EINT15 , 4, "KEY4"},
  32. {IRQ_EINT19, S3C2410_GPG(11), S3C2410_GPG11_EINT19, 5, "KEY5"},
  33. };
  34. static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};
  35. static DECLARE_WAIT_QUEUE_HEAD(button_waitq);
  36. static volatile int ev_press = 0;
  37. static irqreturn_t buttons_interrupt(int irq, void *dev_id)
  38. {
  39. struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
  40. int down;
  41. // udelay(0);
  42. down = !s3c2410_gpio_getpin(button_irqs->pin);
  43. if (down != (key_values[button_irqs->number] & 1)) { // Changed
  44. key_values[button_irqs->number] = '0' + down;
  45. ev_press = 1;
  46. wake_up_interruptible(&button_waitq);
  47. }
  48. return IRQ_RETVAL(IRQ_HANDLED);
  49. }
  50. static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
  51. {
  52. int i;
  53. int err = 0;
  54. for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
  55. if (button_irqs[i].irq < 0) {
  56. continue;
  57. }
  58. err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,
  59. button_irqs[i].name, (void *)&button_irqs[i]);
  60. if (err)
  61. break;
  62. }
  63. if (err) {
  64. i--;
  65. for (; i >= 0; i--) {
  66. if (button_irqs[i].irq < 0) {
  67. continue;
  68. }
  69. disable_irq(button_irqs[i].irq);
  70. free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
  71. }
  72. return -EBUSY;
  73. }
  74. ev_press = 1;
  75. return 0;
  76. }
  77. static int s3c24xx_buttons_close(struct inode *inode, struct file *file)
  78. {
  79. int i;
  80. for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
  81. if (button_irqs[i].irq < 0) {
  82. continue;
  83. }
  84. free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
  85. }
  86. return 0;
  87. }
  88. static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
  89. {
  90. unsigned long err;
  91. if (!ev_press) {
  92. if (filp->f_flags & O_NONBLOCK)
  93. return -EAGAIN;
  94. else
  95. wait_event_interruptible(button_waitq, ev_press);
  96. }
  97. ev_press = 0;
  98. err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));
  99. return err ? -EFAULT : min(sizeof(key_values), count);
  100. }
  101. static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
  102. {
  103. unsigned int mask = 0;
  104. poll_wait(file, &button_waitq, wait);
  105. if (ev_press)
  106. mask |= POLLIN | POLLRDNORM;
  107. return mask;
  108. }
  109. static struct file_operations dev_fops = {
  110. .owner = THIS_MODULE,
  111. .open = s3c24xx_buttons_open,
  112. .release = s3c24xx_buttons_close,
  113. .read = s3c24xx_buttons_read,
  114. .poll = s3c24xx_buttons_poll,
  115. };
  116. static struct miscdevice misc = {
  117. .minor = MISC_DYNAMIC_MINOR,
  118. .name = "my_buttons",
  119. .fops = &dev_fops,
  120. };
  121. #if 1
  122. static int my_plat_probe(struct platform_device *dev)
  123. {
  124. int ret,i;
  125. struct resource *plat_resource;
  126. struct platform_device *pdev = dev;
  127. //printk("----");
  128. for(i = 0;i < 6;i++)
  129. {
  130. plat_resource = platform_get_resource(pdev,IORESOURCE_IRQ,i);
  131. if(plat_resource == NULL)
  132. {
  133. return -ENOENT;
  134. }
  135. button_irqs[i].irq = plat_resource->start;
  136. }
  137. ret = misc_register(&misc);
  138. if(ret)
  139. {
  140. return ret;
  141. }
  142. return 0;
  143. }
  144. #endif
  145. static int my_plat_remove(struct platform_device *dev)
  146. {
  147. printk("my platfrom device has removed.");
  148. misc_deregister(&misc);
  149. return 0;
  150. }
  151. struct platform_driver my_buttons_drv = {
  152. .probe = my_plat_probe,
  153. .remove = my_plat_remove,
  154. .driver = {
  155. .owner = THIS_MODULE,
  156. .name = "my_buttons",
  157. },
  158. };
  159. static int __init platform_drv_init(void)
  160. {
  161. int ret;
  162. ret = platform_driver_register(&my_buttons_drv);
  163. printk (DEVICE_NAME"\tinitialized\n");
  164. return ret;
  165. }
  166. static void __exit platform_drv_exit(void)
  167. {
  168. platform_driver_unregister(&my_buttons_drv);
  169. }
  170. module_init(platform_drv_init);
  171. module_exit(platform_drv_exit);
  172. MODULE_LICENSE("GPL");
  173. MODULE_AUTHOR("Z-YP");
Copyright © Linux教程網 All Rights Reserved