From 8352e987aaf28898bd40841b101de3f7e7b14223 Mon Sep 17 00:00:00 2001
From: Zephaniah E. Hull <warp@agamemnon.b5>
Date: Wed, 13 Jun 2007 15:05:20 -0400
Subject: [PATCH] Clean up the DCON sleep stuff, share the new code between the GX and LX.
Organization: One Laptop Per Child

---
 src/amd.h           |    1 +
 src/amd_common.c    |   47 ++++++++++++++++++++++++
 src/amd_gx_driver.c |   98 ++++++++++++++-------------------------------------
 src/amd_lx_driver.c |   54 ++++------------------------
 4 files changed, 82 insertions(+), 118 deletions(-)

diff --git a/src/amd.h b/src/amd.h
index 868fa25..a1f59fc 100644
--- a/src/amd.h
+++ b/src/amd.h
@@ -460,6 +460,7 @@ void geode_memory_to_screen_blt(unsigned long, unsigned long,
 				unsigned long, unsigned long, long, long, int);
 int GeodeGetRefreshRate(DisplayModePtr);
 void GeodeCopyGreyscale(unsigned char *, unsigned char *, int, int, int, int);
+int DCONDPMSSet(ScrnInfoPtr pScrni, int mode, int flags);
 
 /* amd_gx_video.c */
 
diff --git a/src/amd_common.c b/src/amd_common.c
index f7e0d73..4fa3814 100644
--- a/src/amd_common.c
+++ b/src/amd_common.c
@@ -156,3 +156,50 @@ GeodeCopyGreyscale(unsigned char *src, unsigned char *dst,
     src2 += srcPitch;
   }
 }
