diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-08-25 08:36:40 -0400 |
---|---|---|
committer | Florian Tobias Schandinat <FlorianSchandinat@gmx.de> | 2011-08-31 20:31:05 -0400 |
commit | 43dcd13b9a807ea9e832e4c6b138d825a7b65577 (patch) | |
tree | b2adc72149baf0494b505d00802d0382f7d8d599 /drivers/video/fbmon.c | |
parent | f88a91ccc8c341e6058c017823e2db266f374024 (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.c | 21 |
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 | ||
496 | static int get_std_timing(unsigned char *block, struct fb_videomode *mode) | 496 | static 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 | ||
535 | static int get_dst_timing(unsigned char *block, | 540 | static 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 */ |