Re: Changes to via_drv.o solving problems of hardwired devices.

Damian Janusz Gruszka <[email protected]>
Newsgroups gmane.comp.xfree86.devel
Message-ID <OFADDB1CE6.8869342E-ONC1256FFE.0027A60D-C1256FFE.00440EF5@10.0.19>
Hi,
I wanted to use SR32, witch should reflect connected devices as stated in 
VIA's video bios interface specs.
Basically it should be OEM's independent. But I found some BIOS versions 
that doesn't handle it correctly.
Instead of correction (SR vs. CR), I redesigned this procedure to use int 
0x10 Function 0x4f14  bx=4
(video bios interface specs).
 Mit freundlichen Grüssen / with best regards 
Damian Gruszka



Kontron Embedded Modules GmbH 
"We create digital brains for a more intelligent world" 
Fon: +49 (0)40 20 00 90-0 
Fax: +49 (0)40 20 00 90-10 
email : [email protected] 
www.kontron-emea.com www.kontron-hh.com 



Luc Verhaegen <[email protected]> 
Sent by: [email protected]
11.05.2005 03:23
Please respond to
[email protected]


To
[email protected]
cc
[email protected]
Subject
Re: Changes to via_drv.o solving problems of hardwired devices.






On Mon, May 09, 2005 at 02:51:59PM +0200, damian gruszka wrote:
> Hello,
> to support "hardwired" TV and LVDS devices, which doesn't apear on I2O 
> bus I suggest following changes.
> The Option ConnectedDevice set the correesponding field in 
> VIABIOSInfo.Since my routine and the the "switch" for ActiveDevice
> are quite similar, I also risked to replace  this code  by  new 
> visually shorter  code.
> 
> via.patch  - contains combined changes done to  .c and .h files.
> via_driver.c.patch, via_bios.h.patch and via_bios.c.patch - patches in 
> separate files.
> 
> Pls. comment this changes.
> 
> Best Regards
> Damian
> 
You're grabbing a value from the CrtC registers [0x3d4/5] but your 
comments state SR32. SR tends to imply Sequencer register [0x3c4/5]. 
Please at least adjust one or the other.

How global is this? I wouldn't be one bit surprised if this was all very 
kontron specific. I've been bashed by igel over something their bios did 
differently than the via bios (memory sizing), so this wouldn't exactly 
be a first.

Also, from a quick review of the docs i scraped together, it seems that 
CR3E is the BIOS initialised active device listing. At least it seems to 
be that on the epia M. Then there's SR12, which (somewhat) outlines 
which is connected where...

Luc Verhaegen.
http://unichrome.sf.net/
_______________________________________________
Devel mailing list
[email protected]
http://XFree86.Org/mailman/listinfo/devel
via_driver.c.patch (application/octet-stream, 7.7 KB)
--- via_driver.c	2005-05-09 13:53:06.000000000 +0200
+++ ../via/via_driver.c	2005-05-11 13:37:09.178718080 +0200
@@ -152,7 +152,8 @@
     OPTION_CAP0_DEINTERLACE,
     OPTION_CAP1_DEINTERLACE,
     OPTION_CAP0_FIELDSWAP,
-    OPTION_DRIXINERAMA
+    OPTION_DRIXINERAMA,
+    OPTION_CONNECTED_DEVICE
 } VIAOpts;
 
 
@@ -184,9 +185,31 @@
     {OPTION_CAP1_DEINTERLACE, "Cap1Deinterlace",    OPTV_ANYSTR,  {0}, FALSE},
     {OPTION_CAP0_FIELDSWAP, "Cap0FieldSwap",    OPTV_BOOLEAN,  {0}, FALSE},
     {OPTION_DRIXINERAMA,  "DRIXINERAMA",    OPTV_BOOLEAN, {0}, FALSE},
+    {OPTION_CONNECTED_DEVICE,"ConnectedDevice",OPTV_ANYSTR,{0},FALSE},
     {-1,                NULL,           OPTV_NONE,    {0}, FALSE}
 };
 
