From 935e5f290ec1eb0f1c15004421f5fd3154380fd5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 11 Dec 2008 16:24:52 -0500 Subject: ACPI: video: Fix reversed brightness behavior on ThinkPad SL series Section B.6.2 of ACPI 3.0b specification that defines _BCL method doesn't require the brightness levels returned to be sorted. At least ThinkPad SL300 (and probably all IdeaPads) returns the array reversed (i.e. bightest levels have lowest indexes), which causes the brightness management behave in completely reversed manner on these machines (brightness increases when the laptop is idle, while the display dims when used). Sorting the array by brightness level values after reading the list fixes the issue. http://bugzilla.kernel.org/show_bug.cgi?id=12037 Signed-off-by: Zhang Rui Tested-by: Lubomir Rintel Signed-off-by: Len Brown --- drivers/acpi/video.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index baa44192972..38bf8b43fd1 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -625,6 +626,16 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) return status; } +/* + * Simple comparison function used to sort backlight levels. + */ + +static int +acpi_video_cmp_level(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + /* * Arg: * device : video output device (LCD, CRT, ..) @@ -676,6 +687,10 @@ acpi_video_init_brightness(struct acpi_video_device *device) count++; } + /* don't sort the first two brightness levels */ + sort(&br->levels[2], count - 2, sizeof(br->levels[2]), + acpi_video_cmp_level, NULL); + if (count < 2) goto out_free_levels; -- cgit v1.2.3 From 9e6dada9d255497127251c03aaa59296d186f959 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 31 Dec 2008 10:58:48 +0800 Subject: video: always update the brightness when poking "brightness" always update props.brightness no matter the backlight is changed via procfs, hotkeys or sysfs. Sighed-off-by: Zhang Rui Acked-by: Matthew Garrett Signed-off-by: Len Brown --- drivers/acpi/video.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/acpi/video.c') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index baa44192972..66a610d0e2f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -481,6 +481,7 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) int status = AE_OK; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; + int state; arg0.integer.value = level; @@ -489,6 +490,10 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); device->brightness->curr = level; + for (state = 2; state < device->brightness->count; state++) + if (level == device->brightness->levels[state]) + device->backlight->props.brightness = state - 2; + return status; } -- cgit v1.2.3