diff options
-rw-r--r-- | Documentation/thinkpad-acpi.txt | 96 | ||||
-rw-r--r-- | drivers/acpi/event.c | 2 | ||||
-rw-r--r-- | drivers/acpi/sleep/proc.c | 10 | ||||
-rw-r--r-- | drivers/misc/Kconfig | 20 | ||||
-rw-r--r-- | drivers/misc/msi-laptop.c | 2 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 144 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.h | 1 |
7 files changed, 172 insertions, 103 deletions
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index eb2f5986e1eb..60953d6c919d 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | ThinkPad ACPI Extras Driver | 1 | ThinkPad ACPI Extras Driver |
2 | 2 | ||
3 | Version 0.15 | 3 | Version 0.16 |
4 | July 1st, 2007 | 4 | August 2nd, 2007 |
5 | 5 | ||
6 | Borislav Deianov <borislav@users.sf.net> | 6 | Borislav Deianov <borislav@users.sf.net> |
7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 7 | Henrique de Moraes Holschuh <hmh@hmh.eng.br> |
@@ -161,20 +161,22 @@ system. Enabling the hotkey functionality of thinkpad-acpi signals the | |||
161 | firmware that such a driver is present, and modifies how the ThinkPad | 161 | firmware that such a driver is present, and modifies how the ThinkPad |
162 | firmware will behave in many situations. | 162 | firmware will behave in many situations. |
163 | 163 | ||
164 | The driver enables the hot key feature automatically when loaded. The | ||
165 | feature can later be disabled and enabled back at runtime. The driver | ||
166 | will also restore the hot key feature to its previous state and mask | ||
167 | when it is unloaded. | ||
168 | |||
164 | When the hotkey feature is enabled and the hot key mask is set (see | 169 | When the hotkey feature is enabled and the hot key mask is set (see |
165 | below), the various hot keys either generate ACPI events in the | 170 | below), the driver will report HKEY events in the following format: |
166 | following format: | ||
167 | 171 | ||
168 | ibm/hotkey HKEY 00000080 0000xxxx | 172 | ibm/hotkey HKEY 00000080 0000xxxx |
169 | 173 | ||
170 | or events over the input layer. The input layer support accepts the | 174 | Some of these events refer to hot key presses, but not all. |
171 | standard IOCTLs to remap the keycodes assigned to each hotkey. | ||
172 | 175 | ||
173 | When the input device is open, the driver will suppress any ACPI hot key | 176 | The driver will generate events over the input layer for hot keys and |
174 | events that get translated into a meaningful input layer event, in order | 177 | radio switches, and over the ACPI netlink layer for other events. The |
175 | to avoid sending duplicate events to userspace. Hot keys that are | 178 | input layer support accepts the standard IOCTLs to remap the keycodes |
176 | mapped to KEY_RESERVED in the keymap are not translated, and will always | 179 | assigned to each hot key. |
177 | generate an ACPI ibm/hotkey HKEY event, and no input layer events. | ||
178 | 180 | ||
179 | The hot key bit mask allows some control over which hot keys generate | 181 | The hot key bit mask allows some control over which hot keys generate |
180 | events. If a key is "masked" (bit set to 0 in the mask), the firmware | 182 | events. If a key is "masked" (bit set to 0 in the mask), the firmware |
@@ -256,6 +258,20 @@ sysfs notes: | |||
256 | disabled" postition, and 1 if the switch is in the | 258 | disabled" postition, and 1 if the switch is in the |
257 | "radios enabled" position. | 259 | "radios enabled" position. |
258 | 260 | ||
261 | hotkey_report_mode: | ||
262 | Returns the state of the procfs ACPI event report mode | ||
263 | filter for hot keys. If it is set to 1 (the default), | ||
264 | all hot key presses are reported both through the input | ||
265 | layer and also as ACPI events through procfs (but not | ||
266 | through netlink). If it is set to 2, hot key presses | ||
267 | are reported only through the input layer. | ||
268 | |||
269 | This attribute is read-only in kernels 2.6.23 or later, | ||
270 | and read-write on earlier kernels. | ||
271 | |||
272 | May return -EPERM (write access locked out by module | ||
273 | parameter) or -EACCES (read-only). | ||
274 | |||
259 | input layer notes: | 275 | input layer notes: |
260 | 276 | ||
261 | A Hot key is mapped to a single input layer EV_KEY event, possibly | 277 | A Hot key is mapped to a single input layer EV_KEY event, possibly |
@@ -393,21 +409,63 @@ unknown by the driver if the ThinkPad firmware triggered these events on | |||
393 | hot key press or release, but the firmware will do it for either one, not | 409 | hot key press or release, but the firmware will do it for either one, not |
394 | both. | 410 | both. |
395 | 411 | ||
396 | If a key is mapped to KEY_RESERVED, it generates no input events at all, | 412 | If a key is mapped to KEY_RESERVED, it generates no input events at all. |
397 | and it may generate a legacy thinkpad-acpi ACPI hotkey event. | ||
398 | |||
399 | If a key is mapped to KEY_UNKNOWN, it generates an input event that | 413 | If a key is mapped to KEY_UNKNOWN, it generates an input event that |
400 | includes an scan code, and it may also generate a legacy thinkpad-acpi | 414 | includes an scan code. If a key is mapped to anything else, it will |
401 | ACPI hotkey event. | 415 | generate input device EV_KEY events. |
402 | |||
403 | If a key is mapped to anything else, it will only generate legacy | ||
404 | thinkpad-acpi ACPI hotkey events if nobody has opened the input device. | ||
405 | 416 | ||
406 | Non hot-key ACPI HKEY event map: | 417 | Non hot-key ACPI HKEY event map: |
407 | 0x5001 Lid closed | 418 | 0x5001 Lid closed |
408 | 0x5002 Lid opened | 419 | 0x5002 Lid opened |
409 | 0x7000 Radio Switch may have changed state | 420 | 0x7000 Radio Switch may have changed state |
410 | 421 | ||
422 | The above events are not propagated by the driver, except for legacy | ||
423 | compatibility purposes when hotkey_report_mode is set to 1. | ||
424 | |||
425 | Compatibility notes: | ||
426 | |||
427 | ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never | ||
428 | supported the input layer, and sent events over the procfs ACPI event | ||
429 | interface. | ||
430 | |||
431 | To avoid sending duplicate events over the input layer and the ACPI | ||
432 | event interface, thinkpad-acpi 0.16 implements a module parameter | ||
433 | (hotkey_report_mode), and also a sysfs device attribute with the same | ||
434 | name. | ||
435 | |||
436 | Make no mistake here: userspace is expected to switch to using the input | ||
437 | layer interface of thinkpad-acpi, together with the ACPI netlink event | ||
438 | interface in kernels 2.6.23 and later, or with the ACPI procfs event | ||
439 | interface in kernels 2.6.22 and earlier. | ||
440 | |||
441 | If no hotkey_report_mode module parameter is specified (or it is set to | ||
442 | zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22 | ||
443 | and earlier, also allows one to change the hotkey_report_mode through | ||
444 | sysfs. In kernels 2.6.23 and later, where the netlink ACPI event | ||
445 | interface is available, hotkey_report_mode cannot be changed through | ||
446 | sysfs (it is read-only). | ||
447 | |||
448 | If the hotkey_report_mode module parameter is set to 1 or 2, it cannot | ||
449 | be changed later through sysfs (any writes will return -EPERM to signal | ||
450 | that hotkey_report_mode was locked. On 2.6.23 and later, where | ||
451 | hotkey_report_mode cannot be changed at all, writes will return -EACES). | ||
452 | |||
453 | hotkey_report_mode set to 1 makes the driver export through the procfs | ||
454 | ACPI event interface all hot key presses (which are *also* sent to the | ||
455 | input layer). This is a legacy compatibility behaviour, and it is also | ||
456 | the default mode of operation for the driver. | ||
457 | |||
458 | hotkey_report_mode set to 2 makes the driver filter out the hot key | ||
459 | presses from the procfs ACPI event interface, so these events will only | ||
460 | be sent through the input layer. Userspace that has been updated to use | ||
461 | the thinkpad-acpi input layer interface should set hotkey_report_mode to | ||
462 | 2. | ||
463 | |||
464 | Hot key press events are never sent to the ACPI netlink event interface. | ||
465 | Really up-to-date userspace under kernel 2.6.23 and later is to use the | ||
466 | netlink interface and the input layer interface, and don't bother at all | ||
467 | with hotkey_report_mode. | ||
468 | |||
411 | 469 | ||
412 | Bluetooth | 470 | Bluetooth |
413 | --------- | 471 | --------- |
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index a2b9304596ce..5c95863f8fa9 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c | |||
@@ -240,7 +240,7 @@ int acpi_bus_generate_netlink_event(const char *device_class, | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | EXPORT_SYMBOL(acpi_generate_netlink_event); | 243 | EXPORT_SYMBOL(acpi_bus_generate_netlink_event); |
244 | 244 | ||
245 | static int acpi_event_genetlink_init(void) | 245 | static int acpi_event_genetlink_init(void) |
246 | { | 246 | { |
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c index 66b62b0d3609..3839efd5eaea 100644 --- a/drivers/acpi/sleep/proc.c +++ b/drivers/acpi/sleep/proc.c | |||
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | ACPI_MODULE_NAME("sleep") | 25 | ACPI_MODULE_NAME("sleep") |
26 | #ifdef CONFIG_ACPI_PROCFS_SLEEP | 26 | #ifdef CONFIG_ACPI_PROCFS |
27 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) | 27 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) |
28 | { | 28 | { |
29 | int i; | 29 | int i; |
@@ -76,7 +76,7 @@ acpi_system_write_sleep(struct file *file, | |||
76 | Done: | 76 | Done: |
77 | return error ? error : count; | 77 | return error ? error : count; |
78 | } | 78 | } |
79 | #endif /* CONFIG_ACPI_PROCFS_SLEEP */ | 79 | #endif /* CONFIG_ACPI_PROCFS */ |
80 | 80 | ||
81 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) | 81 | #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) |
82 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ | 82 | /* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ |
@@ -471,7 +471,7 @@ static const struct file_operations acpi_system_wakeup_device_fops = { | |||
471 | .release = single_release, | 471 | .release = single_release, |
472 | }; | 472 | }; |
473 | 473 | ||
474 | #ifdef CONFIG_ACPI_PROCFS_SLEEP | 474 | #ifdef CONFIG_ACPI_PROCFS |
475 | static const struct file_operations acpi_system_sleep_fops = { | 475 | static const struct file_operations acpi_system_sleep_fops = { |
476 | .open = acpi_system_sleep_open_fs, | 476 | .open = acpi_system_sleep_open_fs, |
477 | .read = seq_read, | 477 | .read = seq_read, |
@@ -479,7 +479,7 @@ static const struct file_operations acpi_system_sleep_fops = { | |||
479 | .llseek = seq_lseek, | 479 | .llseek = seq_lseek, |
480 | .release = single_release, | 480 | .release = single_release, |
481 | }; | 481 | }; |
482 | #endif /* CONFIG_ACPI_PROCFS_SLEEP */ | 482 | #endif /* CONFIG_ACPI_PROCFS */ |
483 | 483 | ||
484 | #ifdef HAVE_ACPI_LEGACY_ALARM | 484 | #ifdef HAVE_ACPI_LEGACY_ALARM |
485 | static const struct file_operations acpi_system_alarm_fops = { | 485 | static const struct file_operations acpi_system_alarm_fops = { |
@@ -506,7 +506,7 @@ static int __init acpi_sleep_proc_init(void) | |||
506 | if (acpi_disabled) | 506 | if (acpi_disabled) |
507 | return 0; | 507 | return 0; |
508 | 508 | ||
509 | #ifdef CONFIG_ACPI_PROCFS_SLEEP | 509 | #ifdef CONFIG_ACPI_PROCFS |
510 | /* 'sleep' [R/W] */ | 510 | /* 'sleep' [R/W] */ |
511 | entry = | 511 | entry = |
512 | create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR, | 512 | create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR, |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a26655881e6a..73e248fb2ff1 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -202,25 +202,5 @@ config THINKPAD_ACPI_BAY | |||
202 | 202 | ||
203 | If you are not sure, say Y here. | 203 | If you are not sure, say Y here. |
204 | 204 | ||
205 | config THINKPAD_ACPI_INPUT_ENABLED | ||
206 | bool "Enable input layer support by default" | ||
207 | depends on THINKPAD_ACPI | ||
208 | default n | ||
209 | ---help--- | ||
210 | This option enables thinkpad-acpi hot key handling over the input | ||
211 | layer at driver load time. When it is unset, the driver does not | ||
212 | enable hot key handling by default, and also starts up with a mostly | ||
213 | empty keymap. | ||
214 | |||
215 | This option should be enabled if you have a new enough HAL or other | ||
216 | userspace support that properly handles the thinkpad-acpi event | ||
217 | device. It auto-tunes the hot key support to those reported by the | ||
218 | firmware and enables it automatically. | ||
219 | |||
220 | If unsure, say N here to retain the old behaviour of ibm-acpi, and | ||
221 | thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and | ||
222 | set up the thinkpad-acpi hot key handling using the sysfs interace | ||
223 | after loading the driver. | ||
224 | |||
225 | 205 | ||
226 | endif # MISC_DEVICES | 206 | endif # MISC_DEVICES |
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c index 932a415197b3..349be934db7c 100644 --- a/drivers/misc/msi-laptop.c +++ b/drivers/misc/msi-laptop.c | |||
@@ -353,7 +353,7 @@ static int __init msi_init(void) | |||
353 | if (IS_ERR(msibl_device)) | 353 | if (IS_ERR(msibl_device)) |
354 | return PTR_ERR(msibl_device); | 354 | return PTR_ERR(msibl_device); |
355 | 355 | ||
356 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1, | 356 | msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1; |
357 | 357 | ||
358 | ret = platform_driver_register(&msipf_driver); | 358 | ret = platform_driver_register(&msipf_driver); |
359 | if (ret) | 359 | if (ret) |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index bb8956d0c104..0222bbaf7b76 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * 02110-1301, USA. | 21 | * 02110-1301, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define IBM_VERSION "0.15" | 24 | #define IBM_VERSION "0.16" |
25 | #define TPACPI_SYSFS_VERSION 0x010000 | 25 | #define TPACPI_SYSFS_VERSION 0x010000 |
26 | 26 | ||
27 | /* | 27 | /* |
@@ -906,9 +906,26 @@ static ssize_t hotkey_radio_sw_show(struct device *dev, | |||
906 | static struct device_attribute dev_attr_hotkey_radio_sw = | 906 | static struct device_attribute dev_attr_hotkey_radio_sw = |
907 | __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); | 907 | __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL); |
908 | 908 | ||
909 | /* sysfs hotkey report_mode -------------------------------------------- */ | ||
910 | static ssize_t hotkey_report_mode_show(struct device *dev, | ||
911 | struct device_attribute *attr, | ||
912 | char *buf) | ||
913 | { | ||
914 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
915 | (hotkey_report_mode != 0) ? hotkey_report_mode : 1); | ||
916 | } | ||
917 | |||
918 | static struct device_attribute dev_attr_hotkey_report_mode = | ||
919 | __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL); | ||
920 | |||
909 | /* --------------------------------------------------------------------- */ | 921 | /* --------------------------------------------------------------------- */ |
910 | 922 | ||
911 | static struct attribute *hotkey_mask_attributes[] = { | 923 | static struct attribute *hotkey_attributes[] __initdata = { |
924 | &dev_attr_hotkey_enable.attr, | ||
925 | &dev_attr_hotkey_report_mode.attr, | ||
926 | }; | ||
927 | |||
928 | static struct attribute *hotkey_mask_attributes[] __initdata = { | ||
912 | &dev_attr_hotkey_mask.attr, | 929 | &dev_attr_hotkey_mask.attr, |
913 | &dev_attr_hotkey_bios_enabled.attr, | 930 | &dev_attr_hotkey_bios_enabled.attr, |
914 | &dev_attr_hotkey_bios_mask.attr, | 931 | &dev_attr_hotkey_bios_mask.attr, |
@@ -987,11 +1004,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
987 | str_supported(tp_features.hotkey)); | 1004 | str_supported(tp_features.hotkey)); |
988 | 1005 | ||
989 | if (tp_features.hotkey) { | 1006 | if (tp_features.hotkey) { |
990 | hotkey_dev_attributes = create_attr_set(7, NULL); | 1007 | hotkey_dev_attributes = create_attr_set(8, NULL); |
991 | if (!hotkey_dev_attributes) | 1008 | if (!hotkey_dev_attributes) |
992 | return -ENOMEM; | 1009 | return -ENOMEM; |
993 | res = add_to_attr_set(hotkey_dev_attributes, | 1010 | res = add_many_to_attr_set(hotkey_dev_attributes, |
994 | &dev_attr_hotkey_enable.attr); | 1011 | hotkey_attributes, |
1012 | ARRAY_SIZE(hotkey_attributes)); | ||
995 | if (res) | 1013 | if (res) |
996 | return res; | 1014 | return res; |
997 | 1015 | ||
@@ -1055,11 +1073,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
1055 | TPACPI_HOTKEY_MAP_SIZE); | 1073 | TPACPI_HOTKEY_MAP_SIZE); |
1056 | } | 1074 | } |
1057 | 1075 | ||
1058 | #ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED | ||
1059 | for (i = 0; i < 12; i++) | ||
1060 | hotkey_keycode_map[i] = KEY_UNKNOWN; | ||
1061 | #endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ | ||
1062 | |||
1063 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | 1076 | set_bit(EV_KEY, tpacpi_inputdev->evbit); |
1064 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | 1077 | set_bit(EV_MSC, tpacpi_inputdev->evbit); |
1065 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | 1078 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); |
@@ -1081,14 +1094,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
1081 | set_bit(SW_RADIO, tpacpi_inputdev->swbit); | 1094 | set_bit(SW_RADIO, tpacpi_inputdev->swbit); |
1082 | } | 1095 | } |
1083 | 1096 | ||
1084 | #ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED | ||
1085 | dbg_printk(TPACPI_DBG_INIT, | 1097 | dbg_printk(TPACPI_DBG_INIT, |
1086 | "enabling hot key handling\n"); | 1098 | "enabling hot key handling\n"); |
1087 | res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) | 1099 | res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask) |
1088 | | hotkey_orig_mask); | 1100 | | hotkey_orig_mask); |
1089 | if (res) | 1101 | if (res) |
1090 | return res; | 1102 | return res; |
1091 | #endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */ | 1103 | |
1104 | dbg_printk(TPACPI_DBG_INIT, | ||
1105 | "legacy hot key reporting over procfs %s\n", | ||
1106 | (hotkey_report_mode < 2) ? | ||
1107 | "enabled" : "disabled"); | ||
1092 | } | 1108 | } |
1093 | 1109 | ||
1094 | return (tp_features.hotkey)? 0 : 1; | 1110 | return (tp_features.hotkey)? 0 : 1; |
@@ -1142,58 +1158,65 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
1142 | { | 1158 | { |
1143 | u32 hkey; | 1159 | u32 hkey; |
1144 | unsigned int keycode, scancode; | 1160 | unsigned int keycode, scancode; |
1145 | int sendacpi = 1; | 1161 | int send_acpi_ev = 0; |
1146 | 1162 | ||
1147 | if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { | 1163 | if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { |
1148 | if (tpacpi_inputdev->users > 0) { | 1164 | switch (hkey >> 12) { |
1149 | switch (hkey >> 12) { | 1165 | case 1: |
1150 | case 1: | 1166 | /* 0x1000-0x1FFF: key presses */ |
1151 | /* 0x1000-0x1FFF: key presses */ | 1167 | scancode = hkey & 0xfff; |
1152 | scancode = hkey & 0xfff; | 1168 | if (scancode > 0 && scancode < 0x21) { |
1153 | if (scancode > 0 && scancode < 0x21) { | 1169 | scancode--; |
1154 | scancode--; | 1170 | keycode = hotkey_keycode_map[scancode]; |
1155 | keycode = hotkey_keycode_map[scancode]; | 1171 | tpacpi_input_send_key(scancode, keycode); |
1156 | tpacpi_input_send_key(scancode, keycode); | 1172 | } else { |
1157 | sendacpi = (keycode == KEY_RESERVED | 1173 | printk(IBM_ERR |
1158 | || keycode == KEY_UNKNOWN); | 1174 | "hotkey 0x%04x out of range for keyboard map\n", |
1159 | } else { | 1175 | hkey); |
1160 | printk(IBM_ERR | 1176 | send_acpi_ev = 1; |
1161 | "hotkey 0x%04x out of range for keyboard map\n", | 1177 | } |
1162 | hkey); | 1178 | break; |
1163 | } | 1179 | case 5: |
1164 | break; | 1180 | /* 0x5000-0x5FFF: LID */ |
1165 | case 5: | 1181 | /* we don't handle it through this path, just |
1166 | /* 0x5000-0x5FFF: LID */ | 1182 | * eat up known LID events */ |
1167 | /* we don't handle it through this path, just | 1183 | if (hkey != 0x5001 && hkey != 0x5002) { |
1168 | * eat up known LID events */ | 1184 | printk(IBM_ERR |
1169 | if (hkey != 0x5001 && hkey != 0x5002) { | 1185 | "unknown LID-related hotkey event: 0x%04x\n", |
1170 | printk(IBM_ERR | 1186 | hkey); |
1171 | "unknown LID-related hotkey event: 0x%04x\n", | 1187 | send_acpi_ev = 1; |
1172 | hkey); | 1188 | } |
1173 | } | 1189 | break; |
1190 | case 7: | ||
1191 | /* 0x7000-0x7FFF: misc */ | ||
1192 | if (tp_features.hotkey_wlsw && hkey == 0x7000) { | ||
1193 | tpacpi_input_send_radiosw(); | ||
1174 | break; | 1194 | break; |
1175 | case 7: | ||
1176 | /* 0x7000-0x7FFF: misc */ | ||
1177 | if (tp_features.hotkey_wlsw && hkey == 0x7000) { | ||
1178 | tpacpi_input_send_radiosw(); | ||
1179 | sendacpi = 0; | ||
1180 | break; | ||
1181 | } | ||
1182 | /* fallthrough to default */ | ||
1183 | default: | ||
1184 | /* case 2: dock-related */ | ||
1185 | /* 0x2305 - T43 waking up due to bay lever eject while aslept */ | ||
1186 | /* case 3: ultra-bay related. maybe bay in dock? */ | ||
1187 | /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ | ||
1188 | printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey); | ||
1189 | } | 1195 | } |
1196 | /* fallthrough to default */ | ||
1197 | default: | ||
1198 | /* case 2: dock-related */ | ||
1199 | /* 0x2305 - T43 waking up due to bay lever eject while aslept */ | ||
1200 | /* case 3: ultra-bay related. maybe bay in dock? */ | ||
1201 | /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */ | ||
1202 | printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey); | ||
1203 | send_acpi_ev = 1; | ||
1190 | } | 1204 | } |
1191 | |||
1192 | if (sendacpi) | ||
1193 | acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); | ||
1194 | } else { | 1205 | } else { |
1195 | printk(IBM_ERR "unknown hotkey notification event %d\n", event); | 1206 | printk(IBM_ERR "unknown hotkey notification event %d\n", event); |
1196 | acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); | 1207 | hkey = 0; |
1208 | send_acpi_ev = 1; | ||
1209 | } | ||
1210 | |||
1211 | /* Legacy events */ | ||
1212 | if (send_acpi_ev || hotkey_report_mode < 2) | ||
1213 | acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); | ||
1214 | |||
1215 | /* netlink events */ | ||
1216 | if (send_acpi_ev) { | ||
1217 | acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, | ||
1218 | ibm->acpi->device->dev.bus_id, | ||
1219 | event, hkey); | ||
1197 | } | 1220 | } |
1198 | } | 1221 | } |
1199 | 1222 | ||
@@ -4623,6 +4646,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0); | |||
4623 | static int brightness_mode; | 4646 | static int brightness_mode; |
4624 | module_param_named(brightness_mode, brightness_mode, int, 0); | 4647 | module_param_named(brightness_mode, brightness_mode, int, 0); |
4625 | 4648 | ||
4649 | static unsigned int hotkey_report_mode; | ||
4650 | module_param(hotkey_report_mode, uint, 0); | ||
4651 | |||
4626 | #define IBM_PARAM(feature) \ | 4652 | #define IBM_PARAM(feature) \ |
4627 | module_param_call(feature, set_ibm_param, NULL, NULL, 0) | 4653 | module_param_call(feature, set_ibm_param, NULL, NULL, 0) |
4628 | 4654 | ||
@@ -4648,6 +4674,10 @@ static int __init thinkpad_acpi_module_init(void) | |||
4648 | { | 4674 | { |
4649 | int ret, i; | 4675 | int ret, i; |
4650 | 4676 | ||
4677 | /* Parameter checking */ | ||
4678 | if (hotkey_report_mode > 2) | ||
4679 | return -EINVAL; | ||
4680 | |||
4651 | /* Driver-level probe */ | 4681 | /* Driver-level probe */ |
4652 | 4682 | ||
4653 | get_thinkpad_model_data(&thinkpad_id); | 4683 | get_thinkpad_model_data(&thinkpad_id); |
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h index eee8809a50d9..082a1cbc16c0 100644 --- a/drivers/misc/thinkpad_acpi.h +++ b/drivers/misc/thinkpad_acpi.h | |||
@@ -181,6 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv); | |||
181 | static int experimental; | 181 | static int experimental; |
182 | static u32 dbg_level; | 182 | static u32 dbg_level; |
183 | static int force_load; | 183 | static int force_load; |
184 | static unsigned int hotkey_report_mode; | ||
184 | 185 | ||
185 | static int thinkpad_acpi_module_init(void); | 186 | static int thinkpad_acpi_module_init(void); |
186 | static void thinkpad_acpi_module_exit(void); | 187 | static void thinkpad_acpi_module_exit(void); |