···11 ThinkPad ACPI Extras Driver2233- Version 0.1544- July 1st, 200733+ Version 0.1644+ August 2nd, 20075566 Borislav Deianov <borislav@users.sf.net>77 Henrique de Moraes Holschuh <hmh@hmh.eng.br>···161161firmware that such a driver is present, and modifies how the ThinkPad162162firmware will behave in many situations.163163164164+The driver enables the hot key feature automatically when loaded. The165165+feature can later be disabled and enabled back at runtime. The driver166166+will also restore the hot key feature to its previous state and mask167167+when it is unloaded.168168+164169When the hotkey feature is enabled and the hot key mask is set (see165165-below), the various hot keys either generate ACPI events in the166166-following format:170170+below), the driver will report HKEY events in the following format:167171168172 ibm/hotkey HKEY 00000080 0000xxxx169173170170-or events over the input layer. The input layer support accepts the171171-standard IOCTLs to remap the keycodes assigned to each hotkey.174174+Some of these events refer to hot key presses, but not all.172175173173-When the input device is open, the driver will suppress any ACPI hot key174174-events that get translated into a meaningful input layer event, in order175175-to avoid sending duplicate events to userspace. Hot keys that are176176-mapped to KEY_RESERVED in the keymap are not translated, and will always177177-generate an ACPI ibm/hotkey HKEY event, and no input layer events.176176+The driver will generate events over the input layer for hot keys and177177+radio switches, and over the ACPI netlink layer for other events. The178178+input layer support accepts the standard IOCTLs to remap the keycodes179179+assigned to each hot key.178180179181The hot key bit mask allows some control over which hot keys generate180182events. If a key is "masked" (bit set to 0 in the mask), the firmware···257255 attribute will read 0 if the switch is in the "radios258256 disabled" postition, and 1 if the switch is in the259257 "radios enabled" position.258258+259259+ hotkey_report_mode:260260+ Returns the state of the procfs ACPI event report mode261261+ filter for hot keys. If it is set to 1 (the default),262262+ all hot key presses are reported both through the input263263+ layer and also as ACPI events through procfs (but not264264+ through netlink). If it is set to 2, hot key presses265265+ are reported only through the input layer.266266+267267+ This attribute is read-only in kernels 2.6.23 or later,268268+ and read-write on earlier kernels.269269+270270+ May return -EPERM (write access locked out by module271271+ parameter) or -EACCES (read-only).260272261273input layer notes:262274···409393hot key press or release, but the firmware will do it for either one, not410394both.411395412412-If a key is mapped to KEY_RESERVED, it generates no input events at all,413413-and it may generate a legacy thinkpad-acpi ACPI hotkey event.414414-396396+If a key is mapped to KEY_RESERVED, it generates no input events at all.415397If a key is mapped to KEY_UNKNOWN, it generates an input event that416416-includes an scan code, and it may also generate a legacy thinkpad-acpi417417-ACPI hotkey event.418418-419419-If a key is mapped to anything else, it will only generate legacy420420-thinkpad-acpi ACPI hotkey events if nobody has opened the input device.398398+includes an scan code. If a key is mapped to anything else, it will399399+generate input device EV_KEY events.421400422401Non hot-key ACPI HKEY event map:4234020x5001 Lid closed4244030x5002 Lid opened4254040x7000 Radio Switch may have changed state405405+406406+The above events are not propagated by the driver, except for legacy407407+compatibility purposes when hotkey_report_mode is set to 1.408408+409409+Compatibility notes:410410+411411+ibm-acpi and thinkpad-acpi 0.15 (mainline kernels before 2.6.23) never412412+supported the input layer, and sent events over the procfs ACPI event413413+interface.414414+415415+To avoid sending duplicate events over the input layer and the ACPI416416+event interface, thinkpad-acpi 0.16 implements a module parameter417417+(hotkey_report_mode), and also a sysfs device attribute with the same418418+name.419419+420420+Make no mistake here: userspace is expected to switch to using the input421421+layer interface of thinkpad-acpi, together with the ACPI netlink event422422+interface in kernels 2.6.23 and later, or with the ACPI procfs event423423+interface in kernels 2.6.22 and earlier.424424+425425+If no hotkey_report_mode module parameter is specified (or it is set to426426+zero), the driver defaults to mode 1 (see below), and on kernels 2.6.22427427+and earlier, also allows one to change the hotkey_report_mode through428428+sysfs. In kernels 2.6.23 and later, where the netlink ACPI event429429+interface is available, hotkey_report_mode cannot be changed through430430+sysfs (it is read-only).431431+432432+If the hotkey_report_mode module parameter is set to 1 or 2, it cannot433433+be changed later through sysfs (any writes will return -EPERM to signal434434+that hotkey_report_mode was locked. On 2.6.23 and later, where435435+hotkey_report_mode cannot be changed at all, writes will return -EACES).436436+437437+hotkey_report_mode set to 1 makes the driver export through the procfs438438+ACPI event interface all hot key presses (which are *also* sent to the439439+input layer). This is a legacy compatibility behaviour, and it is also440440+the default mode of operation for the driver.441441+442442+hotkey_report_mode set to 2 makes the driver filter out the hot key443443+presses from the procfs ACPI event interface, so these events will only444444+be sent through the input layer. Userspace that has been updated to use445445+the thinkpad-acpi input layer interface should set hotkey_report_mode to446446+2.447447+448448+Hot key press events are never sent to the ACPI netlink event interface.449449+Really up-to-date userspace under kernel 2.6.23 and later is to use the450450+netlink interface and the input layer interface, and don't bother at all451451+with hotkey_report_mode.426452427453428454Bluetooth
-20
drivers/misc/Kconfig
···202202203203 If you are not sure, say Y here.204204205205-config THINKPAD_ACPI_INPUT_ENABLED206206- bool "Enable input layer support by default"207207- depends on THINKPAD_ACPI208208- default n209209- ---help---210210- This option enables thinkpad-acpi hot key handling over the input211211- layer at driver load time. When it is unset, the driver does not212212- enable hot key handling by default, and also starts up with a mostly213213- empty keymap.214214-215215- This option should be enabled if you have a new enough HAL or other216216- userspace support that properly handles the thinkpad-acpi event217217- device. It auto-tunes the hot key support to those reported by the218218- firmware and enables it automatically.219219-220220- If unsure, say N here to retain the old behaviour of ibm-acpi, and221221- thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and222222- set up the thinkpad-acpi hot key handling using the sysfs interace223223- after loading the driver.224224-225205226206endif # MISC_DEVICES
+88-58
drivers/misc/thinkpad_acpi.c
···2121 * 02110-1301, USA.2222 */23232424-#define IBM_VERSION "0.15"2424+#define IBM_VERSION "0.16"2525#define TPACPI_SYSFS_VERSION 0x01000026262727/*···906906static struct device_attribute dev_attr_hotkey_radio_sw =907907 __ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);908908909909+/* sysfs hotkey report_mode -------------------------------------------- */910910+static ssize_t hotkey_report_mode_show(struct device *dev,911911+ struct device_attribute *attr,912912+ char *buf)913913+{914914+ return snprintf(buf, PAGE_SIZE, "%d\n",915915+ (hotkey_report_mode != 0) ? hotkey_report_mode : 1);916916+}917917+918918+static struct device_attribute dev_attr_hotkey_report_mode =919919+ __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);920920+909921/* --------------------------------------------------------------------- */910922911911-static struct attribute *hotkey_mask_attributes[] = {923923+static struct attribute *hotkey_attributes[] __initdata = {924924+ &dev_attr_hotkey_enable.attr,925925+ &dev_attr_hotkey_report_mode.attr,926926+};927927+928928+static struct attribute *hotkey_mask_attributes[] __initdata = {912929 &dev_attr_hotkey_mask.attr,913930 &dev_attr_hotkey_bios_enabled.attr,914931 &dev_attr_hotkey_bios_mask.attr,···1004987 str_supported(tp_features.hotkey));10059881006989 if (tp_features.hotkey) {10071007- hotkey_dev_attributes = create_attr_set(7, NULL);990990+ hotkey_dev_attributes = create_attr_set(8, NULL);1008991 if (!hotkey_dev_attributes)1009992 return -ENOMEM;10101010- res = add_to_attr_set(hotkey_dev_attributes,10111011- &dev_attr_hotkey_enable.attr);993993+ res = add_many_to_attr_set(hotkey_dev_attributes,994994+ hotkey_attributes,995995+ ARRAY_SIZE(hotkey_attributes));1012996 if (res)1013997 return res;1014998···10731055 TPACPI_HOTKEY_MAP_SIZE);10741056 }1075105710761076-#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED10771077- for (i = 0; i < 12; i++)10781078- hotkey_keycode_map[i] = KEY_UNKNOWN;10791079-#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */10801080-10811058 set_bit(EV_KEY, tpacpi_inputdev->evbit);10821059 set_bit(EV_MSC, tpacpi_inputdev->evbit);10831060 set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);···10941081 set_bit(SW_RADIO, tpacpi_inputdev->swbit);10951082 }1096108310971097-#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED10981084 dbg_printk(TPACPI_DBG_INIT,10991085 "enabling hot key handling\n");11001086 res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)11011087 | hotkey_orig_mask);11021088 if (res)11031089 return res;11041104-#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */10901090+10911091+ dbg_printk(TPACPI_DBG_INIT,10921092+ "legacy hot key reporting over procfs %s\n",10931093+ (hotkey_report_mode < 2) ?10941094+ "enabled" : "disabled");11051095 }1106109611071097 return (tp_features.hotkey)? 0 : 1;···11581142{11591143 u32 hkey;11601144 unsigned int keycode, scancode;11611161- int sendacpi = 1;11451145+ int send_acpi_ev = 0;1162114611631147 if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {11641164- if (tpacpi_inputdev->users > 0) {11651165- switch (hkey >> 12) {11661166- case 1:11671167- /* 0x1000-0x1FFF: key presses */11681168- scancode = hkey & 0xfff;11691169- if (scancode > 0 && scancode < 0x21) {11701170- scancode--;11711171- keycode = hotkey_keycode_map[scancode];11721172- tpacpi_input_send_key(scancode, keycode);11731173- sendacpi = (keycode == KEY_RESERVED11741174- || keycode == KEY_UNKNOWN);11751175- } else {11761176- printk(IBM_ERR11771177- "hotkey 0x%04x out of range for keyboard map\n",11781178- hkey);11791179- }11801180- break;11811181- case 5:11821182- /* 0x5000-0x5FFF: LID */11831183- /* we don't handle it through this path, just11841184- * eat up known LID events */11851185- if (hkey != 0x5001 && hkey != 0x5002) {11861186- printk(IBM_ERR11871187- "unknown LID-related hotkey event: 0x%04x\n",11881188- hkey);11891189- }11901190- break;11911191- case 7:11921192- /* 0x7000-0x7FFF: misc */11931193- if (tp_features.hotkey_wlsw && hkey == 0x7000) {11941194- tpacpi_input_send_radiosw();11951195- sendacpi = 0;11961196- break;11971197- }11981198- /* fallthrough to default */11991199- default:12001200- /* case 2: dock-related */12011201- /* 0x2305 - T43 waking up due to bay lever eject while aslept */12021202- /* case 3: ultra-bay related. maybe bay in dock? */12031203- /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */12041204- printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);11481148+ switch (hkey >> 12) {11491149+ case 1:11501150+ /* 0x1000-0x1FFF: key presses */11511151+ scancode = hkey & 0xfff;11521152+ if (scancode > 0 && scancode < 0x21) {11531153+ scancode--;11541154+ keycode = hotkey_keycode_map[scancode];11551155+ tpacpi_input_send_key(scancode, keycode);11561156+ } else {11571157+ printk(IBM_ERR11581158+ "hotkey 0x%04x out of range for keyboard map\n",11591159+ hkey);11601160+ send_acpi_ev = 1;12051161 }11621162+ break;11631163+ case 5:11641164+ /* 0x5000-0x5FFF: LID */11651165+ /* we don't handle it through this path, just11661166+ * eat up known LID events */11671167+ if (hkey != 0x5001 && hkey != 0x5002) {11681168+ printk(IBM_ERR11691169+ "unknown LID-related hotkey event: 0x%04x\n",11701170+ hkey);11711171+ send_acpi_ev = 1;11721172+ }11731173+ break;11741174+ case 7:11751175+ /* 0x7000-0x7FFF: misc */11761176+ if (tp_features.hotkey_wlsw && hkey == 0x7000) {11771177+ tpacpi_input_send_radiosw();11781178+ break;11791179+ }11801180+ /* fallthrough to default */11811181+ default:11821182+ /* case 2: dock-related */11831183+ /* 0x2305 - T43 waking up due to bay lever eject while aslept */11841184+ /* case 3: ultra-bay related. maybe bay in dock? */11851185+ /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */11861186+ printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);11871187+ send_acpi_ev = 1;12061188 }12071207-12081208- if (sendacpi)12091209- acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);12101189 } else {12111190 printk(IBM_ERR "unknown hotkey notification event %d\n", event);12121212- acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);11911191+ hkey = 0;11921192+ send_acpi_ev = 1;11931193+ }11941194+11951195+ /* Legacy events */11961196+ if (send_acpi_ev || hotkey_report_mode < 2)11971197+ acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);11981198+11991199+ /* netlink events */12001200+ if (send_acpi_ev) {12011201+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,12021202+ ibm->acpi->device->dev.bus_id,12031203+ event, hkey);12131204 }12141205}12151206···46464623static int brightness_mode;46474624module_param_named(brightness_mode, brightness_mode, int, 0);4648462546264626+static unsigned int hotkey_report_mode;46274627+module_param(hotkey_report_mode, uint, 0);46284628+46494629#define IBM_PARAM(feature) \46504630 module_param_call(feature, set_ibm_param, NULL, NULL, 0)46514631···46734647static int __init thinkpad_acpi_module_init(void)46744648{46754649 int ret, i;46504650+46514651+ /* Parameter checking */46524652+ if (hotkey_report_mode > 2)46534653+ return -EINVAL;4676465446774655 /* Driver-level probe */46784656
+1
drivers/misc/thinkpad_acpi.h
···181181static int experimental;182182static u32 dbg_level;183183static int force_load;184184+static unsigned int hotkey_report_mode;184185185186static int thinkpad_acpi_module_init(void);186187static void thinkpad_acpi_module_exit(void);