>From 80e0a2fac7c607ade81387f639c1eef9101b308b Mon Sep 17 00:00:00 2001
From: Matthias Hopf <mhopf@suse.de>
Date: Wed, 13 May 2009 15:44:51 +0200
Subject: [PATCH] Refactor AtomBIOS option handling.

---
 src/rhd_atombios.c |   86 +++++++++++++++++++++++++++++++++++++++++
 src/rhd_atombios.h |    3 +
 src/rhd_driver.c   |  107 +++++++---------------------------------------------
 3 files changed, 103 insertions(+), 93 deletions(-)

diff --git a/src/rhd_atombios.c b/src/rhd_atombios.c
index c055c6c..c30558c 100644
--- a/src/rhd_atombios.c
+++ b/src/rhd_atombios.c
@@ -436,6 +436,92 @@ CailDebug(int scrnIndex, const char *format, ...)
 
 #  endif
 
+static int
+rhdAtomBIOSGetArg(CARD32 *val, char *ptr)
+{
+    int cnt = 0;
+    if (isspace(*ptr) || *ptr == '=') {
+	ptr++;
+	cnt++;
+    }
+    if (!strncasecmp("off",ptr,3)) {
+	*val = RHD_ATOMBIOS_OFF;
+	return cnt + 3;
+    } else if (!strncasecmp("on",ptr,2)) {
+	*val = RHD_ATOMBIOS_ON;
+	return cnt + 2;
+    } else if (!strncasecmp("force_off",ptr,9)) {
+	*val = RHD_ATOMBIOS_OFF | RHD_ATOMBIOS_FORCE;
+	return cnt + 9;
+    } else if (!strncasecmp("force_on",ptr,8)) {
+	*val = RHD_ATOMBIOS_ON | RHD_ATOMBIOS_FORCE;
+	return cnt + 8;
+    } else
+	return 0;
+}
+
+int
+rhdUpdateAtomBIOSUsage(RHDPtr rhdPtr, char *string)
+{
+    char *ptr = string;
+    CARD32 val;
+
+    while (*ptr != '\0') {
+	int c;
+	while (isspace(*ptr))
+	    ptr++;
+	if (*ptr == '\0')
+	    break;
+
+	if (!strncasecmp("crtc",ptr,4)) {
+	    ptr += 4;
+	    if (!(c = rhdAtomBIOSGetArg(&val,ptr)))
+		return FALSE;
+	    ptr += c;
+	    rhdPtr->UseAtomFlags &= ~((RHD_ATOMBIOS_FORCE | RHD_ATOMBIOS_ON | RHD_ATOMBIOS_OFF) << RHD_ATOMBIOS_CRTC);
+	    rhdPtr->UseAtomFlags |= (val << RHD_ATOMBIOS_CRTC);
+	}
+	else if (!strncasecmp("output",ptr,6)) {
+	    ptr += 6;
+	    if (!(c = rhdAtomBIOSGetArg(&val,ptr)))
+		return FALSE;
+	    ptr += c;
+	    rhdPtr->UseAtomFlags &= ~((RHD_ATOMBIOS_FORCE | RHD_ATOMBIOS_ON | RHD_ATOMBIOS_OFF) << RHD_ATOMBIOS_OUTPUT);
+	    rhdPtr->UseAtomFlags |= (val << RHD_ATOMBIOS_OUTPUT);
+	}
+	else if (!strncasecmp("pll",ptr,3)) {
+	    ptr += 3;
+	    if (!(c = rhdAtomBIOSGetArg(&val,ptr)))
+		return FALSE;
+	    ptr += c;
+	    rhdPtr->UseAtomFlags &= ~((RHD_ATOMBIOS_FORCE | RHD_ATOMBIOS_ON | RHD_ATOMBIOS_OFF) << RHD_ATOMBIOS_PLL);
+	    rhdPtr->UseAtomFlags |= (val << RHD_ATOMBIOS_PLL);
+	} else
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+char *
+rhdReturnAtomBIOSUsage(RHDPtr rhdPtr)
+{
+    char *type[] = { "crtc", "output", "pll", NULL };
+    int  shift[] = { RHD_ATOMBIOS_CRTC, RHD_ATOMBIOS_OUTPUT, RHD_ATOMBIOS_PLL };
+    char *vals[] = { "", "on", "off", "unknown", "unknown", "force_on", "force_off", "unknown" };
+    int  i;
+    char buf[40];
+    char *p = buf;
+
+    for (i = 0; type[i]; i++) {
+	int val = (rhdPtr->UseAtomFlags >> shift[i]) & 0x07;
+	if (val)
+	    p += sprintf (p, "%s=%s ", type[i], vals[val]);
+    }
+    if (p != buf)
+	*--p = 0;
+    return strdup(buf);
+}
+
 #  define DEBUG_VERSION(index, handle, version) \
     xf86DrvMsgVerb(handle->scrnIndex, X_INFO, 3, "%s returned version %i for index 0x%x\n" ,__func__,version.cref,index)
 #  define DEBUG_VERSION_NAME(index, handle, name, version)		\
diff --git a/src/rhd_atombios.h b/src/rhd_atombios.h
index c1b73c4..d8f347f 100644
--- a/src/rhd_atombios.h
+++ b/src/rhd_atombios.h
@@ -490,6 +490,9 @@ struct atomCrtcBlank {
     unsigned short r, g, b;
 };
 
+extern int rhdUpdateAtomBIOSUsage(RHDPtr rhdPtr, char *string);
+extern char *rhdReturnAtomBIOSUsage(RHDPtr rhdPtr);
+
 extern AtomBiosResult RHDAtomBiosFunc(int scrnIndex, atomBiosHandlePtr handle,
 		AtomBiosRequestID id, AtomBiosArgPtr data);
 
diff --git a/src/rhd_driver.c b/src/rhd_driver.c
index 612fe4e..434d870 100644
--- a/src/rhd_driver.c
+++ b/src/rhd_driver.c
@@ -2625,94 +2625,6 @@ _RHDWritePLL(int scrnIndex, CARD16 offset, CARD32 data)
     RHDRegWrite(rhdPtr, CLOCK_CNTL_DATA, data);
 }
 
-#ifdef ATOM_BIOS
-
-/*
- *
- */
-static int
-rhdGetArg(ScrnInfoPtr pScrn, CARD32 *val, char *ptr)
-{
-    int cnt = 0;
-    if (isspace(*ptr) || *ptr == '=') {
-	ptr++;
-	cnt++;
-    }
-    if (!strncasecmp("off",ptr,3)) {
-	*val = RHD_ATOMBIOS_OFF;
-	return cnt + 3;
-    } else if (!strncasecmp("on",ptr,2)) {
-	*val = RHD_ATOMBIOS_ON;
-	return cnt + 2;
-    } else if (!strncasecmp("force_off",ptr,9)) {
-	*val = RHD_ATOMBIOS_OFF | RHD_ATOMBIOS_FORCE;
-	return cnt + 9;
-    } else if (!strncasecmp("force_on",ptr,8)) {
-	*val = RHD_ATOMBIOS_ON | RHD_ATOMBIOS_FORCE;
-	return cnt + 8;
-    } else
-	return 0;
-}
-
-/*
- *
- */
-static void
-rhdParseAtomBIOSUsage(ScrnInfoPtr pScrn)
-{
-    RHDPtr rhdPtr = RHDPTR(pScrn);
-    RHDOpt atombios;
-
-    RhdGetOptValString(rhdPtr->Options, OPTION_ATOMBIOS,
-		       &atombios, NULL);
-    if (atombios.set) {
-	if (atombios.val.string) {
-	    char *ptr = atombios.val.string;
-	    CARD32 val;
-
-	    while (*ptr != '\0') {
-		int c;
-		while (isspace(*ptr))
-		    ptr++;
-		if (*ptr == '\0')
-		    break;
-
-		if (!strncasecmp("crtc",ptr,4)) {
-		    ptr += 4;
-		    if (!(c = rhdGetArg(pScrn,&val,ptr)))
-			goto parse_error;
-		    ptr += c;
-		    rhdPtr->UseAtomFlags &= ~((RHD_ATOMBIOS_FORCE | RHD_ATOMBIOS_ON | RHD_ATOMBIOS_OFF) << RHD_ATOMBIOS_CRTC);
-		    rhdPtr->UseAtomFlags |= (val << RHD_ATOMBIOS_CRTC);
-		}
-		else if (!strncasecmp("output",ptr,6)) {
-		    ptr += 6;
-		    if (!(c = rhdGetArg(pScrn,&val,ptr)))
-			goto parse_error;
-		    ptr += c;
-		    rhdPtr->UseAtomFlags &= ~((RHD_ATOMBIOS_FORCE | RHD_ATOMBIOS_ON | RHD_ATOMBIOS_OFF) << RHD_ATOMBIOS_OUTPUT);
-		    rhdPtr->UseAtomFlags |= (val << RHD_ATOMBIOS_OUTPUT);
-		}
-		else if (!strncasecmp("pll",ptr,3)) {
-		    ptr += 3;
-		    if (!(c = rhdGetArg(pScrn,&val,ptr)))
-			goto parse_error;
-		    ptr += c;
-		    rhdPtr->UseAtomFlags &= ~((RHD_ATOMBIOS_FORCE | RHD_ATOMBIOS_ON | RHD_ATOMBIOS_OFF) << RHD_ATOMBIOS_PLL);
-		    rhdPtr->UseAtomFlags |= (val << RHD_ATOMBIOS_PLL);
-		} else goto parse_error;
-	    }
-	}
-    }
-    return;
-
-parse_error:
-    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot parse AtomBIOS usage string: %s\n",atombios.val.string);
-    rhdPtr->UseAtomFlags = 0;
-}
-
-#endif /* ATOM_BIOS */
-
 /*
  * Apart from handling the respective option, this also tries to map out
  * what method is supported on which chips.
@@ -2806,6 +2718,10 @@ rhdProcessOptions(ScrnInfoPtr pScrn)
 {
     RHDPtr rhdPtr = RHDPTR(pScrn);
     RHDOpt hpd;
+#ifdef ATOM_BIOS
+    RHDOpt atombios;
+#endif
+
     /* Collect all of the relevant option flags (fill in pScrn->options) */
     xf86CollectOptions(pScrn, NULL);
     rhdPtr->Options = xnfcalloc(sizeof(RHDOptions), 1);
@@ -2834,10 +2750,6 @@ rhdProcessOptions(ScrnInfoPtr pScrn)
 		       &rhdPtr->scaleTypeOpt, "default");
     RhdGetOptValBool   (rhdPtr->Options, OPTION_UNVERIFIED_FEAT,
 			&rhdPtr->unverifiedFeatures, FALSE);
