From a7ecd1ea913346a72f41a002c365882dc05c9bd5 Mon Sep 17 00:00:00 2001 From: Yu Luming Date: Thu, 23 Aug 2007 23:05:55 -0400 Subject: ACPI: video: Add keycode for ACPI video driver hotkey events. Signed-off-by: Luming Yu Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- include/linux/input.h | 6 ++++++ 1 file changed, 6 insertions(+) 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 { #define KEY_UNKNOWN 240 +#define KEY_VIDEO_NEXT 241 /* drive next video source */ +#define KEY_VIDEO_PREV 242 /* drive previous video source */ +#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */ +#define KEY_BRIGHTNESS_ZERO 244 /* brightness off, use ambient */ +#define KEY_DISPLAY_OFF 245 /* display device to off state */ + #define BTN_MISC 0x100 #define BTN_0 0x100 #define BTN_1 0x101 -- cgit v1.2.3-59-g8ed1b From a1eb96a2f635cdb8f626f4074dae2ba5a6fce1e8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 20 Aug 2007 18:23:51 +0800 Subject: ACPI video hotkey: remove invalid events handler for video output devices Both ACPI_VIDEO_NOTIFY_SWITCH and ACPI_VIDEO_NOTIFY_PROBE are valid for video bus devices only. Actually ACPI video output device should never be notified for a output device switch/probe. ACPI bus devices notify handler already has the code to handle these kinds of events. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d98701941981..8efdea587ae3 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1813,10 +1813,6 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) device = video_device->dev; switch (event) { - case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ - case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */ - acpi_bus_generate_event(device, event, 0); - break; case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ -- cgit v1.2.3-59-g8ed1b From e9dab1960ac9746fa34eff726b81635147615a79 Mon Sep 17 00:00:00 2001 From: Luming Yu Date: Mon, 20 Aug 2007 18:23:53 +0800 Subject: ACPI video hotkey: export missing ACPI video hotkey events via input layer Signed-off-by: Yu Luming Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 8efdea587ae3..d727d2c715df 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -31,7 +31,7 @@ #include #include #include - +#include #include #include #include @@ -138,6 +138,8 @@ struct acpi_video_bus { struct semaphore sem; struct list_head video_device_list; struct proc_dir_entry *dir; + struct input_dev *input; + char phys[32]; /* for input device */ }; struct acpi_video_device_flags { @@ -1764,6 +1766,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_bus *video = data; struct acpi_device *device = NULL; + struct input_dev *input; + int keycode; + printk("video bus notify\n"); @@ -1771,11 +1776,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) return; device = video->device; + input = video->input; switch (event) { case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, * most likely via hotkey. */ acpi_bus_generate_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; 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) acpi_video_device_rebind(video); acpi_video_switch_output(video, event); acpi_bus_generate_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; + break; case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_VIDEO_NEXT; + break; case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ acpi_video_switch_output(video, event); acpi_bus_generate_event(device, event, 0); + keycode = KEY_VIDEO_PREV; break; default: + keycode = KEY_UNKNOWN; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + return; } @@ -1806,26 +1829,55 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; + struct acpi_video_bus *bus; + struct input_dev *input; + int keycode; if (!video_device) return; device = video_device->dev; + bus = video_device->video; + input = bus->input; switch (event) { case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESS_CYCLE; + break; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESSUP; + break; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESSDOWN; + break; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESS_ZERO; + break; case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ acpi_video_switch_brightness(video_device, event); acpi_bus_generate_event(device, event, 0); + keycode = KEY_DISPLAY_OFF; break; default: + keycode = KEY_UNKNOWN; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } + + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + return; } @@ -1834,6 +1886,7 @@ static int acpi_video_bus_add(struct acpi_device *device) int result = 0; acpi_status status = 0; struct acpi_video_bus *video = NULL; + struct input_dev *input; if (!device) @@ -1877,6 +1930,39 @@ static int acpi_video_bus_add(struct acpi_device *device) goto end; } + + video->input = input = input_allocate_device(); + + snprintf(video->phys, sizeof(video->phys), + "%s/video/input0", acpi_device_hid(video->device)); + + input->name = acpi_device_name(video->device); + input->phys = video->phys; + input->id.bustype = BUS_HOST; + input->id.product = 0x06; + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_SWITCHVIDEOMODE, input->keybit); + set_bit(KEY_VIDEO_NEXT, input->keybit); + set_bit(KEY_VIDEO_PREV, input->keybit); + set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); + set_bit(KEY_BRIGHTNESSUP, input->keybit); + set_bit(KEY_BRIGHTNESSDOWN, input->keybit); + set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); + set_bit(KEY_DISPLAY_OFF, input->keybit); + set_bit(KEY_UNKNOWN, input->keybit); + result = input_register_device(input); + if (result) { + acpi_remove_notify_handler(video->device->handle, + ACPI_DEVICE_NOTIFY, + acpi_video_bus_notify); + acpi_video_bus_stop_devices(video); + acpi_video_bus_put_devices(video); + kfree(video->attached_array); + acpi_video_bus_remove_fs(device); + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), video->flags.multihead ? "yes" : "no", @@ -1910,6 +1996,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) acpi_video_bus_put_devices(video); acpi_video_bus_remove_fs(device); + input_unregister_device(video->input); kfree(video->attached_array); kfree(video); -- cgit v1.2.3-59-g8ed1b