OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * LED driver for the RouterBOARD 750 |
||
3 | * |
||
4 | * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> |
||
5 | * |
||
6 | * This program is free software; you can redistribute it and/or modify |
||
7 | * it under the terms of the GNU General Public License version 2 as |
||
8 | * published by the Free Software Foundation. |
||
9 | * |
||
10 | */ |
||
11 | #include <linux/kernel.h> |
||
12 | #include <linux/module.h> |
||
13 | #include <linux/init.h> |
||
14 | #include <linux/platform_device.h> |
||
15 | #include <linux/leds.h> |
||
16 | #include <linux/slab.h> |
||
17 | |||
18 | #include <asm/mach-ath79/mach-rb750.h> |
||
19 | |||
20 | #define DRV_NAME "leds-rb750" |
||
21 | |||
22 | struct rb750_led_dev { |
||
23 | struct led_classdev cdev; |
||
24 | u32 mask; |
||
25 | int active_low; |
||
26 | void (*latch_change)(u32 clear, u32 set); |
||
27 | }; |
||
28 | |||
29 | struct rb750_led_drvdata { |
||
30 | struct rb750_led_dev *led_devs; |
||
31 | int num_leds; |
||
32 | }; |
||
33 | |||
34 | static inline struct rb750_led_dev *to_rbled(struct led_classdev *led_cdev) |
||
35 | { |
||
36 | return (struct rb750_led_dev *)container_of(led_cdev, |
||
37 | struct rb750_led_dev, cdev); |
||
38 | } |
||
39 | |||
40 | static void rb750_led_brightness_set(struct led_classdev *led_cdev, |
||
41 | enum led_brightness value) |
||
42 | { |
||
43 | struct rb750_led_dev *rbled = to_rbled(led_cdev); |
||
44 | int level; |
||
45 | |||
46 | level = (value == LED_OFF) ? 0 : 1; |
||
47 | level ^= rbled->active_low; |
||
48 | |||
49 | if (level) |
||
50 | rbled->latch_change(0, rbled->mask); |
||
51 | else |
||
52 | rbled->latch_change(rbled->mask, 0); |
||
53 | } |
||
54 | |||
55 | static int rb750_led_probe(struct platform_device *pdev) |
||
56 | { |
||
57 | struct rb750_led_platform_data *pdata; |
||
58 | struct rb750_led_drvdata *drvdata; |
||
59 | int ret = 0; |
||
60 | int i; |
||
61 | |||
62 | pdata = pdev->dev.platform_data; |
||
63 | if (!pdata) |
||
64 | return -EINVAL; |
||
65 | |||
66 | drvdata = kzalloc(sizeof(struct rb750_led_drvdata) + |
||
67 | sizeof(struct rb750_led_dev) * pdata->num_leds, |
||
68 | GFP_KERNEL); |
||
69 | if (!drvdata) |
||
70 | return -ENOMEM; |
||
71 | |||
72 | drvdata->num_leds = pdata->num_leds; |
||
73 | drvdata->led_devs = (struct rb750_led_dev *) &drvdata[1]; |
||
74 | |||
75 | for (i = 0; i < drvdata->num_leds; i++) { |
||
76 | struct rb750_led_dev *rbled = &drvdata->led_devs[i]; |
||
77 | struct rb750_led_data *led_data = &pdata->leds[i]; |
||
78 | |||
79 | rbled->cdev.name = led_data->name; |
||
80 | rbled->cdev.default_trigger = led_data->default_trigger; |
||
81 | rbled->cdev.brightness_set = rb750_led_brightness_set; |
||
82 | rbled->cdev.brightness = LED_OFF; |
||
83 | |||
84 | rbled->mask = led_data->mask; |
||
85 | rbled->active_low = !!led_data->active_low; |
||
86 | rbled->latch_change = pdata->latch_change; |
||
87 | |||
88 | ret = led_classdev_register(&pdev->dev, &rbled->cdev); |
||
89 | if (ret) |
||
90 | goto err; |
||
91 | } |
||
92 | |||
93 | platform_set_drvdata(pdev, drvdata); |
||
94 | return 0; |
||
95 | |||
96 | err: |
||
97 | for (i = i - 1; i >= 0; i--) |
||
98 | led_classdev_unregister(&drvdata->led_devs[i].cdev); |
||
99 | |||
100 | kfree(drvdata); |
||
101 | return ret; |
||
102 | } |
||
103 | |||
104 | static int rb750_led_remove(struct platform_device *pdev) |
||
105 | { |
||
106 | struct rb750_led_drvdata *drvdata; |
||
107 | int i; |
||
108 | |||
109 | drvdata = platform_get_drvdata(pdev); |
||
110 | for (i = 0; i < drvdata->num_leds; i++) |
||
111 | led_classdev_unregister(&drvdata->led_devs[i].cdev); |
||
112 | |||
113 | kfree(drvdata); |
||
114 | return 0; |
||
115 | } |
||
116 | |||
117 | static struct platform_driver rb750_led_driver = { |
||
118 | .probe = rb750_led_probe, |
||
119 | .remove = rb750_led_remove, |
||
120 | .driver = { |
||
121 | .name = DRV_NAME, |
||
122 | .owner = THIS_MODULE, |
||
123 | }, |
||
124 | }; |
||
125 | |||
126 | MODULE_ALIAS("platform:leds-rb750"); |
||
127 | |||
128 | static int __init rb750_led_init(void) |
||
129 | { |
||
130 | return platform_driver_register(&rb750_led_driver); |
||
131 | } |
||
132 | |||
133 | static void __exit rb750_led_exit(void) |
||
134 | { |
||
135 | platform_driver_unregister(&rb750_led_driver); |
||
136 | } |
||
137 | |||
138 | module_init(rb750_led_init); |
||
139 | module_exit(rb750_led_exit); |
||
140 | |||
141 | MODULE_DESCRIPTION(DRV_NAME); |
||
142 | MODULE_DESCRIPTION("LED driver for the RouterBOARD 750"); |
||
143 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); |
||
144 | MODULE_LICENSE("GPL v2"); |