aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2005-11-07 04:00:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:53 -0500
commit003cfc0c56977f1c3ce48ddfd2073b7c6d75a5d8 (patch)
tree71095d3b794a6d6294b898a496c8a4e8664066bf
parent14c8102ffc9d08aa86fb08ed4bdb005768650e44 (diff)
[PATCH] fbdev: Add helper to get an appropriate initial mode
Add new helper, fb_find_best_display(), which will search the modelist for the best mode for the attached display. This requires an EDID block that is converted to struct fb_monspecs and a private modelist. The search will be done in this manner: - if 1st detailed timing is preferred, use that - else if dimensions of the display are known, use that to estimate xres and - else if modelist has detailed timings, use the first detailed timing - else, use the very first entry from the modelist Signed-off-by: Antonino Daplas <adaplas@pol.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/video/modedb.c60
-rw-r--r--include/linux/fb.h2
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index aadef046ce7b..1789a52d776a 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -944,6 +944,66 @@ void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
944 } 944 }
945} 945}
946 946
947struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
948 struct list_head *head)
949{
950 struct list_head *pos;
951 struct fb_modelist *modelist;
952 struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
953 int first = 0;
954
955 if (!head->prev || !head->next || list_empty(head))
956 goto finished;
957
958 /* get the first detailed mode and the very first mode */
959 list_for_each(pos, head) {
960 modelist = list_entry(pos, struct fb_modelist, list);
961 m = &modelist->mode;
962
963 if (!first) {
964 m1 = m;
965 first = 1;
966 }
967
968 if (m->flag & FB_MODE_IS_FIRST) {
969 md = m;
970 break;
971 }
972 }
973
974 /* first detailed timing is preferred */
975 if (specs->misc & FB_MISC_1ST_DETAIL) {
976 best = md;
977 goto finished;
978 }
979
980 /* find best mode based on display width and height */
981 if (specs->max_x && specs->max_y) {
982 struct fb_var_screeninfo var;
983
984 memset(&var, 0, sizeof(struct fb_var_screeninfo));
985 var.xres = (specs->max_x * 7200)/254;
986 var.yres = (specs->max_y * 7200)/254;
987 m = fb_find_best_mode(&var, head);
988 if (m) {
989 best = m;
990 goto finished;
991 }
992 }
993
994 /* use first detailed mode */
995 if (md) {
996 best = md;
997 goto finished;
998 }
999
1000 /* last resort, use the very first mode */
1001 best = m1;
1002finished:
1003 return best;
1004}
1005EXPORT_SYMBOL(fb_find_best_display);
1006
947EXPORT_SYMBOL(fb_videomode_to_var); 1007EXPORT_SYMBOL(fb_videomode_to_var);
948EXPORT_SYMBOL(fb_var_to_videomode); 1008EXPORT_SYMBOL(fb_var_to_videomode);
949EXPORT_SYMBOL(fb_mode_is_equal); 1009EXPORT_SYMBOL(fb_mode_is_equal);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 68a787914d85..e7ff98e395f6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -902,6 +902,8 @@ extern struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
902extern void fb_destroy_modelist(struct list_head *head); 902extern void fb_destroy_modelist(struct list_head *head);
903extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num, 903extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
904 struct list_head *head); 904 struct list_head *head);
905extern struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
906 struct list_head *head);
905 907
906/* drivers/video/fbcmap.c */ 908/* drivers/video/fbcmap.c */
907extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); 909extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);