aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/thinkpad-acpi.txt96
-rw-r--r--drivers/misc/Kconfig20
-rw-r--r--drivers/misc/thinkpad_acpi.c144
-rw-r--r--drivers/misc/thinkpad_acpi.h1
4 files changed, 165 insertions, 96 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
161firmware that such a driver is present, and modifies how the ThinkPad 161firmware that such a driver is present, and modifies how the ThinkPad
162firmware will behave in many situations. 162firmware will behave in many situations.
163 163
164The driver enables the hot key feature automatically when loaded. The
165feature can later be disabled and enabled back at runtime. The driver
166will also restore the hot key feature to its previous state and mask
167when it is unloaded.
168
164When the hotkey feature is enabled and the hot key mask is set (see 169When the hotkey feature is enabled and the hot key mask is set (see
165below), the various hot keys either generate ACPI events in the 170below), the driver will report HKEY events in the following format:
166following format:
167 171
168 ibm/hotkey HKEY 00000080 0000xxxx 172 ibm/hotkey HKEY 00000080 0000xxxx
169 173
170or events over the input layer. The input layer support accepts the 174Some of these events refer to hot key presses, but not all.
171standard IOCTLs to remap the keycodes assigned to each hotkey.
172 175
173When the input device is open, the driver will suppress any ACPI hot key 176The driver will generate events over the input layer for hot keys and
174events that get translated into a meaningful input layer event, in order 177radio switches, and over the ACPI netlink layer for other events. The
175to avoid sending duplicate events to userspace. Hot keys that are 178input layer support accepts the standard IOCTLs to remap the keycodes
176mapped to KEY_RESERVED in the keymap are not translated, and will always 179assigned to each hot key.
177generate an ACPI ibm/hotkey HKEY event, and no input layer events.
178 180
179The hot key bit mask allows some control over which hot keys generate 181The hot key bit mask allows some control over which hot keys generate
180events. If a key is "masked" (bit set to 0 in the mask), the firmware 182events. 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
259input layer notes: 275input layer notes:
260 276
261A Hot key is mapped to a single input layer EV_KEY event, possibly 277A 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
393hot key press or release, but the firmware will do it for either one, not 409hot key press or release, but the firmware will do it for either one, not
394both. 410both.
395 411
396If a key is mapped to KEY_RESERVED, it generates no input events at all, 412If a key is mapped to KEY_RESERVED, it generates no input events at all.
397and it may generate a legacy thinkpad-acpi ACPI hotkey event.
398
399If a key is mapped to KEY_UNKNOWN, it generates an input event that 413If a key is mapped to KEY_UNKNOWN, it generates an input event that
400includes an scan code, and it may also generate a legacy thinkpad-acpi 414includes an scan code. If a key is mapped to anything else, it will
401ACPI hotkey event. 415generate input device EV_KEY events.
402
403If a key is mapped to anything else, it will only generate legacy
404thinkpad-acpi ACPI hotkey events if nobody has opened the input device.
405 416
406Non hot-key ACPI HKEY event map: 417Non hot-key ACPI HKEY event map:
4070x5001 Lid closed 4180x5001 Lid closed
4080x5002 Lid opened 4190x5002 Lid opened
4090x7000 Radio Switch may have changed state 4200x7000 Radio Switch may have changed state
410 421
422The above events are not propagated by the driver, except for legacy
423compatibility purposes when hotkey_report_mode is set to 1.
424
425Compatibility notes:
426
427ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never
428supported the input layer, and sent events over the procfs ACPI event
429interface.
430
431To avoid sending duplicate events over the input layer and the ACPI
432event interface, thinkpad-acpi 0.16 implements a module parameter
433(hotkey_report_mode), and also a sysfs device attribute with the same
434name.
435
436Make no mistake here: userspace is expected to switch to using the input
437layer interface of thinkpad-acpi, together with the ACPI netlink event
438interface in kernels 2.6.23 and later, or with the ACPI procfs event
439interface in kernels 2.6.22 and earlier.
440
441If no hotkey_report_mode module parameter is specified (or it is set to
442zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22
443and earlier, also allows one to change the hotkey_report_mode through
444sysfs. In kernels 2.6.23 and later, where the netlink ACPI event
445interface is available, hotkey_report_mode cannot be changed through
446sysfs (it is read-only).
447
448If the hotkey_report_mode module parameter is set to 1 or 2, it cannot
449be changed later through sysfs (any writes will return -EPERM to signal
450that hotkey_report_mode was locked. On 2.6.23 and later, where
451hotkey_report_mode cannot be changed at all, writes will return -EACES).
452
453hotkey_report_mode set to 1 makes the driver export through the procfs
454ACPI event interface all hot key presses (which are *also* sent to the
455input layer). This is a legacy compatibility behaviour, and it is also
456the default mode of operation for the driver.
457
458hotkey_report_mode set to 2 makes the driver filter out the hot key
459presses from the procfs ACPI event interface, so these events will only
460be sent through the input layer. Userspace that has been updated to use
461the thinkpad-acpi input layer interface should set hotkey_report_mode to
4622.
463
464Hot key press events are never sent to the ACPI netlink event interface.
465Really up-to-date userspace under kernel 2.6.23 and later is to use the
466netlink interface and the input layer interface, and don't bother at all
467with hotkey_report_mode.
468
411 469
412Bluetooth 470Bluetooth
413--------- 471---------
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
205config 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
226endif # MISC_DEVICES 206endif # MISC_DEVICES
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,
906static struct device_attribute dev_attr_hotkey_radio_sw = 906static 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 -------------------------------------------- */
910static 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
918static 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
911static struct attribute *hotkey_mask_attributes[] = { 923static struct attribute *hotkey_attributes[] __initdata = {
924 &dev_attr_hotkey_enable.attr,
925 &dev_attr_hotkey_report_mode.attr,
926};
927
928static 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);
4623static int brightness_mode; 4646static int brightness_mode;
4624module_param_named(brightness_mode, brightness_mode, int, 0); 4647module_param_named(brightness_mode, brightness_mode, int, 0);
4625 4648
4649static unsigned int hotkey_report_mode;
4650module_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);
181static int experimental; 181static int experimental;
182static u32 dbg_level; 182static u32 dbg_level;
183static int force_load; 183static int force_load;
184static unsigned int hotkey_report_mode;
184 185
185static int thinkpad_acpi_module_init(void); 186static int thinkpad_acpi_module_init(void);
186static void thinkpad_acpi_module_exit(void); 187static void thinkpad_acpi_module_exit(void);