资源描述
platform_driver与file_operations两种方法开发led驱动
分类: 片内驱动开发(I2C、NAND Flash、LINUX内核) 片外驱动开发(tuner、demod、ca、e2prom)2011-08-08 13:141538人阅读 评论(0) 收藏 举报
filestructmodulectableoutput
下面是两个LED灯的驱动程序 一个用platform_driver 另一个用file_operations
[cpp] view plaincopy
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.");
展开阅读全文