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; |
