diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2007-07-18 22:45:44 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-07-21 23:49:18 -0400 |
commit | edf0e0e56904f794c97ca6c4562d8256e3d8d8e3 (patch) | |
tree | aab531df2112114bc7a855c5b283207de2b37406 | |
parent | 24d3b77467b6aaf59e38dce4aa86d05541858195 (diff) |
ACPI: thinkpad-acpi: react to Lenovo ThinkPad differences in hot key
Lenovo ThinkPads have a slightly different key map layout from IBM
ThinkPads (fn+f2 and fn+f3 are swapped). Knowing which one we are dealing
with, we can properly set a few more hot keys up by default.
Also, export the correct vendor in the input device, as that information
might be useful to userspace.
Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | Documentation/thinkpad-acpi.txt | 40 | ||||
-rw-r--r-- | drivers/misc/thinkpad_acpi.c | 109 |
2 files changed, 109 insertions, 40 deletions
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt index c145bcce2339..5d827ded34d1 100644 --- a/Documentation/thinkpad-acpi.txt +++ b/Documentation/thinkpad-acpi.txt | |||
@@ -270,7 +270,8 @@ remapping KEY_UNKNOWN keys. | |||
270 | The events are available in an input device, with the following id: | 270 | The events are available in an input device, with the following id: |
271 | 271 | ||
272 | Bus: BUS_HOST | 272 | Bus: BUS_HOST |
273 | vendor: 0x1014 (PCI_VENDOR_ID_IBM) | 273 | vendor: 0x1014 (PCI_VENDOR_ID_IBM) or |
274 | 0x17aa (PCI_VENDOR_ID_LENOVO) | ||
274 | product: 0x5054 ("TP") | 275 | product: 0x5054 ("TP") |
275 | version: 0x4101 | 276 | version: 0x4101 |
276 | 277 | ||
@@ -290,12 +291,15 @@ ACPI Scan | |||
290 | event code Key Notes | 291 | event code Key Notes |
291 | 292 | ||
292 | 0x1001 0x00 FN+F1 - | 293 | 0x1001 0x00 FN+F1 - |
293 | 0x1002 0x01 FN+F2 - | 294 | 0x1002 0x01 FN+F2 IBM: battery (rare) |
295 | Lenovo: Screen lock | ||
294 | 296 | ||
295 | 0x1003 0x02 FN+F3 Many models always report this | 297 | 0x1003 0x02 FN+F3 Many IBM models always report |
296 | hot key, even with hot keys | 298 | this hot key, even with hot keys |
297 | disabled or with Fn+F3 masked | 299 | disabled or with Fn+F3 masked |
298 | off | 300 | off |
301 | IBM: screen lock | ||
302 | Lenovo: battery | ||
299 | 303 | ||
300 | 0x1004 0x03 FN+F4 Sleep button (ACPI sleep button | 304 | 0x1004 0x03 FN+F4 Sleep button (ACPI sleep button |
301 | semanthics, i.e. sleep-to-RAM). | 305 | semanthics, i.e. sleep-to-RAM). |
@@ -313,13 +317,19 @@ event code Key Notes | |||
313 | and W-WAN card if left in control | 317 | and W-WAN card if left in control |
314 | of the firmware. Does not affect | 318 | of the firmware. Does not affect |
315 | the WLAN card. | 319 | the WLAN card. |
320 | Should be used to turn on/off all | ||
321 | radios (bluetooth+W-WAN+WLAN), | ||
322 | really. | ||
316 | 323 | ||
317 | 0x1006 0x05 FN+F6 - | 324 | 0x1006 0x05 FN+F6 - |
318 | 325 | ||
319 | 0x1007 0x06 FN+F7 Video output cycle. | 326 | 0x1007 0x06 FN+F7 Video output cycle. |
320 | Do you feel lucky today? | 327 | Do you feel lucky today? |
321 | 328 | ||
322 | 0x1008 0x07 FN+F8 - | 329 | 0x1008 0x07 FN+F8 IBM: toggle screen expand |
330 | Lenovo: configure ultranav | ||
331 | |||
332 | 0x1009 0x08 FN+F9 - | ||
323 | .. .. .. | 333 | .. .. .. |
324 | 0x100B 0x0A FN+F11 - | 334 | 0x100B 0x0A FN+F11 - |
325 | 335 | ||
@@ -338,13 +348,15 @@ event code Key Notes | |||
338 | 0x100F 0x0E FN+DELETE - | 348 | 0x100F 0x0E FN+DELETE - |
339 | 349 | ||
340 | 0x1010 0x0F FN+HOME Brightness up. This key is | 350 | 0x1010 0x0F FN+HOME Brightness up. This key is |
341 | always handled by the firmware, | 351 | always handled by the firmware |
342 | even when unmasked. Just leave | 352 | in IBM ThinkPads, even when |
343 | it alone. | 353 | unmasked. Just leave it alone. |
344 | 0x1011 0x10 FN+END Brightness down. This key is | 354 | For Lenovo ThinkPads with a new |
345 | always handled by the firmware, | 355 | BIOS, it has to be handled either |
346 | even when unmasked. Just leave | 356 | by the ACPI OSI, or by userspace. |
347 | it alone. | 357 | 0x1011 0x10 FN+END Brightness down. See brightness |
358 | up for details. | ||
359 | |||
348 | 0x1012 0x11 FN+PGUP Thinklight toggle. This key is | 360 | 0x1012 0x11 FN+PGUP Thinklight toggle. This key is |
349 | always handled by the firmware, | 361 | always handled by the firmware, |
350 | even when unmasked. | 362 | even when unmasked. |
@@ -356,9 +368,13 @@ event code Key Notes | |||
356 | 0x1015 0x14 VOLUME UP Internal mixer volume up. This | 368 | 0x1015 0x14 VOLUME UP Internal mixer volume up. This |
357 | key is always handled by the | 369 | key is always handled by the |
358 | firmware, even when unmasked. | 370 | firmware, even when unmasked. |
371 | NOTE: Lenovo seems to be changing | ||
372 | this. | ||
359 | 0x1016 0x15 VOLUME DOWN Internal mixer volume up. This | 373 | 0x1016 0x15 VOLUME DOWN Internal mixer volume up. This |
360 | key is always handled by the | 374 | key is always handled by the |
361 | firmware, even when unmasked. | 375 | firmware, even when unmasked. |
376 | NOTE: Lenovo seems to be changing | ||
377 | this. | ||
362 | 0x1017 0x16 MUTE Mute internal mixer. This | 378 | 0x1017 0x16 MUTE Mute internal mixer. This |
363 | key is always handled by the | 379 | key is always handled by the |
364 | firmware, even when unmasked. | 380 | firmware, even when unmasked. |
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index 5318eb272c61..623d36fd8dbe 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c | |||
@@ -758,29 +758,7 @@ static u32 hotkey_orig_mask; | |||
758 | static u32 hotkey_all_mask; | 758 | static u32 hotkey_all_mask; |
759 | static u32 hotkey_reserved_mask; | 759 | static u32 hotkey_reserved_mask; |
760 | 760 | ||
761 | static u16 hotkey_keycode_map[] = { | 761 | static u16 *hotkey_keycode_map; |
762 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | ||
763 | KEY_FN_F1, KEY_FN_F2, KEY_FN_F3, KEY_SLEEP, | ||
764 | KEY_FN_F5, KEY_FN_F6, KEY_FN_F7, KEY_FN_F8, | ||
765 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | ||
766 | /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ | ||
767 | KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ | ||
768 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | ||
769 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | ||
770 | KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ | ||
771 | /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ | ||
772 | KEY_RESERVED, /* 0x10: FN+END (brightness down) */ | ||
773 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ | ||
774 | KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ | ||
775 | KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ | ||
776 | KEY_RESERVED, /* 0x14: VOLUME UP */ | ||
777 | KEY_RESERVED, /* 0x15: VOLUME DOWN */ | ||
778 | KEY_RESERVED, /* 0x16: MUTE */ | ||
779 | KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ | ||
780 | /* (assignments unknown, please report if found) */ | ||
781 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
782 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
783 | }; | ||
784 | 762 | ||
785 | static struct attribute_set *hotkey_dev_attributes; | 763 | static struct attribute_set *hotkey_dev_attributes; |
786 | 764 | ||
@@ -939,6 +917,58 @@ static struct attribute *hotkey_mask_attributes[] = { | |||
939 | 917 | ||
940 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 918 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
941 | { | 919 | { |
920 | |||
921 | static u16 ibm_keycode_map[] __initdata = { | ||
922 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | ||
923 | KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, | ||
924 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | ||
925 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | ||
926 | /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ | ||
927 | KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ | ||
928 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | ||
929 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | ||
930 | KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */ | ||
931 | /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ | ||
932 | KEY_RESERVED, /* 0x10: FN+END (brightness down) */ | ||
933 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ | ||
934 | KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ | ||
935 | KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ | ||
936 | KEY_RESERVED, /* 0x14: VOLUME UP */ | ||
937 | KEY_RESERVED, /* 0x15: VOLUME DOWN */ | ||
938 | KEY_RESERVED, /* 0x16: MUTE */ | ||
939 | KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ | ||
940 | /* (assignments unknown, please report if found) */ | ||
941 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
942 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
943 | }; | ||
944 | static u16 lenovo_keycode_map[] __initdata = { | ||
945 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | ||
946 | KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, | ||
947 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | ||
948 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | ||
949 | /* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */ | ||
950 | KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ | ||
951 | KEY_UNKNOWN, /* 0x0D: FN+INSERT */ | ||
952 | KEY_UNKNOWN, /* 0x0E: FN+DELETE */ | ||
953 | KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ | ||
954 | /* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */ | ||
955 | KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ | ||
956 | KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */ | ||
957 | KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ | ||
958 | KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ | ||
959 | KEY_RESERVED, /* 0x14: VOLUME UP */ | ||
960 | KEY_RESERVED, /* 0x15: VOLUME DOWN */ | ||
961 | KEY_RESERVED, /* 0x16: MUTE */ | ||
962 | KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ | ||
963 | /* (assignments unknown, please report if found) */ | ||
964 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
965 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | ||
966 | }; | ||
967 | |||
968 | #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) | ||
969 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) | ||
970 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) | ||
971 | |||
942 | int res, i; | 972 | int res, i; |
943 | int status; | 973 | int status; |
944 | 974 | ||
@@ -1003,6 +1033,27 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
1003 | if (res) | 1033 | if (res) |
1004 | return res; | 1034 | return res; |
1005 | 1035 | ||
1036 | /* Set up key map */ | ||
1037 | |||
1038 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | ||
1039 | GFP_KERNEL); | ||
1040 | if (!hotkey_keycode_map) { | ||
1041 | printk(IBM_ERR "failed to allocate memory for key map\n"); | ||
1042 | return -ENOMEM; | ||
1043 | } | ||
1044 | |||
1045 | if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { | ||
1046 | dbg_printk(TPACPI_DBG_INIT, | ||
1047 | "using Lenovo default hot key map\n"); | ||
1048 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | ||
1049 | TPACPI_HOTKEY_MAP_SIZE); | ||
1050 | } else { | ||
1051 | dbg_printk(TPACPI_DBG_INIT, | ||
1052 | "using IBM default hot key map\n"); | ||
1053 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
1054 | TPACPI_HOTKEY_MAP_SIZE); | ||
1055 | } | ||
1056 | |||
1006 | #ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED | 1057 | #ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED |
1007 | for (i = 0; i < 12; i++) | 1058 | for (i = 0; i < 12; i++) |
1008 | hotkey_keycode_map[i] = KEY_UNKNOWN; | 1059 | hotkey_keycode_map[i] = KEY_UNKNOWN; |
@@ -1011,10 +1062,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
1011 | set_bit(EV_KEY, tpacpi_inputdev->evbit); | 1062 | set_bit(EV_KEY, tpacpi_inputdev->evbit); |
1012 | set_bit(EV_MSC, tpacpi_inputdev->evbit); | 1063 | set_bit(EV_MSC, tpacpi_inputdev->evbit); |
1013 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); | 1064 | set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); |
1014 | tpacpi_inputdev->keycodesize = sizeof(hotkey_keycode_map[0]); | 1065 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; |
1015 | tpacpi_inputdev->keycodemax = ARRAY_SIZE(hotkey_keycode_map); | 1066 | tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; |
1016 | tpacpi_inputdev->keycode = &hotkey_keycode_map; | 1067 | tpacpi_inputdev->keycode = hotkey_keycode_map; |
1017 | for (i = 0; i < ARRAY_SIZE(hotkey_keycode_map); i++) { | 1068 | for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { |
1018 | if (hotkey_keycode_map[i] != KEY_RESERVED) { | 1069 | if (hotkey_keycode_map[i] != KEY_RESERVED) { |
1019 | set_bit(hotkey_keycode_map[i], | 1070 | set_bit(hotkey_keycode_map[i], |
1020 | tpacpi_inputdev->keybit); | 1071 | tpacpi_inputdev->keybit); |
@@ -4618,7 +4669,9 @@ static int __init thinkpad_acpi_module_init(void) | |||
4618 | tpacpi_inputdev->name = "ThinkPad Extra Buttons"; | 4669 | tpacpi_inputdev->name = "ThinkPad Extra Buttons"; |
4619 | tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0"; | 4670 | tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0"; |
4620 | tpacpi_inputdev->id.bustype = BUS_HOST; | 4671 | tpacpi_inputdev->id.bustype = BUS_HOST; |
4621 | tpacpi_inputdev->id.vendor = TPACPI_HKEY_INPUT_VENDOR; | 4672 | tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ? |
4673 | thinkpad_id.vendor : | ||
4674 | PCI_VENDOR_ID_IBM; | ||
4622 | tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; | 4675 | tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT; |
4623 | tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; | 4676 | tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION; |
4624 | } | 4677 | } |