xf86-video-intel: src/backlight.c src/backlight.h src/sna/sna_display.c src/uxa/intel_display.c

Chris Wilson ickle at kemper.freedesktop.org
Sat Feb 15 21:59:51 CET 2014


 src/backlight.c         |  165 +++++++++++++++++++++++++++++++++++++++-------
 src/backlight.h         |   13 ++-
 src/sna/sna_display.c   |  170 ++++++------------------------------------------
 src/uxa/intel_display.c |   53 +++-----------
 4 files changed, 182 insertions(+), 219 deletions(-)

New commits:
commit 268842a47f05508fc7e1c69cd21e8e66a000dcde
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Feb 15 19:54:30 2014 +0000

    backlight: Amalgamate hardcoded priority tables
    
    Our fallback path for finding the backlight interface uses a hardcoded
    table of known backlight controllers in proirity order. Rather than
    maintain this table twice in the midst of the KMS logic, push it to the
    new set of common backlight routines.
    
    This incorporates bugfixes from SNA to handle unknown backlights, but
    usable, gracefully.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/backlight.c b/src/backlight.c
index b04b5f7..5011cb8 100644
--- a/src/backlight.c
+++ b/src/backlight.c
@@ -29,21 +29,31 @@
 #include "config.h"
 #endif
 
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
+#include <dirent.h>
 
 #include "backlight.h"
 #include "fd.h"
 
+#define BACKLIGHT_CLASS "/sys/class/backlight"
+
 /* Enough for 10 digits of backlight + '\n' + '\0' */
 #define BACKLIGHT_VALUE_LEN 12
 
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
+#endif
+
 /*
  * Unfortunately this is not as simple as I would like it to be. If selinux is
  * dropping dbus messages pkexec may block *forever*.
@@ -110,6 +120,7 @@ int backlight_open(struct backlight *b, char *iface)
 
 	b->max = param.max;
 	b->fd = -1;
+	b->type = BL_PLATFORM;
 
 	return param.curval;
 }
@@ -124,23 +135,38 @@ is_sysfs_fd(int fd)
 }
 
 static int
-__backlight_read(const char *iface, const char *file)
+__backlight_open(const char *iface, const char *file, int mode)
 {
 	char buf[1024];
-	int fd, val;
+	int fd;
 
 	snprintf(buf, sizeof(buf), "%s/%s/%s", BACKLIGHT_CLASS, iface, file);
-	fd = open(buf, O_RDONLY);
+	fd = open(buf, mode);
 	if (fd == -1)
 		return -1;
 
-	if (is_sysfs_fd(fd)) {
-		val = read(fd, buf, BACKLIGHT_VALUE_LEN - 1);
-		if (val > 0) {
-			buf[val] = '\0';
-			val = atoi(buf);
-		} else
-			val = -1;
+	if (!is_sysfs_fd(fd)) {
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
+
+static int
+__backlight_read(const char *iface, const char *file)
+{
+	char buf[BACKLIGHT_VALUE_LEN];
+	int fd, val;
+
+	fd = __backlight_open(iface, file, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	val = read(fd, buf, BACKLIGHT_VALUE_LEN - 1);
+	if (val > 0) {
+		buf[val] = '\0';
+		val = atoi(buf);
 	} else
 		val = -1;
 	close(fd);
@@ -148,15 +174,71 @@ __backlight_read(const char *iface, const char *file)
 	return val;
 }
 
-int backlight_exists(const char *iface)
+/* List of available kernel interfaces in priority order */
+static const char *known_interfaces[] = {
+	"dell_backlight",
+	"gmux_backlight",
+	"asus-laptop",
+	"asus-nb-wmi",
+	"eeepc",
+	"thinkpad_screen",
+	"mbp_backlight",
+	"fujitsu-laptop",
+	"sony",
+	"samsung",
+	"acpi_video1",
+	"acpi_video0",
+	"intel_backlight",
+};
+
+static enum backlight_type __backlight_type(const char *iface)
+{
+	char buf[1024];
+	int fd, v;
+
+	v = -1;
+	fd = __backlight_open(iface, "type", 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 = BL_RAW;
+		else if (strcmp(buf, "platform") == 0)
+			v = BL_PLATFORM;
+		else if (strcmp(buf, "firmware") == 0)
+			v = BL_FIRMWARE;
+		else
+			v = BL_NAMED;
+	} else
+		v = BL_NAMED;
+
+	if (v == BL_NAMED) {
+		int i;
+		for (i = 0; i < ARRAY_SIZE(known_interfaces); i++) {
+			if (strcmp(iface, known_interfaces[i]) == 0)
+				break;
+		}
+		v += i;
+	}
+
+	return v;
+}
+
+enum backlight_type backlight_exists(const char *iface)
 {
 	if (__backlight_read(iface, "brightness") < 0)
-		return 0;
+		return BL_NONE;
 
 	if (__backlight_read(iface, "max_brightness") <= 0)
-		return 0;
+		return BL_NONE;
 
-	return 1;
+	return __backlight_type(iface);
 }
 
 static int __backlight_init(struct backlight *b, char *iface, int fd)
