On 4/24/24 2:28 PM, Hans de Goede wrote: > Switch the hotkey keymap handling over to the sparse-keymap helpers, > there should be no functional changes from this. > > Note all the mappings to KEY_UNKNOWN are removed since that is the default > behavior of sparse_keymap_report_event() for unknown scancodes. > > Also drop the big comment about making changes to the keymaps since > the contents of that comment are mostly obsolete. > > Tested-by: Mark Pearson <mpearson-lenovo@xxxxxxxxx> > Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> Hi, I believe this is what gave me the following error compiling current Linus's master: ERROR: modpost: "sparse_keymap_report_event" [drivers/platform/x86/thinkpad_acpi.ko] undefined! ERROR: modpost: "sparse_keymap_setup" [drivers/platform/x86/thinkpad_acpi.ko] undefined! probably config THINKPAD_ACPI now has to depend/select INPUT_SPARSEKMAP? It's fixed when I configure it =m manually. Thanks, Vlastimil > --- > Changes in v2: > - Use proper multi-line comment style > --- > drivers/platform/x86/thinkpad_acpi.c | 404 ++++++++++----------------- > 1 file changed, 145 insertions(+), 259 deletions(-) > > diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c > index 6a136d124cab..8af9406f2a13 100644 > --- a/drivers/platform/x86/thinkpad_acpi.c > +++ b/drivers/platform/x86/thinkpad_acpi.c > @@ -45,6 +45,7 @@ > #include <linux/hwmon-sysfs.h> > #include <linux/init.h> > #include <linux/input.h> > +#include <linux/input/sparse-keymap.h> > #include <linux/jiffies.h> > #include <linux/kernel.h> > #include <linux/kthread.h> > @@ -1759,12 +1760,12 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ > TP_ACPI_HOTKEYSCAN_THINKPAD, > TP_ACPI_HOTKEYSCAN_UNK1, > TP_ACPI_HOTKEYSCAN_UNK2, > - TP_ACPI_HOTKEYSCAN_UNK3, > + TP_ACPI_HOTKEYSCAN_MICMUTE, > TP_ACPI_HOTKEYSCAN_UNK4, > - TP_ACPI_HOTKEYSCAN_UNK5, > - TP_ACPI_HOTKEYSCAN_UNK6, > - TP_ACPI_HOTKEYSCAN_UNK7, > - TP_ACPI_HOTKEYSCAN_UNK8, > + TP_ACPI_HOTKEYSCAN_CONFIG, > + TP_ACPI_HOTKEYSCAN_SEARCH, > + TP_ACPI_HOTKEYSCAN_SCALE, > + TP_ACPI_HOTKEYSCAN_FILE, > > /* Adaptive keyboard keycodes */ > TP_ACPI_HOTKEYSCAN_ADAPTIVE_START, /* 32 / 0x20 */ > @@ -1779,7 +1780,7 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ > TP_ACPI_HOTKEYSCAN_UNK11, > TP_ACPI_HOTKEYSCAN_UNK12, > TP_ACPI_HOTKEYSCAN_UNK13, > - TP_ACPI_HOTKEYSCAN_CONFIG, > + TP_ACPI_HOTKEYSCAN_CONFIG2, > TP_ACPI_HOTKEYSCAN_NEW_TAB, > TP_ACPI_HOTKEYSCAN_RELOAD, > TP_ACPI_HOTKEYSCAN_BACK, > @@ -1801,9 +1802,6 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ > TP_ACPI_HOTKEYSCAN_NOTIFICATION_CENTER, > TP_ACPI_HOTKEYSCAN_PICKUP_PHONE, > TP_ACPI_HOTKEYSCAN_HANGUP_PHONE, > - > - /* Hotkey keymap size */ > - TPACPI_HOTKEY_MAP_LEN > }; > > enum { /* Keys/events available through NVRAM polling */ > @@ -1916,8 +1914,6 @@ static u32 hotkey_driver_mask; /* events needed by the driver */ > static u32 hotkey_user_mask; /* events visible to userspace */ > static u32 hotkey_acpi_mask; /* events enabled in firmware */ > > -static u16 *hotkey_keycode_map; > - > static bool tpacpi_driver_event(const unsigned int hkey_event); > static void hotkey_poll_setup(const bool may_warn); > > @@ -2252,11 +2248,24 @@ static void tpacpi_input_send_tabletsw(void) > > static bool tpacpi_input_send_key(const u32 hkey, bool *send_acpi_ev) > { > - unsigned int keycode, scancode; > + bool known_ev; > + u32 scancode; > > if (tpacpi_driver_event(hkey)) > return true; > > + /* > + * Before the conversion to using the sparse-keymap helpers the driver used to > + * map the hkey event codes to 0x00 - 0x4d scancodes so that a straight scancode > + * indexed array could be used to map scancodes to keycodes: > + * > + * 0x1001 - 0x1020 -> 0x00 - 0x1f (Original ThinkPad events) > + * 0x1103 - 0x1116 -> 0x20 - 0x33 (Adaptive keyboard, 2014 X1 Carbon) > + * 0x1300 - 0x1319 -> 0x34 - 0x4d (Additional keys send in 2017+ models) > + * > + * The sparse-keymap tables still use these scancodes for these ranges to > + * preserve userspace API compatibility (e.g. hwdb keymappings). > + */ > if (hkey >= TP_HKEY_EV_ORIG_KEY_START && > hkey <= TP_HKEY_EV_ORIG_KEY_END) { > scancode = hkey - TP_HKEY_EV_ORIG_KEY_START; > @@ -2279,23 +2288,14 @@ static bool tpacpi_input_send_key(const u32 hkey, bool *send_acpi_ev) > if (send_acpi_ev) > *send_acpi_ev = false; > > - return false; > + scancode = hkey; > } > > - keycode = hotkey_keycode_map[scancode]; > - > mutex_lock(&tpacpi_inputdev_send_mutex); > - > - input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode); > - input_report_key(tpacpi_inputdev, keycode, 1); > - input_sync(tpacpi_inputdev); > - > - input_report_key(tpacpi_inputdev, keycode, 0); > - input_sync(tpacpi_inputdev); > - > + known_ev = sparse_keymap_report_event(tpacpi_inputdev, scancode, 1, true); > mutex_unlock(&tpacpi_inputdev_send_mutex); > > - return true; > + return known_ev; > } > > #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL > @@ -3124,9 +3124,6 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = { > TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ > }; > > -typedef u16 tpacpi_keymap_entry_t; > -typedef tpacpi_keymap_entry_t tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; > - > static int hotkey_init_tablet_mode(void) > { > int in_tablet_mode = 0, res; > @@ -3163,217 +3160,124 @@ static int hotkey_init_tablet_mode(void) > return in_tablet_mode; > } > > +static const struct key_entry keymap_ibm[] __initconst = { > + /* Original hotkey mappings translated scancodes 0x00 - 0x1f */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF1, { KEY_FN_F1 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF2, { KEY_BATTERY } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF3, { KEY_COFFEE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF4, { KEY_SLEEP } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF5, { KEY_WLAN } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF6, { KEY_FN_F6 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF7, { KEY_SWITCHVIDEOMODE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF8, { KEY_FN_F8 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF9, { KEY_FN_F9 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF10, { KEY_FN_F10 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF11, { KEY_FN_F11 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF12, { KEY_SUSPEND } }, > + /* Brightness: firmware always reacts, suppressed through hotkey_reserved_mask. */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNHOME, { KEY_BRIGHTNESSUP } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNEND, { KEY_BRIGHTNESSDOWN } }, > + /* Thinklight: firmware always reacts, suppressed through hotkey_reserved_mask. */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNPAGEUP, { KEY_KBDILLUMTOGGLE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNSPACE, { KEY_ZOOM } }, > + /* > + * Volume: firmware always reacts and reprograms the built-in *extra* mixer. > + * Suppressed by default through hotkey_reserved_mask. > + */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEUP, { KEY_VOLUMEUP } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, { KEY_VOLUMEDOWN } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MUTE, { KEY_MUTE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_THINKPAD, { KEY_VENDOR } }, > + { KE_END } > +}; > + > +static const struct key_entry keymap_lenovo[] __initconst = { > + /* Original hotkey mappings translated scancodes 0x00 - 0x1f */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF1, { KEY_FN_F1 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF2, { KEY_COFFEE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF3, { KEY_BATTERY } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF4, { KEY_SLEEP } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF5, { KEY_WLAN } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF6, { KEY_CAMERA, } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF7, { KEY_SWITCHVIDEOMODE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF8, { KEY_FN_F8 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF9, { KEY_FN_F9 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF10, { KEY_FN_F10 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF11, { KEY_FN_F11 } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNF12, { KEY_SUSPEND } }, > + /* > + * These should be enabled --only-- when ACPI video is disabled and > + * are handled in a special way by the init code. > + */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNHOME, { KEY_BRIGHTNESSUP } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNEND, { KEY_BRIGHTNESSDOWN } }, > + /* Suppressed by default through hotkey_reserved_mask. */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNPAGEUP, { KEY_KBDILLUMTOGGLE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FNSPACE, { KEY_ZOOM } }, > + /* > + * Volume: z60/z61, T60 (BIOS version?): firmware always reacts and > + * reprograms the built-in *extra* mixer. > + * T60?, T61, R60?, R61: firmware and EC tries to send these over > + * the regular keyboard (not through tpacpi). There are still weird bugs > + * re. MUTE. May cause the BIOS to interfere with the HDA mixer. > + * Suppressed by default through hotkey_reserved_mask. > + */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEUP, { KEY_VOLUMEUP } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, { KEY_VOLUMEDOWN } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MUTE, { KEY_MUTE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_THINKPAD, { KEY_VENDOR } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MICMUTE, { KEY_MICMUTE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CONFIG, { KEY_CONFIG } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_SEARCH, { KEY_SEARCH } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_SCALE, { KEY_SCALE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FILE, { KEY_FILE } }, > + /* Adaptive keyboard mappings for Carbon X1 2014 translated scancodes 0x20 - 0x33 */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MUTE2, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_BRIGHTNESS_ZERO, { KEY_BRIGHTNESS_MIN } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CLOUD, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK9, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_VOICE, { KEY_VOICECOMMAND } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK10, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_GESTURES, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK11, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK12, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_UNK13, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CONFIG2, { KEY_CONFIG } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_NEW_TAB, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_RELOAD, { KEY_REFRESH } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_BACK, { KEY_BACK } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MIC_DOWN, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MIC_UP, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_MIC_CANCELLATION, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CAMERA_MODE, { KEY_RESERVED } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_ROTATE_DISPLAY, { KEY_RESERVED } }, > + /* Extended hotkeys mappings translated scancodes 0x34 - 0x4d */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_STAR, { KEY_BOOKMARKS } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CLIPPING_TOOL2, { KEY_SELECTIVE_SCREENSHOT } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_CALCULATOR, { KEY_CALC } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_BLUETOOTH, { KEY_BLUETOOTH } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_KEYBOARD, { KEY_KEYBOARD } }, > + /* Used by "Lenovo Quick Clean" */ > + { KE_KEY, TP_ACPI_HOTKEYSCAN_FN_RIGHT_SHIFT, { KEY_FN_RIGHT_SHIFT } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_NOTIFICATION_CENTER, { KEY_NOTIFICATION_CENTER } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_PICKUP_PHONE, { KEY_PICKUP_PHONE } }, > + { KE_KEY, TP_ACPI_HOTKEYSCAN_HANGUP_PHONE, { KEY_HANGUP_PHONE } }, > + /* > + * All mapping below are for raw untranslated hkey event codes mapped directly > + * after switching to sparse keymap support. The mappings above use translated > + * scancodes to preserve uAPI compatibility, see tpacpi_input_send_key(). > + */ > + { KE_END } > +}; > + > static int __init hotkey_init(struct ibm_init_struct *iibm) > { > - /* Requirements for changing the default keymaps: > - * > - * 1. Many of the keys are mapped to KEY_RESERVED for very > - * good reasons. Do not change them unless you have deep > - * knowledge on the IBM and Lenovo ThinkPad firmware for > - * the various ThinkPad models. The driver behaves > - * differently for KEY_RESERVED: such keys have their > - * hot key mask *unset* in mask_recommended, and also > - * in the initial hot key mask programmed into the > - * firmware at driver load time, which means the firm- > - * ware may react very differently if you change them to > - * something else; > - * > - * 2. You must be subscribed to the linux-thinkpad and > - * ibm-acpi-devel mailing lists, and you should read the > - * list archives since 2007 if you want to change the > - * keymaps. This requirement exists so that you will > - * know the past history of problems with the thinkpad- > - * acpi driver keymaps, and also that you will be > - * listening to any bug reports; > - * > - * 3. Do not send thinkpad-acpi specific patches directly to > - * for merging, *ever*. Send them to the linux-acpi > - * mailinglist for comments. Merging is to be done only > - * through acpi-test and the ACPI maintainer. > - * > - * If the above is too much to ask, don't change the keymap. > - * Ask the thinkpad-acpi maintainer to do it, instead. > - */ > - > enum keymap_index { > TPACPI_KEYMAP_IBM_GENERIC = 0, > TPACPI_KEYMAP_LENOVO_GENERIC, > }; > > - static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = { > - /* Generic keymap for IBM ThinkPads */ > - [TPACPI_KEYMAP_IBM_GENERIC] = { > - /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ > - KEY_FN_F1, KEY_BATTERY, 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 0x1F: Other ACPI HKEY hot keys */ > - KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ > - KEY_UNKNOWN, /* 0x0D: FN+INSERT */ > - KEY_UNKNOWN, /* 0x0E: FN+DELETE */ > - > - /* brightness: firmware always reacts to them. > - * Suppressed by default through hotkey_reserved_mask. > - */ > - KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ > - KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ > - > - /* Thinklight: firmware always react to it. > - * Suppressed by default through hotkey_reserved_mask. > - */ > - KEY_KBDILLUMTOGGLE, /* 0x11: FN+PGUP (thinklight toggle) */ > - > - KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ > - KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ > - > - /* Volume: firmware always react to it and reprograms > - * the built-in *extra* mixer. Never map it to control > - * another mixer by default. > - * Suppressed by default through hotkey_reserved_mask. > - */ > - KEY_VOLUMEUP, /* 0x14: VOLUME UP */ > - KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */ > - KEY_MUTE, /* 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, > - > - /* No assignments, only used for Adaptive keyboards. */ > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - > - /* No assignment, used for newer Lenovo models */ > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN > - > - }, > - > - /* Generic keymap for Lenovo ThinkPads */ > - [TPACPI_KEYMAP_LENOVO_GENERIC] = { > - /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ > - KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, > - KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8, > - KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, > - > - /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ > - KEY_UNKNOWN, /* 0x0C: FN+BACKSPACE */ > - KEY_UNKNOWN, /* 0x0D: FN+INSERT */ > - KEY_UNKNOWN, /* 0x0E: FN+DELETE */ > - > - /* These should be enabled --only-- when ACPI video > - * is disabled (i.e. in "vendor" mode), and are handled > - * in a special way by the init code */ > - KEY_BRIGHTNESSUP, /* 0x0F: FN+HOME (brightness up) */ > - KEY_BRIGHTNESSDOWN, /* 0x10: FN+END (brightness down) */ > - > - /* Suppressed by default through hotkey_reserved_mask. */ > - KEY_KBDILLUMTOGGLE, /* 0x11: FN+PGUP (thinklight toggle) */ > - > - KEY_UNKNOWN, /* 0x12: FN+PGDOWN */ > - KEY_ZOOM, /* 0x13: FN+SPACE (zoom) */ > - > - /* Volume: z60/z61, T60 (BIOS version?): firmware always > - * react to it and reprograms the built-in *extra* mixer. > - * Never map it to control another mixer by default. > - * > - * T60?, T61, R60?, R61: firmware and EC tries to send > - * these over the regular keyboard, so these are no-ops, > - * but there are still weird bugs re. MUTE, so do not > - * change unless you get test reports from all Lenovo > - * models. May cause the BIOS to interfere with the > - * HDA mixer. > - * Suppressed by default through hotkey_reserved_mask. > - */ > - KEY_VOLUMEUP, /* 0x14: VOLUME UP */ > - KEY_VOLUMEDOWN, /* 0x15: VOLUME DOWN */ > - KEY_MUTE, /* 0x16: MUTE */ > - > - KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ > - > - /* (assignments unknown, please report if found) */ > - KEY_UNKNOWN, KEY_UNKNOWN, > - > - /* > - * The mic mute button only sends 0x1a. It does not > - * automatically mute the mic or change the mute light. > - */ > - KEY_MICMUTE, /* 0x1a: Mic mute (since ?400 or so) */ > - > - /* (assignments unknown, please report if found) */ > - KEY_UNKNOWN, > - > - /* Extra keys in use since the X240 / T440 / T540 */ > - KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_FILE, > - > - /* > - * These are the adaptive keyboard keycodes for Carbon X1 2014. > - * The first item in this list is the Mute button which is > - * emitted with 0x103 through > - * adaptive_keyboard_hotkey_notify_hotkey() when the sound > - * symbol is held. > - * We'll need to offset those by 0x20. > - */ > - KEY_RESERVED, /* Mute held, 0x103 */ > - KEY_BRIGHTNESS_MIN, /* Backlight off */ > - KEY_RESERVED, /* Clipping tool */ > - KEY_RESERVED, /* Cloud */ > - KEY_RESERVED, > - KEY_VOICECOMMAND, /* Voice */ > - KEY_RESERVED, > - KEY_RESERVED, /* Gestures */ > - KEY_RESERVED, > - KEY_RESERVED, > - KEY_RESERVED, > - KEY_CONFIG, /* Settings */ > - KEY_RESERVED, /* New tab */ > - KEY_REFRESH, /* Reload */ > - KEY_BACK, /* Back */ > - KEY_RESERVED, /* Microphone down */ > - KEY_RESERVED, /* Microphone up */ > - KEY_RESERVED, /* Microphone cancellation */ > - KEY_RESERVED, /* Camera mode */ > - KEY_RESERVED, /* Rotate display, 0x116 */ > - > - /* > - * These are found in 2017 models (e.g. T470s, X270). > - * The lowest known value is 0x311, which according to > - * the manual should launch a user defined favorite > - * application. > - * > - * The offset for these is TP_ACPI_HOTKEYSCAN_EXTENDED_START, > - * corresponding to 0x34. > - */ > - > - /* (assignments unknown, please report if found) */ > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, > - KEY_UNKNOWN, > - > - KEY_BOOKMARKS, /* Favorite app, 0x311 */ > - KEY_SELECTIVE_SCREENSHOT, /* Clipping tool */ > - KEY_CALC, /* Calculator (above numpad, P52) */ > - KEY_BLUETOOTH, /* Bluetooth */ > - KEY_KEYBOARD, /* Keyboard, 0x315 */ > - KEY_FN_RIGHT_SHIFT, /* Fn + right Shift */ > - KEY_NOTIFICATION_CENTER, /* Notification Center */ > - KEY_PICKUP_PHONE, /* Answer incoming call */ > - KEY_HANGUP_PHONE, /* Decline incoming call */ > - }, > - }; > - > static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = { > /* Generic maps (fallback) */ > { > @@ -3388,17 +3292,11 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) > }, > }; > > -#define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) > -#define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_entry_t) > - > - int res, i; > - int status; > - int hkeyv; > + unsigned long keymap_id, quirks; > + const struct key_entry *keymap; > bool radiosw_state = false; > bool tabletsw_state = false; > - > - unsigned long quirks; > - unsigned long keymap_id; > + int hkeyv, res, status; > > vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, > "initializing hotkey subdriver\n"); > @@ -3538,7 +3436,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) > /* Set up key map */ > keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable, > ARRAY_SIZE(tpacpi_keymap_qtable)); > - BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps)); > dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, > "using keymap number %lu\n", keymap_id); > > @@ -3551,27 +3448,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) > * Reserve brightness up/down unconditionally on IBM models, on Lenovo > * models these are disabled based on acpi_video_get_backlight_type(). > */ > - if (keymap_id == TPACPI_KEYMAP_IBM_GENERIC) > + if (keymap_id == TPACPI_KEYMAP_IBM_GENERIC) { > hotkey_reserved_mask |= TP_ACPI_HKEY_BRGHTUP_MASK | > TP_ACPI_HKEY_BRGHTDWN_MASK; > - > - hotkey_keycode_map = kmemdup(&tpacpi_keymaps[keymap_id], > - TPACPI_HOTKEY_MAP_SIZE, GFP_KERNEL); > - if (!hotkey_keycode_map) { > - pr_err("failed to allocate memory for key map\n"); > - return -ENOMEM; > + keymap = keymap_ibm; > + } else { > + keymap = keymap_lenovo; > } > > - input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); > - 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) { > - input_set_capability(tpacpi_inputdev, EV_KEY, > - hotkey_keycode_map[i]); > - } > - } > + res = sparse_keymap_setup(tpacpi_inputdev, keymap, NULL); > + if (res) > + return res; > > if (tp_features.hotkey_wlsw) { > input_set_capability(tpacpi_inputdev, EV_SW, SW_RFKILL_ALL); > @@ -11739,7 +11626,6 @@ static void thinkpad_acpi_module_exit(void) > input_unregister_device(tpacpi_inputdev); > else > input_free_device(tpacpi_inputdev); > - kfree(hotkey_keycode_map); > } > > if (tpacpi_sensors_pdev)