Add Option "Backlight" to override the probed backlight control interface

The automatic selection may not correspond with the correct backlight
(such as in a multi-gpu, multi-panel device) or the user may simply
prefer another control interface. This allows them to override the
chosen interface using

  Option "Backlight" "my-backlight"

to specify '/sys/class/backlight/my-backlight' as the interface to use
instead.

Suggested-by: Alon Levy <alevy@redhat.com>
References: https://bugs.freedesktop.org/show_bug.cgi?id=29273
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2012-08-26 19:47:31 +01:00
parent d4f7c58186
commit 414e87255c
5 changed files with 78 additions and 21 deletions

View File

@ -132,6 +132,15 @@ have options for selecting adaptors.
.IP
Default: Textured video adaptor is preferred.
.TP
.BI "Option \*Backlight\*q \*q" string \*q
Override the probed backlight control interface. Sometimes the automatically
selected backlight interface may not correspond to the correct, or simply
most useful, interface available on the system. This allows you to override
by specifying the entry under /sys/class/backlight to use.
server log.
.IP
Default: Automatic selection.
.TP
.BI "Option \*qFallbackDebug\*q \*q" boolean \*q
Enable printing of debugging information on acceleration fallbacks to the
server log.

View File

@ -41,6 +41,7 @@
#include "intel.h"
#include "intel_bufmgr.h"
#include "intel_options.h"
#include "xf86drm.h"
#include "xf86drmMode.h"
#include "X11/Xatom.h"
@ -252,19 +253,36 @@ static void
intel_output_backlight_init(xf86OutputPtr output)
{
struct intel_output *intel_output = output->driver_private;
intel_screen_private *intel = intel_get_screen_private(output->scrn);
char path[BACKLIGHT_PATH_LEN];
struct stat buf;
char *str;
int i;
for (i = 0; backlight_interfaces[i] != NULL; i++) {
char path[BACKLIGHT_PATH_LEN];
struct stat buf;
str = xf86GetOptValString(intel->Options, OPTION_BACKLIGHT);
if (str == NULL) {
sprintf(path, "%s/%s", BACKLIGHT_CLASS, str);
if (!stat(path, &buf)) {
intel_output->backlight_iface = backlight_interfaces[i];
intel_output->backlight_max = intel_output_backlight_get_max(output);
if (intel_output->backlight_max > 0) {
xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG,
"found backlight control interface %s\n", path);
return;
}
}
xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
"unrecognised backlight control interface %s\n", str);
}
for (i = 0; backlight_interfaces[i] != NULL; i++) {
sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]);
if (!stat(path, &buf)) {
intel_output->backlight_iface = backlight_interfaces[i];
intel_output->backlight_max = intel_output_backlight_get_max(output);
if (intel_output->backlight_max > 0) {
intel_output->backlight_active_level = intel_output_backlight_get(output);
xf86DrvMsg(output->scrn->scrnIndex, X_INFO,
xf86DrvMsg(output->scrn->scrnIndex, X_PROBED,
"found backlight control interface %s\n", path);
return;
}

View File

@ -7,6 +7,7 @@
const OptionInfoRec intel_options[] = {
{OPTION_ACCEL_DISABLE, "NoAccel", OPTV_BOOLEAN, {0}, 0},
{OPTION_ACCEL_METHOD, "AccelMethod", OPTV_STRING, {0}, 0},
{OPTION_BACKLIGHT, "Backlight", OPTV_STRING, {0}, 0},
{OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, 1},
{OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, 0},
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, 0},

View File

@ -13,6 +13,7 @@
enum intel_options {
OPTION_ACCEL_DISABLE,
OPTION_ACCEL_METHOD,
OPTION_BACKLIGHT,
OPTION_DRI,
OPTION_VIDEO_KEY,
OPTION_COLOR_KEY,

View File

@ -290,6 +290,31 @@ enum {
NAMED,
};
static char *
has_user_backlight_override(xf86OutputPtr output)
{
struct sna_output *sna_output = output->driver_private;
struct sna *sna = to_sna(output->scrn);
char *str;
int max;
str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT);
if (str == NULL)
return NULL;
sna_output->backlight_iface = str;
max = sna_output_backlight_get_max(output);
sna_output->backlight_iface = NULL;
if (max <= 0) {
xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
"unrecognised backlight control interface '%s'\n",
str);
return NULL;
}
return str;
}
static void
sna_output_backlight_init(xf86OutputPtr output)
{
@ -307,14 +332,17 @@ sna_output_backlight_init(xf86OutputPtr output)
"acpi_video0",
"intel_backlight",
};
MessageType from = X_PROBED;
struct sna_output *sna_output = output->driver_private;
char *best_iface;
int best_type;
DIR *dir;
struct dirent *de;
best_iface = NULL;
best_type = INT_MAX;
best_iface = has_user_backlight_override(output);
if (best_iface)
goto skip;
dir = opendir(BACKLIGHT_CLASS);
if (dir == NULL)
@ -371,6 +399,7 @@ sna_output_backlight_init(xf86OutputPtr output)
sna_output->backlight_iface = de->d_name;
max = sna_output_backlight_get_max(output);
sna_output->backlight_iface = NULL;
if (max <= 0)
continue;
@ -384,24 +413,23 @@ sna_output_backlight_init(xf86OutputPtr output)
}
closedir(dir);
sna_output->backlight_iface = NULL;
if (!best_iface)
return;
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);
skip:
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 INT_MAX: best_iface = "user"; from = X_CONFIG; break;
case FIRMWARE: best_iface = "firmware"; break;
case PLATFORM: best_iface = "platform"; break;
case RAW: best_iface = "raw"; break;
default: best_iface = "unknown"; break;
}
xf86DrvMsg(output->scrn->scrnIndex, from,
"found backlight control interface %s (type '%s')\n",
sna_output->backlight_iface, best_iface);
}