aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r--drivers/acpi/video.c123
1 files changed, 73 insertions, 50 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d089c4519d45..64c889331f3b 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -631,6 +631,76 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
631 * device : video output device (LCD, CRT, ..) 631 * device : video output device (LCD, CRT, ..)
632 * 632 *
633 * Return Value: 633 * Return Value:
634 * Maximum brightness level
635 *
636 * Allocate and initialize device->brightness.
637 */
638
639static int
640acpi_video_init_brightness(struct acpi_video_device *device)
641{
642 union acpi_object *obj = NULL;
643 int i, max_level = 0, count = 0;
644 union acpi_object *o;
645 struct acpi_video_device_brightness *br = NULL;
646
647 if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
648 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
649 "LCD brightness level\n"));
650 goto out;
651 }
652
653 if (obj->package.count < 2)
654 goto out;
655
656 br = kzalloc(sizeof(*br), GFP_KERNEL);
657 if (!br) {
658 printk(KERN_ERR "can't allocate memory\n");
659 goto out;
660 }
661
662 br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
663 GFP_KERNEL);
664 if (!br->levels)
665 goto out_free;
666
667 for (i = 0; i < obj->package.count; i++) {
668 o = (union acpi_object *)&obj->package.elements[i];
669 if (o->type != ACPI_TYPE_INTEGER) {
670 printk(KERN_ERR PREFIX "Invalid data\n");
671 continue;
672 }
673 br->levels[count] = (u32) o->integer.value;
674
675 if (br->levels[count] > max_level)
676 max_level = br->levels[count];
677 count++;
678 }
679
680 if (count < 2)
681 goto out_free_levels;
682
683 br->count = count;
684 device->brightness = br;
685 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
686 kfree(obj);
687 return max_level;
688
689out_free_levels:
690 kfree(br->levels);
691out_free:
692 kfree(br);
693out:
694 device->brightness = NULL;
695 kfree(obj);
696 return 0;
697}
698
699/*
700 * Arg:
701 * device : video output device (LCD, CRT, ..)
702 *
703 * Return Value:
634 * None 704 * None
635 * 705 *
636 * Find out all required AML methods defined under the output 706 * Find out all required AML methods defined under the output
@@ -640,10 +710,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
640static void acpi_video_device_find_cap(struct acpi_video_device *device) 710static void acpi_video_device_find_cap(struct acpi_video_device *device)
641{ 711{
642 acpi_handle h_dummy1; 712 acpi_handle h_dummy1;
643 int i;
644 u32 max_level = 0; 713 u32 max_level = 0;
645 union acpi_object *obj = NULL;
646 struct acpi_video_device_brightness *br = NULL;
647 714
648 715
649 memset(&device->cap, 0, sizeof(device->cap)); 716 memset(&device->cap, 0, sizeof(device->cap));
@@ -672,53 +739,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
672 device->cap._DSS = 1; 739 device->cap._DSS = 1;
673 } 740 }
674 741
675 if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { 742 max_level = acpi_video_init_brightness(device);
676
677 if (obj->package.count >= 2) {
678 int count = 0;
679 union acpi_object *o;
680
681 br = kzalloc(sizeof(*br), GFP_KERNEL);
682 if (!br) {
683 printk(KERN_ERR "can't allocate memory\n");
684 } else {
685 br->levels = kmalloc(obj->package.count *
686 sizeof *(br->levels), GFP_KERNEL);
687 if (!br->levels)
688 goto out;
689
690 for (i = 0; i < obj->package.count; i++) {
691 o = (union acpi_object *)&obj->package.
692 elements[i];
693 if (o->type != ACPI_TYPE_INTEGER) {
694 printk(KERN_ERR PREFIX "Invalid data\n");
695 continue;
696 }
697 br->levels[count] = (u32) o->integer.value;
698
699 if (br->levels[count] > max_level)
700 max_level = br->levels[count];
701 count++;
702 }
703 out:
704 if (count < 2) {
705 kfree(br->levels);
706 kfree(br);
707 } else {
708 br->count = count;
709 device->brightness = br;
710 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
711 "found %d brightness levels\n",
712 count));
713 }
714 }
715 }
716
717 } else {
718 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
719 }
720
721 kfree(obj);
722 743
723 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ 744 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
724 int result; 745 int result;
@@ -1695,6 +1716,8 @@ static void
1695acpi_video_switch_brightness(struct acpi_video_device *device, int event) 1716acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1696{ 1717{
1697 unsigned long level_current, level_next; 1718 unsigned long level_current, level_next;
1719 if (!device->brightness)
1720 return;
1698 acpi_video_device_lcd_get_level_current(device, &level_current); 1721 acpi_video_device_lcd_get_level_current(device, &level_current);
1699 level_next = acpi_video_get_next_level(device, level_current, event); 1722 level_next = acpi_video_get_next_level(device, level_current, event);
1700 acpi_video_device_lcd_set_level(device, level_next); 1723 acpi_video_device_lcd_set_level(device, level_next);