diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-07 18:06:25 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-09-07 18:08:07 +0100 |
commit | 7d76eb155ed78343abfa15b7c8af87fc3d4211e4 (patch) | |
tree | f9a2b23f764616c526de7765b59756fa2be16d1c /src | |
parent | 2de7d2d8150d648815feb74a3ae2239b908b971e (diff) |
sna: First scan for a backlight associated with the device
The goal is to find the right interface in a multi-GPU system.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna_display.c | 125 |
1 files changed, 108 insertions, 17 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index beafb3b4..be5d9834 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -318,8 +318,84 @@ has_user_backlight_override(xf86OutputPtr output) return str; } -static void -sna_output_backlight_init(xf86OutputPtr output) +static char * +has_device_backlight(xf86OutputPtr output, int *best_type) +{ + struct sna_output *sna_output = output->driver_private; + struct sna *sna = to_sna(output->scrn); + struct pci_device *pci = sna->PciInfo; + char path[1024]; + char *best_iface = NULL; + DIR *dir; + struct dirent *de; + + snprintf(path, sizeof(path), + "/sys/bus/pci/devices/%04x:%02x:%02x.%d/backlight", + pci->domain, pci->bus, pci->dev, pci->func); + + DBG(("%s: scanning %s\n", __FUNCTION__, path)); + dir = opendir(path); + if (dir == NULL) + 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; + int max; + + sna_output->backlight_iface = de->d_name; + max = sna_output_backlight_get_max(output); + sna_output->backlight_iface = NULL; + if (max <= 0) + 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[] = { "gmux_backlight", @@ -335,21 +411,14 @@ 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; + char *best_iface = NULL; DIR *dir; struct dirent *de; - best_type = INT_MAX; - best_iface = has_user_backlight_override(output); - if (best_iface) - goto skip; - dir = opendir(BACKLIGHT_CLASS); if (dir == NULL) - return; + return NULL; while ((de = readdir(dir))) { char path[1024]; @@ -394,7 +463,7 @@ sna_output_backlight_init(xf86OutputPtr output) v += i; } - if (v < best_type) { + if (v < *best_type) { char *copy; int max; @@ -410,16 +479,39 @@ sna_output_backlight_init(xf86OutputPtr output) if (copy) { free(best_iface); best_iface = copy; - best_type = v; + *best_type = v; } } } closedir(dir); - if (!best_iface) - return; + return best_iface; +} + +static void +sna_output_backlight_init(xf86OutputPtr output) +{ + struct sna_output *sna_output = output->driver_private; + MessageType from = X_PROBED; + char *best_iface; + int best_type; -skip: + best_type = INT_MAX; + 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); + if (best_iface) + goto done; + + return; + +done: 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); @@ -435,7 +527,6 @@ skip: sna_output->backlight_iface, best_iface); } - static void mode_from_kmode(ScrnInfoPtr scrn, drmModeModeInfoPtr kmode, |