diff options
Diffstat (limited to 'drivers/acpi/video.c')
-rw-r--r-- | drivers/acpi/video.c | 262 |
1 files changed, 185 insertions, 77 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index bd77e81e81c1..7f714fa2a454 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
35 | #include <linux/input.h> | 35 | #include <linux/input.h> |
36 | #include <linux/backlight.h> | 36 | #include <linux/backlight.h> |
37 | #include <linux/thermal.h> | ||
37 | #include <linux/video_output.h> | 38 | #include <linux/video_output.h> |
38 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
39 | 40 | ||
@@ -72,8 +73,12 @@ MODULE_AUTHOR("Bruno Ducrot"); | |||
72 | MODULE_DESCRIPTION("ACPI Video Driver"); | 73 | MODULE_DESCRIPTION("ACPI Video Driver"); |
73 | MODULE_LICENSE("GPL"); | 74 | MODULE_LICENSE("GPL"); |
74 | 75 | ||
76 | static int brightness_switch_enabled = 1; | ||
77 | module_param(brightness_switch_enabled, bool, 0644); | ||
78 | |||
75 | static int acpi_video_bus_add(struct acpi_device *device); | 79 | static int acpi_video_bus_add(struct acpi_device *device); |
76 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 80 | static int acpi_video_bus_remove(struct acpi_device *device, int type); |
81 | static int acpi_video_resume(struct acpi_device *device); | ||
77 | 82 | ||
78 | static const struct acpi_device_id video_device_ids[] = { | 83 | static const struct acpi_device_id video_device_ids[] = { |
79 | {ACPI_VIDEO_HID, 0}, | 84 | {ACPI_VIDEO_HID, 0}, |
@@ -88,6 +93,7 @@ static struct acpi_driver acpi_video_bus = { | |||
88 | .ops = { | 93 | .ops = { |
89 | .add = acpi_video_bus_add, | 94 | .add = acpi_video_bus_add, |
90 | .remove = acpi_video_bus_remove, | 95 | .remove = acpi_video_bus_remove, |
96 | .resume = acpi_video_resume, | ||
91 | }, | 97 | }, |
92 | }; | 98 | }; |
93 | 99 | ||
@@ -179,6 +185,7 @@ struct acpi_video_device { | |||
179 | struct acpi_device *dev; | 185 | struct acpi_device *dev; |
180 | struct acpi_video_device_brightness *brightness; | 186 | struct acpi_video_device_brightness *brightness; |
181 | struct backlight_device *backlight; | 187 | struct backlight_device *backlight; |
188 | struct thermal_cooling_device *cdev; | ||
182 | struct output_device *output_dev; | 189 | struct output_device *output_dev; |
183 | }; | 190 | }; |
184 | 191 | ||
@@ -273,7 +280,6 @@ static void acpi_video_device_rebind(struct acpi_video_bus *video); | |||
273 | static void acpi_video_device_bind(struct acpi_video_bus *video, | 280 | static void acpi_video_device_bind(struct acpi_video_bus *video, |
274 | struct acpi_video_device *device); | 281 | struct acpi_video_device *device); |
275 | static int acpi_video_device_enumerate(struct acpi_video_bus *video); | 282 | static int acpi_video_device_enumerate(struct acpi_video_bus *video); |
276 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event); | ||
277 | static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, | 283 | static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, |
278 | int level); | 284 | int level); |
279 | static int acpi_video_device_lcd_get_level_current( | 285 | static int acpi_video_device_lcd_get_level_current( |
@@ -292,18 +298,26 @@ static int acpi_video_device_set_state(struct acpi_video_device *device, int sta | |||
292 | static int acpi_video_get_brightness(struct backlight_device *bd) | 298 | static int acpi_video_get_brightness(struct backlight_device *bd) |
293 | { | 299 | { |
294 | unsigned long cur_level; | 300 | unsigned long cur_level; |
301 | int i; | ||
295 | struct acpi_video_device *vd = | 302 | struct acpi_video_device *vd = |
296 | (struct acpi_video_device *)bl_get_data(bd); | 303 | (struct acpi_video_device *)bl_get_data(bd); |
297 | acpi_video_device_lcd_get_level_current(vd, &cur_level); | 304 | acpi_video_device_lcd_get_level_current(vd, &cur_level); |
298 | return (int) cur_level; | 305 | for (i = 2; i < vd->brightness->count; i++) { |
306 | if (vd->brightness->levels[i] == cur_level) | ||
307 | /* The first two entries are special - see page 575 | ||
308 | of the ACPI spec 3.0 */ | ||
309 | return i-2; | ||
310 | } | ||
311 | return 0; | ||
299 | } | 312 | } |
300 | 313 | ||
301 | static int acpi_video_set_brightness(struct backlight_device *bd) | 314 | static int acpi_video_set_brightness(struct backlight_device *bd) |
302 | { | 315 | { |
303 | int request_level = bd->props.brightness; | 316 | int request_level = bd->props.brightness+2; |
304 | struct acpi_video_device *vd = | 317 | struct acpi_video_device *vd = |
305 | (struct acpi_video_device *)bl_get_data(bd); | 318 | (struct acpi_video_device *)bl_get_data(bd); |
306 | acpi_video_device_lcd_set_level(vd, request_level); | 319 | acpi_video_device_lcd_set_level(vd, |
320 | vd->brightness->levels[request_level]); | ||
307 | return 0; | 321 | return 0; |
308 | } | 322 | } |
309 | 323 | ||
@@ -334,6 +348,54 @@ static struct output_properties acpi_output_properties = { | |||
334 | .set_state = acpi_video_output_set, | 348 | .set_state = acpi_video_output_set, |
335 | .get_status = acpi_video_output_get, | 349 | .get_status = acpi_video_output_get, |
336 | }; | 350 | }; |
351 | |||
352 | |||
353 | /* thermal cooling device callbacks */ | ||
354 | static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf) | ||
355 | { | ||
356 | struct acpi_device *device = cdev->devdata; | ||
357 | struct acpi_video_device *video = acpi_driver_data(device); | ||
358 | |||
359 | return sprintf(buf, "%d\n", video->brightness->count - 3); | ||
360 | } | ||
361 | |||
362 | static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf) | ||
363 | { | ||
364 | struct acpi_device *device = cdev->devdata; | ||
365 | struct acpi_video_device *video = acpi_driver_data(device); | ||
366 | unsigned long level; | ||
367 | int state; | ||
368 | |||
369 | acpi_video_device_lcd_get_level_current(video, &level); | ||
370 | for (state = 2; state < video->brightness->count; state++) | ||
371 | if (level == video->brightness->levels[state]) | ||
372 | return sprintf(buf, "%d\n", | ||
373 | video->brightness->count - state - 1); | ||
374 | |||
375 | return -EINVAL; | ||
376 | } | ||
377 | |||
378 | static int | ||
379 | video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state) | ||
380 | { | ||
381 | struct acpi_device *device = cdev->devdata; | ||
382 | struct acpi_video_device *video = acpi_driver_data(device); | ||
383 | int level; | ||
384 | |||
385 | if ( state >= video->brightness->count - 2) | ||
386 | return -EINVAL; | ||
387 | |||
388 | state = video->brightness->count - state; | ||
389 | level = video->brightness->levels[state -1]; | ||
390 | return acpi_video_device_lcd_set_level(video, level); | ||
391 | } | ||
392 | |||
393 | static struct thermal_cooling_device_ops video_cooling_ops = { | ||
394 | .get_max_state = video_get_max_state, | ||
395 | .get_cur_state = video_get_cur_state, | ||
396 | .set_cur_state = video_set_cur_state, | ||
397 | }; | ||
398 | |||
337 | /* -------------------------------------------------------------------------- | 399 | /* -------------------------------------------------------------------------- |
338 | Video Management | 400 | Video Management |
339 | -------------------------------------------------------------------------- */ | 401 | -------------------------------------------------------------------------- */ |
@@ -652,7 +714,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
652 | kfree(obj); | 714 | kfree(obj); |
653 | 715 | ||
654 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ | 716 | if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ |
655 | unsigned long tmp; | 717 | int result; |
656 | static int count = 0; | 718 | static int count = 0; |
657 | char *name; | 719 | char *name; |
658 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); | 720 | name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); |
@@ -660,14 +722,30 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) | |||
660 | return; | 722 | return; |
661 | 723 | ||
662 | sprintf(name, "acpi_video%d", count++); | 724 | sprintf(name, "acpi_video%d", count++); |
663 | acpi_video_device_lcd_get_level_current(device, &tmp); | ||
664 | device->backlight = backlight_device_register(name, | 725 | device->backlight = backlight_device_register(name, |
665 | NULL, device, &acpi_backlight_ops); | 726 | NULL, device, &acpi_backlight_ops); |
666 | device->backlight->props.max_brightness = max_level; | 727 | device->backlight->props.max_brightness = device->brightness->count-3; |
667 | device->backlight->props.brightness = (int)tmp; | 728 | device->backlight->props.brightness = acpi_video_get_brightness(device->backlight); |
668 | backlight_update_status(device->backlight); | 729 | backlight_update_status(device->backlight); |
669 | |||
670 | kfree(name); | 730 | kfree(name); |
731 | |||
732 | device->cdev = thermal_cooling_device_register("LCD", | ||
733 | device->dev, &video_cooling_ops); | ||
734 | if (device->cdev) { | ||
735 | printk(KERN_INFO PREFIX | ||
736 | "%s is registered as cooling_device%d\n", | ||
737 | device->dev->dev.bus_id, device->cdev->id); | ||
738 | result = sysfs_create_link(&device->dev->dev.kobj, | ||
739 | &device->cdev->device.kobj, | ||
740 | "thermal_cooling"); | ||
741 | if (result) | ||
742 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
743 | result = sysfs_create_link(&device->cdev->device.kobj, | ||
744 | &device->dev->dev.kobj, | ||
745 | "device"); | ||
746 | if (result) | ||
747 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | ||
748 | } | ||
671 | } | 749 | } |
672 | if (device->cap._DCS && device->cap._DSS){ | 750 | if (device->cap._DCS && device->cap._DSS){ |
673 | static int count = 0; | 751 | static int count = 0; |
@@ -726,11 +804,40 @@ static void acpi_video_bus_find_cap(struct acpi_video_bus *video) | |||
726 | static int acpi_video_bus_check(struct acpi_video_bus *video) | 804 | static int acpi_video_bus_check(struct acpi_video_bus *video) |
727 | { | 805 | { |
728 | acpi_status status = -ENOENT; | 806 | acpi_status status = -ENOENT; |
729 | 807 | long device_id; | |
808 | struct device *dev; | ||
809 | struct acpi_device *device; | ||
730 | 810 | ||
731 | if (!video) | 811 | if (!video) |
732 | return -EINVAL; | 812 | return -EINVAL; |
733 | 813 | ||
814 | device = video->device; | ||
815 | |||
816 | status = | ||
817 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | ||
818 | |||
819 | if (!ACPI_SUCCESS(status)) | ||
820 | return -ENODEV; | ||
821 | |||
822 | /* We need to attempt to determine whether the _ADR refers to a | ||
823 | PCI device or not. There's no terribly good way to do this, | ||
824 | so the best we can hope for is to assume that there'll never | ||
825 | be a video device in the host bridge */ | ||
826 | if (device_id >= 0x10000) { | ||
827 | /* It looks like a PCI device. Does it exist? */ | ||
828 | dev = acpi_get_physical_device(device->handle); | ||
829 | } else { | ||
830 | /* It doesn't look like a PCI device. Does its parent | ||
831 | exist? */ | ||
832 | acpi_handle phandle; | ||
833 | if (acpi_get_parent(device->handle, &phandle)) | ||
834 | return -ENODEV; | ||
835 | dev = acpi_get_physical_device(phandle); | ||
836 | } | ||
837 | if (!dev) | ||
838 | return -ENODEV; | ||
839 | put_device(dev); | ||
840 | |||
734 | /* Since there is no HID, CID and so on for VGA driver, we have | 841 | /* Since there is no HID, CID and so on for VGA driver, we have |
735 | * to check well known required nodes. | 842 | * to check well known required nodes. |
736 | */ | 843 | */ |
@@ -1256,8 +1363,37 @@ acpi_video_bus_write_DOS(struct file *file, | |||
1256 | 1363 | ||
1257 | static int acpi_video_bus_add_fs(struct acpi_device *device) | 1364 | static int acpi_video_bus_add_fs(struct acpi_device *device) |
1258 | { | 1365 | { |
1366 | long device_id; | ||
1367 | int status; | ||
1259 | struct proc_dir_entry *entry = NULL; | 1368 | struct proc_dir_entry *entry = NULL; |
1260 | struct acpi_video_bus *video; | 1369 | struct acpi_video_bus *video; |
1370 | struct device *dev; | ||
1371 | |||
1372 | status = | ||
1373 | acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); | ||
1374 | |||
1375 | if (!ACPI_SUCCESS(status)) | ||
1376 | return -ENODEV; | ||
1377 | |||
1378 | /* We need to attempt to determine whether the _ADR refers to a | ||
1379 | PCI device or not. There's no terribly good way to do this, | ||
1380 | so the best we can hope for is to assume that there'll never | ||
1381 | be a video device in the host bridge */ | ||
1382 | if (device_id >= 0x10000) { | ||
1383 | /* It looks like a PCI device. Does it exist? */ | ||
1384 | dev = acpi_get_physical_device(device->handle); | ||
1385 | } else { | ||
1386 | /* It doesn't look like a PCI device. Does its parent | ||
1387 | exist? */ | ||
1388 | acpi_handle phandle; | ||
1389 | if (acpi_get_parent(device->handle, &phandle)) | ||
1390 | return -ENODEV; | ||
1391 | dev = acpi_get_physical_device(phandle); | ||
1392 | } | ||
1393 | if (!dev) | ||
1394 | return -ENODEV; | ||
1395 | put_device(dev); | ||
1396 | |||
1261 | 1397 | ||
1262 | 1398 | ||
1263 | video = acpi_driver_data(device); | 1399 | video = acpi_driver_data(device); |
@@ -1580,64 +1716,6 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1580 | return status; | 1716 | return status; |
1581 | } | 1717 | } |
1582 | 1718 | ||
1583 | /* | ||
1584 | * Arg: | ||
1585 | * video : video bus device | ||
1586 | * event : notify event | ||
1587 | * | ||
1588 | * Return: | ||
1589 | * < 0 : error | ||
1590 | * | ||
1591 | * 1. Find out the current active output device. | ||
1592 | * 2. Identify the next output device to switch to. | ||
1593 | * 3. call _DSS to do actual switch. | ||
1594 | */ | ||
1595 | |||
1596 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event) | ||
1597 | { | ||
1598 | struct list_head *node; | ||
1599 | struct acpi_video_device *dev = NULL; | ||
1600 | struct acpi_video_device *dev_next = NULL; | ||
1601 | struct acpi_video_device *dev_prev = NULL; | ||
1602 | unsigned long state; | ||
1603 | int status = 0; | ||
1604 | |||
1605 | mutex_lock(&video->device_list_lock); | ||
1606 | |||
1607 | list_for_each(node, &video->video_device_list) { | ||
1608 | dev = container_of(node, struct acpi_video_device, entry); | ||
1609 | status = acpi_video_device_get_state(dev, &state); | ||
1610 | if (state & 0x2) { | ||
1611 | dev_next = container_of(node->next, | ||
1612 | struct acpi_video_device, entry); | ||
1613 | dev_prev = container_of(node->prev, | ||
1614 | struct acpi_video_device, entry); | ||
1615 | goto out; | ||
1616 | } | ||
1617 | } | ||
1618 | |||
1619 | dev_next = container_of(node->next, struct acpi_video_device, entry); | ||
1620 | dev_prev = container_of(node->prev, struct acpi_video_device, entry); | ||
1621 | |||
1622 | out: | ||
1623 | mutex_unlock(&video->device_list_lock); | ||
1624 | |||
1625 | switch (event) { | ||
1626 | case ACPI_VIDEO_NOTIFY_CYCLE: | ||
1627 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: | ||
1628 | acpi_video_device_set_state(dev, 0); | ||
1629 | acpi_video_device_set_state(dev_next, 0x80000001); | ||
1630 | break; | ||
1631 | case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: | ||
1632 | acpi_video_device_set_state(dev, 0); | ||
1633 | acpi_video_device_set_state(dev_prev, 0x80000001); | ||
1634 | default: | ||
1635 | break; | ||
1636 | } | ||
1637 | |||
1638 | return status; | ||
1639 | } | ||
1640 | |||
1641 | static int | 1719 | static int |
1642 | acpi_video_get_next_level(struct acpi_video_device *device, | 1720 | acpi_video_get_next_level(struct acpi_video_device *device, |
1643 | u32 level_current, u32 event) | 1721 | u32 level_current, u32 event) |
@@ -1729,6 +1807,14 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1729 | ACPI_DEVICE_NOTIFY, | 1807 | ACPI_DEVICE_NOTIFY, |
1730 | acpi_video_device_notify); | 1808 | acpi_video_device_notify); |
1731 | backlight_device_unregister(device->backlight); | 1809 | backlight_device_unregister(device->backlight); |
1810 | if (device->cdev) { | ||
1811 | sysfs_remove_link(&device->dev->dev.kobj, | ||
1812 | "thermal_cooling"); | ||
1813 | sysfs_remove_link(&device->cdev->device.kobj, | ||
1814 | "device"); | ||
1815 | thermal_cooling_device_unregister(device->cdev); | ||
1816 | device->cdev = NULL; | ||
1817 | } | ||
1732 | video_output_unregister(device->output_dev); | 1818 | video_output_unregister(device->output_dev); |
1733 | 1819 | ||
1734 | return 0; | 1820 | return 0; |
@@ -1797,23 +1883,19 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | |||
1797 | * connector. */ | 1883 | * connector. */ |
1798 | acpi_video_device_enumerate(video); | 1884 | acpi_video_device_enumerate(video); |
1799 | acpi_video_device_rebind(video); | 1885 | acpi_video_device_rebind(video); |
1800 | acpi_video_switch_output(video, event); | ||
1801 | acpi_bus_generate_proc_event(device, event, 0); | 1886 | acpi_bus_generate_proc_event(device, event, 0); |
1802 | keycode = KEY_SWITCHVIDEOMODE; | 1887 | keycode = KEY_SWITCHVIDEOMODE; |
1803 | break; | 1888 | break; |
1804 | 1889 | ||
1805 | case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ | 1890 | case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ |
1806 | acpi_video_switch_output(video, event); | ||
1807 | acpi_bus_generate_proc_event(device, event, 0); | 1891 | acpi_bus_generate_proc_event(device, event, 0); |
1808 | keycode = KEY_SWITCHVIDEOMODE; | 1892 | keycode = KEY_SWITCHVIDEOMODE; |
1809 | break; | 1893 | break; |
1810 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ | 1894 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ |
1811 | acpi_video_switch_output(video, event); | ||
1812 | acpi_bus_generate_proc_event(device, event, 0); | 1895 | acpi_bus_generate_proc_event(device, event, 0); |
1813 | keycode = KEY_VIDEO_NEXT; | 1896 | keycode = KEY_VIDEO_NEXT; |
1814 | break; | 1897 | break; |
1815 | case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ | 1898 | case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ |
1816 | acpi_video_switch_output(video, event); | ||
1817 | acpi_bus_generate_proc_event(device, event, 0); | 1899 | acpi_bus_generate_proc_event(device, event, 0); |
1818 | keycode = KEY_VIDEO_PREV; | 1900 | keycode = KEY_VIDEO_PREV; |
1819 | break; | 1901 | break; |
@@ -1825,6 +1907,7 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | |||
1825 | break; | 1907 | break; |
1826 | } | 1908 | } |
1827 | 1909 | ||
1910 | acpi_notifier_call_chain(device, event, 0); | ||
1828 | input_report_key(input, keycode, 1); | 1911 | input_report_key(input, keycode, 1); |
1829 | input_sync(input); | 1912 | input_sync(input); |
1830 | input_report_key(input, keycode, 0); | 1913 | input_report_key(input, keycode, 0); |
@@ -1850,27 +1933,32 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1850 | 1933 | ||
1851 | switch (event) { | 1934 | switch (event) { |
1852 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ | 1935 | case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ |
1853 | acpi_video_switch_brightness(video_device, event); | 1936 | if (brightness_switch_enabled) |
1937 | acpi_video_switch_brightness(video_device, event); | ||
1854 | acpi_bus_generate_proc_event(device, event, 0); | 1938 | acpi_bus_generate_proc_event(device, event, 0); |
1855 | keycode = KEY_BRIGHTNESS_CYCLE; | 1939 | keycode = KEY_BRIGHTNESS_CYCLE; |
1856 | break; | 1940 | break; |
1857 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ | 1941 | case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ |
1858 | acpi_video_switch_brightness(video_device, event); | 1942 | if (brightness_switch_enabled) |
1943 | acpi_video_switch_brightness(video_device, event); | ||
1859 | acpi_bus_generate_proc_event(device, event, 0); | 1944 | acpi_bus_generate_proc_event(device, event, 0); |
1860 | keycode = KEY_BRIGHTNESSUP; | 1945 | keycode = KEY_BRIGHTNESSUP; |
1861 | break; | 1946 | break; |
1862 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ | 1947 | case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ |
1863 | acpi_video_switch_brightness(video_device, event); | 1948 | if (brightness_switch_enabled) |
1949 | acpi_video_switch_brightness(video_device, event); | ||
1864 | acpi_bus_generate_proc_event(device, event, 0); | 1950 | acpi_bus_generate_proc_event(device, event, 0); |
1865 | keycode = KEY_BRIGHTNESSDOWN; | 1951 | keycode = KEY_BRIGHTNESSDOWN; |
1866 | break; | 1952 | break; |
1867 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ | 1953 | case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ |
1868 | acpi_video_switch_brightness(video_device, event); | 1954 | if (brightness_switch_enabled) |
1955 | acpi_video_switch_brightness(video_device, event); | ||
1869 | acpi_bus_generate_proc_event(device, event, 0); | 1956 | acpi_bus_generate_proc_event(device, event, 0); |
1870 | keycode = KEY_BRIGHTNESS_ZERO; | 1957 | keycode = KEY_BRIGHTNESS_ZERO; |
1871 | break; | 1958 | break; |
1872 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ | 1959 | case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ |
1873 | acpi_video_switch_brightness(video_device, event); | 1960 | if (brightness_switch_enabled) |
1961 | acpi_video_switch_brightness(video_device, event); | ||
1874 | acpi_bus_generate_proc_event(device, event, 0); | 1962 | acpi_bus_generate_proc_event(device, event, 0); |
1875 | keycode = KEY_DISPLAY_OFF; | 1963 | keycode = KEY_DISPLAY_OFF; |
1876 | break; | 1964 | break; |
@@ -1881,6 +1969,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1881 | break; | 1969 | break; |
1882 | } | 1970 | } |
1883 | 1971 | ||
1972 | acpi_notifier_call_chain(device, event, 0); | ||
1884 | input_report_key(input, keycode, 1); | 1973 | input_report_key(input, keycode, 1); |
1885 | input_sync(input); | 1974 | input_sync(input); |
1886 | input_report_key(input, keycode, 0); | 1975 | input_report_key(input, keycode, 0); |
@@ -1890,6 +1979,25 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1890 | } | 1979 | } |
1891 | 1980 | ||
1892 | static int instance; | 1981 | static int instance; |
1982 | static int acpi_video_resume(struct acpi_device *device) | ||
1983 | { | ||
1984 | struct acpi_video_bus *video; | ||
1985 | struct acpi_video_device *video_device; | ||
1986 | int i; | ||
1987 | |||
1988 | if (!device || !acpi_driver_data(device)) | ||
1989 | return -EINVAL; | ||
1990 | |||
1991 | video = acpi_driver_data(device); | ||
1992 | |||
1993 | for (i = 0; i < video->attached_count; i++) { | ||
1994 | video_device = video->attached_array[i].bind_info; | ||
1995 | if (video_device && video_device->backlight) | ||
1996 | acpi_video_set_brightness(video_device->backlight); | ||
1997 | } | ||
1998 | return AE_OK; | ||
1999 | } | ||
2000 | |||
1893 | static int acpi_video_bus_add(struct acpi_device *device) | 2001 | static int acpi_video_bus_add(struct acpi_device *device) |
1894 | { | 2002 | { |
1895 | acpi_status status; | 2003 | acpi_status status; |