aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/Kconfig2
-rw-r--r--drivers/acpi/video.c71
2 files changed, 70 insertions, 3 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f4f000abc4e9..50e295b08c94 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -107,7 +107,7 @@ config ACPI_BUTTON
107 107
108config ACPI_VIDEO 108config ACPI_VIDEO
109 tristate "Video" 109 tristate "Video"
110 depends on X86 110 depends on X86 && BACKLIGHT_CLASS_DEVICE
111 help 111 help
112 This driver implement the ACPI Extensions For Display Adapters 112 This driver implement the ACPI Extensions For Display Adapters
113 for integrated graphics devices on motherboard, as specified in 113 for integrated graphics devices on motherboard, as specified in
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 3d54680d0333..cf60ca5515d2 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -32,6 +32,7 @@
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34
35#include <linux/backlight.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36 37
37#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -56,6 +57,7 @@
56 57
57#define ACPI_VIDEO_HEAD_INVALID (~0u - 1) 58#define ACPI_VIDEO_HEAD_INVALID (~0u - 1)
58#define ACPI_VIDEO_HEAD_END (~0u) 59#define ACPI_VIDEO_HEAD_END (~0u)
60#define MAX_NAME_LEN 20
59 61
60#define _COMPONENT ACPI_VIDEO_COMPONENT 62#define _COMPONENT ACPI_VIDEO_COMPONENT
61ACPI_MODULE_NAME("acpi_video") 63ACPI_MODULE_NAME("acpi_video")
@@ -142,11 +144,11 @@ struct acpi_video_device_cap {
142 u8 _ADR:1; /*Return the unique ID */ 144 u8 _ADR:1; /*Return the unique ID */
143 u8 _BCL:1; /*Query list of brightness control levels supported */ 145 u8 _BCL:1; /*Query list of brightness control levels supported */
144 u8 _BCM:1; /*Set the brightness level */ 146 u8 _BCM:1; /*Set the brightness level */
147 u8 _BQC:1; /* Get current brightness level */
145 u8 _DDC:1; /*Return the EDID for this device */ 148 u8 _DDC:1; /*Return the EDID for this device */
146 u8 _DCS:1; /*Return status of output device */ 149 u8 _DCS:1; /*Return status of output device */
147 u8 _DGS:1; /*Query graphics state */ 150 u8 _DGS:1; /*Query graphics state */
148 u8 _DSS:1; /*Device state set */ 151 u8 _DSS:1; /*Device state set */
149 u8 _reserved:1;
150}; 152};
151 153
152struct acpi_video_device_brightness { 154struct acpi_video_device_brightness {
@@ -163,6 +165,8 @@ struct acpi_video_device {
163 struct acpi_video_bus *video; 165 struct acpi_video_bus *video;
164 struct acpi_device *dev; 166 struct acpi_device *dev;
165 struct acpi_video_device_brightness *brightness; 167 struct acpi_video_device_brightness *brightness;
168 struct backlight_device *backlight;
169 struct backlight_properties *data;
166}; 170};
167 171
168/* bus */ 172/* bus */
@@ -257,11 +261,35 @@ static void acpi_video_device_bind(struct acpi_video_bus *video,
257 struct acpi_video_device *device); 261 struct acpi_video_device *device);
258static int acpi_video_device_enumerate(struct acpi_video_bus *video); 262static int acpi_video_device_enumerate(struct acpi_video_bus *video);
259static int acpi_video_switch_output(struct acpi_video_bus *video, int event); 263static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
264static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
265 int level);
266static int acpi_video_device_lcd_get_level_current(
267 struct acpi_video_device *device,
268 unsigned long *level);
260static int acpi_video_get_next_level(struct acpi_video_device *device, 269static int acpi_video_get_next_level(struct acpi_video_device *device,
261 u32 level_current, u32 event); 270 u32 level_current, u32 event);
262static void acpi_video_switch_brightness(struct acpi_video_device *device, 271static void acpi_video_switch_brightness(struct acpi_video_device *device,
263 int event); 272 int event);
264 273
274/*backlight device sysfs support*/
275static int acpi_video_get_brightness(struct backlight_device *bd)
276{
277 unsigned long cur_level;
278 struct acpi_video_device *vd =
279 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
280 acpi_video_device_lcd_get_level_current(vd, &cur_level);
281 return (int) cur_level;
282}
283
284static int acpi_video_set_brightness(struct backlight_device *bd)
285{
286 int request_level = bd->props->brightness;
287 struct acpi_video_device *vd =
288 (struct acpi_video_device *)class_get_devdata(&bd->class_dev);
289 acpi_video_device_lcd_set_level(vd, request_level);
290 return 0;
291}
292
265/* -------------------------------------------------------------------------- 293/* --------------------------------------------------------------------------
266 Video Management 294 Video Management
267 -------------------------------------------------------------------------- */ 295 -------------------------------------------------------------------------- */
@@ -499,6 +527,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
499 acpi_integer status; 527 acpi_integer status;
500 acpi_handle h_dummy1; 528 acpi_handle h_dummy1;
501 int i; 529 int i;
530 u32 max_level = 0;
502 union acpi_object *obj = NULL; 531 union acpi_object *obj = NULL;
503 struct acpi_video_device_brightness *br = NULL; 532 struct acpi_video_device_brightness *br = NULL;
504 533
@@ -514,6 +543,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
514 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) { 543 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCM", &h_dummy1))) {
515 device->cap._BCM = 1; 544 device->cap._BCM = 1;
516 } 545 }
546 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
547 device->cap._BQC = 1;
517 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { 548 if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
518 device->cap._DDC = 1; 549 device->cap._DDC = 1;
519 } 550 }
@@ -550,6 +581,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
550 continue; 581 continue;
551 } 582 }
552 br->levels[count] = (u32) o->integer.value; 583 br->levels[count] = (u32) o->integer.value;
584 if (br->levels[count] > max_level)
585 max_level = br->levels[count];
553 count++; 586 count++;
554 } 587 }
555 out: 588 out:
@@ -568,6 +601,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
568 601
569 kfree(obj); 602 kfree(obj);
570 603
604 if (device->cap._BCL && device->cap._BCM && device->cap._BQC){
605 unsigned long tmp;
606 static int count = 0;
607 char *name;
608 struct backlight_properties *acpi_video_data;
609
610 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
611 if (!name)
612 return;
613
614 acpi_video_data = kzalloc(
615 sizeof(struct backlight_properties),
616 GFP_KERNEL);
617 if (!acpi_video_data){
618 kfree(name);
619 return;
620 }
621 acpi_video_data->owner = THIS_MODULE;
622 acpi_video_data->get_brightness =
623 acpi_video_get_brightness;
624 acpi_video_data->update_status =
625 acpi_video_set_brightness;
626 sprintf(name, "acpi_video%d", count++);
627 device->data = acpi_video_data;
628 acpi_video_data->max_brightness = max_level;
629 acpi_video_device_lcd_get_level_current(device, &tmp);
630 acpi_video_data->brightness = (int)tmp;
631 device->backlight = backlight_device_register(name,
632 NULL, device, acpi_video_data);
633 kfree(name);
634 }
571 return; 635 return;
572} 636}
573 637
@@ -1588,7 +1652,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1588 status = acpi_remove_notify_handler(device->dev->handle, 1652 status = acpi_remove_notify_handler(device->dev->handle,
1589 ACPI_DEVICE_NOTIFY, 1653 ACPI_DEVICE_NOTIFY,
1590 acpi_video_device_notify); 1654 acpi_video_device_notify);
1591 1655 if (device->backlight){
1656 backlight_device_unregister(device->backlight);
1657 kfree(device->data);
1658 }
1592 return 0; 1659 return 0;
1593} 1660}
1594 1661