Linux-2.6.12-rc2
[linux-2.6/next.git] / drivers / video / backlight / corgi_bl.c
blob3c026b036c86c6f65c600022f24c9291d017639e
1 /*
2 * Backlight Driver for Sharp Corgi
4 * Copyright (c) 2004-2005 Richard Purdie
6 * Based on Sharp's 2.4 Backlight Driver
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/device.h>
18 #include <linux/spinlock.h>
19 #include <linux/fb.h>
20 #include <linux/backlight.h>
22 #include <asm/arch-pxa/corgi.h>
23 #include <asm/hardware/scoop.h>
25 #define CORGI_MAX_INTENSITY 0x3e
26 #define CORGI_DEFAULT_INTENSITY 0x1f
27 #define CORGI_LIMIT_MASK 0x0b
29 static int corgibl_powermode = FB_BLANK_UNBLANK;
30 static int current_intensity = 0;
31 static int corgibl_limit = 0;
32 static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
34 static void corgibl_send_intensity(int intensity)
36 unsigned long flags;
37 void (*corgi_kick_batt)(void);
39 if (corgibl_powermode != FB_BLANK_UNBLANK) {
40 intensity = 0;
41 } else {
42 if (corgibl_limit)
43 intensity &= CORGI_LIMIT_MASK;
46 /* Skip 0x20 as it will blank the display */
47 if (intensity >= 0x20)
48 intensity++;
50 spin_lock_irqsave(&bl_lock, flags);
51 /* Bits 0-4 are accessed via the SSP interface */
52 corgi_ssp_blduty_set(intensity & 0x1f);
53 /* Bit 5 is via SCOOP */
54 if (intensity & 0x0020)
55 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
56 else
57 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_BACKLIGHT_CONT);
58 spin_unlock_irqrestore(&bl_lock, flags);
61 static void corgibl_blank(int blank)
63 switch(blank) {
65 case FB_BLANK_NORMAL:
66 case FB_BLANK_VSYNC_SUSPEND:
67 case FB_BLANK_HSYNC_SUSPEND:
68 case FB_BLANK_POWERDOWN:
69 if (corgibl_powermode == FB_BLANK_UNBLANK) {
70 corgibl_send_intensity(0);
71 corgibl_powermode = blank;
73 break;
74 case FB_BLANK_UNBLANK:
75 if (corgibl_powermode != FB_BLANK_UNBLANK) {
76 corgibl_powermode = blank;
77 corgibl_send_intensity(current_intensity);
79 break;
83 #ifdef CONFIG_PM
84 static int corgibl_suspend(struct device *dev, u32 state, u32 level)
86 if (level == SUSPEND_POWER_DOWN)
87 corgibl_blank(FB_BLANK_POWERDOWN);
88 return 0;
91 static int corgibl_resume(struct device *dev, u32 level)
93 if (level == RESUME_POWER_ON)
94 corgibl_blank(FB_BLANK_UNBLANK);
95 return 0;
97 #else
98 #define corgibl_suspend NULL
99 #define corgibl_resume NULL
100 #endif
103 static int corgibl_set_power(struct backlight_device *bd, int state)
105 corgibl_blank(state);
106 return 0;
109 static int corgibl_get_power(struct backlight_device *bd)
111 return corgibl_powermode;
114 static int corgibl_set_intensity(struct backlight_device *bd, int intensity)
116 if (intensity > CORGI_MAX_INTENSITY)
117 intensity = CORGI_MAX_INTENSITY;
118 corgibl_send_intensity(intensity);
119 current_intensity=intensity;
120 return 0;
123 static int corgibl_get_intensity(struct backlight_device *bd)
125 return current_intensity;
129 * Called when the battery is low to limit the backlight intensity.
130 * If limit==0 clear any limit, otherwise limit the intensity
132 void corgibl_limit_intensity(int limit)
134 corgibl_limit = (limit ? 1 : 0);
135 corgibl_send_intensity(current_intensity);
137 EXPORT_SYMBOL(corgibl_limit_intensity);
140 static struct backlight_properties corgibl_data = {
141 .owner = THIS_MODULE,
142 .get_power = corgibl_get_power,
143 .set_power = corgibl_set_power,
144 .max_brightness = CORGI_MAX_INTENSITY,
145 .get_brightness = corgibl_get_intensity,
146 .set_brightness = corgibl_set_intensity,
149 static struct backlight_device *corgi_backlight_device;
151 static int __init corgibl_probe(struct device *dev)
153 corgi_backlight_device = backlight_device_register ("corgi-bl",
154 NULL, &corgibl_data);
155 if (IS_ERR (corgi_backlight_device))
156 return PTR_ERR (corgi_backlight_device);
158 corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY);
160 printk("Corgi Backlight Driver Initialized.\n");
161 return 0;
164 static int corgibl_remove(struct device *dev)
166 backlight_device_unregister(corgi_backlight_device);
168 corgibl_set_intensity(NULL, 0);
170 printk("Corgi Backlight Driver Unloaded\n");
171 return 0;
174 static struct device_driver corgibl_driver = {
175 .name = "corgi-bl",
176 .bus = &platform_bus_type,
177 .probe = corgibl_probe,
178 .remove = corgibl_remove,
179 .suspend = corgibl_suspend,
180 .resume = corgibl_resume,
183 static int __init corgibl_init(void)
185 return driver_register(&corgibl_driver);
188 static void __exit corgibl_exit(void)
190 driver_unregister(&corgibl_driver);
193 module_init(corgibl_init);
194 module_exit(corgibl_exit);
196 MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
197 MODULE_DESCRIPTION("Corgi Backlight Driver");
198 MODULE_LICENSE("GPLv2");