diff options
author | Antonino A. Daplas <adaplas@gmail.com> | 2005-11-07 04:00:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:53 -0500 |
commit | 003cfc0c56977f1c3ce48ddfd2073b7c6d75a5d8 (patch) | |
tree | 71095d3b794a6d6294b898a496c8a4e8664066bf | |
parent | 14c8102ffc9d08aa86fb08ed4bdb005768650e44 (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.c | 60 | ||||
-rw-r--r-- | include/linux/fb.h | 2 |
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 | ||
947 | struct 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; | ||
1002 | finished: | ||
1003 | return best; | ||
1004 | } | ||
1005 | EXPORT_SYMBOL(fb_find_best_display); | ||
1006 | |||
947 | EXPORT_SYMBOL(fb_videomode_to_var); | 1007 | EXPORT_SYMBOL(fb_videomode_to_var); |
948 | EXPORT_SYMBOL(fb_var_to_videomode); | 1008 | EXPORT_SYMBOL(fb_var_to_videomode); |
949 | EXPORT_SYMBOL(fb_mode_is_equal); | 1009 | EXPORT_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, | |||
902 | extern void fb_destroy_modelist(struct list_head *head); | 902 | extern void fb_destroy_modelist(struct list_head *head); |
903 | extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num, | 903 | extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num, |
904 | struct list_head *head); | 904 | struct list_head *head); |
905 | extern 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 */ |
907 | extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); | 909 | extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); |