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/modedb.c |
Linux-2.6.12-rc2v2.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/modedb.c')
-rw-r--r-- | drivers/video/modedb.c | 892 |
1 files changed, 892 insertions, 0 deletions
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c new file mode 100644 index 000000000000..fbf659b6dab0 --- /dev/null +++ b/drivers/video/modedb.c | |||
@@ -0,0 +1,892 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/modedb.c -- Standard video mode database management | ||
3 | * | ||
4 | * Copyright (C) 1999 Geert Uytterhoeven | ||
5 | * | ||
6 | * 2001 - Documented with DocBook | ||
7 | * - Brad Douglas <brad@neruo.com> | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/tty.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <linux/sched.h> | ||
18 | |||
19 | #undef DEBUG | ||
20 | |||
21 | #define name_matches(v, s, l) \ | ||
22 | ((v).name && !strncmp((s), (v).name, (l)) && strlen((v).name) == (l)) | ||
23 | #define res_matches(v, x, y) \ | ||
24 | ((v).xres == (x) && (v).yres == (y)) | ||
25 | |||
26 | #ifdef DEBUG | ||
27 | #define DPRINTK(fmt, args...) printk("modedb %s: " fmt, __FUNCTION__ , ## args) | ||
28 | #else | ||
29 | #define DPRINTK(fmt, args...) | ||
30 | #endif | ||
31 | |||
32 | const char *global_mode_option; | ||
33 | |||
34 | /* | ||
35 | * Standard video mode definitions (taken from XFree86) | ||
36 | */ | ||
37 | |||
38 | #define DEFAULT_MODEDB_INDEX 0 | ||
39 | |||
40 | static const struct fb_videomode modedb[] = { | ||
41 | { | ||
42 | /* 640x400 @ 70 Hz, 31.5 kHz hsync */ | ||
43 | NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, | ||
44 | 0, FB_VMODE_NONINTERLACED | ||
45 | }, { | ||
46 | /* 640x480 @ 60 Hz, 31.5 kHz hsync */ | ||
47 | NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, | ||
48 | 0, FB_VMODE_NONINTERLACED | ||
49 | }, { | ||
50 | /* 800x600 @ 56 Hz, 35.15 kHz hsync */ | ||
51 | NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, | ||
52 | 0, FB_VMODE_NONINTERLACED | ||
53 | }, { | ||
54 | /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ | ||
55 | NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, | ||
56 | 0, FB_VMODE_INTERLACED | ||
57 | }, { | ||
58 | /* 640x400 @ 85 Hz, 37.86 kHz hsync */ | ||
59 | NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, | ||
60 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
61 | }, { | ||
62 | /* 640x480 @ 72 Hz, 36.5 kHz hsync */ | ||
63 | NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, | ||
64 | 0, FB_VMODE_NONINTERLACED | ||
65 | }, { | ||
66 | /* 640x480 @ 75 Hz, 37.50 kHz hsync */ | ||
67 | NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, | ||
68 | 0, FB_VMODE_NONINTERLACED | ||
69 | }, { | ||
70 | /* 800x600 @ 60 Hz, 37.8 kHz hsync */ | ||
71 | NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, | ||
72 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
73 | }, { | ||
74 | /* 640x480 @ 85 Hz, 43.27 kHz hsync */ | ||
75 | NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, | ||
76 | 0, FB_VMODE_NONINTERLACED | ||
77 | }, { | ||
78 | /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ | ||
79 | NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, | ||
80 | 0, FB_VMODE_INTERLACED | ||
81 | }, { | ||
82 | /* 800x600 @ 72 Hz, 48.0 kHz hsync */ | ||
83 | NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, | ||
84 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
85 | }, { | ||
86 | /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ | ||
87 | NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, | ||
88 | 0, FB_VMODE_NONINTERLACED | ||
89 | }, { | ||
90 | /* 640x480 @ 100 Hz, 53.01 kHz hsync */ | ||
91 | NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, | ||
92 | 0, FB_VMODE_NONINTERLACED | ||
93 | }, { | ||
94 | /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ | ||
95 | NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, | ||
96 | 0, FB_VMODE_NONINTERLACED | ||
97 | }, { | ||
98 | /* 800x600 @ 85 Hz, 55.84 kHz hsync */ | ||
99 | NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, | ||
100 | 0, FB_VMODE_NONINTERLACED | ||
101 | }, { | ||
102 | /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ | ||
103 | NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, | ||
104 | 0, FB_VMODE_NONINTERLACED | ||
105 | }, { | ||
106 | /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ | ||
107 | NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, | ||
108 | 0, FB_VMODE_INTERLACED | ||
109 | }, { | ||
110 | /* 800x600 @ 100 Hz, 64.02 kHz hsync */ | ||
111 | NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, | ||
112 | 0, FB_VMODE_NONINTERLACED | ||
113 | }, { | ||
114 | /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ | ||
115 | NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, | ||
116 | 0, FB_VMODE_NONINTERLACED | ||
117 | }, { | ||
118 | /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ | ||
119 | NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, | ||
120 | 0, FB_VMODE_NONINTERLACED | ||
121 | }, { | ||
122 | /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ | ||
123 | NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, | ||
124 | 0, FB_VMODE_NONINTERLACED | ||
125 | }, { | ||
126 | /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ | ||
127 | NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, | ||
128 | 0, FB_VMODE_NONINTERLACED | ||
129 | }, { | ||
130 | /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ | ||
131 | NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, | ||
132 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
133 | }, { | ||
134 | /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ | ||
135 | NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, | ||
136 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
137 | }, { | ||
138 | /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ | ||
139 | NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, | ||
140 | 0, FB_VMODE_NONINTERLACED | ||
141 | }, { | ||
142 | /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ | ||
143 | NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, | ||
144 | 0, FB_VMODE_NONINTERLACED | ||
145 | }, { | ||
146 | /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ | ||
147 | NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, | ||
148 | 0, FB_VMODE_NONINTERLACED | ||
149 | }, { | ||
150 | /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ | ||
151 | NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, | ||
152 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
153 | }, { | ||
154 | /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ | ||
155 | NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, | ||
156 | 0, FB_VMODE_NONINTERLACED | ||
157 | }, { | ||
158 | /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ | ||
159 | NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, | ||
160 | 0, FB_VMODE_NONINTERLACED | ||
161 | }, { | ||
162 | /* 1024x768 @ 100Hz, 80.21 kHz hsync */ | ||
163 | NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, | ||
164 | 0, FB_VMODE_NONINTERLACED | ||
165 | }, { | ||
166 | /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ | ||
167 | NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, | ||
168 | 0, FB_VMODE_NONINTERLACED | ||
169 | }, { | ||
170 | /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ | ||
171 | NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, | ||
172 | 0, FB_VMODE_NONINTERLACED | ||
173 | }, { | ||
174 | /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ | ||
175 | NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, | ||
176 | 0, FB_VMODE_NONINTERLACED | ||
177 | }, { | ||
178 | /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ | ||
179 | NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, | ||
180 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
181 | }, { | ||
182 | /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ | ||
183 | NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, | ||
184 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
185 | }, { | ||
186 | /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ | ||
187 | NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, | ||
188 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
189 | }, { | ||
190 | /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ | ||
191 | NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, | ||
192 | 0, FB_VMODE_NONINTERLACED | ||
193 | }, { | ||
194 | /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ | ||
195 | NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, | ||
196 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
197 | }, { | ||
198 | /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ | ||
199 | NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, | ||
200 | FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED | ||
201 | }, { | ||
202 | /* 512x384 @ 78 Hz, 31.50 kHz hsync */ | ||
203 | NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, | ||
204 | 0, FB_VMODE_NONINTERLACED | ||
205 | }, { | ||
206 | /* 512x384 @ 85 Hz, 34.38 kHz hsync */ | ||
207 | NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, | ||
208 | 0, FB_VMODE_NONINTERLACED | ||
209 | }, { | ||
210 | /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ | ||
211 | NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, | ||
212 | 0, FB_VMODE_DOUBLE | ||
213 | }, { | ||
214 | /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ | ||
215 | NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, | ||
216 | 0, FB_VMODE_DOUBLE | ||
217 | }, { | ||
218 | /* 320x240 @ 72 Hz, 36.5 kHz hsync */ | ||
219 | NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, | ||
220 | 0, FB_VMODE_DOUBLE | ||
221 | }, { | ||
222 | /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ | ||
223 | NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, | ||
224 | 0, FB_VMODE_DOUBLE | ||
225 | }, { | ||
226 | /* 400x300 @ 60 Hz, 37.8 kHz hsync */ | ||
227 | NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, | ||
228 | 0, FB_VMODE_DOUBLE | ||
229 | }, { | ||
230 | /* 400x300 @ 72 Hz, 48.0 kHz hsync */ | ||
231 | NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, | ||
232 | 0, FB_VMODE_DOUBLE | ||
233 | }, { | ||
234 | /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ | ||
235 | NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, | ||
236 | 0, FB_VMODE_DOUBLE | ||
237 | }, { | ||
238 | /* 480x300 @ 60 Hz, 37.8 kHz hsync */ | ||
239 | NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, | ||
240 | 0, FB_VMODE_DOUBLE | ||
241 | }, { | ||
242 | /* 480x300 @ 63 Hz, 39.6 kHz hsync */ | ||
243 | NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, | ||
244 | 0, FB_VMODE_DOUBLE | ||
245 | }, { | ||
246 | /* 480x300 @ 72 Hz, 48.0 kHz hsync */ | ||
247 | NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, | ||
248 | 0, FB_VMODE_DOUBLE | ||
249 | }, | ||
250 | }; | ||
251 | |||
252 | #ifdef CONFIG_FB_MODE_HELPERS | ||
253 | const struct fb_videomode vesa_modes[] = { | ||
254 | /* 0 640x350-85 VESA */ | ||
255 | { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, | ||
256 | FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA}, | ||
257 | /* 1 640x400-85 VESA */ | ||
258 | { NULL, 85, 640, 400, 31746, 96, 32, 41, 01, 64, 3, | ||
259 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
260 | /* 2 720x400-85 VESA */ | ||
261 | { NULL, 85, 721, 400, 28169, 108, 36, 42, 01, 72, 3, | ||
262 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
263 | /* 3 640x480-60 VESA */ | ||
264 | { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, | ||
265 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
266 | /* 4 640x480-72 VESA */ | ||
267 | { NULL, 72, 640, 480, 31746, 128, 24, 29, 9, 40, 2, | ||
268 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
269 | /* 5 640x480-75 VESA */ | ||
270 | { NULL, 75, 640, 480, 31746, 120, 16, 16, 01, 64, 3, | ||
271 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
272 | /* 6 640x480-85 VESA */ | ||
273 | { NULL, 85, 640, 480, 27777, 80, 56, 25, 01, 56, 3, | ||
274 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
275 | /* 7 800x600-56 VESA */ | ||
276 | { NULL, 56, 800, 600, 27777, 128, 24, 22, 01, 72, 2, | ||
277 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
278 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
279 | /* 8 800x600-60 VESA */ | ||
280 | { NULL, 60, 800, 600, 25000, 88, 40, 23, 01, 128, 4, | ||
281 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
282 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
283 | /* 9 800x600-72 VESA */ | ||
284 | { NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, | ||
285 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
286 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
287 | /* 10 800x600-75 VESA */ | ||
288 | { NULL, 75, 800, 600, 20202, 160, 16, 21, 01, 80, 3, | ||
289 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
290 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
291 | /* 11 800x600-85 VESA */ | ||
292 | { NULL, 85, 800, 600, 17761, 152, 32, 27, 01, 64, 3, | ||
293 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
294 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
295 | /* 12 1024x768i-43 VESA */ | ||
296 | { NULL, 53, 1024, 768, 22271, 56, 8, 41, 0, 176, 8, | ||
297 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
298 | FB_VMODE_INTERLACED, FB_MODE_IS_VESA }, | ||
299 | /* 13 1024x768-60 VESA */ | ||
300 | { NULL, 60, 1024, 768, 15384, 160, 24, 29, 3, 136, 6, | ||
301 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
302 | /* 14 1024x768-70 VESA */ | ||
303 | { NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, | ||
304 | 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
305 | /* 15 1024x768-75 VESA */ | ||
306 | { NULL, 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3, | ||
307 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
308 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
309 | /* 16 1024x768-85 VESA */ | ||
310 | { NULL, 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3, | ||
311 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
312 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
313 | /* 17 1152x864-75 VESA */ | ||
314 | { NULL, 75, 1153, 864, 9259, 256, 64, 32, 1, 128, 3, | ||
315 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
316 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
317 | /* 18 1280x960-60 VESA */ | ||
318 | { NULL, 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, | ||
319 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
320 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
321 | /* 19 1280x960-85 VESA */ | ||
322 | { NULL, 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3, | ||
323 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
324 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
325 | /* 20 1280x1024-60 VESA */ | ||
326 | { NULL, 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, | ||
327 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
328 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
329 | /* 21 1280x1024-75 VESA */ | ||
330 | { NULL, 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3, | ||
331 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
332 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
333 | /* 22 1280x1024-85 VESA */ | ||
334 | { NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, | ||
335 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
336 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
337 | /* 23 1600x1200-60 VESA */ | ||
338 | { NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, | ||
339 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
340 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
341 | /* 24 1600x1200-65 VESA */ | ||
342 | { NULL, 65, 1600, 1200, 5698, 304, 64, 46, 1, 192, 3, | ||
343 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
344 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
345 | /* 25 1600x1200-70 VESA */ | ||
346 | { NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, | ||
347 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
348 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
349 | /* 26 1600x1200-75 VESA */ | ||
350 | { NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, | ||
351 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
352 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
353 | /* 27 1600x1200-85 VESA */ | ||
354 | { NULL, 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3, | ||
355 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
356 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
357 | /* 28 1792x1344-60 VESA */ | ||
358 | { NULL, 60, 1792, 1344, 4882, 328, 128, 46, 1, 200, 3, | ||
359 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
360 | /* 29 1792x1344-75 VESA */ | ||
361 | { NULL, 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3, | ||
362 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
363 | /* 30 1856x1392-60 VESA */ | ||
364 | { NULL, 60, 1856, 1392, 4580, 352, 96, 43, 1, 224, 3, | ||
365 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
366 | /* 31 1856x1392-75 VESA */ | ||
367 | { NULL, 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3, | ||
368 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
369 | /* 32 1920x1440-60 VESA */ | ||
370 | { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3, | ||
371 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
372 | /* 33 1920x1440-75 VESA */ | ||
373 | { NULL, 60, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, | ||
374 | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | ||
375 | }; | ||
376 | EXPORT_SYMBOL(vesa_modes); | ||
377 | #endif /* CONFIG_FB_MODE_HELPERS */ | ||
378 | |||
379 | static int my_atoi(const char *name) | ||
380 | { | ||
381 | int val = 0; | ||
382 | |||
383 | for (;; name++) { | ||
384 | switch (*name) { | ||
385 | case '0'...'9': | ||
386 | val = 10*val+(*name-'0'); | ||
387 | break; | ||
388 | default: | ||
389 | return val; | ||
390 | } | ||
391 | } | ||
392 | } | ||
393 | |||
394 | /** | ||
395 | * fb_try_mode - test a video mode | ||
396 | * @var: frame buffer user defined part of display | ||
397 | * @info: frame buffer info structure | ||
398 | * @mode: frame buffer video mode structure | ||
399 | * @bpp: color depth in bits per pixel | ||
400 | * | ||
401 | * Tries a video mode to test it's validity for device @info. | ||
402 | * | ||
403 | * Returns 1 on success. | ||
404 | * | ||
405 | */ | ||
406 | |||
407 | static int fb_try_mode(struct fb_var_screeninfo *var, struct fb_info *info, | ||
408 | const struct fb_videomode *mode, unsigned int bpp) | ||
409 | { | ||
410 | int err = 0; | ||
411 | |||
412 | DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname", | ||
413 | mode->xres, mode->yres, bpp, mode->refresh); | ||
414 | var->xres = mode->xres; | ||
415 | var->yres = mode->yres; | ||
416 | var->xres_virtual = mode->xres; | ||
417 | var->yres_virtual = mode->yres; | ||
418 | var->xoffset = 0; | ||
419 | var->yoffset = 0; | ||
420 | var->bits_per_pixel = bpp; | ||
421 | var->activate |= FB_ACTIVATE_TEST; | ||
422 | var->pixclock = mode->pixclock; | ||
423 | var->left_margin = mode->left_margin; | ||
424 | var->right_margin = mode->right_margin; | ||
425 | var->upper_margin = mode->upper_margin; | ||
426 | var->lower_margin = mode->lower_margin; | ||
427 | var->hsync_len = mode->hsync_len; | ||
428 | var->vsync_len = mode->vsync_len; | ||
429 | var->sync = mode->sync; | ||
430 | var->vmode = mode->vmode; | ||
431 | if (info->fbops->fb_check_var) | ||
432 | err = info->fbops->fb_check_var(var, info); | ||
433 | var->activate &= ~FB_ACTIVATE_TEST; | ||
434 | return err; | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * fb_find_mode - finds a valid video mode | ||
439 | * @var: frame buffer user defined part of display | ||
440 | * @info: frame buffer info structure | ||
441 | * @mode_option: string video mode to find | ||
442 | * @db: video mode database | ||
443 | * @dbsize: size of @db | ||
444 | * @default_mode: default video mode to fall back to | ||
445 | * @default_bpp: default color depth in bits per pixel | ||
446 | * | ||
447 | * Finds a suitable video mode, starting with the specified mode | ||
448 | * in @mode_option with fallback to @default_mode. If | ||
449 | * @default_mode fails, all modes in the video mode database will | ||
450 | * be tried. | ||
451 | * | ||
452 | * Valid mode specifiers for @mode_option: | ||
453 | * | ||
454 | * <xres>x<yres>[-<bpp>][@<refresh>] or | ||
455 | * <name>[-<bpp>][@<refresh>] | ||
456 | * | ||
457 | * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and | ||
458 | * <name> a string. | ||
459 | * | ||
460 | * NOTE: The passed struct @var is _not_ cleared! This allows you | ||
461 | * to supply values for e.g. the grayscale and accel_flags fields. | ||
462 | * | ||
463 | * Returns zero for failure, 1 if using specified @mode_option, | ||
464 | * 2 if using specified @mode_option with an ignored refresh rate, | ||
465 | * 3 if default mode is used, 4 if fall back to any valid mode. | ||
466 | * | ||
467 | */ | ||
468 | |||
469 | int fb_find_mode(struct fb_var_screeninfo *var, | ||
470 | struct fb_info *info, const char *mode_option, | ||
471 | const struct fb_videomode *db, unsigned int dbsize, | ||
472 | const struct fb_videomode *default_mode, | ||
473 | unsigned int default_bpp) | ||
474 | { | ||
475 | int i; | ||
476 | |||
477 | /* Set up defaults */ | ||
478 | if (!db) { | ||
479 | db = modedb; | ||
480 | dbsize = sizeof(modedb)/sizeof(*modedb); | ||
481 | } | ||
482 | if (!default_mode) | ||
483 | default_mode = &modedb[DEFAULT_MODEDB_INDEX]; | ||
484 | if (!default_bpp) | ||
485 | default_bpp = 8; | ||
486 | |||
487 | /* Did the user specify a video mode? */ | ||
488 | if (mode_option || (mode_option = global_mode_option)) { | ||
489 | const char *name = mode_option; | ||
490 | unsigned int namelen = strlen(name); | ||
491 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; | ||
492 | unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0; | ||
493 | int yres_specified = 0; | ||
494 | u32 best, diff; | ||
495 | |||
496 | for (i = namelen-1; i >= 0; i--) { | ||
497 | switch (name[i]) { | ||
498 | case '@': | ||
499 | namelen = i; | ||
500 | if (!refresh_specified && !bpp_specified && | ||
501 | !yres_specified) { | ||
502 | refresh = my_atoi(&name[i+1]); | ||
503 | refresh_specified = 1; | ||
504 | } else | ||
505 | goto done; | ||
506 | break; | ||
507 | case '-': | ||
508 | namelen = i; | ||
509 | if (!bpp_specified && !yres_specified) { | ||
510 | bpp = my_atoi(&name[i+1]); | ||
511 | bpp_specified = 1; | ||
512 | } else | ||
513 | goto done; | ||
514 | break; | ||
515 | case 'x': | ||
516 | if (!yres_specified) { | ||
517 | yres = my_atoi(&name[i+1]); | ||
518 | yres_specified = 1; | ||
519 | } else | ||
520 | goto done; | ||
521 | break; | ||
522 | case '0'...'9': | ||
523 | break; | ||
524 | default: | ||
525 | goto done; | ||
526 | } | ||
527 | } | ||
528 | if (i < 0 && yres_specified) { | ||
529 | xres = my_atoi(name); | ||
530 | res_specified = 1; | ||
531 | } | ||
532 | done: | ||
533 | DPRINTK("Trying specified video mode%s %ix%i\n", | ||
534 | refresh_specified ? "" : " (ignoring refresh rate)", xres, yres); | ||
535 | |||
536 | diff = refresh; | ||
537 | best = -1; | ||
538 | for (i = 0; i < dbsize; i++) { | ||
539 | if ((name_matches(db[i], name, namelen) && | ||
540 | !fb_try_mode(var, info, &db[i], bpp))) | ||
541 | return 1; | ||
542 | if (res_specified && res_matches(db[i], xres, yres)) { | ||
543 | if(!fb_try_mode(var, info, &db[i], bpp)) { | ||
544 | if(!refresh_specified || db[i].refresh == refresh) | ||
545 | return 1; | ||
546 | else { | ||
547 | if(diff > abs(db[i].refresh - refresh)) { | ||
548 | diff = abs(db[i].refresh - refresh); | ||
549 | best = i; | ||
550 | } | ||
551 | } | ||
552 | } | ||
553 | } | ||
554 | } | ||
555 | if (best != -1) { | ||
556 | fb_try_mode(var, info, &db[best], bpp); | ||
557 | return 2; | ||
558 | } | ||
559 | |||
560 | diff = xres + yres; | ||
561 | best = -1; | ||
562 | DPRINTK("Trying best-fit modes\n"); | ||
563 | for (i = 0; i < dbsize; i++) { | ||
564 | if (xres <= db[i].xres && yres <= db[i].yres) { | ||
565 | DPRINTK("Trying %ix%i\n", db[i].xres, db[i].yres); | ||
566 | if (!fb_try_mode(var, info, &db[i], bpp)) { | ||
567 | if (diff > (db[i].xres - xres) + (db[i].yres - yres)) { | ||
568 | diff = (db[i].xres - xres) + (db[i].yres - yres); | ||
569 | best = i; | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | } | ||
574 | if (best != -1) { | ||
575 | fb_try_mode(var, info, &db[best], bpp); | ||
576 | return 5; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | DPRINTK("Trying default video mode\n"); | ||
581 | if (!fb_try_mode(var, info, default_mode, default_bpp)) | ||
582 | return 3; | ||
583 | |||
584 | DPRINTK("Trying all modes\n"); | ||
585 | for (i = 0; i < dbsize; i++) | ||
586 | if (!fb_try_mode(var, info, &db[i], default_bpp)) | ||
587 | return 4; | ||
588 | |||
589 | DPRINTK("No valid mode found\n"); | ||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | /** | ||
594 | * fb_var_to_videomode - convert fb_var_screeninfo to fb_videomode | ||
595 | * @mode: pointer to struct fb_videomode | ||
596 | * @var: pointer to struct fb_var_screeninfo | ||
597 | */ | ||
598 | void fb_var_to_videomode(struct fb_videomode *mode, | ||
599 | struct fb_var_screeninfo *var) | ||
600 | { | ||
601 | u32 pixclock, hfreq, htotal, vtotal; | ||
602 | |||
603 | mode->name = NULL; | ||
604 | mode->xres = var->xres; | ||
605 | mode->yres = var->yres; | ||
606 | mode->pixclock = var->pixclock; | ||
607 | mode->hsync_len = var->hsync_len; | ||
608 | mode->vsync_len = var->vsync_len; | ||
609 | mode->left_margin = var->left_margin; | ||
610 | mode->right_margin = var->right_margin; | ||
611 | mode->upper_margin = var->upper_margin; | ||
612 | mode->lower_margin = var->lower_margin; | ||
613 | mode->sync = var->sync; | ||
614 | mode->vmode = var->vmode & FB_VMODE_MASK; | ||
615 | mode->flag = FB_MODE_IS_FROM_VAR; | ||
616 | if (!var->pixclock) | ||
617 | return; | ||
618 | |||
619 | pixclock = PICOS2KHZ(var->pixclock) * 1000; | ||
620 | |||
621 | htotal = var->xres + var->right_margin + var->hsync_len + | ||
622 | var->left_margin; | ||
623 | vtotal = var->yres + var->lower_margin + var->vsync_len + | ||
624 | var->upper_margin; | ||
625 | |||
626 | if (var->vmode & FB_VMODE_INTERLACED) | ||
627 | vtotal /= 2; | ||
628 | if (var->vmode & FB_VMODE_DOUBLE) | ||
629 | vtotal *= 2; | ||
630 | |||
631 | hfreq = pixclock/htotal; | ||
632 | mode->refresh = hfreq/vtotal; | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * fb_videomode_to_var - convert fb_videomode to fb_var_screeninfo | ||
637 | * @var: pointer to struct fb_var_screeninfo | ||
638 | * @mode: pointer to struct fb_videomode | ||
639 | */ | ||
640 | void fb_videomode_to_var(struct fb_var_screeninfo *var, | ||
641 | struct fb_videomode *mode) | ||
642 | { | ||
643 | var->xres = mode->xres; | ||
644 | var->yres = mode->yres; | ||
645 | var->pixclock = mode->pixclock; | ||
646 | var->left_margin = mode->left_margin; | ||
647 | var->hsync_len = mode->hsync_len; | ||
648 | var->vsync_len = mode->vsync_len; | ||
649 | var->right_margin = mode->right_margin; | ||
650 | var->upper_margin = mode->upper_margin; | ||
651 | var->lower_margin = mode->lower_margin; | ||
652 | var->sync = mode->sync; | ||
653 | var->vmode = mode->vmode & FB_VMODE_MASK; | ||
654 | } | ||
655 | |||
656 | /** | ||
657 | * fb_mode_is_equal - compare 2 videomodes | ||
658 | * @mode1: first videomode | ||
659 | * @mode2: second videomode | ||
660 | * | ||
661 | * RETURNS: | ||
662 | * 1 if equal, 0 if not | ||
663 | */ | ||
664 | int fb_mode_is_equal(struct fb_videomode *mode1, | ||
665 | struct fb_videomode *mode2) | ||
666 | { | ||
667 | return (mode1->xres == mode2->xres && | ||
668 | mode1->yres == mode2->yres && | ||
669 | mode1->pixclock == mode2->pixclock && | ||
670 | mode1->hsync_len == mode2->hsync_len && | ||
671 | mode1->vsync_len == mode2->vsync_len && | ||
672 | mode1->left_margin == mode2->left_margin && | ||
673 | mode1->right_margin == mode2->right_margin && | ||
674 | mode1->upper_margin == mode2->upper_margin && | ||
675 | mode1->lower_margin == mode2->lower_margin && | ||
676 | mode1->sync == mode2->sync && | ||
677 | mode1->vmode == mode2->vmode); | ||
678 | } | ||
679 | |||
680 | /** | ||
681 | * fb_find_best_mode - find best matching videomode | ||
682 | * @var: pointer to struct fb_var_screeninfo | ||
683 | * @head: pointer to struct list_head of modelist | ||
684 | * | ||
685 | * RETURNS: | ||
686 | * struct fb_videomode, NULL if none found | ||
687 | * | ||
688 | * IMPORTANT: | ||
689 | * This function assumes that all modelist entries in | ||
690 | * info->modelist are valid. | ||
691 | * | ||
692 | * NOTES: | ||
693 | * Finds best matching videomode which has an equal or greater dimension than | ||
694 | * var->xres and var->yres. If more than 1 videomode is found, will return | ||
695 | * the videomode with the highest refresh rate | ||
696 | */ | ||
697 | struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var, | ||
698 | struct list_head *head) | ||
699 | { | ||
700 | struct list_head *pos; | ||
701 | struct fb_modelist *modelist; | ||
702 | struct fb_videomode *mode, *best = NULL; | ||
703 | u32 diff = -1; | ||
704 | |||
705 | list_for_each(pos, head) { | ||
706 | u32 d; | ||
707 | |||
708 | modelist = list_entry(pos, struct fb_modelist, list); | ||
709 | mode = &modelist->mode; | ||
710 | |||
711 | if (mode->xres >= var->xres && mode->yres >= var->yres) { | ||
712 | d = (mode->xres - var->xres) + | ||
713 | (mode->yres - var->yres); | ||
714 | if (diff > d) { | ||
715 | diff = d; | ||
716 | best = mode; | ||
717 | } else if (diff == d && mode->refresh > best->refresh) | ||
718 | best = mode; | ||
719 | } | ||
720 | } | ||
721 | return best; | ||
722 | } | ||
723 | |||
724 | /** | ||
725 | * fb_find_nearest_mode - find mode closest video mode | ||
726 | * | ||
727 | * @var: pointer to struct fb_var_screeninfo | ||
728 | * @head: pointer to modelist | ||
729 | * | ||
730 | * Finds best matching videomode, smaller or greater in dimension. | ||
731 | * If more than 1 videomode is found, will return the videomode with | ||
732 | * the closest refresh rate | ||
733 | */ | ||
734 | struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var, | ||
735 | struct list_head *head) | ||
736 | { | ||
737 | struct list_head *pos; | ||
738 | struct fb_modelist *modelist; | ||
739 | struct fb_videomode *mode, *best = NULL; | ||
740 | u32 diff = -1, diff_refresh = -1; | ||
741 | |||
742 | list_for_each(pos, head) { | ||
743 | u32 d; | ||
744 | |||
745 | modelist = list_entry(pos, struct fb_modelist, list); | ||
746 | mode = &modelist->mode; | ||
747 | |||
748 | d = abs(mode->xres - var->xres) + | ||
749 | abs(mode->yres - var->yres); | ||
750 | if (diff > d) { | ||
751 | diff = d; | ||
752 | best = mode; | ||
753 | } else if (diff == d) { | ||
754 | d = abs(mode->refresh - best->refresh); | ||
755 | if (diff_refresh > d) { | ||
756 | diff_refresh = d; | ||
757 | best = mode; | ||
758 | } | ||
759 | } | ||
760 | } | ||
761 | |||
762 | return best; | ||
763 | } | ||
764 | |||
765 | /** | ||
766 | * fb_match_mode - find a videomode which exactly matches the timings in var | ||
767 | * @var: pointer to struct fb_var_screeninfo | ||
768 | * @head: pointer to struct list_head of modelist | ||
769 | * | ||
770 | * RETURNS: | ||
771 | * struct fb_videomode, NULL if none found | ||
772 | */ | ||
773 | struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var, | ||
774 | struct list_head *head) | ||
775 | { | ||
776 | struct list_head *pos; | ||
777 | struct fb_modelist *modelist; | ||
778 | struct fb_videomode *m, mode; | ||
779 | |||
780 | fb_var_to_videomode(&mode, var); | ||
781 | list_for_each(pos, head) { | ||
782 | modelist = list_entry(pos, struct fb_modelist, list); | ||
783 | m = &modelist->mode; | ||
784 | if (fb_mode_is_equal(m, &mode)) | ||
785 | return m; | ||
786 | } | ||
787 | return NULL; | ||
788 | } | ||
789 | |||
790 | /** | ||
791 | * fb_add_videomode: adds videomode entry to modelist | ||
792 | * @mode: videomode to add | ||
793 | * @head: struct list_head of modelist | ||
794 | * | ||
795 | * NOTES: | ||
796 | * Will only add unmatched mode entries | ||
797 | */ | ||
798 | int fb_add_videomode(struct fb_videomode *mode, struct list_head *head) | ||
799 | { | ||
800 | struct list_head *pos; | ||
801 | struct fb_modelist *modelist; | ||
802 | struct fb_videomode *m; | ||
803 | int found = 0; | ||
804 | |||
805 | list_for_each(pos, head) { | ||
806 | modelist = list_entry(pos, struct fb_modelist, list); | ||
807 | m = &modelist->mode; | ||
808 | if (fb_mode_is_equal(m, mode)) { | ||
809 | found = 1; | ||
810 | break; | ||
811 | } | ||
812 | } | ||
813 | if (!found) { | ||
814 | modelist = kmalloc(sizeof(struct fb_modelist), | ||
815 | GFP_KERNEL); | ||
816 | |||
817 | if (!modelist) | ||
818 | return -ENOMEM; | ||
819 | modelist->mode = *mode; | ||
820 | list_add(&modelist->list, head); | ||
821 | } | ||
822 | return 0; | ||
823 | } | ||
824 | |||
825 | /** | ||
826 | * fb_delete_videomode: removed videomode entry from modelist | ||
827 | * @mode: videomode to remove | ||
828 | * @head: struct list_head of modelist | ||
829 | * | ||
830 | * NOTES: | ||
831 | * Will remove all matching mode entries | ||
832 | */ | ||
833 | void fb_delete_videomode(struct fb_videomode *mode, struct list_head *head) | ||
834 | { | ||
835 | struct list_head *pos, *n; | ||
836 | struct fb_modelist *modelist; | ||
837 | struct fb_videomode *m; | ||
838 | |||
839 | list_for_each_safe(pos, n, head) { | ||
840 | modelist = list_entry(pos, struct fb_modelist, list); | ||
841 | m = &modelist->mode; | ||
842 | if (fb_mode_is_equal(m, mode)) { | ||
843 | list_del(pos); | ||
844 | kfree(pos); | ||
845 | } | ||
846 | } | ||
847 | } | ||
848 | |||
849 | /** | ||
850 | * fb_destroy_modelist: destroy modelist | ||
851 | * @head: struct list_head of modelist | ||
852 | */ | ||
853 | void fb_destroy_modelist(struct list_head *head) | ||
854 | { | ||
855 | struct list_head *pos, *n; | ||
856 | |||
857 | list_for_each_safe(pos, n, head) { | ||
858 | list_del(pos); | ||
859 | kfree(pos); | ||
860 | } | ||
861 | } | ||
862 | |||
863 | /** | ||
864 | * fb_videomode_to_modelist: convert mode array to mode list | ||
865 | * @modedb: array of struct fb_videomode | ||
866 | * @num: number of entries in array | ||
867 | * @head: struct list_head of modelist | ||
868 | */ | ||
869 | void fb_videomode_to_modelist(struct fb_videomode *modedb, int num, | ||
870 | struct list_head *head) | ||
871 | { | ||
872 | int i; | ||
873 | |||
874 | INIT_LIST_HEAD(head); | ||
875 | |||
876 | for (i = 0; i < num; i++) { | ||
877 | if (fb_add_videomode(&modedb[i], head)) | ||
878 | return; | ||
879 | } | ||
880 | } | ||
881 | |||
882 | EXPORT_SYMBOL(fb_videomode_to_var); | ||
883 | EXPORT_SYMBOL(fb_var_to_videomode); | ||
884 | EXPORT_SYMBOL(fb_mode_is_equal); | ||
885 | EXPORT_SYMBOL(fb_add_videomode); | ||
886 | EXPORT_SYMBOL(fb_delete_videomode); | ||
887 | EXPORT_SYMBOL(fb_destroy_modelist); | ||
888 | EXPORT_SYMBOL(fb_match_mode); | ||
889 | EXPORT_SYMBOL(fb_find_best_mode); | ||
890 | EXPORT_SYMBOL(fb_find_nearest_mode); | ||
891 | EXPORT_SYMBOL(fb_videomode_to_modelist); | ||
892 | EXPORT_SYMBOL(fb_find_mode); | ||