[Intel-gfx] [PATCH] Use enable bit for LVDS detect

Wang, Zhenyu Z zhenyu.z.wang at intel.com
Wed Nov 26 07:30:55 CET 2008


On 2008.11.26 09:06:26 +0800, Wang, Zhenyu Z wrote:
> > 
> > So you just find the first non-special directory entry in the lid dir?  Is one 
> > always guaranteed to exist?
> > 
> 
> If 'lid' dir exists under 'button' dir, that means there's a LID device found,
> and acpi button will create a subdir. And above code has also checked if no LID
> device was found.
> 
> And there's another lid state say 'unsupported' have to be guarded too, only 'open'
> or 'closed' tells the real state.
> 

Here's updated patch, which take care of 'unsupported' state and use SWF definition
from i830_bios.h.

From 17aebdfffb5e233f400065e3ad3234e89f72c463 Mon Sep 17 00:00:00 2001
From: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date: Wed, 26 Nov 2008 14:26:18 +0800
Subject: [PATCH] Try to add LVDS detect support

This one trys to use lid status for LVDS detect,
which works when internal panel is not used as primary
display alone, or there's no internal panel at all.
ACPI button driver's lid state interface is preferred,
and SWF state is also checked if ACPI method failed.
---
 src/i830_lvds.c |  123 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 120 insertions(+), 3 deletions(-)

diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 239bc89..52aa963 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -35,6 +35,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <dirent.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -96,6 +97,15 @@ static char *backlight_interfaces[] = {
 
 static int backlight_index;
 
+enum lid_status {
+    LID_UNKNOWN = -1,
+    LID_OPEN,
+    LID_CLOSE,
+};
+
+#define ACPI_BUTTON "/proc/acpi/button/"
+#define ACPI_LID "/proc/acpi/button/lid/"
+
 static Bool
 i830_kernel_backlight_available(xf86OutputPtr output)
 {
@@ -376,6 +386,105 @@ out_err:
 }
 
 /**
+ *  Get lid state from ACPI button driver
+ */
+static int
+i830_lvds_acpi_lid_open(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    int fd;
+    DIR *button_dir;
+    DIR *lid_dir;
+    struct dirent *lid_dent;
+    char *state_name;
+    char state[64];
+    enum lid_status ret = LID_UNKNOWN;
+
+    button_dir = opendir(ACPI_BUTTON);
+    /* If acpi button driver is not loaded, bypass ACPI check method */
+    if (button_dir == NULL)
+	goto out;
+    closedir(button_dir);
+
+    lid_dir = opendir(ACPI_LID);
+
+    /* if acpi button loaded, but no lid device, assume no panel */
+    if (lid_dir == NULL) {
+	ret = LID_CLOSE;
+	goto out;
+    }
+
+    while (1) {
+	lid_dent = readdir(lid_dir);
+	if (lid_dent == NULL) {
+	    /* no LID object */
+	    closedir(lid_dir);
+	    goto out;
+	}
+	if (strcmp(lid_dent->d_name, ".") &&
+		strcmp(lid_dent->d_name, "..")) {
+	    closedir(lid_dir);
+	    break;
+	}
+    }
+    state_name = malloc(strlen(ACPI_LID) + strlen(lid_dent->d_name) + 7);
+    memset(state_name, 0, sizeof(state_name));
+    strcat(state_name, ACPI_LID);
+    strcat(state_name, lid_dent->d_name);
+    strcat(state_name, "/state");
+
+    if ((fd = open(state_name, O_RDONLY)) == -1) {
+	free(state_name);
+	goto out;
+    }
+    free(state_name);
+    if (read(fd, state, 64) == -1) {
+	close(fd);
+	goto out;
+    }
+    close(fd);
+    if (strstr(state, "open"))
+	ret = LID_OPEN;
+    else if (strstr(state, "closed"))
+	ret = LID_CLOSE;
+    else /* "unsupported" */
+	ret = LID_UNKNOWN;
+
+out:
+    if (pI830->debug_modes && (ret != LID_UNKNOWN))
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"LID switch detect %s with ACPI button\n",
+		ret ? "closed" : "open");
+
+    return ret;
+}
+
+/**
+ * Get LID switch close state from SWF
+ */
+static Bool
+i830_lvds_swf_lid_close(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    I830Ptr pI830 = I830PTR(pScrn);
+    uint32_t swf14 = INREG(SWF14);
+    Bool ret;
+
+    if (swf14 & SWF14_LID_SWITCH_EN)
+	ret = TRUE;
+    else
+	ret = FALSE;
+
+    if (pI830->debug_modes)
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"LID switch detect %s with SWF14 0x%8x\n",
+		ret ? "closed" : "open", swf14);
+
+    return ret;
+}
+
+/**
  * Sets the power state for the panel.
  */
 static void
@@ -764,13 +873,21 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 
 /**
  * Detect the LVDS connection.
- *
- * This always returns OUTPUT_STATUS_CONNECTED.  This output should only have
- * been set up if the LVDS was actually connected anyway.
  */
 static xf86OutputStatus
 i830_lvds_detect(xf86OutputPtr output)
 {
+    enum lid_status lid;
+
+    lid = i830_lvds_acpi_lid_open(output);
+    if (lid == LID_OPEN)
+	return XF86OutputStatusConnected;
+    else if (lid == LID_CLOSE)
+	return XF86OutputStatusDisconnected;
+
+    if (i830_lvds_swf_lid_close(output))
+	return XF86OutputStatusDisconnected;
+
     return XF86OutputStatusConnected;
 }
 
-- 
1.5.6.5


-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081126/4278a767/attachment.sig>


More information about the Intel-gfx mailing list