+struct OutputDesc { char *Name;unsigned char Mask;};
+const static  struct OutputDesc Values[]=
+{
+	{"NONE",0} ,
+	{"BIOS",0xFF} ,
+	{"CRT",VIA_DEVICE_CRT1} ,
+	{"CRT ONLY",VIA_DEVICE_CRT1} ,
+        {"TV", VIA_DEVICE_TV},
+        {"TV ONLY", VIA_DEVICE_TV},
+        {"LCD",VIA_DEVICE_LCD},
+        {"LCD ONLY",VIA_DEVICE_LCD} ,
+	{"DVI",VIA_DEVICE_DFP},
+	{"DVI ONLY",VIA_DEVICE_DFP},
+	{"DFP",VIA_DEVICE_DFP},
+	{"DFP ONLY",VIA_DEVICE_DFP},
+	{"CRT2",VIA_DEVICE_CRT2}
+};
+static char *DevMask2Str[5]=
+{
+	"CRT","LCD","TV","DFP","CRT2"
+};
 
 static const char *vgaHWSymbols[] = {
     "vgaHWGetHWRec",
@@ -346,7 +369,8 @@
 XF86ModuleData viaModuleData = {&VIAVersRec, VIASetup, NULL};
 
 
-static pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin)
+/* static */ 
+pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
     static Bool setupDone = FALSE;
 
@@ -673,8 +697,67 @@
         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
     }
 }
+/***********************************************************
+ Purpose: sets connectedDevice map according to user requirements
 
+ Input:   string passed to driver via ConnectedDevice option
 
+ output:  mask of connected devices
+
+ Remarks: the option BIOS sets the value according to register SR32
+          ~ char negates the value;
+
+************************************************************/ 
+static unsigned char ParseDeviceMask(
+	ScrnInfoPtr  pScrn, 
+	const char *opt_value,
+	const char *opt_name,
+	const int  start)
+{
+        VIABIOSInfoPtr  pBIOSInfo;
+	unsigned char val=0;
+	VIAPtr  pVia = VIAPTR(pScrn);
+    	pBIOSInfo = pVia->pBIOSInfo;
+	do {
+		char str[5],neg=0;
+		unsigned char pv=0;
+		int  n;
+		int  err = 1;
+		const char *p=strchr(opt_value,',');
+		if(!p)
+			p = opt_value + strlen(opt_value);
+		if(*opt_value == '~') {
+			++opt_value;
+			neg=1;
+		}
+		if((n=p - opt_value) <= sizeof(str)) {
+			memcpy(str,opt_value,n*sizeof(str[0]));
+			str[n]='\0';
+			for(n=start;n<sizeof(Values)/sizeof(Values[0]);++n)
+        			if (!xf86NameCmp(str,Values[n].Name))
+					break;
+			if( n < (sizeof(Values)/sizeof(Values[0]))) {
+				pv=Values[n].Mask;
+				if(pv == 0xFF)
+					pv = VIAGetBIOSConnectedDevice(pScrn);
+				if(neg) 
+					val &= ~pv;
+				else
+					val |= pv;
+				err = 0;
+			}
+		}
+		if(err) {
+        		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
+			    "Option %s, value %s is unknown in this context.\n",
+				opt_name, opt_value);
+			
+		}
+		opt_value = p+ ((*p) ? 1:0);
+	} while(*opt_value);
+	return val;
+}
+/*****************************************************************/
 static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags)
 {
     EntityInfoPtr   pEnt;
@@ -984,53 +1067,22 @@
     /* ActiveDevice Option for device selection */
     pBIOSInfo->ActiveDevice = 0x00;
     if ((s = xf86GetOptValString(VIAOptions, OPTION_ACTIVEDEVICE))) {
-        if (!xf86NameCmp(s, "CRT,TV") || !xf86NameCmp(s, "TV,CRT")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_TV;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and TV.\n");
-        }
-        else if(!xf86NameCmp(s, "CRT,LCD") || !xf86NameCmp(s, "LCD,CRT")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_LCD;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and LCD.\n");
-        }
-        else if(!xf86NameCmp(s, "CRT,DFP") || !xf86NameCmp(s, "DFP,CRT")
-                || !xf86NameCmp(s, "CRT,DVI") || !xf86NameCmp(s, "DVI,CRT")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_DFP;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and DFP.\n");
-        }
-        else if(!xf86NameCmp(s, "TV,DFP") || !xf86NameCmp(s, "DFP,TV")
-                || !xf86NameCmp(s, "TV,DVI") || !xf86NameCmp(s, "DVI,TV")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_TV | VIA_DEVICE_DFP;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is TV and DFP.\n");
-        }
-#if 0
-        else if(!xf86NameCmp(s, "DFP,LCD") || !xf86NameCmp(s, "LCD,DFP")
-                || !xf86NameCmp(s, "LCD,DVI") || !xf86NameCmp(s, "DVI,LCD")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_DFP | VIA_DEVICE_LCD;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is DFP and LCD.\n");
-        }
-#endif
-        else if(!xf86NameCmp(s, "CRT") || !xf86NameCmp(s, "CRT ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT Only.\n");
-        }
-        else if(!xf86NameCmp(s, "LCD") || !xf86NameCmp(s, "LCD ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_LCD;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is LCD Only.\n");
-        }
-        else if(!xf86NameCmp(s, "TV") || !xf86NameCmp(s, "TV ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_TV;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is TV Only.\n");
-        }
-        else if(!xf86NameCmp(s, "DFP") || !xf86NameCmp(s, "DFP ONLY")
-                || !xf86NameCmp(s, "DVI") || !xf86NameCmp(s, "DVI ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_DFP;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is DFP Only.\n");
-        }
-        else {
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option \"%s\" can't recognize!, Active Device by default.\n", s);
-        }
+	char ActDevStr[128];
+	int k;
+    	pBIOSInfo->ActiveDevice = ParseDeviceMask(pScrn,s,"ActiveDevice",2);
+	ActDevStr[0]='\0';
+	for(k=0;k<5;++k) {
+		if( pBIOSInfo->ActiveDevice & (1<<k)) {
+			strcat(ActDevStr,DevMask2Str[k]);
+			strcat(ActDevStr,",");
+		}
+	}
+	k = strlen(ActDevStr);
+	if(k)
+		ActDevStr[k-1]='\0'; /* remove last , */
+        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active device is %s.\n",
+		ActDevStr);
     }
