[Intel-gfx] [PATCH] Use enable bit for LVDS detect
Zhenyu Wang
zhenyu.z.wang at intel.com
Tue Nov 25 08:37:19 CET 2008
On 2008.11.22 09:15:28 +0800, Jesse Barnes wrote:
> On Friday, November 21, 2008 11:00 am Keith Packard wrote:
> > On Fri, 2008-11-21 at 10:08 -0800, Jesse Barnes wrote:
> > > if ((I915_READ(LVDS) & LVDS_EN) && i830_lvds_lid_open(pI830))
> > > return TRUE;
> > > return FALSE;
> >
> > I'd say we should use the lid detect but not test whether the LVDS is
> > currently on.
>
> Yeah right after I sent the message I realized that using LVDS_EN would
> prevent a present LVDS from ever being listed as "connected", which would be
> bad. We could return OutputStatusUnknown in that case, but I wonder if just
> checking lid status would work on the Eee box and other mobile chip/desktop
> system type platforms.
>
Here's my testing patch, which uses lid status for LVDS detect.
The method I use is acpi/button driver's lid interface and SWF14 register
state. ACPI button state is preferred. So the detect method does like:
- if acpi button driver is not loaded, check other method
- if no lid device, mark as closed
- use acpi button lid 'state' info
- if acpi button info can't be decided, check with SWF14
From d7e88919beb65483f637cd3d9aeeb5798cddea46 Mon Sep 17 00:00:00 2001
From: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date: Tue, 25 Nov 2008 23:19:12 +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/i810_reg.h | 2 +
src/i830_lvds.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 122 insertions(+), 3 deletions(-)
diff --git a/src/i810_reg.h b/src/i810_reg.h
index e2ffba1..fbfdb51 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -2768,6 +2768,8 @@ typedef enum {
#define SWF12 SWF2
#define SWF13 SWF3
#define SWF14 SWF4
+/* SWF14 lid switch status */
+#define LID_SWITCH_CLOSE (1 << 29)
#define SWF15 SWF5
#define SWF16 SWF6
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 239bc89..028f5b7 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,
+ return TRUE here as to 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
+ ret = LID_CLOSE;
+
+out:
+ if (pI830->debug_modes)
+ 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 & LID_SWITCH_CLOSE)
+ 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/20081125/20149423/attachment.sig>
More information about the Intel-gfx
mailing list