xf86-video-intel: 2 commits - src/intel_display.c src/sna/sna_display.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Jul 2 02:27:12 PDT 2012


 src/intel_display.c   |    1 
 src/sna/sna_display.c |  151 ++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 112 insertions(+), 40 deletions(-)

New commits:
commit e80f9c4670a0e84521907b1baa059322784b1558
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Jul 2 10:21:42 2012 +0100

    sna: Prefer backlight iface based on /sys/class/backlight/*/type
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 07ff607..0d9e474 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -34,8 +34,10 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <dirent.h>
 #include <errno.h>
 #include <poll.h>
+#include <ctype.h>
 
 #include <xorgVersion.h>
 #include <X11/Xatom.h>
@@ -91,7 +93,7 @@ struct sna_output {
 	int panel_vdisplay;
 
 	int dpms_mode;
-	const char *backlight_iface;
+	char *backlight_iface;
 	int backlight_active_level;
 	int backlight_max;
 	struct list link;
@@ -104,28 +106,6 @@ static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
 
 #define BACKLIGHT_CLASS "/sys/class/backlight"
 
-/*
- * List of available kernel interfaces in priority order
- */
-static const char *backlight_interfaces[] = {
-	"intel", /* prefer our own native backlight driver */
-	"asus-laptop",
-	"asus-nb-wmi",
-	"eeepc",
-	"thinkpad_screen",
-	"mbp_backlight",
-	"fujitsu-laptop",
-	"sony",
-	"samsung",
-	"acpi_video1", /* finally fallback to the generic acpi drivers */
-	"acpi_video0",
-	NULL,
-};
-/*
- * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table +
- * '/' + "max_backlight"
- */
-#define BACKLIGHT_PATH_LEN 80
 /* Enough for 10 digits of backlight + '\n' + '\0' */
 #define BACKLIGHT_VALUE_LEN 12
 
@@ -219,14 +199,14 @@ static void
 sna_output_backlight_set(xf86OutputPtr output, int level)
 {
 	struct sna_output *sna_output = output->driver_private;
-	char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+	char path[1024], val[BACKLIGHT_VALUE_LEN];
 	int fd, len, ret;
 
 	DBG(("%s: level=%d\n", __FUNCTION__, level));
 
 	if (level > sna_output->backlight_max)
 		level = sna_output->backlight_max;
-	if (! sna_output->backlight_iface || level < 0)
+	if (!sna_output->backlight_iface || level < 0)
 		return;
 
 	len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level);