-
     /* LCDDualEdge Option */
     pBIOSInfo->LCDDualEdge = FALSE;
     if (xf86ReturnOptValBool(VIAOptions, OPTION_LCDDUALEDGE, FALSE)) {
@@ -1039,7 +1091,9 @@
          "Option: Using Dual Edge mode to set LCD\n");
     }
     else {
-        pBIOSInfo->LCDDualEdge = FALSE;
+	if((pBIOSInfo->ActiveDevice & VIA_DEVICE_LCD)
+	  && (pBIOSInfo->ActiveDevice & (~VIA_DEVICE_LCD)))
+        	pBIOSInfo->LCDDualEdge = TRUE;
     }
 
     /* Digital Output Bus Width Option */
@@ -1306,6 +1360,12 @@
         vbeFree(pVia->pVbe);
         return FALSE;
     }
+    /* now we can check what devices are connected */
+    pBIOSInfo->ConnectedDevice=0;
+    if ((s = xf86GetOptValString(VIAOptions, OPTION_CONNECTED_DEVICE))) {
+    	pBIOSInfo->ConnectedDevice = 
+		ParseDeviceMask(pScrn,s,"ConnectedDevice",0);
+    }
 
     /* Get BIOS ver. From BIOS Call Function */
     tmp = VIABIOS_GetBIOSVersion(pScrn);
@@ -1492,7 +1552,8 @@
     /* Detect TMDS/LVDS Encoder */
     VIAPostDVI(pBIOSInfo);
 	/*VIAGetPanelInfo(pBIOSInfo);*/
-    pBIOSInfo->ConnectedDevice = VIAGetDeviceDetect(pBIOSInfo);
+    if(!pBIOSInfo->ConnectedDevice)
+    	pBIOSInfo->ConnectedDevice = VIAGetDeviceDetect(pBIOSInfo);
 
     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
     pScrn->currentMode = pScrn->modes;
via.patch (application/octet-stream, 9.1 KB)
diff -r -u ./via_bios.c ../via/via_bios.c
--- ./via_bios.c	2005-05-11 13:53:19.260243272 +0200
+++ ../via/via_bios.c	2005-05-11 13:37:35.574705280 +0200
@@ -12556,3 +12556,22 @@
 
     return TRUE;
 }
