aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2009-03-18 04:27:12 -0400
committerLen Brown <len.brown@intel.com>2009-03-27 21:55:58 -0400
commitd32f69470c2081ffdfd82740ac19f940790f9e93 (patch)
treee15e8d5bd6dbc9c1aa03cf1da78bcc75c3ac21fa /drivers
parent24450c7add575cef53097738f16a4c1a720fa5cb (diff)
ACPI video: support _BCL packages that don't export brightness levels when machine is on AC/Battery
Many buggy BIOSes don't export the brightness levels when machine is on AC/Battery in the _BCL method. Reformat the _BCL package for these laptops: now the elements in device->brightness->levels[] are like: levels[0]: brightness level when on AC power. levels[1]: brightness level when on Battery power. levels[2]: supported brightness level 1. levels[3]: supported brightness level 2. ... levels[n]: supported brightness level n-1. levels[n + 1]: supported brightness level n. So if there are n supported brightness levels on this laptop, we will have n+2 entries in device->brightnes->levels[]. level[0] and level[1] are invalid on the laptops that don't export the brightness levels on AC/Battery. Fortunately, we never use these two values at all, even for the valid ones. http://bugzilla.kernel.org/show_bug.cgi?id=12249 Signed-off-by: Zhang Rui <rui.zhang@intel.com> Acked-by: Matthew Garrett <mjg59@srcf.ucam.org> Acked-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/video.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 52f52b32b63f..398b3eee37fb 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -168,10 +168,15 @@ struct acpi_video_device_cap {
168 u8 _DSS:1; /*Device state set */ 168 u8 _DSS:1; /*Device state set */
169}; 169};
170 170
171struct acpi_video_brightness_flags {
172 u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
173};
174
171struct acpi_video_device_brightness { 175struct acpi_video_device_brightness {
172 int curr; 176 int curr;
173 int count; 177 int count;
174 int *levels; 178 int *levels;
179 struct acpi_video_brightness_flags flags;
175}; 180};
176 181
177struct acpi_video_device { 182struct acpi_video_device {
@@ -682,7 +687,7 @@ static int
682acpi_video_init_brightness(struct acpi_video_device *device) 687acpi_video_init_brightness(struct acpi_video_device *device)
683{ 688{
684 union acpi_object *obj = NULL; 689 union acpi_object *obj = NULL;
685 int i, max_level = 0, count = 0; 690 int i, max_level = 0, count = 0, level_ac_battery = 0;
686 union acpi_object *o; 691 union acpi_object *o;
687 struct acpi_video_device_brightness *br = NULL; 692 struct acpi_video_device_brightness *br = NULL;
688 693
@@ -701,7 +706,7 @@ acpi_video_init_brightness(struct acpi_video_device *device)
701 goto out; 706 goto out;
702 } 707 }
703 708
704 br->levels = kmalloc(obj->package.count * sizeof *(br->levels), 709 br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
705 GFP_KERNEL); 710 GFP_KERNEL);
706 if (!br->levels) 711 if (!br->levels)
707 goto out_free; 712 goto out_free;
@@ -719,16 +724,34 @@ acpi_video_init_brightness(struct acpi_video_device *device)
719 count++; 724 count++;
720 } 725 }
721 726
722 /* don't sort the first two brightness levels */ 727 /*
728 * some buggy BIOS don't export the levels
729 * when machine is on AC/Battery in _BCL package.
730 * In this case, the first two elements in _BCL packages
731 * are also supported brightness levels that OS should take care of.
732 */
733 for (i = 2; i < count; i++)
734 if (br->levels[i] == br->levels[0] ||
735 br->levels[i] == br->levels[1])
736 level_ac_battery++;
737
738 if (level_ac_battery < 2) {
739 level_ac_battery = 2 - level_ac_battery;
740 br->flags._BCL_no_ac_battery_levels = 1;
741 for (i = (count - 1 + level_ac_battery); i >= 2; i--)
742 br->levels[i] = br->levels[i - level_ac_battery];
743 count += level_ac_battery;
744 } else if (level_ac_battery > 2)
745 ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
746
747 /* sort all the supported brightness levels */
723 sort(&br->levels[2], count - 2, sizeof(br->levels[2]), 748 sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
724 acpi_video_cmp_level, NULL); 749 acpi_video_cmp_level, NULL);
725 750
726 if (count < 2)
727 goto out_free_levels;
728
729 br->count = count; 751 br->count = count;
730 device->brightness = br; 752 device->brightness = br;
731 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); 753 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
754 "found %d brightness levels\n", count - 2));
732 kfree(obj); 755 kfree(obj);
733 return max_level; 756 return max_level;
734 757