aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/video.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3cdd0471bc63..ed192e5d82b6 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -632,6 +632,56 @@ acpi_video_cmp_level(const void *a, const void *b)
632} 632}
633 633
634/* 634/*
635 * Decides if _BQC/_BCQ for this system is usable
636 *
637 * We do this by changing the level first and then read out the current
638 * brightness level, if the value does not match, find out if it is using
639 * index. If not, clear the _BQC/_BCQ capability.
640 */
641static int acpi_video_bqc_quirk(struct acpi_video_device *device,
642 int max_level, int current_level)
643{
644 struct acpi_video_device_brightness *br = device->brightness;
645 int result;
646 unsigned long long level;
647 int test_level;
648
649 /* don't mess with existing known broken systems */
650 if (bqc_offset_aml_bug_workaround)
651 return 0;
652
653 /*
654 * Some systems always report current brightness level as maximum
655 * through _BQC, we need to test another value for them.
656 */
657 test_level = current_level == max_level ? br->levels[2] : max_level;
658
659 result = acpi_video_device_lcd_set_level(device, test_level);
660 if (result)
661 return result;
662
663 result = acpi_video_device_lcd_get_level_current(device, &level, true);
664 if (result)
665 return result;
666
667 if (level != test_level) {
668 /* buggy _BQC found, need to find out if it uses index */
669 if (level < br->count) {
670 if (br->flags._BCL_reversed)
671 level = br->count - 3 - level;
672 if (br->levels[level + 2] == test_level)
673 br->flags._BQC_use_index = 1;
674 }
675
676 if (!br->flags._BQC_use_index)
677 device->cap._BQC = device->cap._BCQ = 0;
678 }
679
680 return 0;
681}
682
683
684/*
635 * Arg: 685 * Arg:
636 * device : video output device (LCD, CRT, ..) 686 * device : video output device (LCD, CRT, ..)
637 * 687 *
@@ -742,18 +792,15 @@ acpi_video_init_brightness(struct acpi_video_device *device)
742 if (result) 792 if (result)
743 goto out_free_levels; 793 goto out_free_levels;
744 794
745 /* 795 result = acpi_video_bqc_quirk(device, max_level, level_old);
746 * Set the level to maximum and check if _BQC uses indexed value
747 */
748 result = acpi_video_device_lcd_set_level(device, max_level);
749 if (result)
750 goto out_free_levels;
751
752 result = acpi_video_device_lcd_get_level_current(device, &level, true);
753 if (result) 796 if (result)
754 goto out_free_levels; 797 goto out_free_levels;
755 798 /*
756 br->flags._BQC_use_index = (level == max_level ? 0 : 1); 799 * cap._BQC may get cleared due to _BQC is found to be broken
800 * in acpi_video_bqc_quirk, so check again here.
801 */
802 if (!device->cap._BQC)
803 goto set_level;
757 804
758 if (use_bios_initial_backlight) { 805 if (use_bios_initial_backlight) {
759 level = acpi_video_bqc_value_to_level(device, level_old); 806 level = acpi_video_bqc_value_to_level(device, level_old);