+/*************************************************
+ Name   :  VIAGetBIOSConnectedDevice
+ Purpose:  Check BIOS for connected devices
+ Input  :  Pointer to VIA structure
+ Output :  Connected mask, conform to Int 0x10,ax=1414 bx=0x3 
+*************************************************/
+unsigned char  VIAGetBIOSConnectedDevice(ScrnInfoPtr pScrn)
+{
+    VIAPtr  pVia = VIAPTR(pScrn);
+    pVia->pInt10->ax = 0x4F14;
+    pVia->pInt10->bx = 0x4;
+    pVia->pInt10->cx = 0;
+    xf86ExecX86int10(pVia->pInt10);
+    if (pVia->pInt10->ax  != 0x4f /* include status for test */) {
+	/* the user should specify it manually or use the standard procedure */
+	return 0;
+    }
+    return pVia->pInt10->cx;
+}
diff -r -u ./via_bios.h ../via/via_bios.h
--- ./via_bios.h	2005-05-11 13:53:19.261243120 +0200
+++ ../via/via_bios.h	2005-05-11 13:32:20.939537096 +0200
@@ -707,5 +707,5 @@
 void VIAEnabledPrimaryExtendedFIFO(VIABIOSInfoPtr pBIOSInfo);
 void VIAEnabledSecondaryExtendedFIFO(VIABIOSInfoPtr pBIOSInfo);
 void VIAFillExpireNumber(VIABIOSInfoPtr pBIOSInfo);
-
+unsigned char  VIAGetBIOSConnectedDevice(ScrnInfoPtr pScrn);
 #endif /* _VIA_BIOS_H_ */
Nur in .: via_bios.s.
diff -r -u ./via_driver.c ../via/via_driver.c
--- ./via_driver.c	2005-05-11 13:53:19.269241904 +0200
+++ ../via/via_driver.c	2005-05-11 13:37:09.178718080 +0200
@@ -152,7 +152,8 @@
     OPTION_CAP0_DEINTERLACE,
     OPTION_CAP1_DEINTERLACE,
     OPTION_CAP0_FIELDSWAP,
-    OPTION_DRIXINERAMA
+    OPTION_DRIXINERAMA,
+    OPTION_CONNECTED_DEVICE
 } VIAOpts;
 
 
@@ -184,9 +185,31 @@
     {OPTION_CAP1_DEINTERLACE, "Cap1Deinterlace",    OPTV_ANYSTR,  {0}, FALSE},
     {OPTION_CAP0_FIELDSWAP, "Cap0FieldSwap",    OPTV_BOOLEAN,  {0}, FALSE},
     {OPTION_DRIXINERAMA,  "DRIXINERAMA",    OPTV_BOOLEAN, {0}, FALSE},
+    {OPTION_CONNECTED_DEVICE,"ConnectedDevice",OPTV_ANYSTR,{0},FALSE},
     {-1,                NULL,           OPTV_NONE,    {0}, FALSE}
 };
 
+struct OutputDesc { char *Name;unsigned char Mask;};
+const static  struct OutputDesc Values[]=
+{
+	{"NONE",0} ,
+	{"BIOS",0xFF} ,
+	{"CRT",VIA_DEVICE_CRT1} ,
+	{"CRT ONLY",VIA_DEVICE_CRT1} ,
+        {"TV", VIA_DEVICE_TV},
+        {"TV ONLY", VIA_DEVICE_TV},
+        {"LCD",VIA_DEVICE_LCD},
+        {"LCD ONLY",VIA_DEVICE_LCD} ,
+	{"DVI",VIA_DEVICE_DFP},
+	{"DVI ONLY",VIA_DEVICE_DFP},
+	{"DFP",VIA_DEVICE_DFP},
+	{"DFP ONLY",VIA_DEVICE_DFP},
+	{"CRT2",VIA_DEVICE_CRT2}
+};
+static char *DevMask2Str[5]=
+{
+	"CRT","LCD","TV","DFP","CRT2"
+};
 
 static const char *vgaHWSymbols[] = {
     "vgaHWGetHWRec",
@@ -346,7 +369,8 @@
 XF86ModuleData viaModuleData = {&VIAVersRec, VIASetup, NULL};
 
 
-static pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin)
+/* static */ 
+pointer VIASetup(pointer module, pointer opts, int *errmaj, int *errmin)
 {
     static Bool setupDone = FALSE;
 
@@ -673,8 +697,67 @@
         ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
     }
 }
