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.c120
1 files changed, 82 insertions, 38 deletions
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);
273static void acpi_video_switch_brightness(struct acpi_video_device *device, 275static void acpi_video_switch_brightness(struct acpi_video_device *device,
274 int event); 276 int event);
277static int acpi_video_device_get_state(struct acpi_video_device *device,
278 unsigned long *state);
279static int acpi_video_output_get(struct output_device *od);
280static 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*/
277static int acpi_video_get_brightness(struct backlight_device *bd) 283static 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*/
307static 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
316static 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
324static 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
532static void acpi_video_device_find_cap(struct acpi_video_device *device) 560static 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