diff options
Diffstat (limited to 'drivers/video/fbmon.c')
-rw-r--r-- | drivers/video/fbmon.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 4f57485..f3fa446 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -546,6 +546,9 @@ static int get_dst_timing(unsigned char *block, static void get_detailed_timing(unsigned char *block, struct fb_videomode *mode) { + int v_size = V_SIZE; + int h_size = H_SIZE; + mode->xres = H_ACTIVE; mode->yres = V_ACTIVE; mode->pixclock = PIXEL_CLOCK; @@ -574,11 +577,18 @@ static void get_detailed_timing(unsigned char *block, } mode->flag = FB_MODE_IS_DETAILED; + /* get aspect ratio */ + if (h_size * 18 > v_size * 31 && h_size * 18 < v_size * 33) + mode->flag |= FB_FLAG_RATIO_16_9; + if (h_size * 18 > v_size * 23 && h_size * 18 < v_size * 25) + mode->flag |= FB_FLAG_RATIO_4_3; + DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000); DPRINTK("%d %d %d %d ", H_ACTIVE, H_ACTIVE + H_SYNC_OFFSET, H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH, H_ACTIVE + H_BLANKING); DPRINTK("%d %d %d %d ", V_ACTIVE, V_ACTIVE + V_SYNC_OFFSET, V_ACTIVE + V_SYNC_OFFSET + V_SYNC_WIDTH, V_ACTIVE + V_BLANKING); + DPRINTK("%dmm %dmm ", H_SIZE, V_SIZE); DPRINTK("%sHSync %sVSync\n\n", (HSYNC_POSITIVE) ? "+" : "-", (VSYNC_POSITIVE) ? "+" : "-"); } @@ -976,7 +986,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) /** * fb_edid_add_monspecs() - add monitor video modes from E-EDID data * @edid: 128 byte array with an E-EDID block - * @spacs: monitor specs to be extended + * @specs: monitor specs to be extended */ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) { @@ -1001,14 +1011,23 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) while (pos < edid[2]) { u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7; pr_debug("Data block %u of %u bytes\n", type, len); - if (type == 2) + + pos++; + if (type == 2) { for (i = pos; i < pos + len; i++) { - u8 idx = edid[pos + i] & 0x7f; + u8 idx = edid[i] & 0x7f; svd[svd_n++] = idx; pr_debug("N%sative mode #%d\n", - edid[pos + i] & 0x80 ? "" : "on-n", idx); + edid[i] & 0x80 ? "" : "on-n", idx); } - pos += len + 1; + } else if (type == 3 && len >= 3) { + u32 ieee_reg = edid[pos] | (edid[pos + 1] << 8) | + (edid[pos + 2] << 16); + if (ieee_reg == 0x000c03) + specs->misc |= FB_MISC_HDMI; + } + + pos += len; } block = edid + edid[2]; @@ -1041,10 +1060,8 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs) for (i = specs->modedb_len + num; i < specs->modedb_len + num + svd_n; i++) { int idx = svd[i - specs->modedb_len - num]; - if (!idx || idx > 63) { + if (!idx || idx > (CEA_MODEDB_SIZE - 1)) { pr_warning("Reserved SVD code %d\n", idx); - } else if (idx > ARRAY_SIZE(cea_modes) || !cea_modes[idx].xres) { - pr_warning("Unimplemented SVD code %d\n", idx); } else { memcpy(&m[i], cea_modes + idx, sizeof(m[i])); pr_debug("Adding SVD #%d: %ux%u@%u\n", idx, |