aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/laptops/thinkpad-acpi.txt48
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c632
2 files changed, 453 insertions, 227 deletions
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt
index 6d03487ef1c7..aafcaa634191 100644
--- a/Documentation/laptops/thinkpad-acpi.txt
+++ b/Documentation/laptops/thinkpad-acpi.txt
@@ -199,18 +199,22 @@ kind to allow it (and it often doesn't!).
199 199
200Not all bits in the mask can be modified. Not all bits that can be 200Not all bits in the mask can be modified. Not all bits that can be
201modified do anything. Not all hot keys can be individually controlled 201modified do anything. Not all hot keys can be individually controlled
202by the mask. Some models do not support the mask at all, and in those 202by the mask. Some models do not support the mask at all. The behaviour
203models, hot keys cannot be controlled individually. The behaviour of 203of the mask is, therefore, highly dependent on the ThinkPad model.
204the mask is, therefore, highly dependent on the ThinkPad model. 204
205The driver will filter out any unmasked hotkeys, so even if the firmware
206doesn't allow disabling an specific hotkey, the driver will not report
207events for unmasked hotkeys.
205 208
206Note that unmasking some keys prevents their default behavior. For 209Note that unmasking some keys prevents their default behavior. For
207example, if Fn+F5 is unmasked, that key will no longer enable/disable 210example, if Fn+F5 is unmasked, that key will no longer enable/disable
208Bluetooth by itself. 211Bluetooth by itself in firmware.
209 212
210Note also that not all Fn key combinations are supported through ACPI. 213Note also that not all Fn key combinations are supported through ACPI
211For example, on the X40, the brightness, volume and "Access IBM" buttons 214depending on the ThinkPad model and firmware version. On those
212do not generate ACPI events even with this driver. They *can* be used 215ThinkPads, it is still possible to support some extra hotkeys by
213through the "ThinkPad Buttons" utility, see http://www.nongnu.org/tpb/ 216polling the "CMOS NVRAM" at least 10 times per second. The driver
217attempts to enables this functionality automatically when required.
214 218
215procfs notes: 219procfs notes:
216 220
@@ -255,18 +259,11 @@ sysfs notes:
255 1: does nothing 259 1: does nothing
256 260
257 hotkey_mask: 261 hotkey_mask:
258 bit mask to enable driver-handling (and depending on 262 bit mask to enable reporting (and depending on
259 the firmware, ACPI event generation) for each hot key 263 the firmware, ACPI event generation) for each hot key
260 (see above). Returns the current status of the hot keys 264 (see above). Returns the current status of the hot keys
261 mask, and allows one to modify it. 265 mask, and allows one to modify it.
262 266
263 Note: when NVRAM polling is active, the firmware mask
264 will be different from the value returned by
265 hotkey_mask. The driver will retain enabled bits for
266 hotkeys that are under NVRAM polling even if the
267 firmware refuses them, and will not set these bits on
268 the firmware hot key mask.
269
270 hotkey_all_mask: 267 hotkey_all_mask:
271 bit mask that should enable event reporting for all 268 bit mask that should enable event reporting for all
272 supported hot keys, when echoed to hotkey_mask above. 269 supported hot keys, when echoed to hotkey_mask above.
@@ -279,7 +276,8 @@ sysfs notes:
279 bit mask that should enable event reporting for all 276 bit mask that should enable event reporting for all
280 supported hot keys, except those which are always 277 supported hot keys, except those which are always
281 handled by the firmware anyway. Echo it to 278 handled by the firmware anyway. Echo it to
282 hotkey_mask above, to use. 279 hotkey_mask above, to use. This is the default mask
280 used by the driver.
283 281
284 hotkey_source_mask: 282 hotkey_source_mask:
285 bit mask that selects which hot keys will the driver 283 bit mask that selects which hot keys will the driver
@@ -287,9 +285,10 @@ sysfs notes:
287 based on the capabilities reported by the ACPI firmware, 285 based on the capabilities reported by the ACPI firmware,
288 but it can be overridden at runtime. 286 but it can be overridden at runtime.
289 287
290 Hot keys whose bits are set in both hotkey_source_mask 288 Hot keys whose bits are set in hotkey_source_mask are
291 and also on hotkey_mask are polled for in NVRAM. Only a 289 polled for in NVRAM, and reported as hotkey events if
292 few hot keys are available through CMOS NVRAM polling. 290 enabled in hotkey_mask. Only a few hot keys are
291 available through CMOS NVRAM polling.
293 292
294 Warning: when in NVRAM mode, the volume up/down/mute 293 Warning: when in NVRAM mode, the volume up/down/mute
295 keys are synthesized according to changes in the mixer, 294 keys are synthesized according to changes in the mixer,
@@ -525,6 +524,7 @@ compatibility purposes when hotkey_report_mode is set to 1.
5250x2305 System is waking up from suspend to eject bay 5240x2305 System is waking up from suspend to eject bay
5260x2404 System is waking up from hibernation to undock 5250x2404 System is waking up from hibernation to undock
5270x2405 System is waking up from hibernation to eject bay 5260x2405 System is waking up from hibernation to eject bay
5270x5010 Brightness level changed/control event
528 528
529The above events are never propagated by the driver. 529The above events are never propagated by the driver.
530 530
@@ -532,7 +532,6 @@ The above events are never propagated by the driver.
5320x4003 Undocked (see 0x2x04), can sleep again 5320x4003 Undocked (see 0x2x04), can sleep again
5330x500B Tablet pen inserted into its storage bay 5330x500B Tablet pen inserted into its storage bay
5340x500C Tablet pen removed from its storage bay 5340x500C Tablet pen removed from its storage bay
5350x5010 Brightness level changed (newer Lenovo BIOSes)
536 535
537The above events are propagated by the driver. 536The above events are propagated by the driver.
538 537
@@ -621,6 +620,8 @@ For Lenovo models *with* ACPI backlight control:
6212. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi, 6202. Do *NOT* load up ACPI video, enable the hotkeys in thinkpad-acpi,
622 and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process 621 and map them to KEY_BRIGHTNESS_UP and KEY_BRIGHTNESS_DOWN. Process
623 these keys on userspace somehow (e.g. by calling xbacklight). 622 these keys on userspace somehow (e.g. by calling xbacklight).
623 The driver will do this automatically if it detects that ACPI video
624 has been disabled.
624 625
625 626
626Bluetooth 627Bluetooth
@@ -1459,3 +1460,8 @@ Sysfs interface changelog:
14590x020400: Marker for 16 LEDs support. Also, LEDs that are known 14600x020400: Marker for 16 LEDs support. Also, LEDs that are known
1460 to not exist in a given model are not registered with 1461 to not exist in a given model are not registered with
1461 the LED sysfs class anymore. 1462 the LED sysfs class anymore.
1463
14640x020500: Updated hotkey driver, hotkey_mask is always available
1465 and it is always able to disable hot keys. Very old
1466 thinkpads are properly supported. hotkey_bios_mask
1467 is deprecated and marked for removal.
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index f78d27503925..3910f2f3eada 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -22,7 +22,7 @@
22 */ 22 */
23 23
24#define TPACPI_VERSION "0.23" 24#define TPACPI_VERSION "0.23"
25#define TPACPI_SYSFS_VERSION 0x020400 25#define TPACPI_SYSFS_VERSION 0x020500
26 26
27/* 27/*
28 * Changelog: 28 * Changelog:
@@ -145,6 +145,51 @@ enum {
145 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */ 145 TP_ACPI_WGSV_STATE_UWBPWR = 0x0020, /* UWB radio enabled */
146}; 146};
147 147
148/* HKEY events */
149enum tpacpi_hkey_event_t {
150 /* Hotkey-related */
151 TP_HKEY_EV_HOTKEY_BASE = 0x1001, /* first hotkey (FN+F1) */
152 TP_HKEY_EV_BRGHT_UP = 0x1010, /* Brightness up */
153 TP_HKEY_EV_BRGHT_DOWN = 0x1011, /* Brightness down */
154 TP_HKEY_EV_VOL_UP = 0x1015, /* Volume up or unmute */
155 TP_HKEY_EV_VOL_DOWN = 0x1016, /* Volume down or unmute */
156 TP_HKEY_EV_VOL_MUTE = 0x1017, /* Mixer output mute */
157
158 /* Reasons for waking up from S3/S4 */
159 TP_HKEY_EV_WKUP_S3_UNDOCK = 0x2304, /* undock requested, S3 */
160 TP_HKEY_EV_WKUP_S4_UNDOCK = 0x2404, /* undock requested, S4 */
161 TP_HKEY_EV_WKUP_S3_BAYEJ = 0x2305, /* bay ejection req, S3 */
162 TP_HKEY_EV_WKUP_S4_BAYEJ = 0x2405, /* bay ejection req, S4 */
163 TP_HKEY_EV_WKUP_S3_BATLOW = 0x2313, /* battery empty, S3 */
164 TP_HKEY_EV_WKUP_S4_BATLOW = 0x2413, /* battery empty, S4 */
165
166 /* Auto-sleep after eject request */
167 TP_HKEY_EV_BAYEJ_ACK = 0x3003, /* bay ejection complete */
168 TP_HKEY_EV_UNDOCK_ACK = 0x4003, /* undock complete */
169
170 /* Misc bay events */
171 TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */
172
173 /* User-interface events */
174 TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */
175 TP_HKEY_EV_LID_OPEN = 0x5002, /* laptop lid opened */
176 TP_HKEY_EV_TABLET_TABLET = 0x5009, /* tablet swivel up */
177 TP_HKEY_EV_TABLET_NOTEBOOK = 0x500a, /* tablet swivel down */
178 TP_HKEY_EV_PEN_INSERTED = 0x500b, /* tablet pen inserted */
179 TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */
180 TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */
181
182 /* Thermal events */
183 TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */
184 TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */
185 TP_HKEY_EV_ALARM_SENSOR_HOT = 0x6021, /* sensor too hot */
186 TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */
187 TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */
188
189 /* Misc */
190 TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */
191};
192
148/**************************************************************************** 193/****************************************************************************
149 * Main driver 194 * Main driver
150 */ 195 */
@@ -1848,6 +1893,27 @@ static struct ibm_struct thinkpad_acpi_driver_data = {
1848 * Hotkey subdriver 1893 * Hotkey subdriver
1849 */ 1894 */
1850 1895
1896/*
1897 * ThinkPad firmware event model
1898 *
1899 * The ThinkPad firmware has two main event interfaces: normal ACPI
1900 * notifications (which follow the ACPI standard), and a private event
1901 * interface.
1902 *
1903 * The private event interface also issues events for the hotkeys. As
1904 * the driver gained features, the event handling code ended up being
1905 * built around the hotkey subdriver. This will need to be refactored
1906 * to a more formal event API eventually.
1907 *
1908 * Some "hotkeys" are actually supposed to be used as event reports,
1909 * such as "brightness has changed", "volume has changed", depending on
1910 * the ThinkPad model and how the firmware is operating.
1911 *
1912 * Unlike other classes, hotkey-class events have mask/unmask control on
1913 * non-ancient firmware. However, how it behaves changes a lot with the
1914 * firmware model and version.
1915 */
1916
1851enum { /* hot key scan codes (derived from ACPI DSDT) */ 1917enum { /* hot key scan codes (derived from ACPI DSDT) */
1852 TP_ACPI_HOTKEYSCAN_FNF1 = 0, 1918 TP_ACPI_HOTKEYSCAN_FNF1 = 0,
1853 TP_ACPI_HOTKEYSCAN_FNF2, 1919 TP_ACPI_HOTKEYSCAN_FNF2,
@@ -1875,7 +1941,7 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */
1875 TP_ACPI_HOTKEYSCAN_THINKPAD, 1941 TP_ACPI_HOTKEYSCAN_THINKPAD,
1876}; 1942};
1877 1943
1878enum { /* Keys available through NVRAM polling */ 1944enum { /* Keys/events available through NVRAM polling */
1879 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U, 1945 TPACPI_HKEY_NVRAM_KNOWN_MASK = 0x00fb88c0U,
1880 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U, 1946 TPACPI_HKEY_NVRAM_GOOD_MASK = 0x00fb8000U,
1881}; 1947};
@@ -1930,8 +1996,11 @@ static struct task_struct *tpacpi_hotkey_task;
1930static struct mutex hotkey_thread_mutex; 1996static struct mutex hotkey_thread_mutex;
1931 1997
1932/* 1998/*
1933 * Acquire mutex to write poller control variables. 1999 * Acquire mutex to write poller control variables as an
1934 * Increment hotkey_config_change when changing them. 2000 * atomic block.
2001 *
2002 * Increment hotkey_config_change when changing them if you
2003 * want the kthread to forget old state.
1935 * 2004 *
1936 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END 2005 * See HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
1937 */ 2006 */
@@ -1942,6 +2011,11 @@ static unsigned int hotkey_config_change;
1942 * hotkey poller control variables 2011 * hotkey poller control variables
1943 * 2012 *
1944 * Must be atomic or readers will also need to acquire mutex 2013 * Must be atomic or readers will also need to acquire mutex
2014 *
2015 * HOTKEY_CONFIG_CRITICAL_START/HOTKEY_CONFIG_CRITICAL_END
2016 * should be used only when the changes need to be taken as
2017 * a block, OR when one needs to force the kthread to forget
2018 * old state.
1945 */ 2019 */
1946static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */ 2020static u32 hotkey_source_mask; /* bit mask 0=ACPI,1=NVRAM */
1947static unsigned int hotkey_poll_freq = 10; /* Hz */ 2021static unsigned int hotkey_poll_freq = 10; /* Hz */
@@ -1972,10 +2046,12 @@ static enum { /* Reasons for waking up */
1972 2046
1973static int hotkey_autosleep_ack; 2047static int hotkey_autosleep_ack;
1974 2048
1975static u32 hotkey_orig_mask; 2049static u32 hotkey_orig_mask; /* events the BIOS had enabled */
1976static u32 hotkey_all_mask; 2050static u32 hotkey_all_mask; /* all events supported in fw */
1977static u32 hotkey_reserved_mask; 2051static u32 hotkey_reserved_mask; /* events better left disabled */
1978static u32 hotkey_mask; 2052static u32 hotkey_driver_mask; /* events needed by the driver */
2053static u32 hotkey_user_mask; /* events visible to userspace */
2054static u32 hotkey_acpi_mask; /* events enabled in firmware */
1979 2055
1980static unsigned int hotkey_report_mode; 2056static unsigned int hotkey_report_mode;
1981 2057
@@ -1983,6 +2059,9 @@ static u16 *hotkey_keycode_map;
1983 2059
1984static struct attribute_set *hotkey_dev_attributes; 2060static struct attribute_set *hotkey_dev_attributes;
1985 2061
2062static void tpacpi_driver_event(const unsigned int hkey_event);
2063static void hotkey_driver_event(const unsigned int scancode);
2064
1986/* HKEY.MHKG() return bits */ 2065/* HKEY.MHKG() return bits */
1987#define TP_HOTKEY_TABLET_MASK (1 << 3) 2066#define TP_HOTKEY_TABLET_MASK (1 << 3)
1988 2067
@@ -2017,24 +2096,53 @@ static int hotkey_get_tablet_mode(int *status)
2017} 2096}
2018 2097
2019/* 2098/*
2099 * Reads current event mask from firmware, and updates
2100 * hotkey_acpi_mask accordingly. Also resets any bits
2101 * from hotkey_user_mask that are unavailable to be
2102 * delivered (shadow requirement of the userspace ABI).
2103 *
2020 * Call with hotkey_mutex held 2104 * Call with hotkey_mutex held
2021 */ 2105 */
2022static int hotkey_mask_get(void) 2106static int hotkey_mask_get(void)
2023{ 2107{
2024 u32 m = 0;
2025
2026 if (tp_features.hotkey_mask) { 2108 if (tp_features.hotkey_mask) {
2109 u32 m = 0;
2110
2027 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d")) 2111 if (!acpi_evalf(hkey_handle, &m, "DHKN", "d"))
2028 return -EIO; 2112 return -EIO;
2113
2114 hotkey_acpi_mask = m;
2115 } else {
2116 /* no mask support doesn't mean no event support... */
2117 hotkey_acpi_mask = hotkey_all_mask;
2029 } 2118 }
2030 HOTKEY_CONFIG_CRITICAL_START 2119
2031 hotkey_mask = m | (hotkey_source_mask & hotkey_mask); 2120 /* sync userspace-visible mask */
2032 HOTKEY_CONFIG_CRITICAL_END 2121 hotkey_user_mask &= (hotkey_acpi_mask | hotkey_source_mask);
2033 2122
2034 return 0; 2123 return 0;
2035} 2124}
2036 2125
2126void static hotkey_mask_warn_incomplete_mask(void)
2127{
2128 /* log only what the user can fix... */
2129 const u32 wantedmask = hotkey_driver_mask &
2130 ~(hotkey_acpi_mask | hotkey_source_mask) &
2131 (hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);
2132
2133 if (wantedmask)
2134 printk(TPACPI_NOTICE
2135 "required events 0x%08x not enabled!\n",
2136 wantedmask);
2137}
2138
2037/* 2139/*
2140 * Set the firmware mask when supported
2141 *
2142 * Also calls hotkey_mask_get to update hotkey_acpi_mask.
2143 *
2144 * NOTE: does not set bits in hotkey_user_mask, but may reset them.
2145 *
2038 * Call with hotkey_mutex held 2146 * Call with hotkey_mutex held
2039 */ 2147 */
2040static int hotkey_mask_set(u32 mask) 2148static int hotkey_mask_set(u32 mask)
@@ -2042,66 +2150,98 @@ static int hotkey_mask_set(u32 mask)
2042 int i; 2150 int i;
2043 int rc = 0; 2151 int rc = 0;
2044 2152
2045 if (tp_features.hotkey_mask) { 2153 const u32 fwmask = mask & ~hotkey_source_mask;
2046 if (!tp_warned.hotkey_mask_ff &&
2047 (mask == 0xffff || mask == 0xffffff ||
2048 mask == 0xffffffff)) {
2049 tp_warned.hotkey_mask_ff = 1;
2050 printk(TPACPI_NOTICE
2051 "setting the hotkey mask to 0x%08x is likely "
2052 "not the best way to go about it\n", mask);
2053 printk(TPACPI_NOTICE
2054 "please consider using the driver defaults, "
2055 "and refer to up-to-date thinkpad-acpi "
2056 "documentation\n");
2057 }
2058 2154
2059 HOTKEY_CONFIG_CRITICAL_START 2155 if (tp_features.hotkey_mask) {
2060 for (i = 0; i < 32; i++) { 2156 for (i = 0; i < 32; i++) {
2061 u32 m = 1 << i;
2062 /* enable in firmware mask only keys not in NVRAM
2063 * mode, but enable the key in the cached hotkey_mask
2064 * regardless of mode, or the key will end up
2065 * disabled by hotkey_mask_get() */
2066 if (!acpi_evalf(hkey_handle, 2157 if (!acpi_evalf(hkey_handle,
2067 NULL, "MHKM", "vdd", i + 1, 2158 NULL, "MHKM", "vdd", i + 1,
2068 !!((mask & ~hotkey_source_mask) & m))) { 2159 !!(mask & (1 << i)))) {
2069 rc = -EIO; 2160 rc = -EIO;
2070 break; 2161 break;
2071 } else {
2072 hotkey_mask = (hotkey_mask & ~m) | (mask & m);
2073 } 2162 }
2074 } 2163 }
2075 HOTKEY_CONFIG_CRITICAL_END 2164 }
2076 2165
2077 /* hotkey_mask_get must be called unconditionally below */ 2166 /*
2078 if (!hotkey_mask_get() && !rc && 2167 * We *must* make an inconditional call to hotkey_mask_get to
2079 (hotkey_mask & ~hotkey_source_mask) != 2168 * refresh hotkey_acpi_mask and update hotkey_user_mask
2080 (mask & ~hotkey_source_mask)) { 2169 *
2081 printk(TPACPI_NOTICE 2170 * Take the opportunity to also log when we cannot _enable_
2082 "requested hot key mask 0x%08x, but " 2171 * a given event.
2083 "firmware forced it to 0x%08x\n", 2172 */
2084 mask, hotkey_mask); 2173 if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) {
2085 } 2174 printk(TPACPI_NOTICE
2086 } else { 2175 "asked for hotkey mask 0x%08x, but "
2087#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2176 "firmware forced it to 0x%08x\n",
2088 HOTKEY_CONFIG_CRITICAL_START 2177 fwmask, hotkey_acpi_mask);
2089 hotkey_mask = mask & hotkey_source_mask;
2090 HOTKEY_CONFIG_CRITICAL_END
2091 hotkey_mask_get();
2092 if (hotkey_mask != mask) {
2093 printk(TPACPI_NOTICE
2094 "requested hot key mask 0x%08x, "
2095 "forced to 0x%08x (NVRAM poll mask is "
2096 "0x%08x): no firmware mask support\n",
2097 mask, hotkey_mask, hotkey_source_mask);
2098 }
2099#else
2100 hotkey_mask_get();
2101 rc = -ENXIO;
2102#endif /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
2103 } 2178 }
2104 2179
2180 hotkey_mask_warn_incomplete_mask();
2181
2182 return rc;
2183}
2184
2185/*
2186 * Sets hotkey_user_mask and tries to set the firmware mask
2187 *
2188 * Call with hotkey_mutex held
2189 */
2190static int hotkey_user_mask_set(const u32 mask)
2191{
2192 int rc;
2193
2194 /* Give people a chance to notice they are doing something that
2195 * is bound to go boom on their users sooner or later */
2196 if (!tp_warned.hotkey_mask_ff &&
2197 (mask == 0xffff || mask == 0xffffff ||
2198 mask == 0xffffffff)) {
2199 tp_warned.hotkey_mask_ff = 1;
2200 printk(TPACPI_NOTICE
2201 "setting the hotkey mask to 0x%08x is likely "
2202 "not the best way to go about it\n", mask);
2203 printk(TPACPI_NOTICE
2204 "please consider using the driver defaults, "
2205 "and refer to up-to-date thinkpad-acpi "
2206 "documentation\n");
2207 }
2208
2209 /* Try to enable what the user asked for, plus whatever we need.
2210 * this syncs everything but won't enable bits in hotkey_user_mask */
2211 rc = hotkey_mask_set((mask | hotkey_driver_mask) & ~hotkey_source_mask);
2212
2213 /* Enable the available bits in hotkey_user_mask */
2214 hotkey_user_mask = mask & (hotkey_acpi_mask | hotkey_source_mask);
2215
2216 return rc;
2217}
2218
2219/*
2220 * Sets the driver hotkey mask.
2221 *
2222 * Can be called even if the hotkey subdriver is inactive
2223 */
2224static int tpacpi_hotkey_driver_mask_set(const u32 mask)
2225{
2226 int rc;
2227
2228 /* Do the right thing if hotkey_init has not been called yet */
2229 if (!tp_features.hotkey) {
2230 hotkey_driver_mask = mask;
2231 return 0;
2232 }
2233
2234 mutex_lock(&hotkey_mutex);
2235
2236 HOTKEY_CONFIG_CRITICAL_START
2237 hotkey_driver_mask = mask;
2238 hotkey_source_mask |= (mask & ~hotkey_all_mask);
2239 HOTKEY_CONFIG_CRITICAL_END
2240
2241 rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
2242 ~hotkey_source_mask);
2243 mutex_unlock(&hotkey_mutex);
2244
2105 return rc; 2245 return rc;
2106} 2246}
2107 2247
@@ -2137,11 +2277,10 @@ static void tpacpi_input_send_tabletsw(void)
2137 } 2277 }
2138} 2278}
2139 2279
2140static void tpacpi_input_send_key(unsigned int scancode) 2280/* Do NOT call without validating scancode first */
2281static void tpacpi_input_send_key(const unsigned int scancode)
2141{ 2282{
2142 unsigned int keycode; 2283 const unsigned int keycode = hotkey_keycode_map[scancode];
2143
2144 keycode = hotkey_keycode_map[scancode];
2145 2284
2146 if (keycode != KEY_RESERVED) { 2285 if (keycode != KEY_RESERVED) {
2147 mutex_lock(&tpacpi_inputdev_send_mutex); 2286 mutex_lock(&tpacpi_inputdev_send_mutex);
@@ -2162,19 +2301,28 @@ static void tpacpi_input_send_key(unsigned int scancode)
2162 } 2301 }
2163} 2302}
2164 2303
2304/* Do NOT call without validating scancode first */
2305static void tpacpi_input_send_key_masked(const unsigned int scancode)
2306{
2307 hotkey_driver_event(scancode);
2308 if (hotkey_user_mask & (1 << scancode))
2309 tpacpi_input_send_key(scancode);
2310}
2311
2165#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2312#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2166static struct tp_acpi_drv_struct ibm_hotkey_acpidriver; 2313static struct tp_acpi_drv_struct ibm_hotkey_acpidriver;
2167 2314
2315/* Do NOT call without validating scancode first */
2168static void tpacpi_hotkey_send_key(unsigned int scancode) 2316static void tpacpi_hotkey_send_key(unsigned int scancode)
2169{ 2317{
2170 tpacpi_input_send_key(scancode); 2318 tpacpi_input_send_key_masked(scancode);
2171 if (hotkey_report_mode < 2) { 2319 if (hotkey_report_mode < 2) {
2172 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device, 2320 acpi_bus_generate_proc_event(ibm_hotkey_acpidriver.device,
2173 0x80, 0x1001 + scancode); 2321 0x80, TP_HKEY_EV_HOTKEY_BASE + scancode);
2174 } 2322 }
2175} 2323}
2176 2324
2177static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m) 2325static void hotkey_read_nvram(struct tp_nvram_state *n, const u32 m)
2178{ 2326{
2179 u8 d; 2327 u8 d;
2180 2328
@@ -2210,21 +2358,24 @@ static void hotkey_read_nvram(struct tp_nvram_state *n, u32 m)
2210 } 2358 }
2211} 2359}
2212 2360
2361static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2362 struct tp_nvram_state *newn,
2363 const u32 event_mask)
2364{
2365
2213#define TPACPI_COMPARE_KEY(__scancode, __member) \ 2366#define TPACPI_COMPARE_KEY(__scancode, __member) \
2214 do { \ 2367 do { \
2215 if ((mask & (1 << __scancode)) && \ 2368 if ((event_mask & (1 << __scancode)) && \
2216 oldn->__member != newn->__member) \ 2369 oldn->__member != newn->__member) \
2217 tpacpi_hotkey_send_key(__scancode); \ 2370 tpacpi_hotkey_send_key(__scancode); \
2218 } while (0) 2371 } while (0)
2219 2372
2220#define TPACPI_MAY_SEND_KEY(__scancode) \ 2373#define TPACPI_MAY_SEND_KEY(__scancode) \
2221 do { if (mask & (1 << __scancode)) \ 2374 do { \
2222 tpacpi_hotkey_send_key(__scancode); } while (0) 2375 if (event_mask & (1 << __scancode)) \
2376 tpacpi_hotkey_send_key(__scancode); \
2377 } while (0)
2223 2378
2224static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2225 struct tp_nvram_state *newn,
2226 u32 mask)
2227{
2228 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle); 2379 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_THINKPAD, thinkpad_toggle);
2229 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle); 2380 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNSPACE, zoom_toggle);
2230 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle); 2381 TPACPI_COMPARE_KEY(TP_ACPI_HOTKEYSCAN_FNF7, display_toggle);
@@ -2270,15 +2421,22 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
2270 } 2421 }
2271 } 2422 }
2272 } 2423 }
2273}
2274 2424
2275#undef TPACPI_COMPARE_KEY 2425#undef TPACPI_COMPARE_KEY
2276#undef TPACPI_MAY_SEND_KEY 2426#undef TPACPI_MAY_SEND_KEY
2427}
2277 2428
2429/*
2430 * Polling driver
2431 *
2432 * We track all events in hotkey_source_mask all the time, since
2433 * most of them are edge-based. We only issue those requested by
2434 * hotkey_user_mask or hotkey_driver_mask, though.
2435 */
2278static int hotkey_kthread(void *data) 2436static int hotkey_kthread(void *data)
2279{ 2437{
2280 struct tp_nvram_state s[2]; 2438 struct tp_nvram_state s[2];
2281 u32 mask; 2439 u32 poll_mask, event_mask;
2282 unsigned int si, so; 2440 unsigned int si, so;
2283 unsigned long t; 2441 unsigned long t;
2284 unsigned int change_detector, must_reset; 2442 unsigned int change_detector, must_reset;
@@ -2298,10 +2456,12 @@ static int hotkey_kthread(void *data)
2298 /* Initial state for compares */ 2456 /* Initial state for compares */
2299 mutex_lock(&hotkey_thread_data_mutex); 2457 mutex_lock(&hotkey_thread_data_mutex);
2300 change_detector = hotkey_config_change; 2458 change_detector = hotkey_config_change;
2301 mask = hotkey_source_mask & hotkey_mask; 2459 poll_mask = hotkey_source_mask;
2460 event_mask = hotkey_source_mask &
2461 (hotkey_driver_mask | hotkey_user_mask);
2302 poll_freq = hotkey_poll_freq; 2462 poll_freq = hotkey_poll_freq;
2303 mutex_unlock(&hotkey_thread_data_mutex); 2463 mutex_unlock(&hotkey_thread_data_mutex);
2304 hotkey_read_nvram(&s[so], mask); 2464 hotkey_read_nvram(&s[so], poll_mask);
2305 2465
2306 while (!kthread_should_stop()) { 2466 while (!kthread_should_stop()) {
2307 if (t == 0) { 2467 if (t == 0) {
@@ -2324,15 +2484,17 @@ static int hotkey_kthread(void *data)
2324 t = 0; 2484 t = 0;
2325 change_detector = hotkey_config_change; 2485 change_detector = hotkey_config_change;
2326 } 2486 }
2327 mask = hotkey_source_mask & hotkey_mask; 2487 poll_mask = hotkey_source_mask;
2488 event_mask = hotkey_source_mask &
2489 (hotkey_driver_mask | hotkey_user_mask);
2328 poll_freq = hotkey_poll_freq; 2490 poll_freq = hotkey_poll_freq;
2329 mutex_unlock(&hotkey_thread_data_mutex); 2491 mutex_unlock(&hotkey_thread_data_mutex);
2330 2492
2331 if (likely(mask)) { 2493 if (likely(poll_mask)) {
2332 hotkey_read_nvram(&s[si], mask); 2494 hotkey_read_nvram(&s[si], poll_mask);
2333 if (likely(si != so)) { 2495 if (likely(si != so)) {
2334 hotkey_compare_and_issue_event(&s[so], &s[si], 2496 hotkey_compare_and_issue_event(&s[so], &s[si],
2335 mask); 2497 event_mask);
2336 } 2498 }
2337 } 2499 }
2338 2500
@@ -2364,10 +2526,12 @@ static void hotkey_poll_stop_sync(void)
2364/* call with hotkey_mutex held */ 2526/* call with hotkey_mutex held */
2365static void hotkey_poll_setup(bool may_warn) 2527static void hotkey_poll_setup(bool may_warn)
2366{ 2528{
2367 u32 hotkeys_to_poll = hotkey_source_mask & hotkey_mask; 2529 const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
2530 const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
2368 2531
2369 if (hotkeys_to_poll != 0 && hotkey_poll_freq > 0 && 2532 if (hotkey_poll_freq > 0 &&
2370 (tpacpi_inputdev->users > 0 || hotkey_report_mode < 2)) { 2533 (poll_driver_mask ||
2534 (poll_user_mask && tpacpi_inputdev->users > 0))) {
2371 if (!tpacpi_hotkey_task) { 2535 if (!tpacpi_hotkey_task) {
2372 tpacpi_hotkey_task = kthread_run(hotkey_kthread, 2536 tpacpi_hotkey_task = kthread_run(hotkey_kthread,
2373 NULL, TPACPI_NVRAM_KTHREAD_NAME); 2537 NULL, TPACPI_NVRAM_KTHREAD_NAME);
@@ -2380,12 +2544,13 @@ static void hotkey_poll_setup(bool may_warn)
2380 } 2544 }
2381 } else { 2545 } else {
2382 hotkey_poll_stop_sync(); 2546 hotkey_poll_stop_sync();
2383 if (may_warn && hotkeys_to_poll != 0 && 2547 if (may_warn && (poll_driver_mask || poll_user_mask) &&
2384 hotkey_poll_freq == 0) { 2548 hotkey_poll_freq == 0) {
2385 printk(TPACPI_NOTICE 2549 printk(TPACPI_NOTICE
2386 "hot keys 0x%08x require polling, " 2550 "hot keys 0x%08x and/or events 0x%08x "
2387 "which is currently disabled\n", 2551 "require polling, which is currently "
2388 hotkeys_to_poll); 2552 "disabled\n",
2553 poll_user_mask, poll_driver_mask);
2389 } 2554 }
2390 } 2555 }
2391} 2556}
@@ -2403,9 +2568,7 @@ static void hotkey_poll_set_freq(unsigned int freq)
2403 if (!freq) 2568 if (!freq)
2404 hotkey_poll_stop_sync(); 2569 hotkey_poll_stop_sync();
2405 2570
2406 HOTKEY_CONFIG_CRITICAL_START
2407 hotkey_poll_freq = freq; 2571 hotkey_poll_freq = freq;
2408 HOTKEY_CONFIG_CRITICAL_END
2409} 2572}
2410 2573
2411#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ 2574#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
@@ -2440,7 +2603,8 @@ static int hotkey_inputdev_open(struct input_dev *dev)
2440static void hotkey_inputdev_close(struct input_dev *dev) 2603static void hotkey_inputdev_close(struct input_dev *dev)
2441{ 2604{
2442 /* disable hotkey polling when possible */ 2605 /* disable hotkey polling when possible */
2443 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING) 2606 if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING &&
2607 !(hotkey_source_mask & hotkey_driver_mask))
2444 hotkey_poll_setup_safe(false); 2608 hotkey_poll_setup_safe(false);
2445} 2609}
2446 2610
@@ -2488,15 +2652,7 @@ static ssize_t hotkey_mask_show(struct device *dev,
2488 struct device_attribute *attr, 2652 struct device_attribute *attr,
2489 char *buf) 2653 char *buf)
2490{ 2654{
2491 int res; 2655 return snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_user_mask);
2492
2493 if (mutex_lock_killable(&hotkey_mutex))
2494 return -ERESTARTSYS;
2495 res = hotkey_mask_get();
2496 mutex_unlock(&hotkey_mutex);
2497
2498 return (res)?
2499 res : snprintf(buf, PAGE_SIZE, "0x%08x\n", hotkey_mask);
2500} 2656}
2501 2657
2502static ssize_t hotkey_mask_store(struct device *dev, 2658static ssize_t hotkey_mask_store(struct device *dev,
@@ -2512,7 +2668,7 @@ static ssize_t hotkey_mask_store(struct device *dev,
2512 if (mutex_lock_killable(&hotkey_mutex)) 2668 if (mutex_lock_killable(&hotkey_mutex))
2513 return -ERESTARTSYS; 2669 return -ERESTARTSYS;
2514 2670
2515 res = hotkey_mask_set(t); 2671 res = hotkey_user_mask_set(t);
2516 2672
2517#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2673#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2518 hotkey_poll_setup(true); 2674 hotkey_poll_setup(true);
@@ -2594,6 +2750,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2594 const char *buf, size_t count) 2750 const char *buf, size_t count)
2595{ 2751{
2596 unsigned long t; 2752 unsigned long t;
2753 u32 r_ev;
2754 int rc;
2597 2755
2598 if (parse_strtoul(buf, 0xffffffffUL, &t) || 2756 if (parse_strtoul(buf, 0xffffffffUL, &t) ||
2599 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0)) 2757 ((t & ~TPACPI_HKEY_NVRAM_KNOWN_MASK) != 0))
@@ -2606,14 +2764,28 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
2606 hotkey_source_mask = t; 2764 hotkey_source_mask = t;
2607 HOTKEY_CONFIG_CRITICAL_END 2765 HOTKEY_CONFIG_CRITICAL_END
2608 2766
2767 rc = hotkey_mask_set((hotkey_user_mask | hotkey_driver_mask) &
2768 ~hotkey_source_mask);
2609 hotkey_poll_setup(true); 2769 hotkey_poll_setup(true);
2610 hotkey_mask_set(hotkey_mask); 2770
2771 /* check if events needed by the driver got disabled */
2772 r_ev = hotkey_driver_mask & ~(hotkey_acpi_mask & hotkey_all_mask)
2773 & ~hotkey_source_mask & TPACPI_HKEY_NVRAM_KNOWN_MASK;
2611 2774
2612 mutex_unlock(&hotkey_mutex); 2775 mutex_unlock(&hotkey_mutex);
2613 2776
2777 if (rc < 0)
2778 printk(TPACPI_ERR "hotkey_source_mask: failed to update the"
2779 "firmware event mask!\n");
2780
2781 if (r_ev)
2782 printk(TPACPI_NOTICE "hotkey_source_mask: "
2783 "some important events were disabled: "
2784 "0x%04x\n", r_ev);
2785
2614 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t); 2786 tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
2615 2787
2616 return count; 2788 return (rc < 0) ? rc : count;
2617} 2789}
2618 2790
2619static struct device_attribute dev_attr_hotkey_source_mask = 2791static struct device_attribute dev_attr_hotkey_source_mask =
@@ -2731,9 +2903,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_reason =
2731 2903
2732static void hotkey_wakeup_reason_notify_change(void) 2904static void hotkey_wakeup_reason_notify_change(void)
2733{ 2905{
2734 if (tp_features.hotkey_mask) 2906 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2735 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2907 "wakeup_reason");
2736 "wakeup_reason");
2737} 2908}
2738 2909
2739/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */ 2910/* sysfs wakeup hotunplug_complete (pollable) -------------------------- */
@@ -2750,9 +2921,8 @@ static struct device_attribute dev_attr_hotkey_wakeup_hotunplug_complete =
2750 2921
2751static void hotkey_wakeup_hotunplug_complete_notify_change(void) 2922static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2752{ 2923{
2753 if (tp_features.hotkey_mask) 2924 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL,
2754 sysfs_notify(&tpacpi_pdev->dev.kobj, NULL, 2925 "wakeup_hotunplug_complete");
2755 "wakeup_hotunplug_complete");
2756} 2926}
2757 2927
2758/* --------------------------------------------------------------------- */ 2928/* --------------------------------------------------------------------- */
@@ -2760,27 +2930,19 @@ static void hotkey_wakeup_hotunplug_complete_notify_change(void)
2760static struct attribute *hotkey_attributes[] __initdata = { 2930static struct attribute *hotkey_attributes[] __initdata = {
2761 &dev_attr_hotkey_enable.attr, 2931 &dev_attr_hotkey_enable.attr,
2762 &dev_attr_hotkey_bios_enabled.attr, 2932 &dev_attr_hotkey_bios_enabled.attr,
2933 &dev_attr_hotkey_bios_mask.attr,
2763 &dev_attr_hotkey_report_mode.attr, 2934 &dev_attr_hotkey_report_mode.attr,
2764#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 2935 &dev_attr_hotkey_wakeup_reason.attr,
2936 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2765 &dev_attr_hotkey_mask.attr, 2937 &dev_attr_hotkey_mask.attr,
2766 &dev_attr_hotkey_all_mask.attr, 2938 &dev_attr_hotkey_all_mask.attr,
2767 &dev_attr_hotkey_recommended_mask.attr, 2939 &dev_attr_hotkey_recommended_mask.attr,
2940#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2768 &dev_attr_hotkey_source_mask.attr, 2941 &dev_attr_hotkey_source_mask.attr,
2769 &dev_attr_hotkey_poll_freq.attr, 2942 &dev_attr_hotkey_poll_freq.attr,
2770#endif 2943#endif
2771}; 2944};
2772 2945
2773static struct attribute *hotkey_mask_attributes[] __initdata = {
2774 &dev_attr_hotkey_bios_mask.attr,
2775#ifndef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
2776 &dev_attr_hotkey_mask.attr,
2777 &dev_attr_hotkey_all_mask.attr,
2778 &dev_attr_hotkey_recommended_mask.attr,
2779#endif
2780 &dev_attr_hotkey_wakeup_reason.attr,
2781 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2782};
2783
2784/* 2946/*
2785 * Sync both the hw and sw blocking state of all switches 2947 * Sync both the hw and sw blocking state of all switches
2786 */ 2948 */
@@ -2843,16 +3005,16 @@ static void hotkey_exit(void)
2843 3005
2844 kfree(hotkey_keycode_map); 3006 kfree(hotkey_keycode_map);
2845 3007
2846 if (tp_features.hotkey) { 3008 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
2847 dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY, 3009 "restoring original HKEY status and mask\n");
2848 "restoring original hot key mask\n"); 3010 /* yes, there is a bitwise or below, we want the
2849 /* no short-circuit boolean operator below! */ 3011 * functions to be called even if one of them fail */
2850 if ((hotkey_mask_set(hotkey_orig_mask) | 3012 if (((tp_features.hotkey_mask &&
2851 hotkey_status_set(false)) != 0) 3013 hotkey_mask_set(hotkey_orig_mask)) |
2852 printk(TPACPI_ERR 3014 hotkey_status_set(false)) != 0)
2853 "failed to restore hot key mask " 3015 printk(TPACPI_ERR
2854 "to BIOS defaults\n"); 3016 "failed to restore hot key mask "
2855 } 3017 "to BIOS defaults\n");
2856} 3018}
2857 3019
2858static void __init hotkey_unmap(const unsigned int scancode) 3020static void __init hotkey_unmap(const unsigned int scancode)
@@ -2864,6 +3026,35 @@ static void __init hotkey_unmap(const unsigned int scancode)
2864 } 3026 }
2865} 3027}
2866 3028
3029/*
3030 * HKEY quirks:
3031 * TPACPI_HK_Q_INIMASK: Supports FN+F3,FN+F4,FN+F12
3032 */
3033
3034#define TPACPI_HK_Q_INIMASK 0x0001
3035
3036static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
3037 TPACPI_Q_IBM('I', 'H', TPACPI_HK_Q_INIMASK), /* 600E */
3038 TPACPI_Q_IBM('I', 'N', TPACPI_HK_Q_INIMASK), /* 600E */
3039 TPACPI_Q_IBM('I', 'D', TPACPI_HK_Q_INIMASK), /* 770, 770E, 770ED */
3040 TPACPI_Q_IBM('I', 'W', TPACPI_HK_Q_INIMASK), /* A20m */
3041 TPACPI_Q_IBM('I', 'V', TPACPI_HK_Q_INIMASK), /* A20p */
3042 TPACPI_Q_IBM('1', '0', TPACPI_HK_Q_INIMASK), /* A21e, A22e */
3043 TPACPI_Q_IBM('K', 'U', TPACPI_HK_Q_INIMASK), /* A21e */
3044 TPACPI_Q_IBM('K', 'X', TPACPI_HK_Q_INIMASK), /* A21m, A22m */
3045 TPACPI_Q_IBM('K', 'Y', TPACPI_HK_Q_INIMASK), /* A21p, A22p */
3046 TPACPI_Q_IBM('1', 'B', TPACPI_HK_Q_INIMASK), /* A22e */
3047 TPACPI_Q_IBM('1', '3', TPACPI_HK_Q_INIMASK), /* A22m */
3048 TPACPI_Q_IBM('1', 'E', TPACPI_HK_Q_INIMASK), /* A30/p (0) */
3049 TPACPI_Q_IBM('1', 'C', TPACPI_HK_Q_INIMASK), /* R30 */
3050 TPACPI_Q_IBM('1', 'F', TPACPI_HK_Q_INIMASK), /* R31 */
3051 TPACPI_Q_IBM('I', 'Y', TPACPI_HK_Q_INIMASK), /* T20 */
3052 TPACPI_Q_IBM('K', 'Z', TPACPI_HK_Q_INIMASK), /* T21 */
3053 TPACPI_Q_IBM('1', '6', TPACPI_HK_Q_INIMASK), /* T22 */
3054 TPACPI_Q_IBM('I', 'Z', TPACPI_HK_Q_INIMASK), /* X20, X21 */
3055 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
3056};
3057
2867static int __init hotkey_init(struct ibm_init_struct *iibm) 3058static int __init hotkey_init(struct ibm_init_struct *iibm)
2868{ 3059{
2869 /* Requirements for changing the default keymaps: 3060 /* Requirements for changing the default keymaps:
@@ -2906,9 +3097,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2906 KEY_UNKNOWN, /* 0x0D: FN+INSERT */ 3097 KEY_UNKNOWN, /* 0x0D: FN+INSERT */
2907 KEY_UNKNOWN, /* 0x0E: FN+DELETE */ 3098 KEY_UNKNOWN, /* 0x0E: FN+DELETE */
2908 3099
2909 /* brightness: firmware always reacts to them, unless 3100 /* brightness: firmware always reacts to them */
2910 * X.org did some tricks in the radeon BIOS scratch
2911 * registers of *some* models */
2912 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ 3101 KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
2913 KEY_RESERVED, /* 0x10: FN+END (brightness down) */ 3102 KEY_RESERVED, /* 0x10: FN+END (brightness down) */
2914 3103
@@ -2983,6 +3172,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
2983 int status; 3172 int status;
2984 int hkeyv; 3173 int hkeyv;
2985 3174
3175 unsigned long quirks;
3176
2986 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3177 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
2987 "initializing hotkey subdriver\n"); 3178 "initializing hotkey subdriver\n");
2988 3179
@@ -3008,9 +3199,16 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3008 if (!tp_features.hotkey) 3199 if (!tp_features.hotkey)
3009 return 1; 3200 return 1;
3010 3201
3202 quirks = tpacpi_check_quirks(tpacpi_hotkey_qtable,
3203 ARRAY_SIZE(tpacpi_hotkey_qtable));
3204
3011 tpacpi_disable_brightness_delay(); 3205 tpacpi_disable_brightness_delay();
3012 3206
3013 hotkey_dev_attributes = create_attr_set(13, NULL); 3207 /* MUST have enough space for all attributes to be added to
3208 * hotkey_dev_attributes */
3209 hotkey_dev_attributes = create_attr_set(
3210 ARRAY_SIZE(hotkey_attributes) + 2,
3211 NULL);
3014 if (!hotkey_dev_attributes) 3212 if (!hotkey_dev_attributes)
3015 return -ENOMEM; 3213 return -ENOMEM;
3016 res = add_many_to_attr_set(hotkey_dev_attributes, 3214 res = add_many_to_attr_set(hotkey_dev_attributes,
@@ -3019,7 +3217,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3019 if (res) 3217 if (res)
3020 goto err_exit; 3218 goto err_exit;
3021 3219
3022 /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, 3220 /* mask not supported on 600e/x, 770e, 770x, A21e, A2xm/p,
3023 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking 3221 A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
3024 for HKEY interface version 0x100 */ 3222 for HKEY interface version 0x100 */
3025 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { 3223 if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
@@ -3033,10 +3231,22 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3033 * MHKV 0x100 in A31, R40, R40e, 3231 * MHKV 0x100 in A31, R40, R40e,
3034 * T4x, X31, and later 3232 * T4x, X31, and later
3035 */ 3233 */
3036 tp_features.hotkey_mask = 1;
3037 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3234 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3038 "firmware HKEY interface version: 0x%x\n", 3235 "firmware HKEY interface version: 0x%x\n",
3039 hkeyv); 3236 hkeyv);
3237
3238 /* Paranoia check AND init hotkey_all_mask */
3239 if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
3240 "MHKA", "qd")) {
3241 printk(TPACPI_ERR
3242 "missing MHKA handler, "
3243 "please report this to %s\n",
3244 TPACPI_MAIL);
3245 /* Fallback: pre-init for FN+F3,F4,F12 */
3246 hotkey_all_mask = 0x080cU;
3247 } else {
3248 tp_features.hotkey_mask = 1;
3249 }
3040 } 3250 }
3041 } 3251 }
3042 3252
@@ -3044,32 +3254,23 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3044 "hotkey masks are %s\n", 3254 "hotkey masks are %s\n",
3045 str_supported(tp_features.hotkey_mask)); 3255 str_supported(tp_features.hotkey_mask));
3046 3256
3047 if (tp_features.hotkey_mask) { 3257 /* Init hotkey_all_mask if not initialized yet */
3048 if (!acpi_evalf(hkey_handle, &hotkey_all_mask, 3258 if (!tp_features.hotkey_mask && !hotkey_all_mask &&
3049 "MHKA", "qd")) { 3259 (quirks & TPACPI_HK_Q_INIMASK))
3050 printk(TPACPI_ERR 3260 hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
3051 "missing MHKA handler, "
3052 "please report this to %s\n",
3053 TPACPI_MAIL);
3054 /* FN+F12, FN+F4, FN+F3 */
3055 hotkey_all_mask = 0x080cU;
3056 }
3057 }
3058 3261
3059 /* hotkey_source_mask *must* be zero for 3262 /* Init hotkey_acpi_mask and hotkey_orig_mask */
3060 * the first hotkey_mask_get */
3061 if (tp_features.hotkey_mask) { 3263 if (tp_features.hotkey_mask) {
3264 /* hotkey_source_mask *must* be zero for
3265 * the first hotkey_mask_get to return hotkey_orig_mask */
3062 res = hotkey_mask_get(); 3266 res = hotkey_mask_get();
3063 if (res) 3267 if (res)
3064 goto err_exit; 3268 goto err_exit;
3065 3269
3066 hotkey_orig_mask = hotkey_mask; 3270 hotkey_orig_mask = hotkey_acpi_mask;
3067 res = add_many_to_attr_set( 3271 } else {
3068 hotkey_dev_attributes, 3272 hotkey_orig_mask = hotkey_all_mask;
3069 hotkey_mask_attributes, 3273 hotkey_acpi_mask = hotkey_all_mask;
3070 ARRAY_SIZE(hotkey_mask_attributes));
3071 if (res)
3072 goto err_exit;
3073 } 3274 }
3074 3275
3075#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3276#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
@@ -3183,14 +3384,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3183 } 3384 }
3184 3385
3185#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL 3386#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL
3186 if (tp_features.hotkey_mask) { 3387 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3187 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK 3388 & ~hotkey_all_mask
3188 & ~hotkey_all_mask 3389 & ~hotkey_reserved_mask;
3189 & ~hotkey_reserved_mask;
3190 } else {
3191 hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK
3192 & ~hotkey_reserved_mask;
3193 }
3194 3390
3195 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3391 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3196 "hotkey source mask 0x%08x, polling freq %u\n", 3392 "hotkey source mask 0x%08x, polling freq %u\n",
@@ -3204,13 +3400,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3204 hotkey_exit(); 3400 hotkey_exit();
3205 return res; 3401 return res;
3206 } 3402 }
3207 res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) 3403 res = hotkey_mask_set(((hotkey_all_mask & ~hotkey_reserved_mask)
3208 & ~hotkey_reserved_mask) 3404 | hotkey_driver_mask)
3209 | hotkey_orig_mask); 3405 & ~hotkey_source_mask);
3210 if (res < 0 && res != -ENXIO) { 3406 if (res < 0 && res != -ENXIO) {
3211 hotkey_exit(); 3407 hotkey_exit();
3212 return res; 3408 return res;
3213 } 3409 }
3410 hotkey_user_mask = (hotkey_acpi_mask | hotkey_source_mask)
3411 & ~hotkey_reserved_mask;
3412 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3413 "initial masks: user=0x%08x, fw=0x%08x, poll=0x%08x\n",
3414 hotkey_user_mask, hotkey_acpi_mask, hotkey_source_mask);
3214 3415
3215 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3416 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3216 "legacy ibm/hotkey event reporting over procfs %s\n", 3417 "legacy ibm/hotkey event reporting over procfs %s\n",
@@ -3245,7 +3446,7 @@ static bool hotkey_notify_hotkey(const u32 hkey,
3245 if (scancode > 0 && scancode < 0x21) { 3446 if (scancode > 0 && scancode < 0x21) {
3246 scancode--; 3447 scancode--;
3247 if (!(hotkey_source_mask & (1 << scancode))) { 3448 if (!(hotkey_source_mask & (1 << scancode))) {
3248 tpacpi_input_send_key(scancode); 3449 tpacpi_input_send_key_masked(scancode);
3249 *send_acpi_ev = false; 3450 *send_acpi_ev = false;
3250 } else { 3451 } else {
3251 *ignore_acpi_ev = true; 3452 *ignore_acpi_ev = true;
@@ -3264,20 +3465,20 @@ static bool hotkey_notify_wakeup(const u32 hkey,
3264 *ignore_acpi_ev = false; 3465 *ignore_acpi_ev = false;
3265 3466
3266 switch (hkey) { 3467 switch (hkey) {
3267 case 0x2304: /* suspend, undock */ 3468 case TP_HKEY_EV_WKUP_S3_UNDOCK: /* suspend, undock */
3268 case 0x2404: /* hibernation, undock */ 3469 case TP_HKEY_EV_WKUP_S4_UNDOCK: /* hibernation, undock */
3269 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK; 3470 hotkey_wakeup_reason = TP_ACPI_WAKEUP_UNDOCK;
3270 *ignore_acpi_ev = true; 3471 *ignore_acpi_ev = true;
3271 break; 3472 break;
3272 3473
3273 case 0x2305: /* suspend, bay eject */ 3474 case TP_HKEY_EV_WKUP_S3_BAYEJ: /* suspend, bay eject */
3274 case 0x2405: /* hibernation, bay eject */ 3475 case TP_HKEY_EV_WKUP_S4_BAYEJ: /* hibernation, bay eject */
3275 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ; 3476 hotkey_wakeup_reason = TP_ACPI_WAKEUP_BAYEJ;
3276 *ignore_acpi_ev = true; 3477 *ignore_acpi_ev = true;
3277 break; 3478 break;
3278 3479
3279 case 0x2313: /* Battery on critical low level (S3) */ 3480 case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */
3280 case 0x2413: /* Battery on critical low level (S4) */ 3481 case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */
3281 printk(TPACPI_ALERT 3482 printk(TPACPI_ALERT
3282 "EMERGENCY WAKEUP: battery almost empty\n"); 3483 "EMERGENCY WAKEUP: battery almost empty\n");
3283 /* how to auto-heal: */ 3484 /* how to auto-heal: */
@@ -3307,21 +3508,21 @@ static bool hotkey_notify_usrevent(const u32 hkey,
3307 *ignore_acpi_ev = false; 3508 *ignore_acpi_ev = false;
3308 3509
3309 switch (hkey) { 3510 switch (hkey) {
3310 case 0x5010: /* Lenovo new BIOS: brightness changed */ 3511 case TP_HKEY_EV_PEN_INSERTED: /* X61t: tablet pen inserted into bay */
3311 case 0x500b: /* X61t: tablet pen inserted into bay */ 3512 case TP_HKEY_EV_PEN_REMOVED: /* X61t: tablet pen removed from bay */
3312 case 0x500c: /* X61t: tablet pen removed from bay */
3313 return true; 3513 return true;
3314 3514
3315 case 0x5009: /* X41t-X61t: swivel up (tablet mode) */ 3515 case TP_HKEY_EV_TABLET_TABLET: /* X41t-X61t: tablet mode */
3316 case 0x500a: /* X41t-X61t: swivel down (normal mode) */ 3516 case TP_HKEY_EV_TABLET_NOTEBOOK: /* X41t-X61t: normal mode */
3317 tpacpi_input_send_tabletsw(); 3517 tpacpi_input_send_tabletsw();
3318 hotkey_tablet_mode_notify_change(); 3518 hotkey_tablet_mode_notify_change();
3319 *send_acpi_ev = false; 3519 *send_acpi_ev = false;
3320 return true; 3520 return true;
3321 3521
3322 case 0x5001: 3522 case TP_HKEY_EV_LID_CLOSE: /* Lid closed */
3323 case 0x5002: 3523 case TP_HKEY_EV_LID_OPEN: /* Lid opened */
3324 /* LID switch events. Do not propagate */ 3524 case TP_HKEY_EV_BRGHT_CHANGED: /* brightness changed */
3525 /* do not propagate these events */
3325 *ignore_acpi_ev = true; 3526 *ignore_acpi_ev = true;
3326 return true; 3527 return true;
3327 3528
@@ -3339,30 +3540,30 @@ static bool hotkey_notify_thermal(const u32 hkey,
3339 *ignore_acpi_ev = false; 3540 *ignore_acpi_ev = false;
3340 3541
3341 switch (hkey) { 3542 switch (hkey) {
3342 case 0x6011: 3543 case TP_HKEY_EV_ALARM_BAT_HOT:
3343 printk(TPACPI_CRIT 3544 printk(TPACPI_CRIT
3344 "THERMAL ALARM: battery is too hot!\n"); 3545 "THERMAL ALARM: battery is too hot!\n");
3345 /* recommended action: warn user through gui */ 3546 /* recommended action: warn user through gui */
3346 return true; 3547 return true;
3347 case 0x6012: 3548 case TP_HKEY_EV_ALARM_BAT_XHOT:
3348 printk(TPACPI_ALERT 3549 printk(TPACPI_ALERT
3349 "THERMAL EMERGENCY: battery is extremely hot!\n"); 3550 "THERMAL EMERGENCY: battery is extremely hot!\n");
3350 /* recommended action: immediate sleep/hibernate */ 3551 /* recommended action: immediate sleep/hibernate */
3351 return true; 3552 return true;
3352 case 0x6021: 3553 case TP_HKEY_EV_ALARM_SENSOR_HOT:
3353 printk(TPACPI_CRIT 3554 printk(TPACPI_CRIT
3354 "THERMAL ALARM: " 3555 "THERMAL ALARM: "
3355 "a sensor reports something is too hot!\n"); 3556 "a sensor reports something is too hot!\n");
3356 /* recommended action: warn user through gui, that */ 3557 /* recommended action: warn user through gui, that */
3357 /* some internal component is too hot */ 3558 /* some internal component is too hot */
3358 return true; 3559 return true;
3359 case 0x6022: 3560 case TP_HKEY_EV_ALARM_SENSOR_XHOT:
3360 printk(TPACPI_ALERT 3561 printk(TPACPI_ALERT
3361 "THERMAL EMERGENCY: " 3562 "THERMAL EMERGENCY: "
3362 "a sensor reports something is extremely hot!\n"); 3563 "a sensor reports something is extremely hot!\n");
3363 /* recommended action: immediate sleep/hibernate */ 3564 /* recommended action: immediate sleep/hibernate */
3364 return true; 3565 return true;
3365 case 0x6030: 3566 case TP_HKEY_EV_THM_TABLE_CHANGED:
3366 printk(TPACPI_INFO 3567 printk(TPACPI_INFO
3367 "EC reports that Thermal Table has changed\n"); 3568 "EC reports that Thermal Table has changed\n");
3368 /* recommended action: do nothing, we don't have 3569 /* recommended action: do nothing, we don't have
@@ -3420,7 +3621,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3420 break; 3621 break;
3421 case 3: 3622 case 3:
3422 /* 0x3000-0x3FFF: bay-related wakeups */ 3623 /* 0x3000-0x3FFF: bay-related wakeups */
3423 if (hkey == 0x3003) { 3624 if (hkey == TP_HKEY_EV_BAYEJ_ACK) {
3424 hotkey_autosleep_ack = 1; 3625 hotkey_autosleep_ack = 1;
3425 printk(TPACPI_INFO 3626 printk(TPACPI_INFO
3426 "bay ejected\n"); 3627 "bay ejected\n");
@@ -3432,7 +3633,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3432 break; 3633 break;
3433 case 4: 3634 case 4:
3434 /* 0x4000-0x4FFF: dock-related wakeups */ 3635 /* 0x4000-0x4FFF: dock-related wakeups */
3435 if (hkey == 0x4003) { 3636 if (hkey == TP_HKEY_EV_UNDOCK_ACK) {
3436 hotkey_autosleep_ack = 1; 3637 hotkey_autosleep_ack = 1;
3437 printk(TPACPI_INFO 3638 printk(TPACPI_INFO
3438 "undocked\n"); 3639 "undocked\n");
@@ -3454,7 +3655,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
3454 break; 3655 break;
3455 case 7: 3656 case 7:
3456 /* 0x7000-0x7FFF: misc */ 3657 /* 0x7000-0x7FFF: misc */
3457 if (tp_features.hotkey_wlsw && hkey == 0x7000) { 3658 if (tp_features.hotkey_wlsw &&
3659 hkey == TP_HKEY_EV_RFKILL_CHANGED) {
3458 tpacpi_send_radiosw_update(); 3660 tpacpi_send_radiosw_update();
3459 send_acpi_ev = 0; 3661 send_acpi_ev = 0;
3460 known_ev = true; 3662 known_ev = true;
@@ -3500,10 +3702,12 @@ static void hotkey_resume(void)
3500{ 3702{
3501 tpacpi_disable_brightness_delay(); 3703 tpacpi_disable_brightness_delay();
3502 3704
3503 if (hotkey_mask_get()) 3705 if (hotkey_status_set(true) < 0 ||
3706 hotkey_mask_set(hotkey_acpi_mask) < 0)
3504 printk(TPACPI_ERR 3707 printk(TPACPI_ERR
3505 "error while trying to read hot key mask " 3708 "error while attempting to reset the event "
3506 "from firmware\n"); 3709 "firmware interface\n");
3710
3507 tpacpi_send_radiosw_update(); 3711 tpacpi_send_radiosw_update();
3508 hotkey_tablet_mode_notify_change(); 3712 hotkey_tablet_mode_notify_change();
3509 hotkey_wakeup_reason_notify_change(); 3713 hotkey_wakeup_reason_notify_change();
@@ -3532,8 +3736,8 @@ static int hotkey_read(char *p)
3532 return res; 3736 return res;
3533 3737
3534 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0)); 3738 len += sprintf(p + len, "status:\t\t%s\n", enabled(status, 0));
3535 if (tp_features.hotkey_mask) { 3739 if (hotkey_all_mask) {
3536 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_mask); 3740 len += sprintf(p + len, "mask:\t\t0x%08x\n", hotkey_user_mask);
3537 len += sprintf(p + len, 3741 len += sprintf(p + len,
3538 "commands:\tenable, disable, reset, <mask>\n"); 3742 "commands:\tenable, disable, reset, <mask>\n");
3539 } else { 3743 } else {
@@ -3570,7 +3774,7 @@ static int hotkey_write(char *buf)
3570 if (mutex_lock_killable(&hotkey_mutex)) 3774 if (mutex_lock_killable(&hotkey_mutex))
3571 return -ERESTARTSYS; 3775 return -ERESTARTSYS;
3572 3776
3573 mask = hotkey_mask; 3777 mask = hotkey_user_mask;
3574 3778
3575 res = 0; 3779 res = 0;
3576 while ((cmd = next_cmd(&buf))) { 3780 while ((cmd = next_cmd(&buf))) {
@@ -3592,12 +3796,11 @@ static int hotkey_write(char *buf)
3592 } 3796 }
3593 } 3797 }
3594 3798
3595 if (!res) 3799 if (!res) {
3596 tpacpi_disclose_usertask("procfs hotkey", 3800 tpacpi_disclose_usertask("procfs hotkey",
3597 "set mask to 0x%08x\n", mask); 3801 "set mask to 0x%08x\n", mask);
3598 3802 res = hotkey_user_mask_set(mask);
3599 if (!res && mask != hotkey_mask) 3803 }
3600 res = hotkey_mask_set(mask);
3601 3804
3602errexit: 3805errexit:
3603 mutex_unlock(&hotkey_mutex); 3806 mutex_unlock(&hotkey_mutex);
@@ -6010,8 +6213,10 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
6010 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL, 6213 TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
6011 &ibm_backlight_data); 6214 &ibm_backlight_data);
6012 if (IS_ERR(ibm_backlight_device)) { 6215 if (IS_ERR(ibm_backlight_device)) {
6216 int rc = PTR_ERR(ibm_backlight_device);
6217 ibm_backlight_device = NULL;
6013 printk(TPACPI_ERR "Could not register backlight device\n"); 6218 printk(TPACPI_ERR "Could not register backlight device\n");
6014 return PTR_ERR(ibm_backlight_device); 6219 return rc;
6015 } 6220 }
6016 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, 6221 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
6017 "brightness is supported\n"); 6222 "brightness is supported\n");
@@ -7499,6 +7704,21 @@ static struct ibm_struct fan_driver_data = {
7499 **************************************************************************** 7704 ****************************************************************************
7500 ****************************************************************************/ 7705 ****************************************************************************/
7501 7706
7707/*
7708 * HKEY event callout for other subdrivers go here
7709 * (yes, it is ugly, but it is quick, safe, and gets the job done
7710 */
7711static void tpacpi_driver_event(const unsigned int hkey_event)
7712{
7713}
7714
7715
7716
7717static void hotkey_driver_event(const unsigned int scancode)
7718{
7719 tpacpi_driver_event(TP_HKEY_EV_HOTKEY_BASE + scancode);
7720}
7721
7502/* sysfs name ---------------------------------------------------------- */ 7722/* sysfs name ---------------------------------------------------------- */
7503static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, 7723static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
7504 struct device_attribute *attr, 7724 struct device_attribute *attr,