diff options
author | Henrique de Moraes Holschuh <hmh@hmh.eng.br> | 2010-08-09 22:48:21 -0400 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2010-08-16 11:54:55 -0400 |
commit | d1e14dca6a18aa40394316c872993ae3bc7e311a (patch) | |
tree | 242299c9e69785b3b2b388da7988934f478bda67 | |
parent | 34a656d22f5539f613b93e7a1d14b4bd53592505 (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.c | 60 |
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 | ||
3096 | typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | ||
3097 | |||
3096 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 3098 | static 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; |