@@ -168,19 +250,12 @@ static int __backlight_init(struct backlight *b, char *iface, int fd)
 
 static int __backlight_direct_init(struct backlight *b, char *iface)
 {
-	char path[1024];
 	int fd;
 
-	snprintf(path, sizeof(path), "%s/%s/brightness", BACKLIGHT_CLASS, iface);
-	fd = open(path, O_RDWR);
+	fd = __backlight_open(iface, "brightness", O_RDWR);
 	if (fd < 0)
 		return 0;
 
-	if (!is_sysfs_fd(fd)) {
-		close(fd);
-		return 0;
-	}
-
 	return __backlight_init(b, iface, fd);
 }
 
@@ -242,13 +317,51 @@ static int __backlight_helper_init(struct backlight *b, char *iface)
 #endif
 }
 
+static char *
+__backlight_find(void)
+{
+	char *best_iface = NULL;
+	unsigned best_type = INT_MAX;
+	DIR *dir;
+	struct dirent *de;
+
+	dir = opendir(BACKLIGHT_CLASS);
+	if (dir == NULL)
+		return NULL;
+
+	while ((de = readdir(dir))) {
+		int v;
+
+		if (*de->d_name == '.')
+			continue;
+
+		/* Fallback to priority list of known iface for old kernels */
+		v = backlight_exists(de->d_name);
+		if (v < best_type) {
+			char *copy = strdup(de->d_name);
+			if (copy) {
+				free(best_iface);
+				best_iface = copy;
+				best_type = v;
+			}
+		}
+	}
+	closedir(dir);
+
+	return best_iface;
+}
+
 int backlight_open(struct backlight *b, char *iface)
 {
 	int level;
 
 	if (iface == NULL)
+		iface = __backlight_find();
+	if (iface == NULL)
 		return -1;
 
+	b->type = __backlight_type(iface);
+
 	b->max = __backlight_read(iface, "max_brightness");
 	if (b->max <= 0)
 		return -1;
diff --git a/src/backlight.h b/src/backlight.h
index deecbd0..6eeaff6 100644
--- a/src/backlight.h
+++ b/src/backlight.h
@@ -27,15 +27,22 @@
 #ifndef BACKLIGHT_H
 #define BACKLIGHT_H
 
+enum backlight_type {
+	BL_NONE = -1,
+	BL_PLATFORM,
+	BL_FIRMWARE,
+	BL_RAW,
+	BL_NAMED,
+};
+
 struct backlight {
 	char *iface;
+	enum backlight_type type;
 	int max;
 	int pid, fd;
 };
 
-#define BACKLIGHT_CLASS "/sys/class/backlight"
-
-int backlight_exists(const char *iface);
+enum backlight_type backlight_exists(const char *iface);
 
 int backlight_open(struct backlight *backlight, char *iface);
 int backlight_set(struct backlight *backlight, int level);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 83b043c..e769546 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -327,13 +327,6 @@ sna_output_backlight_get(xf86OutputPtr output)
 	return level;
 }
 