+/***********************************************************
+ Purpose: sets connectedDevice map according to user requirements
 
+ Input:   string passed to driver via ConnectedDevice option
 
+ output:  mask of connected devices
+
+ Remarks: the option BIOS sets the value according to register SR32
+          ~ char negates the value;
+
+************************************************************/ 
+static unsigned char ParseDeviceMask(
+	ScrnInfoPtr  pScrn, 
+	const char *opt_value,
+	const char *opt_name,
+	const int  start)
+{
+        VIABIOSInfoPtr  pBIOSInfo;
+	unsigned char val=0;
+	VIAPtr  pVia = VIAPTR(pScrn);
+    	pBIOSInfo = pVia->pBIOSInfo;
+	do {
+		char str[5],neg=0;
+		unsigned char pv=0;
+		int  n;
+		int  err = 1;
+		const char *p=strchr(opt_value,',');
+		if(!p)
+			p = opt_value + strlen(opt_value);
+		if(*opt_value == '~') {
+			++opt_value;
+			neg=1;
+		}
+		if((n=p - opt_value) <= sizeof(str)) {
+			memcpy(str,opt_value,n*sizeof(str[0]));
+			str[n]='\0';
+			for(n=start;n<sizeof(Values)/sizeof(Values[0]);++n)
+        			if (!xf86NameCmp(str,Values[n].Name))
+					break;
+			if( n < (sizeof(Values)/sizeof(Values[0]))) {
+				pv=Values[n].Mask;
+				if(pv == 0xFF)
+					pv = VIAGetBIOSConnectedDevice(pScrn);
+				if(neg) 
+					val &= ~pv;
+				else
+					val |= pv;
+				err = 0;
+			}
+		}
+		if(err) {
+        		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
+			    "Option %s, value %s is unknown in this context.\n",
+				opt_name, opt_value);
+			
+		}
+		opt_value = p+ ((*p) ? 1:0);
+	} while(*opt_value);
+	return val;
+}
+/*****************************************************************/
 static Bool VIAPreInit(ScrnInfoPtr pScrn, int flags)
 {
     EntityInfoPtr   pEnt;
@@ -984,53 +1067,22 @@
     /* ActiveDevice Option for device selection */
     pBIOSInfo->ActiveDevice = 0x00;
     if ((s = xf86GetOptValString(VIAOptions, OPTION_ACTIVEDEVICE))) {
-        if (!xf86NameCmp(s, "CRT,TV") || !xf86NameCmp(s, "TV,CRT")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_TV;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and TV.\n");
-        }
-        else if(!xf86NameCmp(s, "CRT,LCD") || !xf86NameCmp(s, "LCD,CRT")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_LCD;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and LCD.\n");
-        }
-        else if(!xf86NameCmp(s, "CRT,DFP") || !xf86NameCmp(s, "DFP,CRT")
-                || !xf86NameCmp(s, "CRT,DVI") || !xf86NameCmp(s, "DVI,CRT")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1 | VIA_DEVICE_DFP;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT and DFP.\n");
-        }
-        else if(!xf86NameCmp(s, "TV,DFP") || !xf86NameCmp(s, "DFP,TV")
-                || !xf86NameCmp(s, "TV,DVI") || !xf86NameCmp(s, "DVI,TV")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_TV | VIA_DEVICE_DFP;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is TV and DFP.\n");
-        }
-#if 0
-        else if(!xf86NameCmp(s, "DFP,LCD") || !xf86NameCmp(s, "LCD,DFP")
-                || !xf86NameCmp(s, "LCD,DVI") || !xf86NameCmp(s, "DVI,LCD")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_DFP | VIA_DEVICE_LCD;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is DFP and LCD.\n");
-        }
-#endif
-        else if(!xf86NameCmp(s, "CRT") || !xf86NameCmp(s, "CRT ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_CRT1;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is CRT Only.\n");
-        }
-        else if(!xf86NameCmp(s, "LCD") || !xf86NameCmp(s, "LCD ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_LCD;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is LCD Only.\n");
-        }
-        else if(!xf86NameCmp(s, "TV") || !xf86NameCmp(s, "TV ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_TV;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is TV Only.\n");
-        }
-        else if(!xf86NameCmp(s, "DFP") || !xf86NameCmp(s, "DFP ONLY")
-                || !xf86NameCmp(s, "DVI") || !xf86NameCmp(s, "DVI ONLY")) {
-            pBIOSInfo->ActiveDevice = VIA_DEVICE_DFP;
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active Device is DFP Only.\n");
-        }
-        else {
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option \"%s\" can't recognize!, Active Device by default.\n", s);
-        }
+	char ActDevStr[128];
+	int k;
+    	pBIOSInfo->ActiveDevice = ParseDeviceMask(pScrn,s,"ActiveDevice",2);
+	ActDevStr[0]='\0';
+	for(k=0;k<5;++k) {
+		if( pBIOSInfo->ActiveDevice & (1<<k)) {
+			strcat(ActDevStr,DevMask2Str[k]);
+			strcat(ActDevStr,",");
+		}
+	}
+	k = strlen(ActDevStr);
+	if(k)
+		ActDevStr[k-1]='\0'; /* remove last , */
+        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Active device is %s.\n",
+		ActDevStr);
     }
