diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/video/backlight/corgi_bl.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/video/backlight/corgi_bl.c')
-rw-r--r-- | drivers/video/backlight/corgi_bl.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c new file mode 100644 index 00000000000..3c026b036c8 --- /dev/null +++ b/drivers/video/backlight/corgi_bl.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * Backlight Driver for Sharp Corgi | ||
3 | * | ||
4 | * Copyright (c) 2004-2005 Richard Purdie | ||
5 | * | ||
6 | * Based on Sharp's 2.4 Backlight Driver | ||
7 | * | ||
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. | ||
11 | * | ||
12 | */ | ||
13 | |||
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> | ||
21 | |||
22 | #include <asm/arch-pxa/corgi.h> | ||
23 | #include <asm/hardware/scoop.h> | ||
24 | |||
25 | #define CORGI_MAX_INTENSITY 0x3e | ||
26 | #define CORGI_DEFAULT_INTENSITY 0x1f | ||
27 | #define CORGI_LIMIT_MASK 0x0b | ||
28 | |||
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; | ||
33 | |||
34 | static void corgibl_send_intensity(int intensity) | ||
35 | { | ||
36 | unsigned long flags; | ||
37 | void (*corgi_kick_batt)(void); | ||
38 | |||
39 | if (corgibl_powermode != FB_BLANK_UNBLANK) { | ||
40 | intensity = 0; | ||
41 | } else { | ||
42 | if (corgibl_limit) | ||
43 | intensity &= CORGI_LIMIT_MASK; | ||
44 | } | ||
45 | |||
46 | /* Skip 0x20 as it will blank the display */ | ||
47 | if (intensity >= 0x20) | ||
48 | intensity++; | ||
49 | |||
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); | ||
59 | } | ||
60 | |||
61 | static void corgibl_blank(int blank) | ||
62 | { | ||
63 | switch(blank) { | ||
64 | |||
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; | ||
72 | } | ||
73 | break; | ||
74 | case FB_BLANK_UNBLANK: | ||
75 | if (corgibl_powermode != FB_BLANK_UNBLANK) { | ||
76 | corgibl_powermode = blank; | ||
77 | corgibl_send_intensity(current_intensity); | ||
78 | } | ||
79 | break; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | #ifdef CONFIG_PM | ||
84 | static int corgibl_suspend(struct device *dev, u32 state, u32 level) | ||
85 | { | ||
86 | if (level == SUSPEND_POWER_DOWN) | ||
87 | corgibl_blank(FB_BLANK_POWERDOWN); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | static int corgibl_resume(struct device *dev, u32 level) | ||
92 | { | ||
93 | if (level == RESUME_POWER_ON) | ||
94 | corgibl_blank(FB_BLANK_UNBLANK); | ||
95 | return 0; | ||
96 | } | ||
97 | #else | ||
98 | #define corgibl_suspend NULL | ||
99 | #define corgibl_resume NULL | ||
100 | #endif | ||
101 | |||
102 | |||
103 | static int corgibl_set_power(struct backlight_device *bd, int state) | ||
104 | { | ||
105 | corgibl_blank(state); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int corgibl_get_power(struct backlight_device *bd) | ||
110 | { | ||
111 | return corgibl_powermode; | ||
112 | } | ||
113 | |||
114 | static int corgibl_set_intensity(struct backlight_device *bd, int intensity) | ||
115 | { | ||
116 | if (intensity > CORGI_MAX_INTENSITY) | ||
117 | intensity = CORGI_MAX_INTENSITY; | ||
118 | corgibl_send_intensity(intensity); | ||
119 | current_intensity=intensity; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static int corgibl_get_intensity(struct backlight_device *bd) | ||
124 | { | ||
125 | return current_intensity; | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Called when the battery is low to limit the backlight intensity. | ||
130 | * If limit==0 clear any limit, otherwise limit the intensity | ||
131 | */ | ||
132 | void corgibl_limit_intensity(int limit) | ||
133 | { | ||
134 | corgibl_limit = (limit ? 1 : 0); | ||
135 | corgibl_send_intensity(current_intensity); | ||
136 | } | ||
137 | EXPORT_SYMBOL(corgibl_limit_intensity); | ||
138 | |||
139 | |||
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, | ||
147 | }; | ||
148 | |||
149 | static struct backlight_device *corgi_backlight_device; | ||
150 | |||
151 | static int __init corgibl_probe(struct device *dev) | ||
152 | { | ||
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); | ||
157 | |||
158 | corgibl_set_intensity(NULL, CORGI_DEFAULT_INTENSITY); | ||
159 | |||
160 | printk("Corgi Backlight Driver Initialized.\n"); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int corgibl_remove(struct device *dev) | ||
165 | { | ||
166 | backlight_device_unregister(corgi_backlight_device); | ||
167 | |||
168 | corgibl_set_intensity(NULL, 0); | ||
169 | |||
170 | printk("Corgi Backlight Driver Unloaded\n"); | ||
171 | return 0; | ||
172 | } | ||
173 | |||
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, | ||
181 | }; | ||
182 | |||
183 | static int __init corgibl_init(void) | ||
184 | { | ||
185 | return driver_register(&corgibl_driver); | ||
186 | } | ||
187 | |||
188 | static void __exit corgibl_exit(void) | ||
189 | { | ||
190 | driver_unregister(&corgibl_driver); | ||
191 | } | ||
192 | |||
193 | module_init(corgibl_init); | ||
194 | module_exit(corgibl_exit); | ||
195 | |||
196 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | ||
197 | MODULE_DESCRIPTION("Corgi Backlight Driver"); | ||
198 | MODULE_LICENSE("GPLv2"); | ||