diff options
-rw-r--r-- | drivers/acpi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/acpi/video.c | 120 | ||||
-rw-r--r-- | drivers/video/Kconfig | 7 | ||||
-rw-r--r-- | drivers/video/Makefile | 3 |
4 files changed, 93 insertions, 39 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 501ed6ffa40f..408b45168aba 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -118,7 +118,7 @@ config ACPI_BUTTON | |||
118 | 118 | ||
119 | config ACPI_VIDEO | 119 | config ACPI_VIDEO |
120 | tristate "Video" | 120 | tristate "Video" |
121 | depends on X86 && BACKLIGHT_CLASS_DEVICE | 121 | depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL |
122 | help | 122 | help |
123 | This driver implement the ACPI Extensions For Display Adapters | 123 | This driver implement the ACPI Extensions For Display Adapters |
124 | for integrated graphics devices on motherboard, as specified in | 124 | for integrated graphics devices on motherboard, as specified in |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 00d25b347255..5f014d3764c8 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | 34 | ||
35 | #include <linux/backlight.h> | 35 | #include <linux/backlight.h> |
36 | #include <linux/video_output.h> | ||
36 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
37 | 38 | ||
38 | #include <acpi/acpi_bus.h> | 39 | #include <acpi/acpi_bus.h> |
@@ -169,6 +170,7 @@ struct acpi_video_device { | |||
169 | struct acpi_device *dev; | 170 | struct acpi_device *dev; |
170 | struct acpi_video_device_brightness *brightness; | 171 | struct acpi_video_device_brightness *brightness; |
171 | struct backlight_device *backlight; | 172 | struct backlight_device *backlight; |
173 | struct output_device *output_dev; | ||
172 | }; | 174 | }; |
173 | 175 | ||
174 | /* bus */ | 176 | /* bus */ |
@@ -272,6 +274,10 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, | |||
272 | u32 level_current, u32 event); | 274 | u32 level_current, u32 event); |
273 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 275 | static void acpi_video_switch_brightness(struct acpi_video_device *device, |
274 | int event); | 276 | int event); |
277 | static int acpi_video_device_get_state(struct acpi_video_device *device, | ||
278 | unsigned long *state); | ||
279 | static int acpi_video_output_get(struct output_device *od); | ||
280 | static int acpi_video_device_set_state(struct acpi_video_device *device, int state); | ||
275 | 281 | ||
276 | /*backlight device sysfs support*/ | 282 | /*backlight device sysfs support*/ |
277 | static int acpi_video_get_brightness(struct backlight_device *bd) | 283 | static int acpi_video_get_brightness(struct backlight_device *bd) |
@@ -297,6 +303,28 @@ static struct backlight_ops acpi_backlight_ops = { | |||
297 | .update_status = acpi_video_set_brightness, | 303 | .update_status = acpi_video_set_brightness, |
298 | }; | 304 | }; |
299 | 305 | ||
306 | /*video output device sysfs support*/ | ||
307 | static int acpi_video_output_get(struct output_device *od) | ||
308 | { | ||
309 | unsigned long state; | ||
310 | struct acpi_video_device *vd = | ||
311 | (struct acpi_video_device *)class_get_devdata(&od->class_dev); | ||
312 | acpi_video_device_get_state(vd, &state); | ||
313 | return (int)state; | ||
314 | } | ||
315 | |||
316 | static int acpi_video_output_set(struct output_device *od) | ||
317 | { | ||
318 | unsigned long state = od->request_state; | ||
319 | struct acpi_video_device *vd= | ||
320 | (struct acpi_video_device *)class_get_devdata(&od->class_dev); | ||
321 | return acpi_video_device_set_state(vd, state); | ||
322 | } | ||
323 | |||
324 | static struct output_properties acpi_output_properties = { | ||
325 | .set_state = acpi_video_output_set, | ||
326 | .get_status = acpi_video_output_get, | ||
327 | }; | ||
300 | /* -------------------------------------------------------------------------- | 328 | /* -------------------------------------------------------------------------- |
301 | Video Management | 329 | Video Management |
302 | -------------------------------------------------------------------------- */ | 330 | -------------------------------------------------------------------------- */ |
@@ -531,7 +559,6 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) | |||
531 | 559 | ||
532 | static void acpi_video_device_find_cap(struct acpi_video_device *device) | 560 | static void acpi_video_device_find_cap(struct acpi_video_device *device) |
533 | { | 561 | { |
534 | acpi_integer status; | ||
535 | acpi_handle h_dummy1; | 562 | acpi_handle h_dummy1; |
536 | int i; | 563 | int i; |
537 | u32 max_level = 0; | 564 | u32 max_level = 0; |
@@ -565,50 +592,55 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
565 | device->cap._DSS = 1; | 592 | device->cap._DSS = 1; |
566 | } | 593 | } |
567 | 594 | ||
568 | status = acpi_video_device_lcd_query_levels(device, &obj); | 595 | if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) { |
569 | 596 | ||
570 | if (obj && obj->type == ACPI_TYPE_PACKAGE && obj->package.count >= 2) { | 597 | if (obj->package.count >= 2) { |
571 | int count = 0; | 598 | int count = 0; |
572 | union acpi_object *o; | 599 | union acpi_object *o; |
573 | 600 | ||
574 | br = kzalloc(sizeof(*br), GFP_KERNEL); | 601 | br = kzalloc(sizeof(*br), GFP_KERNEL); |
575 | if (!br) { | 602 | if (!br) { |
576 | printk(KERN_ERR "can't allocate memory\n"); | 603 | printk(KERN_ERR "can't allocate memory\n"); |
577 | } else { | ||
578 | br->levels = kmalloc(obj->package.count * | ||
579 | sizeof *(br->levels), GFP_KERNEL); | ||
580 | if (!br->levels) | ||
581 | goto out; | ||
582 | |||
583 | for (i = 0; i < obj->package.count; i++) { | ||
584 | o = (union acpi_object *)&obj->package. | ||
585 | elements[i]; | ||
586 | if (o->type != ACPI_TYPE_INTEGER) { | ||
587 | printk(KERN_ERR PREFIX "Invalid data\n"); | ||
588 | continue; | ||
589 | } | ||
590 | br->levels[count] = (u32) o->integer.value; | ||
591 | if (br->levels[count] > max_level) | ||
592 | max_level = br->levels[count]; | ||
593 | count++; | ||
594 | } | ||
595 | out: | ||
596 | if (count < 2) { | ||
597 | kfree(br->levels); | ||
598 | kfree(br); | ||
599 | } else { | 604 | } else { |
600 | br->count = count; | 605 | br->levels = kmalloc(obj->package.count * |
601 | device->brightness = br; | 606 | sizeof *(br->levels), GFP_KERNEL); |
602 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 607 | if (!br->levels) |
603 | "found %d brightness levels\n", | 608 | goto out; |
604 | count)); | 609 | |
610 | for (i = 0; i < obj->package.count; i++) { | ||
611 | o = (union acpi_object *)&obj->package. | ||
612 | elements[i]; | ||
613 | if (o->type != ACPI_TYPE_INTEGER) { | ||
614 | printk(KERN_ERR PREFIX "Invalid data\n"); | ||
615 | continue; | ||
616 | } | ||
617 | br->levels[count] = (u32) o->integer.value; | ||
618 | |||
619 | if (br->levels[count] > max_level) | ||
620 | max_level = br->levels[count]; | ||
621 | count++; | ||
622 | } | ||
623 | out: | ||
624 | if (count < 2) { | ||
625 | kfree(br->levels); | ||
626 | kfree(br); | ||
627 | } else { | ||
628 | br->count = count; | ||
629 | device->brightness = br; | ||
630 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
631 | "found %d brightness levels\n", | ||
632 | count)); | ||
633 | } | ||
605 | } | 634 | } |
606 | } | 635 | } |
636 | |||
637 | } else { | ||
638 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n")); | ||
607 | } | 639 | } |
608 | 640 | ||
609 | kfree(obj); | 641 | kfree(obj); |
610 | 642 | ||
611 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ | 643 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ |
612 | unsigned long tmp; | 644 | unsigned long tmp; |
613 | static int count = 0; | 645 | static int count = 0; |
614 | char *name; | 646 | char *name; |
@@ -626,6 +658,17 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
626 | 658 | ||
627 | kfree(name); | 659 | kfree(name); |
628 | } | 660 | } |
661 | if (device->cap._DCS && device->cap._DSS){ | ||
662 | static int count = 0; | ||
663 | char *name; | ||
664 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | ||
665 | if (!name) | ||
666 | return; | ||
667 | sprintf(name, "acpi_video%d", count++); | ||
668 | device->output_dev = video_output_register(name, | ||
669 | NULL, device, &acpi_output_properties); | ||
670 | kfree(name); | ||
671 | } | ||
629 | return; | 672 | return; |
630 | } | 673 | } |
631 | 674 | ||
@@ -1669,6 +1712,7 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1669 | ACPI_DEVICE_NOTIFY, | 1712 | ACPI_DEVICE_NOTIFY, |
1670 | acpi_video_device_notify); | 1713 | acpi_video_device_notify); |
1671 | backlight_device_unregister(device->backlight); | 1714 | backlight_device_unregister(device->backlight); |
1715 | video_output_unregister(device->output_dev); | ||
1672 | return 0; | 1716 | return 0; |
1673 | } | 1717 | } |
1674 | 1718 | ||
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2a237f09ee5d..564cc9b51822 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -12,6 +12,13 @@ config VGASTATE | |||
12 | tristate | 12 | tristate |
13 | default n | 13 | default n |
14 | 14 | ||
15 | config VIDEO_OUTPUT_CONTROL | ||
16 | tristate "Lowlevel video output switch controls" | ||
17 | default m | ||
18 | help | ||
19 | This framework adds support for low-level control of the video | ||
20 | output switch. | ||
21 | |||
15 | config FB | 22 | config FB |
16 | tristate "Support for frame buffer devices" | 23 | tristate "Support for frame buffer devices" |
17 | ---help--- | 24 | ---help--- |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index a562f9d69d2c..518933d4905f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -123,3 +123,6 @@ obj-$(CONFIG_FB_OF) += offb.o | |||
123 | 123 | ||
124 | # the test framebuffer is last | 124 | # the test framebuffer is last |
125 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o | 125 | obj-$(CONFIG_FB_VIRTUAL) += vfb.o |
126 | |||
127 | #video output switch sysfs driver | ||
128 | obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o | ||