aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/backlight
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@rpsys.net>2006-03-31 05:31:49 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-31 15:19:00 -0500
commit6ca017658b1f902c9bba2cc1017e301581f7728d (patch)
tree9180b3923d4f6ef09c11d7f7386024f391508759 /drivers/video/backlight
parent9b0e1c5dd2941aec566047e10a5cc929ca7f7d4f (diff)
[PATCH] backlight: Backlight Class Improvements
Backlight class attributes are currently easy to implement incorrectly. Moving certain handling into the backlight core prevents this whilst at the same time makes the drivers simpler and consistent. The following changes are included: The brightness attribute only sets and reads the brightness variable in the backlight_properties structure. The power attribute only sets and reads the power variable in the backlight_properties structure. Any framebuffer blanking events change a variable fb_blank in the backlight_properties structure. The backlight driver has only two functions to implement. One function is called when any of the above properties change (to update the backlight brightness), the second is called to return the current backlight brightness value. A new attribute "actual_brightness" is added to return this brightness as determined by the driver having combined all the above factors (and any driver/device specific factors). Additionally, the backlight core takes care of checking the maximum brightness is not exceeded and of turning off the backlight before device removal. The corgi backlight driver is updated to reflect these changes. Signed-off-by: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/video/backlight')
-rw-r--r--drivers/video/backlight/backlight.c84
-rw-r--r--drivers/video/backlight/corgi_bl.c99
2 files changed, 92 insertions, 91 deletions
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 151fda8dded0..334b1db1bd7c 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -16,14 +16,12 @@
16 16
17static ssize_t backlight_show_power(struct class_device *cdev, char *buf) 17static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
18{ 18{
19 int rc; 19 int rc = -ENXIO;
20 struct backlight_device *bd = to_backlight_device(cdev); 20 struct backlight_device *bd = to_backlight_device(cdev);
21 21
22 down(&bd->sem); 22 down(&bd->sem);
23 if (likely(bd->props && bd->props->get_power)) 23 if (likely(bd->props))
24 rc = sprintf(buf, "%d\n", bd->props->get_power(bd)); 24 rc = sprintf(buf, "%d\n", bd->props->power);
25 else
26 rc = -ENXIO;
27 up(&bd->sem); 25 up(&bd->sem);
28 26
29 return rc; 27 return rc;
@@ -31,7 +29,7 @@ static ssize_t backlight_show_power(struct class_device *cdev, char *buf)
31 29
32static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count) 30static ssize_t backlight_store_power(struct class_device *cdev, const char *buf, size_t count)
33{ 31{
34 int rc, power; 32 int rc = -ENXIO, power;
35 char *endp; 33 char *endp;
36 struct backlight_device *bd = to_backlight_device(cdev); 34 struct backlight_device *bd = to_backlight_device(cdev);
37 35
@@ -40,12 +38,13 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
40 return -EINVAL; 38 return -EINVAL;
41 39
42 down(&bd->sem); 40 down(&bd->sem);
43 if (likely(bd->props && bd->props->set_power)) { 41 if (likely(bd->props)) {
44 pr_debug("backlight: set power to %d\n", power); 42 pr_debug("backlight: set power to %d\n", power);
45 bd->props->set_power(bd, power); 43 bd->props->power = power;
44 if (likely(bd->props->update_status))
45 bd->props->update_status(bd);
46 rc = count; 46 rc = count;
47 } else 47 }
48 rc = -ENXIO;
49 up(&bd->sem); 48 up(&bd->sem);
50 49
51 return rc; 50 return rc;
@@ -53,14 +52,12 @@ static ssize_t backlight_store_power(struct class_device *cdev, const char *buf,
53 52
54static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf) 53static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
55{ 54{
56 int rc; 55 int rc = -ENXIO;
57 struct backlight_device *bd = to_backlight_device(cdev); 56 struct backlight_device *bd = to_backlight_device(cdev);
58 57
59 down(&bd->sem); 58 down(&bd->sem);
60 if (likely(bd->props && bd->props->get_brightness)) 59 if (likely(bd->props))
61 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd)); 60 rc = sprintf(buf, "%d\n", bd->props->brightness);
62 else
63 rc = -ENXIO;
64 up(&bd->sem); 61 up(&bd->sem);
65 62
66 return rc; 63 return rc;
@@ -68,7 +65,7 @@ static ssize_t backlight_show_brightness(struct class_device *cdev, char *buf)
68 65
69static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count) 66static ssize_t backlight_store_brightness(struct class_device *cdev, const char *buf, size_t count)
70{ 67{
71 int rc, brightness; 68 int rc = -ENXIO, brightness;
72 char *endp; 69 char *endp;
73 struct backlight_device *bd = to_backlight_device(cdev); 70 struct backlight_device *bd = to_backlight_device(cdev);
74 71
@@ -77,12 +74,18 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
77 return -EINVAL; 74 return -EINVAL;
78 75
79 down(&bd->sem); 76 down(&bd->sem);
80 if (likely(bd->props && bd->props->set_brightness)) { 77 if (likely(bd->props)) {
81 pr_debug("backlight: set brightness to %d\n", brightness); 78 if (brightness > bd->props->max_brightness)
82 bd->props->set_brightness(bd, brightness); 79 rc = -EINVAL;
83 rc = count; 80 else {
84 } else 81 pr_debug("backlight: set brightness to %d\n",
85 rc = -ENXIO; 82 brightness);
83 bd->props->brightness = brightness;
84 if (likely(bd->props->update_status))
85 bd->props->update_status(bd);
86 rc = count;
87 }
88 }
86 up(&bd->sem); 89 up(&bd->sem);
87 90
88 return rc; 91 return rc;
@@ -90,14 +93,26 @@ static ssize_t backlight_store_brightness(struct class_device *cdev, const char
90 93
91static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf) 94static ssize_t backlight_show_max_brightness(struct class_device *cdev, char *buf)
92{ 95{
93 int rc; 96 int rc = -ENXIO;
94 struct backlight_device *bd = to_backlight_device(cdev); 97 struct backlight_device *bd = to_backlight_device(cdev);
95 98
96 down(&bd->sem); 99 down(&bd->sem);
97 if (likely(bd->props)) 100 if (likely(bd->props))
98 rc = sprintf(buf, "%d\n", bd->props->max_brightness); 101 rc = sprintf(buf, "%d\n", bd->props->max_brightness);
99 else 102 up(&bd->sem);
100 rc = -ENXIO; 103
104 return rc;
105}
106
107static ssize_t backlight_show_actual_brightness(struct class_device *cdev,
108 char *buf)
109{
110 int rc = -ENXIO;
111 struct backlight_device *bd = to_backlight_device(cdev);
112
113 down(&bd->sem);
114 if (likely(bd->props && bd->props->get_brightness))
115 rc = sprintf(buf, "%d\n", bd->props->get_brightness(bd));
101 up(&bd->sem); 116 up(&bd->sem);
102 117
103 return rc; 118 return rc;
@@ -123,7 +138,10 @@ static struct class backlight_class = {
123 138
124static struct class_device_attribute bl_class_device_attributes[] = { 139static struct class_device_attribute bl_class_device_attributes[] = {
125 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power), 140 DECLARE_ATTR(power, 0644, backlight_show_power, backlight_store_power),
126 DECLARE_ATTR(brightness, 0644, backlight_show_brightness, backlight_store_brightness), 141 DECLARE_ATTR(brightness, 0644, backlight_show_brightness,
142 backlight_store_brightness),
143 DECLARE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness,
144 NULL),
127 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), 145 DECLARE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL),
128}; 146};
129 147
@@ -144,8 +162,12 @@ static int fb_notifier_callback(struct notifier_block *self,
144 bd = container_of(self, struct backlight_device, fb_notif); 162 bd = container_of(self, struct backlight_device, fb_notif);
145 down(&bd->sem); 163 down(&bd->sem);
146 if (bd->props) 164 if (bd->props)
147 if (!bd->props->check_fb || bd->props->check_fb(evdata->info)) 165 if (!bd->props->check_fb ||
148 bd->props->set_power(bd, *(int *)evdata->data); 166 bd->props->check_fb(evdata->info)) {
167 bd->props->fb_blank = *(int *)evdata->data;
168 if (likely(bd->props && bd->props->update_status))
169 bd->props->update_status(bd);
170 }
149 up(&bd->sem); 171 up(&bd->sem);
150 return 0; 172 return 0;
151} 173}
@@ -231,6 +253,12 @@ void backlight_device_unregister(struct backlight_device *bd)
231 &bl_class_device_attributes[i]); 253 &bl_class_device_attributes[i]);
232 254
233 down(&bd->sem); 255 down(&bd->sem);
256 if (likely(bd->props && bd->props->update_status)) {
257 bd->props->brightness = 0;
258 bd->props->power = 0;
259 bd->props->update_status(bd);
260 }
261
234 bd->props = NULL; 262 bd->props = NULL;
235 up(&bd->sem); 263 up(&bd->sem);
236 264
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index d0aaf450e8c7..f86213b4a8fb 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -25,24 +25,30 @@
25#define CORGI_DEFAULT_INTENSITY 0x1f 25#define CORGI_DEFAULT_INTENSITY 0x1f
26#define CORGI_LIMIT_MASK 0x0b 26#define CORGI_LIMIT_MASK 0x0b
27 27
28static int corgibl_powermode = FB_BLANK_UNBLANK; 28static int corgibl_intensity;
29static int current_intensity = 0;
30static int corgibl_limit = 0;
31static void (*corgibl_mach_set_intensity)(int intensity); 29static void (*corgibl_mach_set_intensity)(int intensity);
32static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; 30static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
33static struct backlight_properties corgibl_data; 31static struct backlight_properties corgibl_data;
32static struct backlight_device *corgi_backlight_device;
33
34static unsigned long corgibl_flags;
35#define CORGIBL_SUSPENDED 0x01
36#define CORGIBL_BATTLOW 0x02
34 37
35static void corgibl_send_intensity(int intensity) 38static int corgibl_send_intensity(struct backlight_device *bd)
36{ 39{
37 unsigned long flags; 40 unsigned long flags;
38 void (*corgi_kick_batt)(void); 41 void (*corgi_kick_batt)(void);
42 int intensity = bd->props->brightness;
39 43
40 if (corgibl_powermode != FB_BLANK_UNBLANK) { 44 if (bd->props->power != FB_BLANK_UNBLANK)
45 intensity = 0;
46 if (bd->props->fb_blank != FB_BLANK_UNBLANK)
41 intensity = 0; 47 intensity = 0;
42 } else { 48 if (corgibl_flags & CORGIBL_SUSPENDED)
43 if (corgibl_limit) 49 intensity = 0;
44 intensity &= CORGI_LIMIT_MASK; 50 if (corgibl_flags & CORGIBL_BATTLOW)
45 } 51 intensity &= CORGI_LIMIT_MASK;
46 52
47 spin_lock_irqsave(&bl_lock, flags); 53 spin_lock_irqsave(&bl_lock, flags);
48 54
@@ -50,45 +56,29 @@ static void corgibl_send_intensity(int intensity)
50 56
51 spin_unlock_irqrestore(&bl_lock, flags); 57 spin_unlock_irqrestore(&bl_lock, flags);
52 58
59 corgibl_intensity = intensity;
60
53 corgi_kick_batt = symbol_get(sharpsl_battery_kick); 61 corgi_kick_batt = symbol_get(sharpsl_battery_kick);
54 if (corgi_kick_batt) { 62 if (corgi_kick_batt) {
55 corgi_kick_batt(); 63 corgi_kick_batt();
56 symbol_put(sharpsl_battery_kick); 64 symbol_put(sharpsl_battery_kick);
57 } 65 }
58}
59 66
60static void corgibl_blank(int blank) 67 return 0;
61{
62 switch(blank) {
63
64 case FB_BLANK_NORMAL:
65 case FB_BLANK_VSYNC_SUSPEND:
66 case FB_BLANK_HSYNC_SUSPEND:
67 case FB_BLANK_POWERDOWN:
68 if (corgibl_powermode == FB_BLANK_UNBLANK) {
69 corgibl_send_intensity(0);
70 corgibl_powermode = blank;
71 }
72 break;
73 case FB_BLANK_UNBLANK:
74 if (corgibl_powermode != FB_BLANK_UNBLANK) {
75 corgibl_powermode = blank;
76 corgibl_send_intensity(current_intensity);
77 }
78 break;
79 }
80} 68}
81 69
82#ifdef CONFIG_PM 70#ifdef CONFIG_PM
83static int corgibl_suspend(struct platform_device *dev, pm_message_t state) 71static int corgibl_suspend(struct platform_device *dev, pm_message_t state)
84{ 72{
85 corgibl_blank(FB_BLANK_POWERDOWN); 73 corgibl_flags |= CORGIBL_SUSPENDED;
74 corgibl_send_intensity(corgi_backlight_device);
86 return 0; 75 return 0;
87} 76}
88 77
89static int corgibl_resume(struct platform_device *dev) 78static int corgibl_resume(struct platform_device *dev)
90{ 79{
91 corgibl_blank(FB_BLANK_UNBLANK); 80 corgibl_flags &= ~CORGIBL_SUSPENDED;
81 corgibl_send_intensity(corgi_backlight_device);
92 return 0; 82 return 0;
93} 83}
94#else 84#else
@@ -96,54 +86,38 @@ static int corgibl_resume(struct platform_device *dev)
96#define corgibl_resume NULL 86#define corgibl_resume NULL
97#endif 87#endif
98 88
99 89static int corgibl_get_intensity(struct backlight_device *bd)
100static int corgibl_set_power(struct backlight_device *bd, int state)
101{
102 corgibl_blank(state);
103 return 0;
104}
105
106static int corgibl_get_power(struct backlight_device *bd)
107{ 90{
108 return corgibl_powermode; 91 return corgibl_intensity;
109} 92}
110 93
111static int corgibl_set_intensity(struct backlight_device *bd, int intensity) 94static int corgibl_set_intensity(struct backlight_device *bd)
112{ 95{
113 if (intensity > corgibl_data.max_brightness) 96 corgibl_send_intensity(corgi_backlight_device);
114 intensity = corgibl_data.max_brightness;
115 corgibl_send_intensity(intensity);
116 current_intensity=intensity;
117 return 0; 97 return 0;
118} 98}
119 99
120static int corgibl_get_intensity(struct backlight_device *bd)
121{
122 return current_intensity;
123}
124
125/* 100/*
126 * Called when the battery is low to limit the backlight intensity. 101 * Called when the battery is low to limit the backlight intensity.
127 * If limit==0 clear any limit, otherwise limit the intensity 102 * If limit==0 clear any limit, otherwise limit the intensity
128 */ 103 */
129void corgibl_limit_intensity(int limit) 104void corgibl_limit_intensity(int limit)
130{ 105{
131 corgibl_limit = (limit ? 1 : 0); 106 if (limit)
132 corgibl_send_intensity(current_intensity); 107 corgibl_flags |= CORGIBL_BATTLOW;
108 else
109 corgibl_flags &= ~CORGIBL_BATTLOW;
110 corgibl_send_intensity(corgi_backlight_device);
133} 111}
134EXPORT_SYMBOL(corgibl_limit_intensity); 112EXPORT_SYMBOL(corgibl_limit_intensity);
135 113
136 114
137static struct backlight_properties corgibl_data = { 115static struct backlight_properties corgibl_data = {
138 .owner = THIS_MODULE, 116 .owner = THIS_MODULE,
139 .get_power = corgibl_get_power,
140 .set_power = corgibl_set_power,
141 .get_brightness = corgibl_get_intensity, 117 .get_brightness = corgibl_get_intensity,
142 .set_brightness = corgibl_set_intensity, 118 .update_status = corgibl_set_intensity,
143}; 119};
144 120
145static struct backlight_device *corgi_backlight_device;
146
147static int __init corgibl_probe(struct platform_device *pdev) 121static int __init corgibl_probe(struct platform_device *pdev)
148{ 122{
149 struct corgibl_machinfo *machinfo = pdev->dev.platform_data; 123 struct corgibl_machinfo *machinfo = pdev->dev.platform_data;
@@ -156,8 +130,9 @@ static int __init corgibl_probe(struct platform_device *pdev)
156 if (IS_ERR (corgi_backlight_device)) 130 if (IS_ERR (corgi_backlight_device))
157 return PTR_ERR (corgi_backlight_device); 131 return PTR_ERR (corgi_backlight_device);
158 132
159 corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); 133 corgibl_data.power = FB_BLANK_UNBLANK;
160 corgibl_limit_intensity(0); 134 corgibl_data.brightness = CORGI_DEFAULT_INTENSITY;
135 corgibl_send_intensity(corgi_backlight_device);
161 136
162 printk("Corgi Backlight Driver Initialized.\n"); 137 printk("Corgi Backlight Driver Initialized.\n");
163 return 0; 138 return 0;
@@ -167,8 +142,6 @@ static int corgibl_remove(struct platform_device *dev)
167{ 142{
168 backlight_device_unregister(corgi_backlight_device); 143 backlight_device_unregister(corgi_backlight_device);
169 144
170 corgibl_set_intensity(NULL, 0);
171
172 printk("Corgi Backlight Driver Unloaded\n"); 145 printk("Corgi Backlight Driver Unloaded\n");
173 return 0; 146 return 0;
174} 147}