diff options
Diffstat (limited to 'drivers/video/backlight/locomolcd.c')
-rw-r--r-- | drivers/video/backlight/locomolcd.c | 123 |
1 files changed, 107 insertions, 16 deletions
diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index 60831bb23685..bd879b7ec119 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/fb.h> | ||
21 | #include <linux/backlight.h> | ||
20 | 22 | ||
21 | #include <asm/hardware/locomo.h> | 23 | #include <asm/hardware/locomo.h> |
22 | #include <asm/irq.h> | 24 | #include <asm/irq.h> |
@@ -25,7 +27,10 @@ | |||
25 | 27 | ||
26 | #include "../../../arch/arm/mach-sa1100/generic.h" | 28 | #include "../../../arch/arm/mach-sa1100/generic.h" |
27 | 29 | ||
30 | static struct backlight_device *locomolcd_bl_device; | ||
28 | static struct locomo_dev *locomolcd_dev; | 31 | static struct locomo_dev *locomolcd_dev; |
32 | static unsigned long locomolcd_flags; | ||
33 | #define LOCOMOLCD_SUSPENDED 0x01 | ||
29 | 34 | ||
30 | static void locomolcd_on(int comadj) | 35 | static void locomolcd_on(int comadj) |
31 | { | 36 | { |
@@ -89,12 +94,10 @@ void locomolcd_power(int on) | |||
89 | } | 94 | } |
90 | 95 | ||
91 | /* read comadj */ | 96 | /* read comadj */ |
92 | if (comadj == -1) { | 97 | if (comadj == -1 && machine_is_collie()) |
93 | if (machine_is_poodle()) | 98 | comadj = 128; |
94 | comadj = 118; | 99 | if (comadj == -1 && machine_is_poodle()) |
95 | if (machine_is_collie()) | 100 | comadj = 118; |
96 | comadj = 128; | ||
97 | } | ||
98 | 101 | ||
99 | if (on) | 102 | if (on) |
100 | locomolcd_on(comadj); | 103 | locomolcd_on(comadj); |
@@ -105,26 +108,100 @@ void locomolcd_power(int on) | |||
105 | } | 108 | } |
106 | EXPORT_SYMBOL(locomolcd_power); | 109 | EXPORT_SYMBOL(locomolcd_power); |
107 | 110 | ||
108 | static int poodle_lcd_probe(struct locomo_dev *dev) | 111 | |
112 | static int current_intensity; | ||
113 | |||
114 | static int locomolcd_set_intensity(struct backlight_device *bd) | ||
115 | { | ||
116 | int intensity = bd->props->brightness; | ||
117 | |||
118 | if (bd->props->power != FB_BLANK_UNBLANK) | ||
119 | intensity = 0; | ||
120 | if (bd->props->fb_blank != FB_BLANK_UNBLANK) | ||
121 | intensity = 0; | ||
122 | if (locomolcd_flags & LOCOMOLCD_SUSPENDED) | ||
123 | intensity = 0; | ||
124 | |||
125 | switch (intensity) { | ||
126 | /* AC and non-AC are handled differently, but produce same results in sharp code? */ | ||
127 | case 0: locomo_frontlight_set(locomolcd_dev, 0, 0, 161); break; | ||
128 | case 1: locomo_frontlight_set(locomolcd_dev, 117, 0, 161); break; | ||
129 | case 2: locomo_frontlight_set(locomolcd_dev, 163, 0, 148); break; | ||
130 | case 3: locomo_frontlight_set(locomolcd_dev, 194, 0, 161); break; | ||
131 | case 4: locomo_frontlight_set(locomolcd_dev, 194, 1, 161); break; | ||
132 | |||
133 | default: | ||
134 | return -ENODEV; | ||
135 | } | ||
136 | current_intensity = intensity; | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int locomolcd_get_intensity(struct backlight_device *bd) | ||
141 | { | ||
142 | return current_intensity; | ||
143 | } | ||
144 | |||
145 | static struct backlight_properties locomobl_data = { | ||
146 | .owner = THIS_MODULE, | ||
147 | .get_brightness = locomolcd_get_intensity, | ||
148 | .update_status = locomolcd_set_intensity, | ||
149 | .max_brightness = 4, | ||
150 | }; | ||
151 | |||
152 | #ifdef CONFIG_PM | ||
153 | static int locomolcd_suspend(struct locomo_dev *dev, pm_message_t state) | ||
154 | { | ||
155 | locomolcd_flags |= LOCOMOLCD_SUSPENDED; | ||
156 | locomolcd_set_intensity(locomolcd_bl_device); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int locomolcd_resume(struct locomo_dev *dev) | ||
161 | { | ||
162 | locomolcd_flags &= ~LOCOMOLCD_SUSPENDED; | ||
163 | locomolcd_set_intensity(locomolcd_bl_device); | ||
164 | return 0; | ||
165 | } | ||
166 | #else | ||
167 | #define locomolcd_suspend NULL | ||
168 | #define locomolcd_resume NULL | ||
169 | #endif | ||
170 | |||
171 | static int locomolcd_probe(struct locomo_dev *dev) | ||
109 | { | 172 | { |
110 | unsigned long flags; | 173 | unsigned long flags; |
111 | 174 | ||
112 | local_irq_save(flags); | 175 | local_irq_save(flags); |
113 | locomolcd_dev = dev; | 176 | locomolcd_dev = dev; |
114 | 177 | ||
178 | locomo_gpio_set_dir(dev, LOCOMO_GPIO_FL_VR, 0); | ||
179 | |||
115 | /* the poodle_lcd_power function is called for the first time | 180 | /* the poodle_lcd_power function is called for the first time |
116 | * from fs_initcall, which is before locomo is activated. | 181 | * from fs_initcall, which is before locomo is activated. |
117 | * We need to recall poodle_lcd_power here*/ | 182 | * We need to recall poodle_lcd_power here*/ |
118 | #ifdef CONFIG_MACH_POODLE | 183 | if (machine_is_poodle()) |
119 | locomolcd_power(1); | 184 | locomolcd_power(1); |
120 | #endif | 185 | |
121 | local_irq_restore(flags); | 186 | local_irq_restore(flags); |
187 | |||
188 | locomolcd_bl_device = backlight_device_register("locomo-bl", NULL, &locomobl_data); | ||
189 | |||
190 | if (IS_ERR (locomolcd_bl_device)) | ||
191 | return PTR_ERR (locomolcd_bl_device); | ||
192 | |||
193 | /* Set up frontlight so that screen is readable */ | ||
194 | locomobl_data.brightness = 2; | ||
195 | locomolcd_set_intensity(locomolcd_bl_device); | ||
196 | |||
122 | return 0; | 197 | return 0; |
123 | } | 198 | } |
124 | 199 | ||
125 | static int poodle_lcd_remove(struct locomo_dev *dev) | 200 | static int locomolcd_remove(struct locomo_dev *dev) |
126 | { | 201 | { |
127 | unsigned long flags; | 202 | unsigned long flags; |
203 | |||
204 | backlight_device_unregister(locomolcd_bl_device); | ||
128 | local_irq_save(flags); | 205 | local_irq_save(flags); |
129 | locomolcd_dev = NULL; | 206 | locomolcd_dev = NULL; |
130 | local_irq_restore(flags); | 207 | local_irq_restore(flags); |
@@ -136,19 +213,33 @@ static struct locomo_driver poodle_lcd_driver = { | |||
136 | .name = "locomo-backlight", | 213 | .name = "locomo-backlight", |
137 | }, | 214 | }, |
138 | .devid = LOCOMO_DEVID_BACKLIGHT, | 215 | .devid = LOCOMO_DEVID_BACKLIGHT, |
139 | .probe = poodle_lcd_probe, | 216 | .probe = locomolcd_probe, |
140 | .remove = poodle_lcd_remove, | 217 | .remove = locomolcd_remove, |
218 | .suspend = locomolcd_suspend, | ||
219 | .resume = locomolcd_resume, | ||
141 | }; | 220 | }; |
142 | 221 | ||
143 | static int __init poodle_lcd_init(void) | 222 | |
223 | static int __init locomolcd_init(void) | ||
144 | { | 224 | { |
145 | int ret = locomo_driver_register(&poodle_lcd_driver); | 225 | int ret = locomo_driver_register(&poodle_lcd_driver); |
146 | if (ret) return ret; | 226 | if (ret) |
227 | return ret; | ||
147 | 228 | ||
148 | #ifdef CONFIG_SA1100_COLLIE | 229 | #ifdef CONFIG_SA1100_COLLIE |
149 | sa1100fb_lcd_power = locomolcd_power; | 230 | sa1100fb_lcd_power = locomolcd_power; |
150 | #endif | 231 | #endif |
151 | return 0; | 232 | return 0; |
152 | } | 233 | } |
153 | device_initcall(poodle_lcd_init); | ||
154 | 234 | ||
235 | static void __exit locomolcd_exit(void) | ||
236 | { | ||
237 | locomo_driver_unregister(&poodle_lcd_driver); | ||
238 | } | ||
239 | |||
240 | module_init(locomolcd_init); | ||
241 | module_exit(locomolcd_exit); | ||
242 | |||
243 | MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@suse.cz>"); | ||
244 | MODULE_DESCRIPTION("Collie LCD driver"); | ||
245 | MODULE_LICENSE("GPL"); | ||