]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - drivers/video/fbmon.c
i2c: tegra: Add stub runtime power management
[linux-2.6.git] / drivers / video / fbmon.c
index b9f47816fd958434debec1f5f8f06750e88b5451..62dd32b39aac8e29bb2890d8c7a83f0d185ff2c1 100644 (file)
@@ -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)
 {
@@ -993,7 +1003,7 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
                return;
 
        if (edid[0] != 0x2 ||
-           edid[2] < 4 || edid[2] > 128 - DETAILED_TIMING_DESCRIPTION_SIZE)
+           edid[2] < 4 || edid[2] > 128)
                return;
 
        DPRINTK("  Short Video Descriptors\n");
@@ -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];