Commit edf0e0e5 authored by Henrique de Moraes Holschuh's avatar Henrique de Moraes Holschuh Committed by Len Brown

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: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 24d3b774
......@@ -270,7 +270,8 @@ remapping KEY_UNKNOWN keys.
The events are available in an input device, with the following id:
Bus: BUS_HOST
vendor: 0x1014 (PCI_VENDOR_ID_IBM)
vendor: 0x1014 (PCI_VENDOR_ID_IBM) or
0x17aa (PCI_VENDOR_ID_LENOVO)
product: 0x5054 ("TP")
version: 0x4101
......@@ -290,12 +291,15 @@ ACPI Scan
event code Key Notes
0x1001 0x00 FN+F1 -
0x1002 0x01 FN+F2 -
0x1002 0x01 FN+F2 IBM: battery (rare)
Lenovo: Screen lock
0x1003 0x02 FN+F3 Many models always report this
hot key, even with hot keys
0x1003 0x02 FN+F3 Many IBM models always report
this hot key, even with hot keys
disabled or with Fn+F3 masked
off
IBM: screen lock
Lenovo: battery
0x1004 0x03 FN+F4 Sleep button (ACPI sleep button
semanthics, i.e. sleep-to-RAM).
......@@ -313,13 +317,19 @@ event code Key Notes
and W-WAN card if left in control
of the firmware. Does not affect
the WLAN card.
Should be used to turn on/off all
radios (bluetooth+W-WAN+WLAN),
really.
0x1006 0x05 FN+F6 -
0x1007 0x06 FN+F7 Video output cycle.
Do you feel lucky today?
0x1008 0x07 FN+F8 -
0x1008 0x07 FN+F8 IBM: toggle screen expand
Lenovo: configure ultranav
0x1009 0x08 FN+F9 -
.. .. ..
0x100B 0x0A FN+F11 -
......@@ -338,13 +348,15 @@ event code Key Notes
0x100F 0x0E FN+DELETE -
0x1010 0x0F FN+HOME Brightness up. This key is
always handled by the firmware,
even when unmasked. Just leave
it alone.
0x1011 0x10 FN+END Brightness down. This key is
always handled by the firmware,
even when unmasked. Just leave
it alone.
always handled by the firmware
in IBM ThinkPads, even when
unmasked. Just leave it alone.
For Lenovo ThinkPads with a new
BIOS, it has to be handled either
by the ACPI OSI, or by userspace.
0x1011 0x10 FN+END Brightness down. See brightness
up for details.
0x1012 0x11 FN+PGUP Thinklight toggle. This key is
always handled by the firmware,
even when unmasked.
......@@ -356,9 +368,13 @@ event code Key Notes
0x1015 0x14 VOLUME UP Internal mixer volume up. This
key is always handled by the
firmware, even when unmasked.
NOTE: Lenovo seems to be changing
this.
0x1016 0x15 VOLUME DOWN Internal mixer volume up. This
key is always handled by the
firmware, even when unmasked.
NOTE: Lenovo seems to be changing
this.
0x1017 0x16 MUTE Mute internal mixer. This
key is always handled by the
firmware, even when unmasked.
......
......@@ -758,29 +758,7 @@ static u32 hotkey_orig_mask;
static u32 hotkey_all_mask;
static u32 hotkey_reserved_mask;
static u16 hotkey_keycode_map[] = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
KEY_FN_F1, KEY_FN_F2, KEY_FN_F3, KEY_SLEEP,
KEY_FN_F5, KEY_FN_F6, KEY_FN_F7, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
/* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
KEY_RESERVED, /* 0x10: FN+END (brightness down) */
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
KEY_RESERVED, /* 0x14: VOLUME UP */
KEY_RESERVED, /* 0x15: VOLUME DOWN */
KEY_RESERVED, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
};
static u16 *hotkey_keycode_map;
static struct attribute_set *hotkey_dev_attributes;
......@@ -939,6 +917,58 @@ static struct attribute *hotkey_mask_attributes[] = {
static int __init hotkey_init(struct ibm_init_struct *iibm)
{
static u16 ibm_keycode_map[] __initdata = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP,
KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
/* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
KEY_RESERVED, /* 0x0F: FN+HOME (brightness up) */
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
KEY_RESERVED, /* 0x10: FN+END (brightness down) */
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
KEY_RESERVED, /* 0x14: VOLUME UP */
KEY_RESERVED, /* 0x15: VOLUME DOWN */
KEY_RESERVED, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
};
static u16 lenovo_keycode_map[] __initdata = {
/* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
/* Scan codes 0x0C to 0x0F: Other ACPI HKEY hot keys */
KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */
KEY_UNKNOWN, /* 0x0D: FN+INSERT */
KEY_UNKNOWN, /* 0x0E: FN+DELETE */
KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */
/* Scan codes 0x10 to 0x1F: Extended ACPI HKEY hot keys */
KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */
KEY_RESERVED, /* 0x11: FN+PGUP (thinklight toggle) */
KEY_UNKNOWN, /* 0x12: FN+PGDOWN */
KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */
KEY_RESERVED, /* 0x14: VOLUME UP */
KEY_RESERVED, /* 0x15: VOLUME DOWN */
KEY_RESERVED, /* 0x16: MUTE */
KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */
/* (assignments unknown, please report if found) */
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
};
#define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map)
#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map)
#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0])
int res, i;
int status;
......@@ -1003,6 +1033,27 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
if (res)
return res;
/* Set up key map */
hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
GFP_KERNEL);
if (!hotkey_keycode_map) {
printk(IBM_ERR "failed to allocate memory for key map\n");
return -ENOMEM;
}
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
dbg_printk(TPACPI_DBG_INIT,
"using Lenovo default hot key map\n");
memcpy(hotkey_keycode_map, &lenovo_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
} else {
dbg_printk(TPACPI_DBG_INIT,
"using IBM default hot key map\n");
memcpy(hotkey_keycode_map, &ibm_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
}
#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
for (i = 0; i < 12; i++)
hotkey_keycode_map[i] = KEY_UNKNOWN;
......@@ -1011,10 +1062,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
set_bit(EV_KEY, tpacpi_inputdev->evbit);
set_bit(EV_MSC, tpacpi_inputdev->evbit);
set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
tpacpi_inputdev->keycodesize = sizeof(hotkey_keycode_map[0]);
tpacpi_inputdev->keycodemax = ARRAY_SIZE(hotkey_keycode_map);
tpacpi_inputdev->keycode = &hotkey_keycode_map;
for (i = 0; i < ARRAY_SIZE(hotkey_keycode_map); i++) {
tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;
tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN;
tpacpi_inputdev->keycode = hotkey_keycode_map;
for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) {
if (hotkey_keycode_map[i] != KEY_RESERVED) {
set_bit(hotkey_keycode_map[i],
tpacpi_inputdev->keybit);
......@@ -4618,7 +4669,9 @@ static int __init thinkpad_acpi_module_init(void)
tpacpi_inputdev->name = "ThinkPad Extra Buttons";
tpacpi_inputdev->phys = IBM_DRVR_NAME "/input0";
tpacpi_inputdev->id.bustype = BUS_HOST;
tpacpi_inputdev->id.vendor = TPACPI_HKEY_INPUT_VENDOR;
tpacpi_inputdev->id.vendor = (thinkpad_id.vendor) ?
thinkpad_id.vendor :
PCI_VENDOR_ID_IBM;
tpacpi_inputdev->id.product = TPACPI_HKEY_INPUT_PRODUCT;
tpacpi_inputdev->id.version = TPACPI_HKEY_INPUT_VERSION;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment