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.c112
1 files changed, 101 insertions, 11 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d98701941981..d05891f16282 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -31,7 +31,7 @@
31#include <linux/list.h> 31#include <linux/list.h>
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#include <linux/input.h>
35#include <linux/backlight.h> 35#include <linux/backlight.h>
36#include <linux/video_output.h> 36#include <linux/video_output.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -138,6 +138,8 @@ struct acpi_video_bus {
138 struct semaphore sem; 138 struct semaphore sem;
139 struct list_head video_device_list; 139 struct list_head video_device_list;
140 struct proc_dir_entry *dir; 140 struct proc_dir_entry *dir;
141 struct input_dev *input;
142 char phys[32]; /* for input device */
141}; 143};
142 144
143struct acpi_video_device_flags { 145struct acpi_video_device_flags {
@@ -415,7 +417,6 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
415 arg0.integer.value = level; 417 arg0.integer.value = level;
416 status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); 418 status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
417 419
418 printk(KERN_DEBUG "set_level status: %x\n", status);
419 return status; 420 return status;
420} 421}
421 422
@@ -1752,7 +1753,7 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1752 1753
1753static int acpi_video_bus_start_devices(struct acpi_video_bus *video) 1754static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1754{ 1755{
1755 return acpi_video_bus_DOS(video, 1, 0); 1756 return acpi_video_bus_DOS(video, 0, 0);
1756} 1757}
1757 1758
1758static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 1759static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
@@ -1764,6 +1765,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1764{ 1765{
1765 struct acpi_video_bus *video = data; 1766 struct acpi_video_bus *video = data;
1766 struct acpi_device *device = NULL; 1767 struct acpi_device *device = NULL;
1768 struct input_dev *input;
1769 int keycode;
1770
1767 1771
1768 printk("video bus notify\n"); 1772 printk("video bus notify\n");
1769 1773
@@ -1771,11 +1775,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1771 return; 1775 return;
1772 1776
1773 device = video->device; 1777 device = video->device;
1778 input = video->input;
1774 1779
1775 switch (event) { 1780 switch (event) {
1776 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 1781 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
1777 * most likely via hotkey. */ 1782 * most likely via hotkey. */
1778 acpi_bus_generate_event(device, event, 0); 1783 acpi_bus_generate_proc_event(device, event, 0);
1784 keycode = KEY_SWITCHVIDEOMODE;
1779 break; 1785 break;
1780 1786
1781 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 1787 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1783,22 +1789,38 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1783 acpi_video_device_enumerate(video); 1789 acpi_video_device_enumerate(video);
1784 acpi_video_device_rebind(video); 1790 acpi_video_device_rebind(video);
1785 acpi_video_switch_output(video, event); 1791 acpi_video_switch_output(video, event);
1786 acpi_bus_generate_event(device, event, 0); 1792 acpi_bus_generate_proc_event(device, event, 0);
1793 keycode = KEY_SWITCHVIDEOMODE;
1787 break; 1794 break;
1788 1795
1789 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ 1796 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
1797 acpi_video_switch_output(video, event);
1798 acpi_bus_generate_proc_event(device, event, 0);
1799 keycode = KEY_SWITCHVIDEOMODE;
1800 break;
1790 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ 1801 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
1802 acpi_video_switch_output(video, event);
1803 acpi_bus_generate_proc_event(device, event, 0);
1804 keycode = KEY_VIDEO_NEXT;
1805 break;
1791 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ 1806 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
1792 acpi_video_switch_output(video, event); 1807 acpi_video_switch_output(video, event);
1793 acpi_bus_generate_event(device, event, 0); 1808 acpi_bus_generate_proc_event(device, event, 0);
1809 keycode = KEY_VIDEO_PREV;
1794 break; 1810 break;
1795 1811
1796 default: 1812 default:
1813 keycode = KEY_UNKNOWN;
1797 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1814 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1798 "Unsupported event [0x%x]\n", event)); 1815 "Unsupported event [0x%x]\n", event));
1799 break; 1816 break;
1800 } 1817 }
1801 1818
1819 input_report_key(input, keycode, 1);
1820 input_sync(input);
1821 input_report_key(input, keycode, 0);
1822 input_sync(input);
1823
1802 return; 1824 return;
1803} 1825}
1804 1826
@@ -1806,38 +1828,65 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1806{ 1828{
1807 struct acpi_video_device *video_device = data; 1829 struct acpi_video_device *video_device = data;
1808 struct acpi_device *device = NULL; 1830 struct acpi_device *device = NULL;
1831 struct acpi_video_bus *bus;
1832 struct input_dev *input;
1833 int keycode;
1809 1834
1810 if (!video_device) 1835 if (!video_device)
1811 return; 1836 return;
1812 1837
1813 device = video_device->dev; 1838 device = video_device->dev;
1839 bus = video_device->video;
1840 input = bus->input;
1814 1841
1815 switch (event) { 1842 switch (event) {
1816 case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
1817 case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
1818 acpi_bus_generate_event(device, event, 0);
1819 break;
1820 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ 1843 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
1844 acpi_video_switch_brightness(video_device, event);
1845 acpi_bus_generate_proc_event(device, event, 0);
1846 keycode = KEY_BRIGHTNESS_CYCLE;
1847 break;
1821 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ 1848 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
1849 acpi_video_switch_brightness(video_device, event);
1850 acpi_bus_generate_proc_event(device, event, 0);
1851 keycode = KEY_BRIGHTNESSUP;
1852 break;
1822 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ 1853 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
1854 acpi_video_switch_brightness(video_device, event);
1855 acpi_bus_generate_proc_event(device, event, 0);
1856 keycode = KEY_BRIGHTNESSDOWN;
1857 break;
1823 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ 1858 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
1859 acpi_video_switch_brightness(video_device, event);
1860 acpi_bus_generate_proc_event(device, event, 0);
1861 keycode = KEY_BRIGHTNESS_ZERO;
1862 break;
1824 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ 1863 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
1825 acpi_video_switch_brightness(video_device, event); 1864 acpi_video_switch_brightness(video_device, event);
1826 acpi_bus_generate_event(device, event, 0); 1865 acpi_bus_generate_proc_event(device, event, 0);
1866 keycode = KEY_DISPLAY_OFF;
1827 break; 1867 break;
1828 default: 1868 default:
1869 keycode = KEY_UNKNOWN;
1829 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1870 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1830 "Unsupported event [0x%x]\n", event)); 1871 "Unsupported event [0x%x]\n", event));
1831 break; 1872 break;
1832 } 1873 }
1874
1875 input_report_key(input, keycode, 1);
1876 input_sync(input);
1877 input_report_key(input, keycode, 0);
1878 input_sync(input);
1879
1833 return; 1880 return;
1834} 1881}
1835 1882
1883static int instance;
1836static int acpi_video_bus_add(struct acpi_device *device) 1884static int acpi_video_bus_add(struct acpi_device *device)
1837{ 1885{
1838 int result = 0; 1886 int result = 0;
1839 acpi_status status = 0; 1887 acpi_status status = 0;
1840 struct acpi_video_bus *video = NULL; 1888 struct acpi_video_bus *video = NULL;
1889 struct input_dev *input;
1841 1890
1842 1891
1843 if (!device) 1892 if (!device)
@@ -1847,6 +1896,13 @@ static int acpi_video_bus_add(struct acpi_device *device)
1847 if (!video) 1896 if (!video)
1848 return -ENOMEM; 1897 return -ENOMEM;
1849 1898
1899 /* a hack to fix the duplicate name "VID" problem on T61 */
1900 if (!strcmp(device->pnp.bus_id, "VID")) {
1901 if (instance)
1902 device->pnp.bus_id[3] = '0' + instance;
1903 instance ++;
1904 }
1905
1850 video->device = device; 1906 video->device = device;
1851 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); 1907 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
1852 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1908 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
@@ -1881,6 +1937,39 @@ static int acpi_video_bus_add(struct acpi_device *device)
1881 goto end; 1937 goto end;
1882 } 1938 }
1883 1939
1940
1941 video->input = input = input_allocate_device();
1942
1943 snprintf(video->phys, sizeof(video->phys),
1944 "%s/video/input0", acpi_device_hid(video->device));
1945
1946 input->name = acpi_device_name(video->device);
1947 input->phys = video->phys;
1948 input->id.bustype = BUS_HOST;
1949 input->id.product = 0x06;
1950 input->evbit[0] = BIT(EV_KEY);
1951 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1952 set_bit(KEY_VIDEO_NEXT, input->keybit);
1953 set_bit(KEY_VIDEO_PREV, input->keybit);
1954 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
1955 set_bit(KEY_BRIGHTNESSUP, input->keybit);
1956 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
1957 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1958 set_bit(KEY_DISPLAY_OFF, input->keybit);
1959 set_bit(KEY_UNKNOWN, input->keybit);
1960 result = input_register_device(input);
1961 if (result) {
1962 acpi_remove_notify_handler(video->device->handle,
1963 ACPI_DEVICE_NOTIFY,
1964 acpi_video_bus_notify);
1965 acpi_video_bus_stop_devices(video);
1966 acpi_video_bus_put_devices(video);
1967 kfree(video->attached_array);
1968 acpi_video_bus_remove_fs(device);
1969 goto end;
1970 }
1971
1972
1884 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 1973 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1885 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 1974 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
1886 video->flags.multihead ? "yes" : "no", 1975 video->flags.multihead ? "yes" : "no",
@@ -1914,6 +2003,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1914 acpi_video_bus_put_devices(video); 2003 acpi_video_bus_put_devices(video);
1915 acpi_video_bus_remove_fs(device); 2004 acpi_video_bus_remove_fs(device);
1916 2005
2006 input_unregister_device(video->input);
1917 kfree(video->attached_array); 2007 kfree(video->attached_array);
1918 kfree(video); 2008 kfree(video);
1919 2009