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 /drivers/acpi/video.c | |
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>
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 71 |
1 files changed, 69 insertions, 2 deletions
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 | ||