Skip to contentSkip to conversation

More X1 Carbon (2nd gen) adaptive keyboard support

PATCH Bastien Nocera 1 participant 1 message Jan 13, 2015

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hey,

I'm currently working on adding support for the extra "adaptive" keys for the X1 Carbon 2014 (2nd gen).

Below is the (non-working) patch to add support for some of those keys. I'm working with Benjamin Tissoires to add the necessary, missing, Linux keycodes.

A couple of questions though:
- Should I expand the main "hotkey" keymap? I don't really understand that code (and don't really want to read the archives since 2007 ;)
- A couple of keys don't go through the same "hotkey" interface:
- show all applications
- show overview/exposé
- search
- webcam on/off
- wireless on/off

Any ideas how those could be exported? Any specific data you would need (de-compiled DSDT?)? Debug I can turn on?

Some interesting kernel messages:

--8<--

[13747.860235] thinkpad_acpi_adaptive: ThinkPad BIOS GRET42WW (1.19 ), EC unknown
[13747.860236] thinkpad_acpi_adaptive: Lenovo ThinkPad X1 Carbon 2nd, model 20A7002WUS
[13747.860865] thinkpad_acpi_adaptive: tpacpi_acpi_handle_locate: Found ACPI handle for video
[13747.861114] thinkpad_acpi_adaptive: Unsupported brightness interface, please contact [email protected]
[13747.861127] thinkpad_acpi_adaptive: drv_acpi_handle_init: Found ACPI handle HKEY for hkey
[13747.861141] thinkpad_acpi_adaptive: unknown version of the HKEY interface: 0x200
[13747.861142] thinkpad_acpi_adaptive: please report this to [email protected]

--8<--

Patch below,

Cheers

drivers/platform/x86/thinkpad_acpi.c +49 -1
index 721905b..ebf2fb2 100644
@@ -3526,6 +3526,31 @@ const int adaptive_keyboard_modes[] = {
 
 #define DFR_CHANGE_ROW			0x101
 #define DFR_SHOW_QUICKVIEW_ROW		0x102
+#define FIRST_ADAPTIVE_KEY		0x105
+
+/* The first item in this list is the Clipping tool button
+ * which is emitted with 0x105 through
+ * adaptive_keyboard_hotkey_notify_hotkey ()*/
+static int adaptive_keycodes[] = {
+	KEY_RESERVED, /* Clipping tool, 0x105 */
+	KEY_RESERVED, /* Cloud */
+	KEY_RESERVED,
+	KEY_RESERVED, /* Voice */
+	KEY_RESERVED,
+	KEY_RESERVED, /* Gestures */
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED,
+	KEY_RESERVED, /* 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 */
+};
 
 /* press Fn key a while second, it will switch to Function Mode. Then
  * release Fn key, previous mode be restored.
@@ -3583,6 +3608,7 @@ static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode)
 {
 	u32 current_mode = 0;
 	int new_mode = 0;
+	int keycode;
 
 	switch (scancode) {
 	case DFR_CHANGE_ROW:
@@ -3615,7 +3641,26 @@ static bool adaptive_keyboard_hotkey_notify_hotkey(unsigned int scancode)
 		return true;
 
 	default:
-		return false;
+		if (scancode < FIRST_ADAPTIVE_KEY ||
+			scancode > FIRST_ADAPTIVE_KEY +
+				ARRAY_SIZE(adaptive_keycodes)) {
+			pr_info("Unhandled adaptive keyboard key: 0x%x\n",
+					scancode);
+			return false;
+		}
+		keycode = adaptive_keycodes[scancode - FIRST_ADAPTIVE_KEY];
+		if (keycode != KEY_RESERVED) {
+			mutex_lock(&tpacpi_inputdev_send_mutex);
+
+			input_report_key(tpacpi_inputdev, keycode, 1);
+			input_sync(tpacpi_inputdev);
+
+			input_report_key(tpacpi_inputdev, keycode, 0);
+			input_sync(tpacpi_inputdev);
+
+			mutex_unlock(&tpacpi_inputdev_send_mutex);
+		}
+		return true;
 	}
 }
 
@@ -3628,6 +3673,8 @@ static bool hotkey_notify_hotkey(const u32 hkey,
 	*send_acpi_ev = true;
 	*ignore_acpi_ev = false;
 
+	pr_err ("hotkey_notify_hotkey: 0x%x\n", hkey);
+
 	/* HKEY event 0x1001 is scancode 0x00 */
 	if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) {
 		scancode--;
@@ -3639,6 +3686,7 @@ static bool hotkey_notify_hotkey(const u32 hkey,
 		}
 		return true;
 	} else {
+		pr_err ("scancode: 0x%x\n", scancode);
 		return adaptive_keyboard_hotkey_notify_hotkey(scancode);
 	}
 	return false;

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html