-enum {
-	PLATFORM,
-	FIRMWARE,
-	RAW,
-	NAMED,
-};
-
 static char *
 has_user_backlight_override(xf86OutputPtr output)
 {
@@ -344,7 +337,9 @@ has_user_backlight_override(xf86OutputPtr output)
 	if (str == NULL)
 		return NULL;
 
-	if (!backlight_exists(str)) {
+	DBG(("%s(s) requested %s\n", __FUNCTION__, output->name, str));
+
+	if (backlight_exists(str) == BL_NONE) {
 		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
 			   "Unrecognised backlight control interface '%s'\n",
 			   str);
@@ -355,11 +350,12 @@ has_user_backlight_override(xf86OutputPtr output)
 }
 
 static char *
-has_device_backlight(xf86OutputPtr output, int *best_type)
+has_device_backlight(xf86OutputPtr output)
 {
 	struct sna *sna = to_sna(output->scrn);
 	struct pci_device *pci;
 	char path[1024];
+	unsigned best_type = INT_MAX;
 	char *best_iface = NULL;
 	DIR *dir;
 	struct dirent *de;
@@ -378,139 +374,20 @@ has_device_backlight(xf86OutputPtr output, int *best_type)
 		return NULL;
 
 	while ((de = readdir(dir))) {
-		char buf[100];
-		int fd, v;
-
-		if (*de->d_name == '.')
-			continue;
-
-		DBG(("%s: %s\n", __FUNCTION__, de->d_name));
-		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 = INT_MAX;
-		} else
-			v = INT_MAX;
-
-		if (v < *best_type) {
-			char *copy;
-
-			if (!backlight_exists(de->d_name))
-				continue;
-
-			copy = strdup(de->d_name);
-			if (copy) {
-				free(best_iface);
-				best_iface = copy;
-				*best_type = v;
-			}
-		}
-	}
-	closedir(dir);
-
-	return best_iface;
-}
-
-static char *
-has_backlight(xf86OutputPtr output, int *best_type)
-{
-	static const char *known_interfaces[] = {
-		"dell_backlight",
-		"gmux_backlight",
-		"asus-laptop",
-		"asus-nb-wmi",
-		"eeepc",
-		"thinkpad_screen",
-		"mbp_backlight",
-		"fujitsu-laptop",
-		"sony",
-		"samsung",
-		"acpi_video1",
-		"acpi_video0",
-		"intel_backlight",
-	};
-	char *best_iface = NULL;
-	DIR *dir;
-	struct dirent *de;
-
-	dir = opendir(BACKLIGHT_CLASS);
-	if (dir == NULL)
-		return NULL;
-
-	while ((de = readdir(dir))) {
-		char path[1024];
-		char buf[100];
-		int fd, v;
+		int v;
 
 		if (*de->d_name == '.')
 			continue;
 
-		snprintf(path, sizeof(path), "%s/%s/type",
-			 BACKLIGHT_CLASS, de->d_name);
+		v = backlight_exists(de->d_name);
+		DBG(("%s: %s: exists=%d\n", __FUNCTION__, de->d_name, v));
 
-		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;
-
-			/* XXX detect right backlight for multi-GPU/panels */
-
-			if (!backlight_exists(de->d_name))
-				continue;
-
-			copy = strdup(de->d_name);
+		if (v < best_type) {
+			char *copy = strdup(de->d_name);
 			if (copy) {
 				free(best_iface);
 				best_iface = copy;
-				*best_type = v;
+				best_type = v;
 			}
 		}
 	}
@@ -523,37 +400,34 @@ static void
 sna_output_backlight_init(xf86OutputPtr output)
 {
 	struct sna_output *sna_output = output->driver_private;
-	MessageType from = X_PROBED;
+	MessageType from;
 	char *best_iface;
-	int best_type;
 
-	best_type = INT_MAX;
+	from = X_CONFIG;
 	best_iface = has_user_backlight_override(output);
 	if (best_iface)
 		goto done;
 
-	best_iface = has_device_backlight(output, &best_type);
-	if (best_iface)
-		goto done;
-
-	best_iface = has_backlight(output, &best_type);
+	/* XXX detect right backlight for multi-GPU/panels */
+	from = X_PROBED;
+	best_iface = has_device_backlight(output);
 	if (best_iface)
 		goto done;
 
-	best_type = PLATFORM;
 	best_iface = NULL;
 
 done:
+	DBG(("%s(%s) opening backlight %s\n", __FUNCTION__,
+	     output->name, best_iface ?: "none"));
 	sna_output->backlight_active_level =
 		backlight_open(&sna_output->backlight, best_iface);
 	if (sna_output->backlight_active_level < 0)
 		return;
 
-	switch (best_type) {
-	case INT_MAX: best_iface = (char *)"user"; from = X_CONFIG; break;
-	case FIRMWARE: best_iface = (char *)"firmware"; break;
-	case PLATFORM: best_iface = (char *)"platform"; break;
-	case RAW: best_iface = (char *)"raw"; break;
+	switch (sna_output->backlight.type) {
+	case BL_FIRMWARE: best_iface = (char *)"firmware"; break;
+	case BL_PLATFORM: best_iface = (char *)"platform"; break;
+	case BL_RAW: best_iface = (char *)"raw"; break;
 	default: best_iface = (char *)"unknown"; break;
 	}
 	xf86DrvMsg(output->scrn->scrnIndex, from,
diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index c7c2d7c..0f06793 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -139,26 +139,6 @@ crtc_id(struct intel_crtc *crtc)
 	return crtc->mode_crtc->crtc_id;
 }
 
-/*
- * List of available kernel interfaces in priority order
- */
-static const char *backlight_interfaces[] = {
-	"dell_backlight",
-	"gmux_backlight",
-	"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",
-	"intel_backlight",
-	NULL,
-};
-
 static void
 intel_output_backlight_set(xf86OutputPtr output, int level)
 {
@@ -181,46 +161,35 @@ intel_output_backlight_get(xf86OutputPtr output)
 static void
 intel_output_backlight_init(xf86OutputPtr output)
 {
-#ifdef __OpenBSD__
-	intel_output->backlight_active_level =
-		backlight_init(&intel_output->backlight, NULL);
-	if (intel_output->backlight_active_level != -1) {
-		xf86DrvMsg(output->scrn->scrnIndex, X_PROBED,
-			   "found backlight control interface\n");
-	}
-#else
 	struct intel_output *intel_output = output->driver_private;
 	intel_screen_private *intel = intel_get_screen_private(output->scrn);
 	char *str;
-	int i;
 
 	str = xf86GetOptValString(intel->Options, OPTION_BACKLIGHT);
 	if (str != NULL) {
-		if (backlight_exists(str)) {
+		if (backlight_exists(str) != BL_NONE) {
 			intel_output->backlight_active_level =
-				backlight_open(&intel_output->backlight, strdup(str));
+				backlight_open(&intel_output->backlight,
+					       strdup(str));
 			if (intel_output->backlight_active_level != -1) {
 				xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG,
 					   "found backlight control interface %s\n", str);
 				return;
 			}
 		}
+
 		xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
 			   "unrecognised backlight control interface %s\n", str);
 	}
 
-	for (i = 0; backlight_interfaces[i] != NULL; i++) {
-		if (backlight_exists(backlight_interfaces[i])) {
-			intel_output->backlight_active_level =
-				backlight_open(&intel_output->backlight, strdup(backlight_interfaces[i]));
-			if (intel_output->backlight_active_level != -1) {
-				xf86DrvMsg(output->scrn->scrnIndex, X_PROBED,
-					   "found backlight control interface %s\n", backlight_interfaces[i]);
-				return;
-			}
-		}
+	intel_output->backlight_active_level =
+		backlight_open(&intel_output->backlight, NULL);
+	if (intel_output->backlight_active_level != -1) {
+		xf86DrvMsg(output->scrn->scrnIndex, X_PROBED,
+			   "found backlight control interface %s\n",
+			   intel_output->backlight.iface);
+		return;
 	}
-#endif
 }
 
 static void


More information about the xorg-commit mailing list