aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-02-13 10:32:51 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-02-19 19:33:40 -0500
commitbd8ba20597f0cfef3ef65c3fd2aa92ab23d4c8e1 (patch)
treeeda5610d33563b13411d8768ee4c817f8366006e /drivers/acpi
parent6d0abeca3242a88cab8232e4acd7e2bf088f3bc2 (diff)
ACPI / video: Filter the _BCL table for duplicate brightness values
Some devices have duplicate entries in there brightness levels table, ie on my Dell Latitude E6430 the table looks like this: [ 3.686060] acpi backlight index 0, val 80 [ 3.686095] acpi backlight index 1, val 50 [ 3.686122] acpi backlight index 2, val 5 [ 3.686147] acpi backlight index 3, val 5 [ 3.686172] acpi backlight index 4, val 5 [ 3.686197] acpi backlight index 5, val 5 [ 3.686223] acpi backlight index 6, val 5 [ 3.686248] acpi backlight index 7, val 5 [ 3.686273] acpi backlight index 8, val 6 [ 3.686332] acpi backlight index 9, val 7 [ 3.686356] acpi backlight index 10, val 8 [ 3.686380] acpi backlight index 11, val 9 etc. Notice that brightness values 0-5 are all mapped to 5. This means that if userspace writes any value between 0 and 5 to the brightness sysfs attribute and then reads it, it will always return 0, which is somewhat unexpected. This is a problem for ie gnome-settings-daemon, which uses read-modify-write logic when the users presses the brightness up or down keys. This is done this way to take brightness changes from other sources into account. On this specific laptop what happens once the brightness has been set to 0, is that gsd reads 0, adds 5, writes 5, and on the next brightness up key press again reads 0, so things get stuck at the lowest brightness setting. Filtering out the duplicate table entries, makes any write to brightness read back as the written value as one would expect, fixing this. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Aaron Lu <aaron.lu@intel.com> Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/video.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index b727d105046d..ea9d914d937a 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -685,6 +685,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
685 union acpi_object *o; 685 union acpi_object *o;
686 struct acpi_video_device_brightness *br = NULL; 686 struct acpi_video_device_brightness *br = NULL;
687 int result = -EINVAL; 687 int result = -EINVAL;
688 u32 value;
688 689
689 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { 690 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
690 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available " 691 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -715,7 +716,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
715 printk(KERN_ERR PREFIX "Invalid data\n"); 716 printk(KERN_ERR PREFIX "Invalid data\n");
716 continue; 717 continue;
717 } 718 }
718 br->levels[count] = (u32) o->integer.value; 719 value = (u32) o->integer.value;
720 /* Skip duplicate entries */
721 if (count > 2 && br->levels[count - 1] == value)
722 continue;
723
724 br->levels[count] = value;
719 725
720 if (br->levels[count] > max_level) 726 if (br->levels[count] > max_level)
721 max_level = br->levels[count]; 727 max_level = br->levels[count];