+
+
+/*
+ * Stuff for the OLPC DCON which is shared between the GX and LX.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include "amd.h"
+
+#define DCON_SLEEP_FILE "/sys/devices/platform/dcon/sleep"
+
+int
+DCONDPMSSet(ScrnInfoPtr pScrni, int mode, int flags)
+{
+  static int failed = 0;
+  int fd;
+  char value[1];
+
+  if (failed)
+    return 0;
+
+  fd = open(DCON_SLEEP_FILE, O_WRONLY);
+  if (fd < 0) {
+    failed = 1;
+    return 0;
+  }
+
+  switch (mode) {
+    case DPMSModeOn:
+      value[0] = '0';
+      break;
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+    case DPMSModeOff:
+      value[0] = '1';
+      break;
+  }
+
+  write (fd, value, sizeof(value));
+  close (fd);
+
+  return 1;
+}
+
diff --git a/src/amd_gx_driver.c b/src/amd_gx_driver.c
index 9989d59..adae7d2 100644
--- a/src/amd_gx_driver.c
+++ b/src/amd_gx_driver.c
@@ -1086,106 +1086,62 @@ GXPanelPower(int enable)
   WRITE_VID32(RCDF_POWER_MANAGEMENT, power);
 }
 
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-
-#define DCON_SLEEP_FILE "/sys/devices/platform/dcon/sleep"
-
-/* Set up the OLPC DCON to sleep if so requested */
-
-static void DCONSleep(int state)
-{
-	char val = (state) ? '1' : '0';
-	FILE *stream = fopen(DCON_SLEEP_FILE, "w");
-	if (stream == NULL) {
-		ErrorF("Couldn't open the DCON sleep file");
-		return;
-	}
-
-	fprintf(stream, "%c\n", val);
-	fclose(stream);
-}
-
 static void
 GXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags)
 {
-  static int dconAvail = -1;
-  int ret;
   GeodeRec *pGeode;
 
+  if (DCONDPMSSet(pScrni, mode, flags))
+    return;
+
   pGeode = GEODEPTR(pScrni);
 
   if (!pScrni->vtSema)
     return;
 
-  /* For now - we use the presence of the DCON sleep file as a positive
-     indicator that the DCON is attached.  This should be transitioned to
-     the device tree.
-   */
-
-  if (dconAvail == -1)
-    dconAvail = (!access(DCON_SLEEP_FILE, R_OK)) ? 1 : 0;
-
   switch (mode) {
   case DPMSModeOn:
-    if (dconAvail) {
-      DCONSleep(0);
-    } else {
-      /* Screen: On; HSync: On; VSync: On */
-      GFX(set_crt_enable(CRT_ENABLE));
+    /* Screen: On; HSync: On; VSync: On */
+    GFX(set_crt_enable(CRT_ENABLE));
 #if defined(PNL_SUP)
-      if (pGeode->Panel) {
-	Pnl_PowerUp();
-	GXPanelPower(1);
-      }
-#endif
+    if (pGeode->Panel) {
+      Pnl_PowerUp();
+      GXPanelPower(1);
     }
+#endif
     break;
 
   case DPMSModeStandby:
-    if (dconAvail) {
-      DCONSleep(1);
-    } else {
-      /* Screen: Off; HSync: Off; VSync: On */
-      GFX(set_crt_enable(CRT_STANDBY));
+    /* Screen: Off; HSync: Off; VSync: On */
+    GFX(set_crt_enable(CRT_STANDBY));
 #if defined(PNL_SUP)
-      if (pGeode->Panel) {
-	Pnl_PowerDown();
-	GXPanelPower(0);
-      }
-#endif
+    if (pGeode->Panel) {
+      Pnl_PowerDown();
+      GXPanelPower(0);
     }
+#endif
     break;
 
   case DPMSModeSuspend:
-    if (dconAvail) {
-      DCONSleep(1);
-    } else {
-      /* Screen: Off; HSync: On; VSync: Off */
-      GFX(set_crt_enable(CRT_SUSPEND));
+    /* Screen: Off; HSync: On; VSync: Off */
+    GFX(set_crt_enable(CRT_SUSPEND));
 #if defined(PNL_SUP)
-      if (pGeode->Panel) {
-	Pnl_PowerDown();
-	GXPanelPower(0);
-      }
-#endif
+    if (pGeode->Panel) {
+      Pnl_PowerDown();
+      GXPanelPower(0);
     }
+#endif
     break;
 
   case DPMSModeOff:
-    if (dconAvail) {
-      DCONSleep(1);
-    } else {
-      /* Screen: Off; HSync: Off; VSync: Off */
-      GFX(set_crt_enable(CRT_DISABLE));
+    /* Screen: Off; HSync: Off; VSync: Off */
+    GFX(set_crt_enable(CRT_DISABLE));
 #if defined(PNL_SUP)
-      if (pGeode->Panel) {
-	Pnl_PowerDown();
-	GXPanelPower(0);
-      }
-#endif
+    if (pGeode->Panel) {
+      Pnl_PowerDown();
+      GXPanelPower(0);
     }
+#endif
     break;
   }
 }
diff --git a/src/amd_lx_driver.c b/src/amd_lx_driver.c
index 1209ebd..cb42e37 100644
--- a/src/amd_lx_driver.c
+++ b/src/amd_lx_driver.c
@@ -1137,72 +1137,32 @@ LXLoadPalette(ScrnInfoPtr pScrni,
 
 #ifdef DPMSExtension
 
-#include <stdio.h>
-#include <unistd.h>
-
-#define DCON_SLEEP_FILE "/sys/devices/platform/dcon/sleep"
-
-/* Set up the OLPC DCON to sleep if so requested */
-
-static void DCONSleep(int state)
-{
-	char val = (state) ? '1' : '0';
-	FILE *stream = fopen(DCON_SLEEP_FILE, "w");
-	if (stream == NULL) {
-		ErrorF("Couldn't open the DCON sleep file");
-		return;
-	}
-
-	fprintf(stream, "%c\n", val);
-	fclose(stream);
-}
-
 static void
 LXDPMSSet(ScrnInfoPtr pScrni, int mode, int flags)
 {
-  static int dconAvail = -1;
-  GeodeRec *pGeode = GEODEPTR(pScrni);
-  
-    if (!pScrni->vtSema)
+    if (DCONDPMSSet(pScrni, mode, flags))
 	return;
 
-    /* For now - we use the presence of the DCON sleep file as a positive
-       indicator that the DCON is attached.  This should be transitioned to
-       the device tree.
-    */
+    if (!pScrni->vtSema)
+	return;
 
-    if (dconAvail == -1)
-      dconAvail = (!access(DCON_SLEEP_FILE, R_OK)) ? 1 : 0;
-    
     switch (mode) {
     case DPMSModeOn:
-      if (dconAvail == 1)
-	DCONSleep(0);
-      else
-	lx_enable_dac_power(pScrni, 1);
+      lx_enable_dac_power(pScrni, 1);
 
       break;
 
     case DPMSModeStandby:
-      if (dconAvail == 1)
-	DCONSleep(1);
-      else
-	lx_disable_dac_power(pScrni, DF_CRT_STANDBY);
+      lx_disable_dac_power(pScrni, DF_CRT_STANDBY);
 
       break;
 
     case DPMSModeSuspend:
-      if (dconAvail == 1)
-	DCONSleep(1);
-      else
-	lx_disable_dac_power(pScrni, DF_CRT_SUSPEND);
+      lx_disable_dac_power(pScrni, DF_CRT_SUSPEND);
       break;
 
     case DPMSModeOff:
-      if (dconAvail == 1)
-	DCONSleep(1);
-      else
-	lx_disable_dac_power(pScrni, DF_CRT_DISABLE);
+      lx_disable_dac_power(pScrni, DF_CRT_DISABLE);
       break;
     }
 }
-- 
1.5.2.2