@@ -252,7 +232,7 @@ static int
 sna_output_backlight_get(xf86OutputPtr output)
 {
 	struct sna_output *sna_output = output->driver_private;
-	char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+	char path[1024], val[BACKLIGHT_VALUE_LEN];
 	int fd, level;
 
 	sprintf(path, "%s/%s/actual_brightness",
@@ -287,7 +267,7 @@ static int
 sna_output_backlight_get_max(xf86OutputPtr output)
 {
 	struct sna_output *sna_output = output->driver_private;
-	char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN];
+	char path[1024], val[BACKLIGHT_VALUE_LEN];
 	int fd, max = 0;
 
 	sprintf(path, "%s/%s/max_brightness",
@@ -313,29 +293,117 @@ sna_output_backlight_get_max(xf86OutputPtr output)
 	return max;
 }
 
+enum {
+	FIRMWARE,
+	PLATFORM,
+	RAW,
+	NAMED,
+};
+
 static void
 sna_output_backlight_init(xf86OutputPtr output)
 {
+	static const char *known_interfaces[] = {
+		"asus-laptop",
+		"asus-nb-wmi",
+		"eeepc",
+		"thinkpad_screen",
+		"mbp_backlight",
+		"fujitsu-laptop",
+		"sony",
+		"samsung",
+		"acpi_video1",
+		"acpi_video0",
+		"intel_backlight",
+	};
 	struct sna_output *sna_output = output->driver_private;
-	int i;
+	char *best_iface;
+	int best_type;
+	DIR *dir;
+	struct dirent *de;
+
+	best_iface = NULL;
+	best_type = INT_MAX;
+
+	dir = opendir(BACKLIGHT_CLASS);
+	while ((de = readdir(dir))) {
+		char path[1024];
+		char buf[100];
+		int fd, v;
+
+		snprintf(path, sizeof(path), "%s/%s/type",
+			 BACKLIGHT_CLASS, de->d_name);
+
+		v = -1;
+		fd = open(path, O_RDONLY);
+		if (fd >= 0) {
+			v = read(fd, buf, sizeof(buf)-1);
+			close(fd);
+		}
+		if (v > 0) {
+			while (v > 0 && isspace(buf[v-1]))
+				v--;
+			buf[v] = '\0';
+
+			if (strcmp(buf, "raw") == 0)
+				v = RAW;
+			else if (strcmp(buf, "platform") == 0)
+				v = PLATFORM;
+			else if (strcmp(buf, "firmware") == 0)
+				v = FIRMWARE;
+			else
+				v = NAMED;
+		} else
+			v = NAMED;
+
+		/* Fallback to priority list of known iface for old kernels */
+		if (v == NAMED) {
+			int i;
+			for (i = 0; i < ARRAY_SIZE(known_interfaces); i++) {
+				if (strcmp(de->d_name, known_interfaces[i]) == 0)
+					break;
+			}
+			v += i;
+		}
+
+		if (v < best_type) {
+			char *copy;
+			int max;
+
+			/* XXX detect right backlight for multi-GPU/panels */
+
+			sna_output->backlight_iface = de->d_name;
+			max = sna_output_backlight_get_max(output);
+			if (max <= 0)
+				continue;
 
-	for (i = 0; backlight_interfaces[i] != NULL; i++) {
-		char path[BACKLIGHT_PATH_LEN];
-		struct stat buf;
-
-		sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]);
-		if (!stat(path, &buf)) {
-			sna_output->backlight_iface = backlight_interfaces[i];
-			sna_output->backlight_max = sna_output_backlight_get_max(output);
-			if (sna_output->backlight_max > 0) {
-				sna_output->backlight_active_level = sna_output_backlight_get(output);
-				xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
-					   "found backlight control interface %s\n", path);
-				return;
+			copy = strdup(de->d_name);
+			if (copy) {
+				free(best_iface);
+				best_iface = copy;
+				best_type = v;
 			}
 		}
 	}
+
 	sna_output->backlight_iface = NULL;
+
+	if (best_iface) {
+		const char *str;
+
+		sna_output->backlight_iface = best_iface;
+		sna_output->backlight_max = sna_output_backlight_get_max(output);
+		sna_output->backlight_active_level = sna_output_backlight_get(output);
+		switch (best_type) {
+		case FIRMWARE: str = "firmware"; break;
+		case PLATFORM: str = "platform"; break;
+		case RAW: str = "raw"; break;
+		default: str = "unknown"; break;
+		}
+		xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
+			   "found backlight control interface %s (type '%s')\n",
+			   best_iface, str);
+	}
 }
 
 
@@ -1515,6 +1583,8 @@ sna_output_destroy(xf86OutputPtr output)
 	drmModeFreeConnector(sna_output->mode_output);
 	sna_output->mode_output = NULL;
 
+	free(sna_output->backlight_iface);
+
 	list_del(&sna_output->link);
 	free(sna_output);
 
commit 61e16dc5673a1ac96b2ecee072cc3e80971be5d9
Author: Tom Hughes <tom at compton.nu>
Date:   Mon Jul 2 10:23:56 2012 +0100

    Add asus-nb-wmi backlight control
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=51593

diff --git a/src/intel_display.c b/src/intel_display.c
index 949a822..2e2a9b1 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -128,6 +128,7 @@ intel_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode);
  */
 static const char *backlight_interfaces[] = {
 	"asus-laptop",
+	"asus-nb-wmi",
 	"eeepc",
 	"thinkpad_screen",
 	"mbp_backlight",
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index f1e0bed..07ff607 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -110,6 +110,7 @@ static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
 static const char *backlight_interfaces[] = {
 	"intel", /* prefer our own native backlight driver */
 	"asus-laptop",
+	"asus-nb-wmi",
 	"eeepc",
 	"thinkpad_screen",
 	"mbp_backlight",


More information about the xorg-commit mailing list