aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/video.c91
-rw-r--r--include/linux/input.h6
2 files changed, 93 insertions, 4 deletions
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d98701941981..d727d2c715df 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 {
@@ -1764,6 +1766,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1764{ 1766{
1765 struct acpi_video_bus *video = data; 1767 struct acpi_video_bus *video = data;
1766 struct acpi_device *device = NULL; 1768 struct acpi_device *device = NULL;
1769 struct input_dev *input;
1770 int keycode;
1771
1767 1772
1768 printk("video bus notify\n"); 1773 printk("video bus notify\n");
1769 1774
@@ -1771,11 +1776,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1771 return; 1776 return;
1772 1777
1773 device = video->device; 1778 device = video->device;
1779 input = video->input;
1774 1780
1775 switch (event) { 1781 switch (event) {
1776 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 1782 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
1777 * most likely via hotkey. */ 1783 * most likely via hotkey. */
1778 acpi_bus_generate_event(device, event, 0); 1784 acpi_bus_generate_event(device, event, 0);
1785 keycode = KEY_SWITCHVIDEOMODE;
1779 break; 1786 break;
1780 1787
1781 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 1788 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1784,21 +1791,37 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1784 acpi_video_device_rebind(video); 1791 acpi_video_device_rebind(video);
1785 acpi_video_switch_output(video, event); 1792 acpi_video_switch_output(video, event);
1786 acpi_bus_generate_event(device, event, 0); 1793 acpi_bus_generate_event(device, event, 0);
1794 keycode = KEY_SWITCHVIDEOMODE;
1787 break; 1795 break;
1788 1796
1789 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ 1797 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
1798 acpi_video_switch_output(video, event);
1799 acpi_bus_generate_event(device, event, 0);
1800 keycode = KEY_SWITCHVIDEOMODE;
1801 break;
1790 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ 1802 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
1803 acpi_video_switch_output(video, event);
1804 acpi_bus_generate_event(device, event, 0);
1805 keycode = KEY_VIDEO_NEXT;
1806 break;
1791 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ 1807 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
1792 acpi_video_switch_output(video, event); 1808 acpi_video_switch_output(video, event);
1793 acpi_bus_generate_event(device, event, 0); 1809 acpi_bus_generate_event(device, event, 0);
1810 keycode = KEY_VIDEO_PREV;
1794 break; 1811 break;
1795 1812
1796 default: 1813 default:
1814 keycode = KEY_UNKNOWN;
1797 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1815 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1798 "Unsupported event [0x%x]\n", event)); 1816 "Unsupported event [0x%x]\n", event));
1799 break; 1817 break;
1800 } 1818 }
1801 1819
1820 input_report_key(input, keycode, 1);
1821 input_sync(input);
1822 input_report_key(input, keycode, 0);
1823 input_sync(input);
1824
1802 return; 1825 return;
1803} 1826}
1804 1827
@@ -1806,30 +1829,55 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1806{ 1829{
1807 struct acpi_video_device *video_device = data; 1830 struct acpi_video_device *video_device = data;
1808 struct acpi_device *device = NULL; 1831 struct acpi_device *device = NULL;
1832 struct acpi_video_bus *bus;
1833 struct input_dev *input;
1834 int keycode;
1809 1835
1810 if (!video_device) 1836 if (!video_device)
1811 return; 1837 return;
1812 1838
1813 device = video_device->dev; 1839 device = video_device->dev;
1840 bus = video_device->video;
1841 input = bus->input;
1814 1842
1815 switch (event) { 1843 switch (event) {
1816 case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ 1844 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
1817 case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */ 1845 acpi_video_switch_brightness(video_device, event);
1818 acpi_bus_generate_event(device, event, 0); 1846 acpi_bus_generate_event(device, event, 0);
1847 keycode = KEY_BRIGHTNESS_CYCLE;
1819 break; 1848 break;
1820 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
1821 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ 1849 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
1850 acpi_video_switch_brightness(video_device, event);
1851 acpi_bus_generate_event(device, event, 0);
1852 keycode = KEY_BRIGHTNESSUP;
1853 break;
1822 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ 1854 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
1855 acpi_video_switch_brightness(video_device, event);
1856 acpi_bus_generate_event(device, event, 0);
1857 keycode = KEY_BRIGHTNESSDOWN;
1858 break;
1823 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ 1859 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
1860 acpi_video_switch_brightness(video_device, event);
1861 acpi_bus_generate_event(device, event, 0);
1862 keycode = KEY_BRIGHTNESS_ZERO;
1863 break;
1824 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ 1864 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
1825 acpi_video_switch_brightness(video_device, event); 1865 acpi_video_switch_brightness(video_device, event);
1826 acpi_bus_generate_event(device, event, 0); 1866 acpi_bus_generate_event(device, event, 0);
1867 keycode = KEY_DISPLAY_OFF;
1827 break; 1868 break;
1828 default: 1869 default:
1870 keycode = KEY_UNKNOWN;
1829 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1871 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1830 "Unsupported event [0x%x]\n", event)); 1872 "Unsupported event [0x%x]\n", event));
1831 break; 1873 break;
1832 } 1874 }
1875
1876 input_report_key(input, keycode, 1);
1877 input_sync(input);
1878 input_report_key(input, keycode, 0);
1879 input_sync(input);
1880
1833 return; 1881 return;
1834} 1882}
1835 1883
@@ -1838,6 +1886,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
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)
@@ -1881,6 +1930,39 @@ static int acpi_video_bus_add(struct acpi_device *device)
1881 goto end; 1930 goto end;
1882 } 1931 }
1883 1932
1933
1934 video->input = input = input_allocate_device();
1935
1936 snprintf(video->phys, sizeof(video->phys),
1937 "%s/video/input0", acpi_device_hid(video->device));
1938
1939 input->name = acpi_device_name(video->device);
1940 input->phys = video->phys;
1941 input->id.bustype = BUS_HOST;
1942 input->id.product = 0x06;
1943 input->evbit[0] = BIT(EV_KEY);
1944 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1945 set_bit(KEY_VIDEO_NEXT, input->keybit);
1946 set_bit(KEY_VIDEO_PREV, input->keybit);
1947 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
1948 set_bit(KEY_BRIGHTNESSUP, input->keybit);
1949 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
1950 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1951 set_bit(KEY_DISPLAY_OFF, input->keybit);
1952 set_bit(KEY_UNKNOWN, input->keybit);
1953 result = input_register_device(input);
1954 if (result) {
1955 acpi_remove_notify_handler(video->device->handle,
1956 ACPI_DEVICE_NOTIFY,
1957 acpi_video_bus_notify);
1958 acpi_video_bus_stop_devices(video);
1959 acpi_video_bus_put_devices(video);
1960 kfree(video->attached_array);
1961 acpi_video_bus_remove_fs(device);
1962 goto end;
1963 }
1964
1965
1884 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 1966 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1885 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 1967 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
1886 video->flags.multihead ? "yes" : "no", 1968 video->flags.multihead ? "yes" : "no",
@@ -1914,6 +1996,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1914 acpi_video_bus_put_devices(video); 1996 acpi_video_bus_put_devices(video);
1915 acpi_video_bus_remove_fs(device); 1997 acpi_video_bus_remove_fs(device);
1916 1998
1999 input_unregister_device(video->input);
1917 kfree(video->attached_array); 2000 kfree(video->attached_array);
1918 kfree(video); 2001 kfree(video);
1919 2002
diff --git a/include/linux/input.h b/include/linux/input.h
index e02c6a66b2ba..cf2b5619aa13 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -363,6 +363,12 @@ struct input_absinfo {
363 363
364#define KEY_UNKNOWN 240 364#define KEY_UNKNOWN 240
365 365
366#define KEY_VIDEO_NEXT 241 /* drive next video source */
367#define KEY_VIDEO_PREV 242 /* drive previous video source */
368#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
369#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */
370#define KEY_DISPLAY_OFF 245 /* display device to off state */
371
366#define BTN_MISC 0x100 372#define BTN_MISC 0x100
367#define BTN_0 0x100 373#define BTN_0 0x100
368#define BTN_1 0x101 374#define BTN_1 0x101