platform_driver与file_operations两种方法开发led驱动

下面是两个LED灯的驱动程序 一个用platform_driver 另一个用file_operations

[cpp]  view plain copy
  1. #include <linux/kernel.h>  
  2. #include <linux/init.h>  
  3. #include <linux/platform_device.h>  
  4. #include <linux/leds.h>  
  5.   
  6. #include <mach/hardware.h>  
  7. #include <mach/regs-gpio.h>  
  8. #include <mach/leds-gpio.h>  
  9.   
  10. /* our context */  
  11.   
  12. struct s3c24xx_gpio_led {  
  13. struct led_classdev cdev;  
  14. struct s3c24xx_led_platdata *pdata;  
  15. };  
  16.   
  17. static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev)  
  18. {  
  19. return platform_get_drvdata(dev);  
  20. }  
  21.   
  22. static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev)  
  23. {  
  24. return container_of(led_cdev, struct s3c24xx_gpio_led, cdev);  
  25. }  
  26.   
  27. static void s3c24xx_led_set(struct led_classdev *led_cdev,  
  28. enum led_brightness value)  
  29. {  
  30. struct s3c24xx_gpio_led *led = to_gpio(led_cdev);  
  31. struct s3c24xx_led_platdata *pd = led->pdata;  
  32.   
  33. /* there will be a short delay between setting the output and 
  34. * going from output to input when using tristate. */  
  35.   
  36. s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^  
  37. (pd->flags & S3C24XX_LEDF_ACTLOW));  
  38.   
  39. if (pd->flags & S3C24XX_LEDF_TRISTATE)  
  40. s3c2410_gpio_cfgpin(pd->gpio,  
  41. value ? S3C2410_GPIO_OUTPUT : S3C2410_GPIO_INPUT);  
  42.   
  43. }  
  44.   
  45. static int s3c24xx_led_remove(struct platform_device *dev)  
  46. {  
  47. struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);  
  48.   
  49. led_classdev_unregister(&led->cdev);  
  50. kfree(led);  
  51.   
  52. return 0;  
  53. }  
  54.   
  55. static int s3c24xx_led_probe(struct platform_device *dev)  
  56. {  
  57. struct s3c24xx_led_platdata *pdata = dev->dev.platform_data;  
  58. struct s3c24xx_gpio_led *led;  
  59. int ret;  
  60.   
  61. led = kzalloc(sizeof(struct s3c24xx_gpio_led), GFP_KERNEL);  
  62. if (led == NULL) {  
  63. dev_err(&dev->dev, "No memory for device\n");  
  64. return -ENOMEM;  
  65. }  
  66.   
  67. platform_set_drvdata(dev, led);  
  68.   
  69. led->cdev.brightness_set = s3c24xx_led_set;  
  70. led->cdev.default_trigger = pdata->def_trigger;  
  71. led->cdev.name = pdata->name;  
  72.   
  73. led->pdata = pdata;  
  74.   
  75. /* no point in having a pull-up if we are always driving */  
  76.   
  77. if (pdata->flags & S3C24XX_LEDF_TRISTATE) {  
  78. s3c2410_gpio_setpin(pdata->gpio, 0);  
  79. s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_INPUT);  
  80. else {  
  81. s3c2410_gpio_pullup(pdata->gpio, 0);  
  82. s3c2410_gpio_setpin(pdata->gpio, 0);  
  83. s3c2410_gpio_cfgpin(pdata->gpio, S3C2410_GPIO_OUTPUT);  
  84. }  
  85.   
  86. /* register our new led device */  
  87.   
  88. ret = led_classdev_register(&dev->dev, &led->cdev);  
  89. if (ret < 0) {  
  90. dev_err(&dev->dev, "led_classdev_register failed\n");  
  91. goto exit_err1;  
  92. }  
  93.   
  94. return 0;  
  95.   
  96.  exit_err1:  
  97. kfree(led);  
  98. return ret;  
  99. }  
  100.   
  101.   
  102. #ifdef CONFIG_PM  
  103. static int s3c24xx_led_suspend(struct platform_device *dev, pm_message_t state)  
  104. {  
  105. struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);  
  106.   
  107. led_classdev_suspend(&led->cdev);  
  108. return 0;  
  109. }  
  110.   
  111. static int s3c24xx_led_resume(struct platform_device *dev)  
  112. {  
  113. struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);  
  114.   
  115. led_classdev_resume(&led->cdev);  
  116. return 0;  
  117. }  
  118. #else  
  119. #define s3c24xx_led_suspend NULL  
  120. #define s3c24xx_led_resume NULL  
  121. #endif  
  122.   
  123. static struct platform_driver s3c24xx_led_driver = {  
  124. .probe = s3c24xx_led_probe,  
  125. .remove = s3c24xx_led_remove,  
  126. .suspend = s3c24xx_led_suspend,  
  127. .resume = s3c24xx_led_resume,  
  128. .driver = {  
  129. .name = "s3c24xx_led",  
  130. .owner = THIS_MODULE,  
  131. },  
  132. };  
  133.   
  134. static int __init s3c24xx_led_init(void)  
  135. {  
  136. return platform_driver_register(&s3c24xx_led_driver);  
  137. }  
  138.   
  139. static void __exit s3c24xx_led_exit(void)  
  140. {  
  141. platform_driver_unregister(&s3c24xx_led_driver);  
  142. }  
  143.   
  144. module_init(s3c24xx_led_init);  
  145. module_exit(s3c24xx_led_exit);  
  146.   
  147. MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");  
  148. MODULE_DESCRIPTION("S3C24XX LED driver");  
  149. MODULE_LICENSE("GPL");  
  150. MODULE_ALIAS("platform:s3c24xx_led");  
  151.   
  152.   
  153.   
  154.   
  155. 另一个如下:  
  156.   
  157.   #include <asm/uaccess.h>   
  158.   #include <asm/atomic.h>   
  159.   #include <asm/unistd.h>   
  160.   
  161.   #define DEVICE_NAME "leds"   
  162.   
  163.   static unsigned long led_table [] = {   
  164.   S3C2410_GPB5,   
  165.   
  166.   S3C2410_GPB6,   
  167.   S3C2410_GPB7,   
  168.   S3C2410_GPB8,   
  169. };   
  170.   
  171. static unsigned int led_cfg_table [] = {   
  172.   S3C2410_GPB5_OUTP,   
  173.   
  174.   S3C2410_GPB6_OUTP,   
  175.   S3C2410_GPB7_OUTP,   
  176.   S3C2410_GPB8_OUTP,   
  177. };   
  178.   
  179. static int sbc2440_leds_ioctl(   
  180.   struct inode *inode,   
  181.   struct file *file,   
  182.   unsigned int cmd,   
  183.   unsigned long arg)   
  184. {   
  185.   switch(cmd) {   
  186.   case 0:   
  187.   case 1:   
  188.   if (arg > 4) {   
  189.   return -EINVAL;   
  190.   }   
  191.   s3c2410_gpio_setpin(led_table[arg], !cmd);   
  192.   return 0;   
  193.   default:   
  194.   return -EINVAL;   
  195.   }   
  196. }   
  197.   
  198. static struct file_operations dev_fops = {   
  199.   .owner = THIS_MODULE,   
  200.   .ioctl = sbc2440_leds_ioctl,   
  201. };   
  202.   
  203. static struct miscdevice misc = {   
  204.   .minor = MISC_DYNAMIC_MINOR,   
  205.   .name = DEVICE_NAME,   
  206.   .fops = &dev_fops,   
  207. };   
  208.   
  209. static int __init dev_init(void)   
  210.   {   
  211.   int ret;   
  212.   
  213.   int i;   
  214.   
  215.   for (i = 0; i < 4; i++) {   
  216.   s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);   
  217.   s3c2410_gpio_setpin(led_table[i], 0);   
  218.   }   
  219.   
  220.   ret = misc_register(&misc);   
  221.   
  222.   printk (DEVICE_NAME"\tinitialized\n");   
  223.   
  224.   return ret;   
  225. }   
  226.   
  227. static void __exit dev_exit(void)   
  228. {   
  229.   misc_deregister(&misc);   
  230. }   
  231.   
  232. module_init(dev_init);   
  233. module_exit(dev_exit);   
  234. MODULE_LICENSE("GPL");   
  235. MODULE_AUTHOR("FriendlyARM Inc.");    
原文地址 http://blog.csdn.net/sdustliyang/article/details/6668929 
后记:仔细看两种驱动结构的区别,这里有一个问题我想问s3c24xx_led_set 在platform driver驱动中是如何被上层调用的?file 形式的驱动很明显,但是platform的驱动太蛋疼了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值