All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Kobel <a-kobel@a-kobel.de>
To: Hans de Goede <hdegoede@redhat.com>,
	Nitin Joshi1 <njoshi1@lenovo.com>,
	"platform-driver-x86@vger.kernel.org" 
	<platform-driver-x86@vger.kernel.org>,
	Mark Pearson <mpearson@lenovo.com>
Subject: [PATCH v2] platform/x86: thinkpad_acpi: Handle keyboard cover attach/detach events
Date: Wed, 10 Feb 2021 18:54:25 +0100	[thread overview]
Message-ID: <00d3570a-8624-89ca-7216-7d648b0a2f0b@a-kobel.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 5942 bytes --]

ThinkPad X1 Tablets emit HKEY 0x4012 and 0x4013 events when a keyboard
cover is attached/detached or folded to the back of the device. They are
used to switch from normal to tablet mode in userspace; e.g., to offer
touch keyboard choices when focus goes to a text box and no keyboard is
attached, or to enable autorotation of the display according to the
built-in orientation sensor.

This patch handles the two events by issuing corresponding
SW_TABLET_MODE notifications to the ACPI userspace.

Tested as working on a ThinkPad X1 Tablet Gen 2, 20JCS00C00, and as
non-interfering with a ThinkPad X1 Carbon 7th, 20QESABM02 (normal
clamshell, so it does not have a keyboard cover).

Signed-off-by: Alexander Kobel <a-kobel@a-kobel.de>
---
 drivers/platform/x86/thinkpad_acpi.c | 91 +++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index c404706379d9..8c1ff555f10b 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -174,6 +174,11 @@ enum tpacpi_hkey_event_t {
 						     or port replicator */
 	TP_HKEY_EV_HOTPLUG_UNDOCK	= 0x4011, /* undocked from hotplug
 						     dock or port replicator */
+	/* Thinkpad X1 Tablet series (and probably other GTOP type 4) emit 0x4012 and 0x4013
+	 * when keyboard cover is attached, detached or folded onto the back
+	 */
+	TP_HKEY_EV_KBD_COVER_ATTACH	= 0x4012, /* keyboard cover attached */
+	TP_HKEY_EV_KBD_COVER_DETACH	= 0x4013, /* keyboard cover detached or folded back */
 
 	/* User-interface events */
 	TP_HKEY_EV_LID_CLOSE		= 0x5001, /* laptop lid closed */
@@ -308,6 +313,8 @@ static struct {
 		TP_HOTKEY_TABLET_NONE = 0,
 		TP_HOTKEY_TABLET_USES_MHKG,
 		TP_HOTKEY_TABLET_USES_GMMS,
+		TP_HOTKEY_TABLET_USES_GTOP_ANY_TYPE,
+		TP_HOTKEY_TABLET_USES_GTOP_X1_TABLET_TYPE,
 	} hotkey_tablet;
 	u32 kbdlight:1;
 	u32 light:1;
@@ -2166,11 +2173,32 @@ static int hotkey_gmms_get_tablet_mode(int s, int *has_tablet_mode)
 	return !!(mode & TP_ACPI_MULTI_MODE_TABLET_LIKE);
 }
 
