aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-06-15 21:08:07 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-06-15 21:08:07 -0400
commit7eef4091a653c243a87e5375c54504cc03bec4d8 (patch)
treef65b77f830b2c8f7d014512badfef5df0d591ee9 /drivers/acpi/video.c
parent0a93a47f042c459f0f46942c3a920e3c81878031 (diff)
parent07a2039b8eb0af4ff464efd3dfd95de5c02648c6 (diff)
Merge commit 'v2.6.30' into for-2.6.31
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c108
1 files changed, 83 insertions, 25 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index cd4fb7543a90..1bdfb37377e3 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -538,6 +538,57 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
538 return -EINVAL; 538 return -EINVAL;
539} 539}
540 540
541/*
542 * For some buggy _BQC methods, we need to add a constant value to
543 * the _BQC return value to get the actual current brightness level
544 */
545
546static int bqc_offset_aml_bug_workaround;
547static int __init video_set_bqc_offset(const struct dmi_system_id *d)
548{
549 bqc_offset_aml_bug_workaround = 9;
550 return 0;
551}
552
553static struct dmi_system_id video_dmi_table[] __initdata = {
554 /*
555 * Broken _BQC workaround http://bugzilla.kernel.org/show_bug.cgi?id=13121
556 */
557 {
558 .callback = video_set_bqc_offset,
559 .ident = "Acer Aspire 5720",
560 .matches = {
561 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
562 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5720"),
563 },
564 },
565 {
566 .callback = video_set_bqc_offset,
567 .ident = "Acer Aspire 5710Z",
568 .matches = {
569 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
570 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"),
571 },
572 },
573 {
574 .callback = video_set_bqc_offset,
575 .ident = "eMachines E510",
576 .matches = {
577 DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"),
578 DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"),
579 },
580 },
581 {
582 .callback = video_set_bqc_offset,
583 .ident = "Acer Aspire 5315",
584 .matches = {
585 DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
586 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
587 },
588 },
589 {}
590};
591
541static int 592static int
542acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 593acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
543 unsigned long long *level) 594 unsigned long long *level)
@@ -557,6 +608,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
557 *level = device->brightness->levels[*level + 2]; 608 *level = device->brightness->levels[*level + 2];
558 609
559 } 610 }
611 *level += bqc_offset_aml_bug_workaround;
560 device->brightness->curr = *level; 612 device->brightness->curr = *level;
561 return 0; 613 return 0;
562 } else { 614 } else {
@@ -770,10 +822,12 @@ acpi_video_init_brightness(struct acpi_video_device *device)
770 * In this case, the first two elements in _BCL packages 822 * In this case, the first two elements in _BCL packages
771 * are also supported brightness levels that OS should take care of. 823 * are also supported brightness levels that OS should take care of.
772 */ 824 */
773 for (i = 2; i < count; i++) 825 for (i = 2; i < count; i++) {
774 if (br->levels[i] == br->levels[0] || 826 if (br->levels[i] == br->levels[0])
775 br->levels[i] == br->levels[1])
776 level_ac_battery++; 827 level_ac_battery++;
828 if (br->levels[i] == br->levels[1])
829 level_ac_battery++;
830 }
777 831
778 if (level_ac_battery < 2) { 832 if (level_ac_battery < 2) {
779 level_ac_battery = 2 - level_ac_battery; 833 level_ac_battery = 2 - level_ac_battery;
@@ -807,12 +861,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
807 br->flags._BCM_use_index = br->flags._BCL_use_index; 861 br->flags._BCM_use_index = br->flags._BCL_use_index;
808 862
809 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */ 863 /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
810 br->curr = max_level; 864 br->curr = level_old = max_level;
865
866 if (!device->cap._BQC)
867 goto set_level;
868
811 result = acpi_video_device_lcd_get_level_current(device, &level_old); 869 result = acpi_video_device_lcd_get_level_current(device, &level_old);
812 if (result) 870 if (result)
813 goto out_free_levels; 871 goto out_free_levels;
814 872
815 result = acpi_video_device_lcd_set_level(device, br->curr); 873 /*
874 * Set the level to maximum and check if _BQC uses indexed value
875 */
876 result = acpi_video_device_lcd_set_level(device, max_level);
816 if (result) 877 if (result)
817 goto out_free_levels; 878 goto out_free_levels;
818 879
@@ -820,25 +881,19 @@ acpi_video_init_brightness(struct acpi_video_device *device)
820 if (result) 881 if (result)
821 goto out_free_levels; 882 goto out_free_levels;
822 883
823 if ((level != level_old) && !br->flags._BCM_use_index) { 884 br->flags._BQC_use_index = (level == max_level ? 0 : 1);
824 /* Note: 885
825 * This piece of code does not work correctly if the current 886 if (!br->flags._BQC_use_index)
826 * brightness levels is 0. 887 goto set_level;
827 * But I guess boxes that boot with such a dark screen are rare 888
828 * and no more code is needed to cover this specifial case. 889 if (br->flags._BCL_reversed)
829 */ 890 level_old = (br->count - 1) - level_old;
830 891 level_old = br->levels[level_old];
831 if (level_ac_battery != 2) { 892
832 /* 893set_level:
833 * For now, we don't support the _BCL like this: 894 result = acpi_video_device_lcd_set_level(device, level_old);
834 * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16 895 if (result)
835 * because we may mess up the index returned by _BQC. 896 goto out_free_levels;
836 * Plus: we have not got a box like this.
837 */
838 ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
839 }
840 br->flags._BQC_use_index = 1;
841 }
842 897
843 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 898 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
844 "found %d brightness levels\n", count - 2)); 899 "found %d brightness levels\n", count - 2));
@@ -2287,13 +2342,15 @@ EXPORT_SYMBOL(acpi_video_register);
2287 2342
2288static int __init acpi_video_init(void) 2343static int __init acpi_video_init(void)
2289{ 2344{
2345 dmi_check_system(video_dmi_table);
2346
2290 if (intel_opregion_present()) 2347 if (intel_opregion_present())
2291 return 0; 2348 return 0;
2292 2349
2293 return acpi_video_register(); 2350 return acpi_video_register();
2294} 2351}
2295 2352
2296static void __exit acpi_video_exit(void) 2353void acpi_video_exit(void)
2297{ 2354{
2298 2355
2299 acpi_bus_unregister_driver(&acpi_video_bus); 2356 acpi_bus_unregister_driver(&acpi_video_bus);
@@ -2302,6 +2359,7 @@ static void __exit acpi_video_exit(void)
2302 2359
2303 return; 2360 return;
2304} 2361}
2362EXPORT_SYMBOL(acpi_video_exit);
2305 2363
2306module_init(acpi_video_init); 2364module_init(acpi_video_init);
2307module_exit(acpi_video_exit); 2365module_exit(acpi_video_exit);