aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/backlight/backlight.c84
-rw-r--r--drivers/video/backlight/corgi_bl.c99
-rw-r--r--include/linux/backlight.h25
3 files changed, 107 insertions, 101 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}
diff --git a/include/linux/backlight.h b/include/linux/backlight.h
index bb9e54322322..75e91f5b6a04 100644
--- a/include/linux/backlight.h
+++ b/include/linux/backlight.h
@@ -19,20 +19,25 @@ struct fb_info;
19struct backlight_properties { 19struct backlight_properties {
20 /* Owner module */ 20 /* Owner module */
21 struct module *owner; 21 struct module *owner;
22 /* Get the backlight power status (0: full on, 1..3: power saving 22
23 modes; 4: full off), see FB_BLANK_XXX */ 23 /* Notify the backlight driver some property has changed */
24 int (*get_power)(struct backlight_device *); 24 int (*update_status)(struct backlight_device *);
25 /* Enable or disable power to the LCD (0: on; 4: off, see FB_BLANK_XXX) */ 25 /* Return the current backlight brightness (accounting for power,
26 int (*set_power)(struct backlight_device *, int power); 26 fb_blank etc.) */
27 /* Maximal value for brightness (read-only) */
28 int max_brightness;
29 /* Get current backlight brightness */
30 int (*get_brightness)(struct backlight_device *); 27 int (*get_brightness)(struct backlight_device *);
31 /* Set backlight brightness (0..max_brightness) */
32 int (*set_brightness)(struct backlight_device *, int brightness);
33 /* Check if given framebuffer device is the one bound to this backlight; 28 /* Check if given framebuffer device is the one bound to this backlight;
34 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */ 29 return 0 if not, !=0 if it is. If NULL, backlight always matches the fb. */
35 int (*check_fb)(struct fb_info *); 30 int (*check_fb)(struct fb_info *);
31
32 /* Current User requested brightness (0 - max_brightness) */
33 int brightness;
34 /* Maximal value for brightness (read-only) */
35 int max_brightness;
36 /* Current FB Power mode (0: full on, 1..3: power saving
37 modes; 4: full off), see FB_BLANK_XXX */
38 int power;
39 /* FB Blanking active? (values as for power) */
40 int fb_blank;
36}; 41};
37 42
38struct backlight_device { 43struct backlight_device {