+static int hotkey_gtop_any_type_get_tablet_mode(int s)
+{
+	return !(s & 0x1);
+}
+
+static int hotkey_gtop_x1_tablet_type_get_tablet_mode(int s)
+{
+	return (!(s & 0x1) /* keyboard NOT attached */
+		|| ((s >> 16) & 0x1) /* or folded onto the back */);
+}
+
 static int hotkey_get_tablet_mode(int *status)
 {
 	int s;
 
 	switch (tp_features.hotkey_tablet) {
+	case TP_HOTKEY_TABLET_USES_GTOP_ANY_TYPE:
+		if (!acpi_evalf(hkey_handle, &s, "GTOP", "dd", 0x0200))
+			return -EIO;
+		*status = hotkey_gtop_any_type_get_tablet_mode(s);
+		break;
+	case TP_HOTKEY_TABLET_USES_GTOP_X1_TABLET_TYPE:
+		if (!acpi_evalf(hkey_handle, &s, "GTOP", "dd", 0x0200))
+			return -EIO;
+		*status = hotkey_gtop_x1_tablet_type_get_tablet_mode(s);
+		break;
 	case TP_HOTKEY_TABLET_USES_MHKG:
 		if (!acpi_evalf(hkey_handle, &s, "MHKG", "d"))
 			return -EIO;
@@ -3213,7 +3241,62 @@ static int hotkey_init_tablet_mode(void)
 	int in_tablet_mode = 0, res;
 	char *type = NULL;
 
-	if (acpi_evalf(hkey_handle, &res, "GMMS", "qdd", 0)) {
+	if (acpi_evalf(hkey_handle, &res, "GTOP", "qdd", 0x0000)
+	    && res >= 0x0103
+	    && acpi_evalf(hkey_handle, &res, "GTOP", "qdd", 0x0100)) {
+		/*
+		 * GTOP ("Get Tablet OPtion") state ASL method definition:
+		 * - Input: 0x0000: Query version
+		 *   Output: 0x0103 (version 1.03)
+		 * - Input: 0x0100: Query interface type
+		 *   Output: DWORD But 31-0 Interface type
+		 *     0: Reserved
+		 *     1: Any type
+		 *     2: ThinkPad Helix series
+		 *     3: ThinkPad 10 series
+		 *     4: ThinkPad X1 Tablet series
+		 * - Input: 0x0200: Get attach option
+		 *   Output: Option attach state
+		 *     (0: detached, 1: attached)
+		 *     version >= 1.03 and interface type 1:
+		 *       Bit 0: Any option attach state
+		 *       Bit 31-1: Reserved(0)
+		 *     version >= 1.03 and interface type 4:
+		 *       Bit 0: Thin-KBD attach state
+		 *       Bit 1: Pro-Cartridge attach state
+		 *       Bit 3-2: Pico-Cartridge attach state
+		 *         00: detached
+		 *         01: attached
+		 *         10: attached with battery error
+		 *         11: Reserved
+		 *       Bit 4: 3D Cartridge attach state
+		 *       Bit 5: Reserve 1 attach state
+		 *       Bit 6: Reserve 2 attach state
+		 *       Bit 15-7: Reserved(0)
+		 *       Bit 16: Folio keyboard location
+		 *         (valid if folio attached)
+		 *         0: keyboard is NOT folded onto the back
+		 *         1: keyboard is folded onto the back of the system
+		 *       Bit 31-17: Reserved(0)
+		 */
+		switch (res) {
+		case 1:
+			tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GTOP_ANY_TYPE;
+			if (acpi_evalf(hkey_handle, &res, "GTOP", "qdd", 0x200))
+				in_tablet_mode = hotkey_gtop_any_type_get_tablet_mode(res);
+			type = "GTOP";
+			break;
+		case 4:
+			tp_features.hotkey_tablet = TP_HOTKEY_TABLET_USES_GTOP_X1_TABLET_TYPE;
+			if (acpi_evalf(hkey_handle, &res, "GTOP", "qdd", 0x200))
+				in_tablet_mode = hotkey_gtop_x1_tablet_type_get_tablet_mode(res);
+			type = "GTOP";
+			break;
+		default:
+			pr_err("unsupported GTOP type, please report this to %s\n", TPACPI_MAIL);
+			break;
+		}
+	} else if (acpi_evalf(hkey_handle, &res, "GMMS", "qdd", 0)) {
 		int has_tablet_mode;
 
 		in_tablet_mode = hotkey_gmms_get_tablet_mode(res,
@@ -3989,6 +4072,12 @@ static bool hotkey_notify_dockevent(const u32 hkey,
 	case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */
 		pr_info("undocked from hotplug port replicator\n");
 		return true;
+	case TP_HKEY_EV_KBD_COVER_ATTACH:
+	case TP_HKEY_EV_KBD_COVER_DETACH:
+		tpacpi_input_send_tabletsw();
+		hotkey_tablet_mode_notify_change();
+		*send_acpi_ev = false;
+		return true;
 
 	default:
 		return false;
-- 
2.30.1



[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 5916 bytes --]

             reply	other threads:[~2021-02-10 17:55 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-10 17:54 Alexander Kobel [this message]
2021-02-10 21:48 ` [PATCH v2] platform/x86: thinkpad_acpi: Handle keyboard cover attach/detach events Barnabás Pőcze
2021-02-10 23:46   ` Alexander Kobel
2021-02-13 15:13 Alexander Kobel
2021-02-15 14:28 ` Hans de Goede
2021-03-04 11:02 ` Hans de Goede

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=00d3570a-8624-89ca-7216-7d648b0a2f0b@a-kobel.de \
    --to=a-kobel@a-kobel.de \
    --cc=hdegoede@redhat.com \
    --cc=mpearson@lenovo.com \
    --cc=njoshi1@lenovo.com \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.