aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2010-08-09 22:48:21 -0400
committerMatthew Garrett <mjg@redhat.com>2010-08-16 11:54:55 -0400
commitd1e14dca6a18aa40394316c872993ae3bc7e311a (patch)
tree242299c9e69785b3b2b388da7988934f478bda67
parent34a656d22f5539f613b93e7a1d14b4bd53592505 (diff)
thinkpad-acpi: add support for model-specific keymaps
Use the quirks engine to select model-specific keymaps, which makes it much easier to extend should we need it. Keycodes are based on the tables at http://www.thinkwiki.org/wiki/Default_meanings_of_special_keys. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Matthew Garrett <mjg@redhat.com>
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index b0b66fbd796c..9ebe4f7d044e 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3093,6 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = {
3093 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ 3093 TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */
3094}; 3094};
3095 3095
3096typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN];
3097
3096static int __init hotkey_init(struct ibm_init_struct *iibm) 3098static int __init hotkey_init(struct ibm_init_struct *iibm)
3097{ 3099{
3098 /* Requirements for changing the default keymaps: 3100 /* Requirements for changing the default keymaps:
@@ -3124,9 +3126,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3124 * If the above is too much to ask, don't change the keymap. 3126 * If the above is too much to ask, don't change the keymap.
3125 * Ask the thinkpad-acpi maintainer to do it, instead. 3127 * Ask the thinkpad-acpi maintainer to do it, instead.
3126 */ 3128 */
3127 static u16 ibm_keycode_map[TPACPI_HOTKEY_MAP_LEN] __initdata = { 3129
3130 enum keymap_index {
3131 TPACPI_KEYMAP_IBM_GENERIC = 0,
3132 TPACPI_KEYMAP_LENOVO_GENERIC,
3133 };
3134
3135 static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = {
3136 /* Generic keymap for IBM ThinkPads */
3137 [TPACPI_KEYMAP_IBM_GENERIC] = {
3128 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 3138 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
3129 KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, 3139 KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP,
3130 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 3140 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
3131 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, 3141 KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND,
3132 3142
@@ -3157,8 +3167,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3157 /* (assignments unknown, please report if found) */ 3167 /* (assignments unknown, please report if found) */
3158 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3168 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3159 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3169 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3160 }; 3170 },
3161 static u16 lenovo_keycode_map[TPACPI_HOTKEY_MAP_LEN] __initdata = { 3171
3172 /* Generic keymap for Lenovo ThinkPads */
3173 [TPACPI_KEYMAP_LENOVO_GENERIC] = {
3162 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ 3174 /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */
3163 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, 3175 KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP,
3164 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, 3176 KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8,
@@ -3200,10 +3212,25 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3200 /* (assignments unknown, please report if found) */ 3212 /* (assignments unknown, please report if found) */
3201 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3213 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3202 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, 3214 KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN,
3215 },
3203 }; 3216 };
3204 3217
3205#define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) 3218 static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = {
3206#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) 3219 /* Generic maps (fallback) */
3220 {
3221 .vendor = PCI_VENDOR_ID_IBM,
3222 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
3223 .quirks = TPACPI_KEYMAP_IBM_GENERIC,
3224 },
3225 {
3226 .vendor = PCI_VENDOR_ID_LENOVO,
3227 .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY,
3228 .quirks = TPACPI_KEYMAP_LENOVO_GENERIC,
3229 },
3230 };
3231
3232#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t)
3233#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0])
3207 3234
3208 int res, i; 3235 int res, i;
3209 int status; 3236 int status;
@@ -3212,6 +3239,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3212 bool tabletsw_state = false; 3239 bool tabletsw_state = false;
3213 3240
3214 unsigned long quirks; 3241 unsigned long quirks;
3242 unsigned long keymap_id;
3215 3243
3216 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3244 vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3217 "initializing hotkey subdriver\n"); 3245 "initializing hotkey subdriver\n");
@@ -3352,7 +3380,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3352 goto err_exit; 3380 goto err_exit;
3353 3381
3354 /* Set up key map */ 3382 /* Set up key map */
3355
3356 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, 3383 hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
3357 GFP_KERNEL); 3384 GFP_KERNEL);
3358 if (!hotkey_keycode_map) { 3385 if (!hotkey_keycode_map) {
@@ -3362,17 +3389,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
3362 goto err_exit; 3389 goto err_exit;
3363 } 3390 }
3364 3391
3365 if (tpacpi_is_lenovo()) { 3392 keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable,
3366 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3393 ARRAY_SIZE(tpacpi_keymap_qtable));
3367 "using Lenovo default hot key map\n"); 3394 BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps));
3368 memcpy(hotkey_keycode_map, &lenovo_keycode_map, 3395 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
3369 TPACPI_HOTKEY_MAP_SIZE); 3396 "using keymap number %lu\n", keymap_id);
3370 } else { 3397
3371 dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, 3398 memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id],
3372 "using IBM default hot key map\n"); 3399 TPACPI_HOTKEY_MAP_SIZE);
3373 memcpy(hotkey_keycode_map, &ibm_keycode_map,
3374 TPACPI_HOTKEY_MAP_SIZE);
3375 }
3376 3400
3377 input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); 3401 input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN);
3378 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; 3402 tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE;