diff options
-rw-r--r-- | drivers/video/fbmon.c | 37 | ||||
-rw-r--r-- | drivers/video/modedb.c | 43 | ||||
-rw-r--r-- | include/linux/fb.h | 1 |
3 files changed, 77 insertions, 4 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index b25399abcf49..4f57485f8c54 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -983,7 +983,8 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
983 | unsigned char *block; | 983 | unsigned char *block; |
984 | struct fb_videomode *m; | 984 | struct fb_videomode *m; |
985 | int num = 0, i; | 985 | int num = 0, i; |
986 | u8 edt[(128 - 4) / DETAILED_TIMING_DESCRIPTION_SIZE]; | 986 | u8 svd[64], edt[(128 - 4) / DETAILED_TIMING_DESCRIPTION_SIZE]; |
987 | u8 pos = 4, svd_n = 0; | ||
987 | 988 | ||
988 | if (!edid) | 989 | if (!edid) |
989 | return; | 990 | return; |
@@ -995,6 +996,21 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
995 | edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE) | 996 | edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE) |
996 | return; | 997 | return; |
997 | 998 | ||
999 | DPRINTK(" Short Video Descriptors\n"); | ||
1000 | |||
1001 | while (pos < edid[2]) { | ||
1002 | u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7; | ||
1003 | pr_debug("Data block %u of %u bytes\n", type, len); | ||
1004 | if (type == 2) | ||
1005 | for (i = pos; i < pos + len; i++) { | ||
1006 | u8 idx = edid[pos + i] & 0x7f; | ||
1007 | svd[svd_n++] = idx; | ||
1008 | pr_debug("N%sative mode #%d\n", | ||
1009 | edid[pos + i] & 0x80 ? "" : "on-n", idx); | ||
1010 | } | ||
1011 | pos += len + 1; | ||
1012 | } | ||
1013 | |||
998 | block = edid + edid[2]; | 1014 | block = edid + edid[2]; |
999 | 1015 | ||
1000 | DPRINTK(" Extended Detailed Timings\n"); | 1016 | DPRINTK(" Extended Detailed Timings\n"); |
@@ -1005,10 +1021,10 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
1005 | edt[num++] = block - edid; | 1021 | edt[num++] = block - edid; |
1006 | 1022 | ||
1007 | /* Yikes, EDID data is totally useless */ | 1023 | /* Yikes, EDID data is totally useless */ |
1008 | if (!num) | 1024 | if (!(num + svd_n)) |
1009 | return; | 1025 | return; |
1010 | 1026 | ||
1011 | m = kzalloc((specs->modedb_len + num) * | 1027 | m = kzalloc((specs->modedb_len + num + svd_n) * |
1012 | sizeof(struct fb_videomode), GFP_KERNEL); | 1028 | sizeof(struct fb_videomode), GFP_KERNEL); |
1013 | 1029 | ||
1014 | if (!m) | 1030 | if (!m) |
@@ -1023,9 +1039,22 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
1023 | pr_debug("Adding %ux%u@%u\n", m[i].xres, m[i].yres, m[i].refresh); | 1039 | pr_debug("Adding %ux%u@%u\n", m[i].xres, m[i].yres, m[i].refresh); |
1024 | } | 1040 | } |
1025 | 1041 | ||
1042 | for (i = specs->modedb_len + num; i < specs->modedb_len + num + svd_n; i++) { | ||
1043 | int idx = svd[i - specs->modedb_len - num]; | ||
1044 | if (!idx || idx > 63) { | ||
1045 | pr_warning("Reserved SVD code %d\n", idx); | ||
1046 | } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) { | ||
1047 | pr_warning("Unimplemented SVD code %d\n", idx); | ||
1048 | } else { | ||
1049 | memcpy(&m[i], cea_modes + idx, sizeof(m[i])); | ||
1050 | pr_debug("Adding SVD #%d: %ux%u@%u\n", idx, | ||
1051 | m[i].xres, m[i].yres, m[i].refresh); | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1026 | kfree(specs->modedb); | 1055 | kfree(specs->modedb); |
1027 | specs->modedb = m; | 1056 | specs->modedb = m; |
1028 | specs->modedb_len = specs->modedb_len + num; | 1057 | specs->modedb_len = specs->modedb_len + num + svd_n; |
1029 | } | 1058 | } |
1030 | 1059 | ||
1031 | /* | 1060 | /* |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 0a4dbdc1693a..9a0ae6ca5427 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -278,6 +278,49 @@ static const struct fb_videomode modedb[] = { | |||
278 | }; | 278 | }; |
279 | 279 | ||
280 | #ifdef CONFIG_FB_MODE_HELPERS | 280 | #ifdef CONFIG_FB_MODE_HELPERS |
281 | const struct fb_videomode cea_modes[64] = { | ||
282 | /* #1: 640x480p@59.94/60Hz */ | ||
283 | [1] = { | ||
284 | NULL, 60, 640, 480, 39722, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, 0, | ||
285 | }, | ||
286 | /* #3: 720x480p@59.94/60Hz */ | ||
287 | [3] = { | ||
288 | NULL, 60, 720, 480, 37037, 60, 16, 30, 9, 62, 6, 0, FB_VMODE_NONINTERLACED, 0, | ||
289 | }, | ||
290 | /* #5: 1920x1080i@59.94/60Hz */ | ||
291 | [5] = { | ||
292 | NULL, 60, 1920, 1080, 13763, 148, 88, 15, 2, 44, 5, 0, FB_VMODE_INTERLACED, 0, | ||
293 | }, | ||
294 | /* #7: 720(1440)x480iH@59.94/60Hz */ | ||
295 | [7] = { | ||
296 | NULL, 60, 1440, 480, 18554/*37108*/, 114, 38, 15, 4, 124, 3, 0, FB_VMODE_INTERLACED, 0, | ||
297 | }, | ||
298 | /* #9: 720(1440)x240pH@59.94/60Hz */ | ||
299 | [9] = { | ||
300 | NULL, 60, 1440, 240, 18554, 114, 38, 16, 4, 124, 3, 0, FB_VMODE_NONINTERLACED, 0, | ||
301 | }, | ||
302 | /* #18: 720x576pH@50Hz */ | ||
303 | [18] = { | ||
304 | NULL, 50, 720, 576, 37037, 68, 12, 39, 5, 64, 5, 0, FB_VMODE_NONINTERLACED, 0, | ||
305 | }, | ||
306 | /* #19: 1280x720p@50Hz */ | ||
307 | [19] = { | ||
308 | NULL, 50, 1280, 720, 13468, 220, 440, 20, 5, 40, 5, 0, FB_VMODE_NONINTERLACED, 0, | ||
309 | }, | ||
310 | /* #20: 1920x1080i@50Hz */ | ||
311 | [20] = { | ||
312 | NULL, 50, 1920, 1080, 13480, 148, 528, 15, 5, 528, 5, 0, FB_VMODE_INTERLACED, 0, | ||
313 | }, | ||
314 | /* #32: 1920x1080p@23.98/24Hz */ | ||
315 | [32] = { | ||
316 | NULL, 24, 1920, 1080, 13468, 148, 638, 36, 4, 44, 5, 0, FB_VMODE_NONINTERLACED, 0, | ||
317 | }, | ||
318 | /* #35: (2880)x480p4x@59.94/60Hz */ | ||
319 | [35] = { | ||
320 | NULL, 50, 2880, 480, 11100, 240, 64, 30, 9, 248, 6, 0, FB_VMODE_NONINTERLACED, 0, | ||
321 | }, | ||
322 | }; | ||
323 | |||
281 | const struct fb_videomode vesa_modes[] = { | 324 | const struct fb_videomode vesa_modes[] = { |
282 | /* 0 640x350-85 VESA */ | 325 | /* 0 640x350-85 VESA */ |
283 | { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, | 326 | { NULL, 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, |
diff --git a/include/linux/fb.h b/include/linux/fb.h index 6f0274d96f0c..e154a79b8322 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h | |||
@@ -1151,6 +1151,7 @@ struct fb_videomode { | |||
1151 | 1151 | ||
1152 | extern const char *fb_mode_option; | 1152 | extern const char *fb_mode_option; |
1153 | extern const struct fb_videomode vesa_modes[]; | 1153 | extern const struct fb_videomode vesa_modes[]; |
1154 | extern const struct fb_videomode cea_modes[64]; | ||
1154 | 1155 | ||
1155 | struct fb_modelist { | 1156 | struct fb_modelist { |
1156 | struct list_head list; | 1157 | struct list_head list; |