-#ifdef ATOM_BIOS
-    RhdGetOptValBool   (rhdPtr->Options, OPTION_USE_ATOMBIOS,
-			&rhdPtr->UseAtomBIOS, FALSE);
-#endif
     RhdGetOptValBool   (rhdPtr->Options, OPTION_AUDIO,
 			&rhdPtr->audio, TRUE);
     RhdGetOptValString (rhdPtr->Options, OPTION_HDMI,
@@ -2850,8 +2762,17 @@ rhdProcessOptions(ScrnInfoPtr pScrn)
                         &rhdPtr->lowPowerModeEngineClock, 0);
 
 #ifdef ATOM_BIOS
-    rhdParseAtomBIOSUsage(pScrn);
+    RhdGetOptValBool   (rhdPtr->Options, OPTION_USE_ATOMBIOS,
+			&rhdPtr->UseAtomBIOS, FALSE);
+    RhdGetOptValString (rhdPtr->Options, OPTION_ATOMBIOS,
+			&atombios, NULL);
+    if (atombios.set && atombios.val.string) {
+	if (! rhdUpdateAtomBIOSUsage (rhdPtr, atombios.val.string))
+	    xf86DrvMsg(rhdPtr->scrnIndex, X_ERROR, "Cannot parse AtomBIOS usage string: %s\n",
+		       atombios.val.string);
+    }
 #endif
+
     rhdAccelOptionsHandle(pScrn);
 
     rhdPtr->hpdUsage = RHD_HPD_USAGE_AUTO;
-- 
1.6.0.2

