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 | ||
