From: "Antonino A. Daplas" <adaplas@hotpop.com>

Add Viewsonic PF775a to broken display database

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/video/fbmon.c |   67 +++++++++++++++++++++++-------------------
 1 files changed, 37 insertions(+), 30 deletions(-)

diff -puN drivers/video/fbmon.c~fbdev-add-viewsonic-pf775a-to-broken-display-database drivers/video/fbmon.c
--- 25/drivers/video/fbmon.c~fbdev-add-viewsonic-pf775a-to-broken-display-database	Thu Dec 23 14:11:13 2004
+++ 25-akpm/drivers/video/fbmon.c	Thu Dec 23 14:11:13 2004
@@ -50,6 +50,7 @@
 #endif
 
 #define FBMON_FIX_HEADER 1
+#define FBMON_FIX_INPUT  2
 
 #ifdef CONFIG_FB_MODE_HELPERS
 struct broken_edid {
@@ -60,9 +61,16 @@ struct broken_edid {
 
 static struct broken_edid brokendb[] = {
 	/* DEC FR-PCXAV-YZ */
-	{ .manufacturer = "DEC",
-	  .model        = 0x073a,
-	  .fix          = FBMON_FIX_HEADER,
+	{
+		.manufacturer = "DEC",
+		.model        = 0x073a,
+		.fix          = FBMON_FIX_HEADER,
+	},
+	/* ViewSonic PF775a */
+	{
+		.manufacturer = "VSC",
+		.model        = 0x5a44,
+		.fix          = FBMON_FIX_INPUT,
 	},
 };
 
@@ -81,9 +89,10 @@ static void copy_string(unsigned char *c
   while (i-- && (*--s == 0x20)) *s = 0;
 }
 
-static void fix_broken_edid(unsigned char *edid)
+static void fix_edid(unsigned char *edid)
 {
 	unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
+	unsigned char *b;
 	u32 model, i;
 
 	manufacturer[0] = ((block[0] & 0x7c) >> 2) + '@';
@@ -96,15 +105,25 @@ static void fix_broken_edid(unsigned cha
 	for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
 		if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
 			brokendb[i].model == model) {
+
+			printk("fbmon: The EDID Block of "
+			       "Manufacturer: %s Model: 0x%x is known to "
+			       "be broken,\n",  manufacturer, model);
 			switch (brokendb[i].fix) {
 			case FBMON_FIX_HEADER:
-				printk("fbmon: The EDID header of "
-				       "Manufacturer: %s Model: 0x%x is "
-				       "known to be broken,\n"
-				       "fbmon: trying a header "
-				       "reconstruct\n", manufacturer, model);
+				printk("fbmon: trying a header "
+				       "reconstruct\n");
 				memcpy(edid, edid_v1_header, 8);
 				break;
+			case FBMON_FIX_INPUT:
+				printk("fbmon: trying to fix input type\n");
+				b = edid + EDID_STRUCT_DISPLAY;
+				/* Only if display is GTF capable will
+				   the input type be reset to analog */
+				if (b[4] & 0x01) {
+					b[0] &= ~0x80;
+					edid[127] += 0x80;
+				}
 			}
 		}
 	}
@@ -113,6 +132,9 @@ static void fix_broken_edid(unsigned cha
 static int edid_checksum(unsigned char *edid)
 {
 	unsigned char i, csum = 0, all_null = 0;
+	int err = 0;
+
+	fix_edid(edid);
 
 	for (i = 0; i < EDID_LENGTH; i++) {
 		csum += edid[i];
@@ -121,38 +143,23 @@ static int edid_checksum(unsigned char *
 
 	if (csum == 0x00 && all_null) {
 		/* checksum passed, everything's good */
-		return 1;
+		err = 1;
 	}
 
-	fix_broken_edid(edid);
-	csum = all_null = 0;
-	for (i = 0; i < EDID_LENGTH; i++) {
-		csum += edid[i];
-		all_null |= edid[i];
-	}
-	if (csum != 0x00 || !all_null) {
-		printk("EDID checksum failed, aborting\n");
-		return 0;
-	}
-	return 1;
+	return err;
 }
 
 static int edid_check_header(unsigned char *edid)
 {
-	int i, fix = 0;
+	int i, err = 1;
 
-	for (i = 0; i < 8; i++) {
-		if (edid[i] != edid_v1_header[i])
-			fix = 1;
-	}
-	if (!fix)
-		return 1;
+	fix_edid(edid);
 
-	fix_broken_edid(edid);
 	for (i = 0; i < 8; i++) {
 		if (edid[i] != edid_v1_header[i])
-			return 0;
+			err = 0;
 	}
+
 	return 1;
 }
 
_