diff options
| author | Yu Luming <luming.yu@gmail.com> | 2006-11-10 13:40:34 -0500 | 
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2006-12-20 21:23:16 -0500 | 
| commit | 2f3d000a133f68250635f14f6caf24d32d358090 (patch) | |
| tree | 23d6aa85616e75a08e2eb162c8ac79df3f36d29e | |
| parent | a8274d57afb83e4954ddcb3f8b7dd1c03a379bd4 (diff) | |
ACPI: Adds backlight sysfs support for acpi video driver.
Adds backlight sysfs support for acpi video driver.
signed-off-by: Luming Yu <Luming.yu@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
| -rw-r--r-- | drivers/acpi/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/acpi/video.c | 71 | 
2 files changed, 70 insertions, 3 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 6f8c50ea54e1..e3f77e2ce25f 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig  | |||
| @@ -106,7 +106,7 @@ config ACPI_BUTTON | |||
| 106 | 106 | ||
| 107 | config ACPI_VIDEO | 107 | config ACPI_VIDEO | 
| 108 | tristate "Video" | 108 | tristate "Video" | 
| 109 | depends on X86 | 109 | depends on X86 && BACKLIGHT_CLASS_DEVICE | 
| 110 | help | 110 | help | 
| 111 | This driver implement the ACPI Extensions For Display Adapters | 111 | This driver implement the ACPI Extensions For Display Adapters | 
| 112 | for integrated graphics devices on motherboard, as specified in | 112 | for integrated graphics devices on motherboard, as specified in | 
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 9200a46c38bd..4b09a021b434 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 | 
| 61 | ACPI_MODULE_NAME("acpi_video") | 63 | ACPI_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 | ||
| 152 | struct acpi_video_device_brightness { | 154 | struct 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); | 
| 258 | static int acpi_video_device_enumerate(struct acpi_video_bus *video); | 262 | static int acpi_video_device_enumerate(struct acpi_video_bus *video); | 
| 259 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event); | 263 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event); | 
| 264 | static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, | ||
| 265 | int level); | ||
| 266 | static int acpi_video_device_lcd_get_level_current( | ||
| 267 | struct acpi_video_device *device, | ||
| 268 | unsigned long *level); | ||
| 260 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 269 | static int acpi_video_get_next_level(struct acpi_video_device *device, | 
| 261 | u32 level_current, u32 event); | 270 | u32 level_current, u32 event); | 
| 262 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 271 | static void acpi_video_switch_brightness(struct acpi_video_device *device, | 
| 263 | int event); | 272 | int event); | 
| 264 | 273 | ||
| 274 | /*backlight device sysfs support*/ | ||
| 275 | static 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 | |||
| 284 | static 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 | } | 
| @@ -551,6 +582,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
| 551 | continue; | 582 | continue; | 
| 552 | } | 583 | } | 
| 553 | br->levels[count] = (u32) o->integer.value; | 584 | br->levels[count] = (u32) o->integer.value; | 
| 585 | if (br->levels[count] > max_level) | ||
| 586 | max_level = br->levels[count]; | ||
| 554 | count++; | 587 | count++; | 
| 555 | } | 588 | } | 
| 556 | out: | 589 | out: | 
| @@ -569,6 +602,37 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
| 569 | 602 | ||
| 570 | kfree(obj); | 603 | kfree(obj); | 
| 571 | 604 | ||
| 605 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC){ | ||
| 606 | unsigned long tmp; | ||
| 607 | static int count = 0; | ||
| 608 | char *name; | ||
| 609 | struct backlight_properties *acpi_video_data; | ||
| 610 | |||
| 611 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | ||
| 612 | if (!name) | ||
| 613 | return; | ||
| 614 | |||
| 615 | acpi_video_data = kzalloc( | ||
| 616 | sizeof(struct backlight_properties), | ||
| 617 | GFP_KERNEL); | ||
| 618 | if (!acpi_video_data){ | ||
| 619 | kfree(name); | ||
| 620 | return; | ||
| 621 | } | ||
| 622 | acpi_video_data->owner = THIS_MODULE; | ||
| 623 | acpi_video_data->get_brightness = | ||
| 624 | acpi_video_get_brightness; | ||
| 625 | acpi_video_data->update_status = | ||
| 626 | acpi_video_set_brightness; | ||
| 627 | sprintf(name, "acpi_video%d", count++); | ||
| 628 | device->data = acpi_video_data; | ||
| 629 | acpi_video_data->max_brightness = max_level; | ||
| 630 | acpi_video_device_lcd_get_level_current(device, &tmp); | ||
| 631 | acpi_video_data->brightness = (int)tmp; | ||
| 632 | device->backlight = backlight_device_register(name, | ||
| 633 | NULL, device, acpi_video_data); | ||
| 634 | kfree(name); | ||
| 635 | } | ||
| 572 | return; | 636 | return; | 
| 573 | } | 637 | } | 
| 574 | 638 | ||
| @@ -1595,7 +1659,10 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
| 1595 | status = acpi_remove_notify_handler(device->dev->handle, | 1659 | status = acpi_remove_notify_handler(device->dev->handle, | 
| 1596 | ACPI_DEVICE_NOTIFY, | 1660 | ACPI_DEVICE_NOTIFY, | 
| 1597 | acpi_video_device_notify); | 1661 | acpi_video_device_notify); | 
| 1598 | 1662 | if (device->backlight){ | |
| 1663 | backlight_device_unregister(device->backlight); | ||
| 1664 | kfree(device->data); | ||
| 1665 | } | ||
| 1599 | return 0; | 1666 | return 0; | 
| 1600 | } | 1667 | } | 
| 1601 | 1668 | ||