-
     /* LCDDualEdge Option */
     pBIOSInfo->LCDDualEdge = FALSE;
     if (xf86ReturnOptValBool(VIAOptions, OPTION_LCDDUALEDGE, FALSE)) {
@@ -1039,7 +1091,9 @@
          "Option: Using Dual Edge mode to set LCD\n");
     }
     else {
-        pBIOSInfo->LCDDualEdge = FALSE;
+	if((pBIOSInfo->ActiveDevice & VIA_DEVICE_LCD)
+	  && (pBIOSInfo->ActiveDevice & (~VIA_DEVICE_LCD)))
+        	pBIOSInfo->LCDDualEdge = TRUE;
     }
 
     /* Digital Output Bus Width Option */
@@ -1306,6 +1360,12 @@
         vbeFree(pVia->pVbe);
         return FALSE;
     }
+    /* now we can check what devices are connected */
+    pBIOSInfo->ConnectedDevice=0;
+    if ((s = xf86GetOptValString(VIAOptions, OPTION_CONNECTED_DEVICE))) {
+    	pBIOSInfo->ConnectedDevice = 
+		ParseDeviceMask(pScrn,s,"ConnectedDevice",0);
+    }
 
     /* Get BIOS ver. From BIOS Call Function */
     tmp = VIABIOS_GetBIOSVersion(pScrn);
@@ -1492,7 +1552,8 @@
     /* Detect TMDS/LVDS Encoder */
     VIAPostDVI(pBIOSInfo);
 	/*VIAGetPanelInfo(pBIOSInfo);*/
-    pBIOSInfo->ConnectedDevice = VIAGetDeviceDetect(pBIOSInfo);
+    if(!pBIOSInfo->ConnectedDevice)
+    	pBIOSInfo->ConnectedDevice = VIAGetDeviceDetect(pBIOSInfo);
 
     xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
     pScrn->currentMode = pScrn->modes;
via_bios.c.patch (application/octet-stream, 863 B)
--- via_bios.c	2005-05-09 13:53:06.000000000 +0200
+++ ../via/via_bios.c	2005-05-11 13:37:35.574705280 +0200
@@ -12556,3 +12556,22 @@
 
     return TRUE;
 }
+/*************************************************
+ Name   :  VIAGetBIOSConnectedDevice
+ Purpose:  Check BIOS for connected devices
+ Input  :  Pointer to VIA structure
+ Output :  Connected mask, conform to Int 0x10,ax=1414 bx=0x3 
+*************************************************/
+unsigned char  VIAGetBIOSConnectedDevice(ScrnInfoPtr pScrn)
+{
+    VIAPtr  pVia = VIAPTR(pScrn);
+    pVia->pInt10->ax = 0x4F14;
+    pVia->pInt10->bx = 0x4;
+    pVia->pInt10->cx = 0;
+    xf86ExecX86int10(pVia->pInt10);
+    if (pVia->pInt10->ax  != 0x4f /* include status for test */) {
+	/* the user should specify it manually or use the standard procedure */
+	return 0;
+    }
+    return pVia->pInt10->cx;
+}
via_bios.h.patch (application/octet-stream, 401 B)
--- via_bios.h	2005-05-09 13:53:06.000000000 +0200
+++ ../via/via_bios.h	2005-05-11 13:32:20.939537096 +0200
@@ -707,5 +707,5 @@
 void VIAEnabledPrimaryExtendedFIFO(VIABIOSInfoPtr pBIOSInfo);
 void VIAEnabledSecondaryExtendedFIFO(VIABIOSInfoPtr pBIOSInfo);
 void VIAFillExpireNumber(VIABIOSInfoPtr pBIOSInfo);
-
+unsigned char  VIAGetBIOSConnectedDevice(ScrnInfoPtr pScrn);
 #endif /* _VIA_BIOS_H_ */
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.