aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbmon.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2011-08-25 08:36:40 -0400
committerFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2011-08-31 20:31:05 -0400
commit43dcd13b9a807ea9e832e4c6b138d825a7b65577 (patch)
treeb2adc72149baf0494b505d00802d0382f7d8d599 /drivers/video/fbmon.c
parentf88a91ccc8c341e6058c017823e2db266f374024 (diff)
fbdev: fix parsing of standard timings
The standard timings parses uses 1:1 dimensions when the ratio in the EDID data is 0. However, for EDID 1.3 and later the dimensions are 16:10 when the ratio is 0. Pass the version and revision numbers to get_std_timing() which can then make the right decision about dimensions. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com> Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video/fbmon.c')
-rw-r--r--drivers/video/fbmon.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 4f57485f8c54..cef65574db6c 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -493,7 +493,8 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode)
493 return num; 493 return num;
494} 494}
495 495
496static int get_std_timing(unsigned char *block, struct fb_videomode *mode) 496static int get_std_timing(unsigned char *block, struct fb_videomode *mode,
497 int ver, int rev)
497{ 498{
498 int xres, yres = 0, refresh, ratio, i; 499 int xres, yres = 0, refresh, ratio, i;
499 500
@@ -504,7 +505,11 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
504 ratio = (block[1] & 0xc0) >> 6; 505 ratio = (block[1] & 0xc0) >> 6;
505 switch (ratio) { 506 switch (ratio) {
506 case 0: 507 case 0:
507 yres = xres; 508 /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */
509 if (ver < 1 || (ver == 1 && rev < 3))
510 yres = xres;
511 else
512 yres = (xres * 10)/16;
508 break; 513 break;
509 case 1: 514 case 1:
510 yres = (xres * 3)/4; 515 yres = (xres * 3)/4;
@@ -533,12 +538,12 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode)
533} 538}
534 539
535static int get_dst_timing(unsigned char *block, 540static int get_dst_timing(unsigned char *block,
536 struct fb_videomode *mode) 541 struct fb_videomode *mode, int ver, int rev)
537{ 542{
538 int j, num = 0; 543 int j, num = 0;
539 544
540 for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE) 545 for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE)
541 num += get_std_timing(block, &mode[num]); 546 num += get_std_timing(block, &mode[num], ver, rev);
542 547
543 return num; 548 return num;
544} 549}
@@ -599,6 +604,10 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
599 struct fb_videomode *mode, *m; 604 struct fb_videomode *mode, *m;
600 unsigned char *block; 605 unsigned char *block;
601 int num = 0, i, first = 1; 606 int num = 0, i, first = 1;
607 int ver, rev;
608
609 ver = edid[EDID_STRUCT_VERSION];
610 rev = edid[EDID_STRUCT_REVISION];
602 611
603 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); 612 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
604 if (mode == NULL) 613 if (mode == NULL)
@@ -632,12 +641,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
632 DPRINTK(" Standard Timings\n"); 641 DPRINTK(" Standard Timings\n");
633 block = edid + STD_TIMING_DESCRIPTIONS_START; 642 block = edid + STD_TIMING_DESCRIPTIONS_START;
634 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) 643 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
635 num += get_std_timing(block, &mode[num]); 644 num += get_std_timing(block, &mode[num], ver, rev);
636 645
637 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 646 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
638 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { 647 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
639 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) 648 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
640 num += get_dst_timing(block + 5, &mode[num]); 649 num += get_dst_timing(block + 5, &mode[num], ver, rev);
641 } 650 }
642 651
643 /* Yikes, EDID data is totally useless */ 652 /* Yikes, EDID data is totally useless */