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.c262
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");
72MODULE_DESCRIPTION("ACPI Video Driver"); 73MODULE_DESCRIPTION("ACPI Video Driver");
73MODULE_LICENSE("GPL"); 74MODULE_LICENSE("GPL");
74 75
76static int brightness_switch_enabled = 1;
77module_param(brightness_switch_enabled, bool, 0644);
78
75static int acpi_video_bus_add(struct acpi_device *device); 79static int acpi_video_bus_add(struct acpi_device *device);
76static int acpi_video_bus_remove(struct acpi_device *device, int type); 80static int acpi_video_bus_remove(struct acpi_device *device, int type);
81static int acpi_video_resume(struct acpi_device *device);
77 82
78static const struct acpi_device_id video_device_ids[] = { 83static 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);
273static void acpi_video_device_bind(struct acpi_video_bus *video, 280static void acpi_video_device_bind(struct acpi_video_bus *video,
274 struct acpi_video_device *device); 281 struct acpi_video_device *device);
275static int acpi_video_device_enumerate(struct acpi_video_bus *video); 282static int acpi_video_device_enumerate(struct acpi_video_bus *video);
276static int acpi_video_switch_output(struct acpi_video_bus *video, int event);
277static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, 283static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
278 int level); 284 int level);
279static int acpi_video_device_lcd_get_level_current( 285static 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
292static int acpi_video_get_brightness(struct backlight_device *bd) 298static 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
301static int acpi_video_set_brightness(struct backlight_device *bd) 314static 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 */
354static 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
362static 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
378static int
379video_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
393static 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)
726static int acpi_video_bus_check(struct acpi_video_bus *video) 804static 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
1257static int acpi_video_bus_add_fs(struct acpi_device *device) 1364static 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
1596static 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
1641static int 1719static int
1642acpi_video_get_next_level(struct acpi_video_device *device, 1720acpi_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
1892static int instance; 1981static int instance;
1982static 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
1893static int acpi_video_bus_add(struct acpi_device *device) 2001static int acpi_video_bus_add(struct acpi_device *device)
1894{ 2002{
1895 acpi_status status; 2003 acpi_status status;