From nobody Tue Sep 9 16:36:52 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEAF22EB879; Mon, 8 Sep 2025 22:35:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757370960; cv=none; b=ij+wgIsZR42uJQ7LamP+GynU3hl3l7hdeGadFjJsRxwcZgDJNtmQ18g2AUOJJLIJroIwlkNj4K6FsKPMi2DxrgHLJzR6zsnGi79PJG2Y1AnTkrYqc9ppzMC6cAWdACA22euBiTGQ5yaSfB6ySGtqIBxJEWrof9CjsDTv3X+DjZg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757370960; c=relaxed/simple; bh=jvo7GR+au7e8XXiUD6Y887uMomLI0ITYe2QUQ37dR0o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lLEYVkzxW6znopvY1+pVc5MqMagEvFvZK3tKNc3Jls93/BoNxyBdK7lNxqBLsChyjEDmnUPWSs3cpOMlK3u+wakXwWdYEo+GUBey2SisjnEm2FtHsAuY+NMXLewzFhk/un77pjndj+2HQ1Wt/chsNlxNUW7xf7+hzHGf1J8ixZo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f9I350wd; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f9I350wd" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73B20C4AF09; Mon, 8 Sep 2025 22:35:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757370959; bh=jvo7GR+au7e8XXiUD6Y887uMomLI0ITYe2QUQ37dR0o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=f9I350wd78Fr5gwaeyN/SzocdApzb/NdTcCfxJMlXAcdSW7o5FlftTp93MQQ2IXaz 3v5KL0/RhzUNrxsqOAoq6l02M4yjHWI71e9oFSRJ1c7+1eYpSJrhYwGrWs+TwJvvXU RrxSIM4jnlgCLB2qSakmGBS/yyjVjqcoU29BUWkbvmyT8BAk9VSr5naucX5aFFU632 3czDUafpnbKceqZ2Qb9mgetTjiyBEJE0waVK19AGd4t+YrgGz0sTmOElhqzQ84P2d2 yF+8aqzgGH+2uFQNKUnh+/pbvhWBDv8EcOoa9DzKPd0uCeOJ6AxKYILjcB/5sV5R31 L7GO1pOiHbE0w== Received: by venus (Postfix, from userid 1000) id 90F43180644; Tue, 09 Sep 2025 00:35:57 +0200 (CEST) From: Sebastian Reichel Date: Tue, 09 Sep 2025 00:35:50 +0200 Subject: [PATCH v4 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250909-thinkpad-t14s-ec-v4-1-caf6159daaee@collabora.com> References: <20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com> In-Reply-To: <20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com> To: Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Bryan O'Donoghue , Bjorn Andersson , Konrad Dybcio , Mark Pearson Cc: "Derek J. Clark" , Henrique de Moraes Holschuh , Neil Armstrong , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-arm-msm@vger.kernel.org, Krzysztof Kozlowski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2093; i=sebastian.reichel@collabora.com; h=from:subject:message-id; bh=jvo7GR+au7e8XXiUD6Y887uMomLI0ITYe2QUQ37dR0o=; b=owEBbQKS/ZANAwAKAdju1/PIO/qaAcsmYgBov1pMir9Op9qRrz8Bi1rKFPqNJBrjqtfkNJRuK howxO7fHPuJAjMEAAEKAB0WIQTvZg0HRj+Lcmp5VBPY7tfzyDv6mgUCaL9aTAAKCRDY7tfzyDv6 mrAKD/9nqPRb+FwFSfgTgnv/zlhAIuVQ6kBVtvsLKD5GcKLHFbV4hk6wT6WWzDhX5HJXTa8cDnw fyTnZeCIH/Y8ltCoVZTEwLz44fy2wqK176WgcU9eTRcwH/qbzja9G0TkvO5o6wP/paDlZBQCFq0 NnOtixbFzSVoxlV0X0rhnqew/OtXWJ/NRjvyoWLB4SwkpjA64u/Kete59mITxjsRZ0UDRunVMKk p3vOstsc4xA1IN5c3o0QvCjW/whbXVY6lyBmCcZTFbXpaBM5OEhishDEfdQPFV8Dkx8PjE5AzZl kfg/Wg7t7VH7dazs3eXoTHMKm73cb6bo8PfzviBt7A3HUwtATOKAda+YyuHECRmMAFKiTaSN8kc 1DT7Ebi1gVolYTH6hi7S/SCdTaMaZyMMrvDQnH9kfe5XSkV2UwhVz3oPt6wGAskp2fGyKleF2lk jDDp4OqkTcJLWLCEGAcFwNYV5jcPPfa+s10af3LPehWTopWab5jvc4btm+B7mjtFR+EuRDfEMwe gKyfaXHKNhwtwSp2ueBgzV7ZelCBRAoF6DzBKlb8KO2eM7X1bnwnChQS/wJGIFmBRmUBtLsSUP6 oLE4OQ4PlWcLDKltq25BXekF5kmUguD6jzyLtlKOQj2MAD11b/T4++bMMdJf2YlGtK7qLpmsfTk +NgnPvgq4Om3ZaQ== X-Developer-Key: i=sebastian.reichel@collabora.com; a=openpgp; fpr=EF660D07463F8B726A795413D8EED7F3C83BFA9A Add binding for the EC found in the Thinkpad T14s Gen6 Snapdragon, which is based on the Qualcomm X1 Elite. Some of the system LEDs and extra keys are only accessible via the EC. Reviewed-by: Bryan O'Donoghue Reviewed-by: Krzysztof Kozlowski Signed-off-by: Sebastian Reichel --- .../lenovo,thinkpad-t14s-ec.yaml | 50 ++++++++++++++++++= ++++ 1 file changed, 50 insertions(+) diff --git a/Documentation/devicetree/bindings/embedded-controller/lenovo,t= hinkpad-t14s-ec.yaml b/Documentation/devicetree/bindings/embedded-controlle= r/lenovo,thinkpad-t14s-ec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c87ccb5b30868c7a616ec08b869= 286d627dd7406 --- /dev/null +++ b/Documentation/devicetree/bindings/embedded-controller/lenovo,thinkpad= -t14s-ec.yaml @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/embedded-controller/lenovo,thinkpad-t14= s-ec.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Lenovo Thinkpad T14s Embedded Controller + +maintainers: + - Sebastian Reichel + +description: + The Qualcomm Snapdragon-based Lenovo Thinkpad T14s has an Embedded Contr= oller + (EC) which handles things such as keyboard backlight, LEDs or non-standa= rd + keys. + +properties: + compatible: + const: lenovo,thinkpad-t14s-ec + + reg: + const: 0x28 + + interrupts: + maxItems: 1 + + wakeup-source: true + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - |+ + #include + i2c { + #address-cells =3D <1>; + #size-cells =3D <0>; + + embedded-controller@28 { + compatible =3D "lenovo,thinkpad-t14s-ec"; + reg =3D <0x28>; + interrupts-extended =3D <&tlmm 66 IRQ_TYPE_LEVEL_LOW>; + wakeup-source; + }; + }; +... --=20 2.51.0 From nobody Tue Sep 9 16:36:52 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 712EE2EF64F; Mon, 8 Sep 2025 22:36:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757370960; cv=none; b=jtFaLkJEUkn/3Stm0wzQbY+H5kLdHt+PPEj1QXMDlIl8Qa1FPvM47YZg8awohs69XvuCXZk5ztGoTZrvJZQPrYJeIdZImtHomRzHjNzPctGjXnQQbSGVPGigma6rN3tOQqpoInw7M9DJy2e7J0P07YV1PYGJd+G0mtnSJaVgJ3A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757370960; c=relaxed/simple; bh=bKdKbLSrbAX1nk02pRPvhl+IYbwqxwHMYlZRxPStILI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pONK+yvKiqvAdb0tYC1MfT8xC8wKp0qtzV+xI5cSegKy9kus1JoBSRf+VDy+DDUH4k5lQ9Rur9zAKAISd/MU5parTtwG8X7ckJ9rJt1SS1M7DSxWGtlfeu6yfMy+/Z108tQuEvGL4MfvkOQK+5T1eAGKxvKC27dZ3nqGVC+4EFQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gGxN4peW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gGxN4peW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6FBF2C4CEF7; Mon, 8 Sep 2025 22:35:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757370959; bh=bKdKbLSrbAX1nk02pRPvhl+IYbwqxwHMYlZRxPStILI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=gGxN4peWcTx1Dg1J+csbPmlSI9BsemyBdzgaiyfGHe8zP18dRYWvU0M3DePi0M1ml oYkfdm8JvH+wcRlHtk8y+IvaH3OQ5uttQemfGFJOLuDEa3tThs1qer/6DnU59ghgSD aaOOj56L4d+2T72pVP/FMhN6uW0aid4/zVYLpUM9SOwVVCHs4a+5u712LuFUHMCfFz yvYzRdtdhOA7L5+gs8XOmodor8hdXJFD9a2Vlw/sJOJNXC0H6pkbQGagOp3L3n3Yjq vglBg+am03jl6h7UXKyQ4PMVd8AkFM8DSm5/5ZuXSgLRoYvwxmdk3A+D0E5bpjY4OW DZKKkNFEZClOA== Received: by venus (Postfix, from userid 1000) id 9174C180B18; Tue, 09 Sep 2025 00:35:57 +0200 (CEST) From: Sebastian Reichel Date: Tue, 09 Sep 2025 00:35:51 +0200 Subject: [PATCH v4 2/3] platform: arm64: thinkpad-t14s-ec: new driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250909-thinkpad-t14s-ec-v4-2-caf6159daaee@collabora.com> References: <20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com> In-Reply-To: <20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com> To: Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Bryan O'Donoghue , Bjorn Andersson , Konrad Dybcio , Mark Pearson Cc: "Derek J. Clark" , Henrique de Moraes Holschuh , Neil Armstrong , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-arm-msm@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=22489; i=sebastian.reichel@collabora.com; h=from:subject:message-id; bh=bKdKbLSrbAX1nk02pRPvhl+IYbwqxwHMYlZRxPStILI=; b=owEBbQKS/ZANAwAKAdju1/PIO/qaAcsmYgBov1pMkCSEKpSETWVbTVYx8nBnFIE50IrJwBnGB pCtoXyvY2qJAjMEAAEKAB0WIQTvZg0HRj+Lcmp5VBPY7tfzyDv6mgUCaL9aTAAKCRDY7tfzyDv6 mtPJEACMKfaTB7No7qnQVPmNXuiF4WvL7UaN5xMLhirnJ7d+s10cKyKnRdhCcm6Hw7vbd55BcQ0 ppuAI8oW4h8SiI4/g+LP6SqX1EpVuxIPEZBnpITXibQ4ODdj9LJiXY69TwkX3xwUVxemdeMe3yT 3fZZsqB2Fw3dk1efHWX6N9Em2HSCYcvSyI9uSMxsbenaSZWhjj1tHbJXYq6F11dJUTIVxzlVPsi WGCUBfgiezAm18HMT9IP2zvGvqm5Hz1LRQTT+L+vkWwGB2TXpNtwXRHXYYxhqPMtnNyVY1YD5iK iDzNDN9LflPPdrFa55DPMeCgJDSeZKrtWVPCZLZvMPqmgEw/SVvB3cQLsyLbjfM9Xgnr8RGohlX /sF6H6ZUoj+DqQiv9o7NQ+wk9eFZTxpnja8QZUYgVPX8EEnzUjTHJlWqKHhJEit2/t1nue2Vu7l whaBoESva7J3KofRVeTRSpCy+ZN9rTNELsBGngNAIIuVjuBeFT6v5KX4njjmtjhJucqX+FE5h1R D15RvJiXSh4o4UcCUdIfJt20ZwfJVL5dMEvSktMJrYzBjxIkcC6c81wP/um+Sk4SxsTUuFR/Dgm JOZHx1ZOU4ftBynE18SHCp4xyPtLjJXvAKg/OalKzp3o/mpNSn6hDnmixh5E4pJ29rBkIKcNYyC Fn28DEFEy2mBykA== X-Developer-Key: i=sebastian.reichel@collabora.com; a=openpgp; fpr=EF660D07463F8B726A795413D8EED7F3C83BFA9A Introduce EC driver for the ThinkPad T14s Gen6 Snapdragon, which is in theory compatible with ThinkPad ACPI. On Linux the system is booted with device tree, which is not supported by the ThinkPad ACPI driver (drivers/platform/x86/lenovo/thinkpad_acpi.c). Also most of the hardware compatibility is handled via ACPI tables, which are obviously not used when booting via device tree. Thus adding DT compatibility to the existing driver is not worth it as there is almost no code sharing. The driver currently exposes features, which are not available via other means: * Extra Keys * System LEDs * Keyboard Backlight Control The driver has been developed by reading the ACPI DSDT. There are some more features around thermal control, which are not yet supported by the driver. The speaker mute and mic mute LEDs need some additional changes in the ALSA UCM to be set automatically. Tested-by: Neil Armstrong # on Thinkpad T14S OL= ED Reviewed-by: Bryan O'Donoghue Signed-off-by: Sebastian Reichel --- MAINTAINERS | 6 + drivers/platform/arm64/Kconfig | 20 + drivers/platform/arm64/Makefile | 1 + drivers/platform/arm64/lenovo-thinkpad-t14s.c | 619 ++++++++++++++++++++++= ++++ 4 files changed, 646 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index cd7ff55b5d321752ac44c91d2d7e74de28e08960..73a685a75d7a15b75bbc97c25ae= 0428bdf21e2ef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25100,6 +25100,12 @@ W: http://thinkwiki.org/wiki/Ibm-acpi T: git git://repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git F: drivers/platform/x86/lenovo/thinkpad_acpi.c =20 +THINKPAD T14S EMBEDDED CONTROLLER DRIVER +M: Sebastian Reichel +S: Maintained +F: Documentation/devicetree/bindings/platform/lenovo,thinkpad-t14s-ec.yaml +F: drivers/platform/arm64/lenovo-thinkpad-t14s.c + THINKPAD LMI DRIVER M: Mark Pearson L: platform-driver-x86@vger.kernel.org diff --git a/drivers/platform/arm64/Kconfig b/drivers/platform/arm64/Kconfig index 06288aebc5599435065a37f8dacd046b5def80bd..10f905d7d6bfa5fad30a0689d3a= 20481268c781e 100644 --- a/drivers/platform/arm64/Kconfig +++ b/drivers/platform/arm64/Kconfig @@ -70,4 +70,24 @@ config EC_LENOVO_YOGA_C630 =20 Say M or Y here to include this support. =20 +config EC_LENOVO_THINKPAD_T14S + tristate "Lenovo Thinkpad T14s Embedded Controller driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on I2C + depends on INPUT + select INPUT_SPARSEKMAP + select LEDS_CLASS + select NEW_LEDS + select SND_CTL_LED if SND + help + Driver for the Embedded Controller in the Qualcomm Snapdragon-based + Lenovo Thinkpad T14s, which provides access to keyboard backlight + and status LEDs. + + This driver provides support for the mentioned laptop where this + information is not properly exposed via the standard Qualcomm + devices. + + Say M or Y here to include this support. + endif # ARM64_PLATFORM_DEVICES diff --git a/drivers/platform/arm64/Makefile b/drivers/platform/arm64/Makef= ile index 46a99eba3264cc40e812567d1533bb86031a6af3..60c131cff6a15bb51a49c9edab9= 5badf513ee0f6 100644 --- a/drivers/platform/arm64/Makefile +++ b/drivers/platform/arm64/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_EC_ACER_ASPIRE1) +=3D acer-aspire1-ec.o obj-$(CONFIG_EC_HUAWEI_GAOKUN) +=3D huawei-gaokun-ec.o obj-$(CONFIG_EC_LENOVO_YOGA_C630) +=3D lenovo-yoga-c630.o +obj-$(CONFIG_EC_LENOVO_THINKPAD_T14S) +=3D lenovo-thinkpad-t14s.o diff --git a/drivers/platform/arm64/lenovo-thinkpad-t14s.c b/drivers/platfo= rm/arm64/lenovo-thinkpad-t14s.c new file mode 100644 index 0000000000000000000000000000000000000000..7f355f749c012cfc7013fd07c94= b389317f75fba --- /dev/null +++ b/drivers/platform/arm64/lenovo-thinkpad-t14s.c @@ -0,0 +1,619 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025, Sebastian Reichel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define T14S_EC_CMD_ECRD 0x02 +#define T14S_EC_CMD_ECWR 0x03 +#define T14S_EC_CMD_EVT 0xf0 + +#define T14S_EC_REG_LED 0x0c +#define T14S_EC_REG_KBD_BL1 0x0d +#define T14S_EC_REG_KBD_BL2 0xe1 +#define T14S_EC_KBD_BL1_MASK GENMASK_U8(7, 6) +#define T14S_EC_KBD_BL2_MASK GENMASK_U8(3, 2) +#define T14S_EC_REG_AUD 0x30 +#define T14S_EC_MIC_MUTE_LED BIT(5) +#define T14S_EC_SPK_MUTE_LED BIT(6) + +#define T14S_EC_EVT_NONE 0x00 +#define T14S_EC_EVT_KEY_FN_4 0x13 +#define T14S_EC_EVT_KEY_FN_F7 0x16 +#define T14S_EC_EVT_KEY_FN_SPACE 0x1f +#define T14S_EC_EVT_KEY_TP_DOUBLE_TAP 0x20 +#define T14S_EC_EVT_AC_CONNECTED 0x26 +#define T14S_EC_EVT_AC_DISCONNECTED 0x27 +#define T14S_EC_EVT_KEY_POWER 0x28 +#define T14S_EC_EVT_LID_OPEN 0x2a +#define T14S_EC_EVT_LID_CLOSED 0x2b +#define T14S_EC_EVT_THERMAL_TZ40 0x5c +#define T14S_EC_EVT_THERMAL_TZ42 0x5d +#define T14S_EC_EVT_THERMAL_TZ39 0x5e +#define T14S_EC_EVT_KEY_FN_F12 0x62 +#define T14S_EC_EVT_KEY_FN_TAB 0x63 +#define T14S_EC_EVT_KEY_FN_F8 0x64 +#define T14S_EC_EVT_KEY_FN_F10 0x65 +#define T14S_EC_EVT_KEY_FN_F4 0x6a +#define T14S_EC_EVT_KEY_FN_D 0x6b +#define T14S_EC_EVT_KEY_FN_T 0x6c +#define T14S_EC_EVT_KEY_FN_H 0x6d +#define T14S_EC_EVT_KEY_FN_M 0x6e +#define T14S_EC_EVT_KEY_FN_L 0x6f +#define T14S_EC_EVT_KEY_FN_RIGHT_SHIFT 0x71 +#define T14S_EC_EVT_KEY_FN_ESC 0x74 +#define T14S_EC_EVT_KEY_FN_N 0x79 +#define T14S_EC_EVT_KEY_FN_F11 0x7a +#define T14S_EC_EVT_KEY_FN_G 0x7e + +/* Hardware LED blink rate is 1 Hz (500ms off, 500ms on) */ +#define T14S_EC_BLINK_RATE_ON_OFF_MS 500 + +/* + * Add a virtual offset on all key event codes for sparse keymap handling, + * since the sparse keymap infrastructure does not map some raw key event + * codes used by the EC. For example 0x16 (T14S_EC_EVT_KEY_FN_F7) is mapped + * to KEY_MUTE if no offset is applied. + */ +#define T14S_EC_KEY_EVT_OFFSET 0x1000 +#define T14S_EC_KEY_ENTRY(key, value) \ + { KE_KEY, T14S_EC_KEY_EVT_OFFSET + T14S_EC_EVT_KEY_##key, { value } } + +enum thinkpad_t14s_ec_led_status_t { + T14S_EC_LED_OFF =3D 0x00, + T14S_EC_LED_ON =3D 0x80, + T14S_EC_LED_BLINK =3D 0xc0, +}; + +struct thinkpad_t14s_ec_led_classdev { + struct led_classdev led_classdev; + int led; + enum thinkpad_t14s_ec_led_status_t cache; + struct thinkpad_t14s_ec *ec; +}; + +struct thinkpad_t14s_ec { + struct regmap *regmap; + struct device *dev; + struct thinkpad_t14s_ec_led_classdev led_pwr_btn; + struct thinkpad_t14s_ec_led_classdev led_chrg_orange; + struct thinkpad_t14s_ec_led_classdev led_chrg_white; + struct thinkpad_t14s_ec_led_classdev led_lid_logo_dot; + struct led_classdev kbd_backlight; + struct led_classdev led_mic_mute; + struct led_classdev led_spk_mute; + struct input_dev *inputdev; +}; + +static const struct regmap_config thinkpad_t14s_ec_regmap_config =3D { + .reg_bits =3D 8, + .val_bits =3D 8, + .max_register =3D 0xff, +}; + +static int thinkpad_t14s_ec_write(void *context, unsigned int reg, + unsigned int val) +{ + u8 buf[5] =3D {T14S_EC_CMD_ECWR, reg, 0x00, 0x01, val}; + struct thinkpad_t14s_ec *ec =3D context; + struct i2c_client *client =3D to_i2c_client(ec->dev); + int ret; + + ret =3D i2c_master_send(client, buf, sizeof(buf)); + if (ret < 0) + return ret; + + return 0; +} + +static int thinkpad_t14s_ec_read(void *context, unsigned int reg, + unsigned int *val) +{ + u8 buf[4] =3D {T14S_EC_CMD_ECRD, reg, 0x00, 0x01}; + struct thinkpad_t14s_ec *ec =3D context; + struct i2c_client *client =3D to_i2c_client(ec->dev); + struct i2c_msg request, response; + u8 result; + int ret; + + request.addr =3D client->addr; + request.flags =3D I2C_M_STOP; + request.len =3D sizeof(buf); + request.buf =3D buf; + response.addr =3D client->addr; + response.flags =3D I2C_M_RD; + response.len =3D 1; + response.buf =3D &result; + + i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); + + ret =3D __i2c_transfer(client->adapter, &request, 1); + if (ret < 0) + goto out; + + ret =3D __i2c_transfer(client->adapter, &response, 1); + if (ret < 0) + goto out; + + *val =3D result; + ret =3D 0; + +out: + i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); + return ret; +} + +static const struct regmap_bus thinkpad_t14s_ec_regmap_bus =3D { + .reg_write =3D thinkpad_t14s_ec_write, + .reg_read =3D thinkpad_t14s_ec_read, +}; + +static int thinkpad_t14s_ec_read_evt(struct thinkpad_t14s_ec *ec, u8 *val) +{ + u8 buf[4] =3D {T14S_EC_CMD_EVT, 0x00, 0x00, 0x01}; + struct i2c_client *client =3D to_i2c_client(ec->dev); + struct i2c_msg request, response; + int ret; + + request.addr =3D client->addr; + request.flags =3D I2C_M_STOP; + request.len =3D sizeof(buf); + request.buf =3D buf; + response.addr =3D client->addr; + response.flags =3D I2C_M_RD; + response.len =3D 1; + response.buf =3D val; + + i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); + + ret =3D __i2c_transfer(client->adapter, &request, 1); + if (ret < 0) + goto out; + + ret =3D __i2c_transfer(client->adapter, &response, 1); + if (ret < 0) + goto out; + + ret =3D 0; + +out: + i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); + return ret; +} + +static int thinkpad_t14s_led_set_status(struct thinkpad_t14s_ec *ec, + struct thinkpad_t14s_ec_led_classdev *led, + const enum thinkpad_t14s_ec_led_status_t ledstatus) +{ + int ret; + + ret =3D regmap_write(ec->regmap, T14S_EC_REG_LED, + led->led | ledstatus); + if (ret < 0) + return ret; + + led->cache =3D ledstatus; + return 0; +} + +static int thinkpad_t14s_led_brightness_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct thinkpad_t14s_ec_led_classdev *led =3D container_of(led_cdev, + struct thinkpad_t14s_ec_led_classdev, led_classdev); + enum thinkpad_t14s_ec_led_status_t new_state; + + if (brightness =3D=3D LED_OFF) + new_state =3D T14S_EC_LED_OFF; + else if (led->cache =3D=3D T14S_EC_LED_BLINK) + new_state =3D T14S_EC_LED_BLINK; + else + new_state =3D T14S_EC_LED_ON; + + return thinkpad_t14s_led_set_status(led->ec, led, new_state); +} + +static int thinkpad_t14s_led_blink_set(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct thinkpad_t14s_ec_led_classdev *led =3D container_of(led_cdev, + struct thinkpad_t14s_ec_led_classdev, led_classdev); + + if (*delay_on =3D=3D 0 && *delay_off =3D=3D 0) { + /* Userspace does not provide a blink rate; we can choose it */ + *delay_on =3D T14S_EC_BLINK_RATE_ON_OFF_MS; + *delay_off =3D T14S_EC_BLINK_RATE_ON_OFF_MS; + } else if ((*delay_on !=3D T14S_EC_BLINK_RATE_ON_OFF_MS) || + (*delay_off !=3D T14S_EC_BLINK_RATE_ON_OFF_MS)) + return -EINVAL; + + return thinkpad_t14s_led_set_status(led->ec, led, T14S_EC_LED_BLINK); +} + +static int thinkpad_t14s_init_led(struct thinkpad_t14s_ec *ec, + struct thinkpad_t14s_ec_led_classdev *led, + u8 id, const char *name) +{ + led->led_classdev.name =3D name; + led->led_classdev.flags =3D LED_RETAIN_AT_SHUTDOWN; + led->led_classdev.max_brightness =3D 1; + led->led_classdev.brightness_set_blocking =3D thinkpad_t14s_led_brightnes= s_set; + led->led_classdev.blink_set =3D thinkpad_t14s_led_blink_set; + led->ec =3D ec; + led->led =3D id; + + return devm_led_classdev_register(ec->dev, &led->led_classdev); +} + +static int thinkpad_t14s_leds_probe(struct thinkpad_t14s_ec *ec) +{ + int ret; + + ret =3D thinkpad_t14s_init_led(ec, &ec->led_pwr_btn, 0, + "platform::power"); + if (ret) + return ret; + + ret =3D thinkpad_t14s_init_led(ec, &ec->led_chrg_orange, 1, + "platform:amber:battery-charging"); + if (ret) + return ret; + + ret =3D thinkpad_t14s_init_led(ec, &ec->led_chrg_white, 2, + "platform:white:battery-full"); + if (ret) + return ret; + + ret =3D thinkpad_t14s_init_led(ec, &ec->led_lid_logo_dot, 10, + "platform::lid_logo_dot"); + if (ret) + return ret; + + return 0; +} + +static int thinkpad_t14s_kbd_bl_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct thinkpad_t14s_ec *ec =3D container_of(led_cdev, + struct thinkpad_t14s_ec, kbd_backlight); + int ret; + u8 val; + + val =3D FIELD_PREP(T14S_EC_KBD_BL1_MASK, brightness); + ret =3D regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL1, + T14S_EC_KBD_BL1_MASK, val); + if (ret < 0) + return ret; + + val =3D FIELD_PREP(T14S_EC_KBD_BL2_MASK, brightness); + ret =3D regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL2, + T14S_EC_KBD_BL2_MASK, val); + if (ret < 0) + return ret; + + return 0; +} + +static enum led_brightness thinkpad_t14s_kbd_bl_get(struct led_classdev *l= ed_cdev) +{ + struct thinkpad_t14s_ec *ec =3D container_of(led_cdev, + struct thinkpad_t14s_ec, kbd_backlight); + unsigned int val; + int ret; + + ret =3D regmap_read(ec->regmap, T14S_EC_REG_KBD_BL1, &val); + if (ret < 0) + return ret; + + return FIELD_GET(T14S_EC_KBD_BL1_MASK, val); +} + +static void thinkpad_t14s_kbd_bl_update(struct thinkpad_t14s_ec *ec) +{ + enum led_brightness brightness =3D thinkpad_t14s_kbd_bl_get(&ec->kbd_back= light); + + led_classdev_notify_brightness_hw_changed(&ec->kbd_backlight, brightness); +} + +static int thinkpad_t14s_kbd_backlight_probe(struct thinkpad_t14s_ec *ec) +{ + ec->kbd_backlight.name =3D "platform::kbd_backlight"; + ec->kbd_backlight.flags =3D LED_BRIGHT_HW_CHANGED; + ec->kbd_backlight.max_brightness =3D 2; + ec->kbd_backlight.brightness_set_blocking =3D thinkpad_t14s_kbd_bl_set; + ec->kbd_backlight.brightness_get =3D thinkpad_t14s_kbd_bl_get; + + return devm_led_classdev_register(ec->dev, &ec->kbd_backlight); +} + +static enum led_brightness thinkpad_t14s_audio_led_get(struct thinkpad_t14= s_ec *ec, + u8 led_bit) +{ + unsigned int val; + int ret; + + ret =3D regmap_read(ec->regmap, T14S_EC_REG_AUD, &val); + if (ret < 0) + return ret; + + return !!(val & led_bit) ? LED_ON : LED_OFF; +} + +static enum led_brightness thinkpad_t14s_audio_led_set(struct thinkpad_t14= s_ec *ec, + u8 led_mask, + enum led_brightness brightness) +{ + return regmap_assign_bits(ec->regmap, T14S_EC_REG_AUD, led_mask, brightne= ss > 0); +} + +static enum led_brightness thinkpad_t14s_mic_mute_led_get(struct led_class= dev *led_cdev) +{ + struct thinkpad_t14s_ec *ec =3D container_of(led_cdev, + struct thinkpad_t14s_ec, led_mic_mute); + + return thinkpad_t14s_audio_led_get(ec, T14S_EC_MIC_MUTE_LED); +} + +static int thinkpad_t14s_mic_mute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct thinkpad_t14s_ec *ec =3D container_of(led_cdev, + struct thinkpad_t14s_ec, led_mic_mute); + + return thinkpad_t14s_audio_led_set(ec, T14S_EC_MIC_MUTE_LED, brightness); +} + +static enum led_brightness thinkpad_t14s_spk_mute_led_get(struct led_class= dev *led_cdev) +{ + struct thinkpad_t14s_ec *ec =3D container_of(led_cdev, + struct thinkpad_t14s_ec, led_spk_mute); + + return thinkpad_t14s_audio_led_get(ec, T14S_EC_SPK_MUTE_LED); +} + +static int thinkpad_t14s_spk_mute_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct thinkpad_t14s_ec *ec =3D container_of(led_cdev, + struct thinkpad_t14s_ec, led_spk_mute); + + return thinkpad_t14s_audio_led_set(ec, T14S_EC_SPK_MUTE_LED, brightness); +} + +static int thinkpad_t14s_kbd_audio_led_probe(struct thinkpad_t14s_ec *ec) +{ + int ret; + + ec->led_mic_mute.name =3D "platform::micmute"; + ec->led_mic_mute.max_brightness =3D 1, + ec->led_mic_mute.default_trigger =3D "audio-micmute", + ec->led_mic_mute.brightness_set_blocking =3D thinkpad_t14s_mic_mute_led_s= et; + ec->led_mic_mute.brightness_get =3D thinkpad_t14s_mic_mute_led_get; + + ec->led_spk_mute.name =3D "platform::mute"; + ec->led_spk_mute.max_brightness =3D 1, + ec->led_spk_mute.default_trigger =3D "audio-mute", + ec->led_spk_mute.brightness_set_blocking =3D thinkpad_t14s_spk_mute_led_s= et; + ec->led_spk_mute.brightness_get =3D thinkpad_t14s_spk_mute_led_get; + + ret =3D devm_led_classdev_register(ec->dev, &ec->led_mic_mute); + if (ret) + return ret; + + return devm_led_classdev_register(ec->dev, &ec->led_spk_mute); +} + +static const struct key_entry thinkpad_t14s_keymap[] =3D { + T14S_EC_KEY_ENTRY(FN_4, KEY_SLEEP), + T14S_EC_KEY_ENTRY(FN_N, KEY_VENDOR), + T14S_EC_KEY_ENTRY(FN_F4, KEY_MICMUTE), + T14S_EC_KEY_ENTRY(FN_F7, KEY_SWITCHVIDEOMODE), + T14S_EC_KEY_ENTRY(FN_F8, KEY_PERFORMANCE), + T14S_EC_KEY_ENTRY(FN_F10, KEY_SELECTIVE_SCREENSHOT), + T14S_EC_KEY_ENTRY(FN_F11, KEY_LINK_PHONE), + T14S_EC_KEY_ENTRY(FN_F12, KEY_BOOKMARKS), + T14S_EC_KEY_ENTRY(FN_SPACE, KEY_KBDILLUMTOGGLE), + T14S_EC_KEY_ENTRY(FN_ESC, KEY_FN_ESC), + T14S_EC_KEY_ENTRY(FN_TAB, KEY_ZOOM), + T14S_EC_KEY_ENTRY(FN_RIGHT_SHIFT, KEY_FN_RIGHT_SHIFT), + T14S_EC_KEY_ENTRY(TP_DOUBLE_TAP, KEY_PROG4), + { KE_END } +}; + +static int thinkpad_t14s_input_probe(struct thinkpad_t14s_ec *ec) +{ + int ret; + + ec->inputdev =3D devm_input_allocate_device(ec->dev); + if (!ec->inputdev) + return -ENOMEM; + + ec->inputdev->name =3D "ThinkPad Extra Buttons"; + ec->inputdev->phys =3D "thinkpad/input0"; + ec->inputdev->id.bustype =3D BUS_HOST; + ec->inputdev->dev.parent =3D ec->dev; + + ret =3D sparse_keymap_setup(ec->inputdev, thinkpad_t14s_keymap, NULL); + if (ret) + return ret; + + return input_register_device(ec->inputdev); +} + +static irqreturn_t thinkpad_t14s_ec_irq_handler(int irq, void *data) +{ + struct thinkpad_t14s_ec *ec =3D data; + int ret; + u8 val; + + ret =3D thinkpad_t14s_ec_read_evt(ec, &val); + if (ret < 0) { + dev_err(ec->dev, "Failed to read event\n"); + return IRQ_HANDLED; + } + + switch (val) { + case T14S_EC_EVT_NONE: + break; + case T14S_EC_EVT_KEY_FN_SPACE: + thinkpad_t14s_kbd_bl_update(ec); + fallthrough; + case T14S_EC_EVT_KEY_FN_F4: + case T14S_EC_EVT_KEY_FN_F7: + case T14S_EC_EVT_KEY_FN_4: + case T14S_EC_EVT_KEY_FN_F8: + case T14S_EC_EVT_KEY_FN_F12: + case T14S_EC_EVT_KEY_FN_TAB: + case T14S_EC_EVT_KEY_FN_F10: + case T14S_EC_EVT_KEY_FN_N: + case T14S_EC_EVT_KEY_FN_F11: + case T14S_EC_EVT_KEY_FN_ESC: + case T14S_EC_EVT_KEY_FN_RIGHT_SHIFT: + case T14S_EC_EVT_KEY_TP_DOUBLE_TAP: + sparse_keymap_report_event(ec->inputdev, + T14S_EC_KEY_EVT_OFFSET + val, 1, true); + break; + case T14S_EC_EVT_AC_CONNECTED: + dev_dbg(ec->dev, "AC connected\n"); + break; + case T14S_EC_EVT_AC_DISCONNECTED: + dev_dbg(ec->dev, "AC disconnected\n"); + break; + case T14S_EC_EVT_KEY_POWER: + dev_dbg(ec->dev, "power button\n"); + break; + case T14S_EC_EVT_LID_OPEN: + dev_dbg(ec->dev, "LID open\n"); + break; + case T14S_EC_EVT_LID_CLOSED: + dev_dbg(ec->dev, "LID closed\n"); + break; + case T14S_EC_EVT_THERMAL_TZ40: + dev_dbg(ec->dev, "Thermal Zone 40 Status Change Event (CPU/GPU)\n"); + break; + case T14S_EC_EVT_THERMAL_TZ42: + dev_dbg(ec->dev, "Thermal Zone 42 Status Change Event (Battery)\n"); + break; + case T14S_EC_EVT_THERMAL_TZ39: + dev_dbg(ec->dev, "Thermal Zone 39 Status Change Event (CPU/GPU)\n"); + break; + case T14S_EC_EVT_KEY_FN_G: + dev_dbg(ec->dev, "FN + G - toggle double-tapping\n"); + break; + case T14S_EC_EVT_KEY_FN_L: + dev_dbg(ec->dev, "FN + L - low performance mode\n"); + break; + case T14S_EC_EVT_KEY_FN_M: + dev_dbg(ec->dev, "FN + M - medium performance mode\n"); + break; + case T14S_EC_EVT_KEY_FN_H: + dev_dbg(ec->dev, "FN + H - high performance mode\n"); + break; + case T14S_EC_EVT_KEY_FN_T: + dev_dbg(ec->dev, "FN + T - toggle intelligent cooling mode\n"); + break; + case T14S_EC_EVT_KEY_FN_D: + dev_dbg(ec->dev, "FN + D - toggle privacy guard mode\n"); + break; + default: + dev_info(ec->dev, "Unknown EC event: 0x%02x\n", val); + break; + } + + return IRQ_HANDLED; +} + +static int thinkpad_t14s_ec_probe(struct i2c_client *client) +{ + struct device *dev =3D &client->dev; + struct thinkpad_t14s_ec *ec; + int ret; + + ec =3D devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL); + if (!ec) + return -ENOMEM; + + ec->dev =3D dev; + + ec->regmap =3D devm_regmap_init(dev, &thinkpad_t14s_ec_regmap_bus, + ec, &thinkpad_t14s_ec_regmap_config); + if (IS_ERR(ec->regmap)) + return dev_err_probe(dev, PTR_ERR(ec->regmap), + "Failed to init regmap\n"); + + ret =3D devm_request_threaded_irq(dev, client->irq, NULL, + thinkpad_t14s_ec_irq_handler, + IRQF_ONESHOT, dev_name(dev), ec); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to get IRQ\n"); + + ret =3D thinkpad_t14s_leds_probe(ec); + if (ret < 0) + return ret; + + ret =3D thinkpad_t14s_kbd_backlight_probe(ec); + if (ret < 0) + return ret; + + ret =3D thinkpad_t14s_kbd_audio_led_probe(ec); + if (ret < 0) + return ret; + + ret =3D thinkpad_t14s_input_probe(ec); + if (ret < 0) + return ret; + + /* + * Disable wakeup support by default, because the driver currently does + * not support masking any events and the laptop should not wake up when + * the LID is closed. + */ + device_wakeup_disable(dev); + + return 0; +} + +static const struct of_device_id thinkpad_t14s_ec_of_match[] =3D { + { .compatible =3D "lenovo,thinkpad-t14s-ec" }, + {} +}; +MODULE_DEVICE_TABLE(of, thinkpad_t14s_ec_of_match); + +static const struct i2c_device_id thinkpad_t14s_ec_i2c_id_table[] =3D { + { "thinkpad-t14s-ec", }, + {} +}; +MODULE_DEVICE_TABLE(i2c, thinkpad_t14s_ec_i2c_id_table); + +static struct i2c_driver thinkpad_t14s_ec_i2c_driver =3D { + .driver =3D { + .name =3D "thinkpad-t14s-ec", + .of_match_table =3D thinkpad_t14s_ec_of_match, + }, + .probe =3D thinkpad_t14s_ec_probe, + .id_table =3D thinkpad_t14s_ec_i2c_id_table, +}; +module_i2c_driver(thinkpad_t14s_ec_i2c_driver); + +MODULE_AUTHOR("Sebastian Reichel "); +MODULE_DESCRIPTION("Lenovo Thinkpad T14s Embedded Controller"); +MODULE_LICENSE("GPL"); --=20 2.51.0 From nobody Tue Sep 9 16:36:52 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EEA7F2E7F3A; Mon, 8 Sep 2025 22:35:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757370960; cv=none; b=udK2mB0dbWj+Eup7bfVTveEkpCI3YTJCOTbdEEzAbi03lfyE1d7lVE9nkqpLFhs5p486rT58D1EIXb7cRNXZDgax36gMT+3gSA92bNhO9GebzMv90dhw9vZG5N/CLxStMpq3KKyRwQxSTmySiIQ1fsZKxxx8ZJTgrKb90yE4HjU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757370960; c=relaxed/simple; bh=dSo8PyCv5W3wiR8ABae/XBucYd73xpUbLl7qWfh1KCs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=E/0gpl2OZmD4GQ0RAsEmoTaC1+BEqOV+G2i3VUCMLOxmFBvQZ9Ai4UsvGc14aJLA/5EHdfvCL+egXnpDQqA5uRAjU7LEZiSYjhZ3JQe3LngIIs3n9l1GusyhJ7OpIvIbDb87ahXWMHIx24ZUJBbpZSGgzDnXSHRlHtDPKJl6MH4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jTA4gPp+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jTA4gPp+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 76309C4CEF9; Mon, 8 Sep 2025 22:35:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1757370959; bh=dSo8PyCv5W3wiR8ABae/XBucYd73xpUbLl7qWfh1KCs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jTA4gPp+ocKNmBDCeGmINDHmBHy+lIHT3uhGbvYbyaNA0SGZXpZSvSwzGiJka5o/a G6Gt0NwUQCqKj8iC311VexXJ9MrDU7jafO0ZEoZd0zEQhibJzVUNmBVMt93pZj3JlC IKN351YNKJJvBv9ENA57y3/mgXaE8O6D85Ig/hzxlxLz85vUaLbgHOD27nXaZmspFO iYL6qKaAeQRI4MNyAI4uLYNDYpAI3ACQFgkTrQdfi4sJAHD/WZQ5pNz92qYdIIZoLc 6wbn9w8yOdT26Rf9ChWBGcpJ4dWu5UJ83FYPVCpp6JraSKFBSOtVyA90UUDXRXaSSn 7UcD3Hj32LNiQ== Received: by venus (Postfix, from userid 1000) id 930A5180B28; Tue, 09 Sep 2025 00:35:57 +0200 (CEST) From: Sebastian Reichel Date: Tue, 09 Sep 2025 00:35:52 +0200 Subject: [PATCH v4 3/3] arm64: dts: qcom: x1e80100-t14s: add EC Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250909-thinkpad-t14s-ec-v4-3-caf6159daaee@collabora.com> References: <20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com> In-Reply-To: <20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com> To: Sebastian Reichel , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Hans de Goede , =?utf-8?q?Ilpo_J=C3=A4rvinen?= , Bryan O'Donoghue , Bjorn Andersson , Konrad Dybcio , Mark Pearson Cc: "Derek J. Clark" , Henrique de Moraes Holschuh , Neil Armstrong , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-arm-msm@vger.kernel.org, Konrad Dybcio X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1616; i=sebastian.reichel@collabora.com; h=from:subject:message-id; bh=dSo8PyCv5W3wiR8ABae/XBucYd73xpUbLl7qWfh1KCs=; b=owEBbQKS/ZANAwAKAdju1/PIO/qaAcsmYgBov1pN4xXXWqqAUYl/XplCfBRpZhO0iboVVnUyH 84Ht5jLde2JAjMEAAEKAB0WIQTvZg0HRj+Lcmp5VBPY7tfzyDv6mgUCaL9aTQAKCRDY7tfzyDv6 mieND/98CMoNikOQp2nJAi1uy5oRMwdxN+n/3m9Mp+qzQ3gPZtsIHOWQEGQrrqHFW4mbmqIEipY yraXvOEjkJFzFNWGoX8z/p3pnFzICyThSAddkTq84jXjWCwSKmRfx14QXtVHXsahGN2HVmXXVVx 7DdSEUUyTW37BygroH05SZnaiyjzf5nY/AFYvQbED0lo4FIK7q1nasq4S073B+qJyYKuUMFbMko 2obFwFvQZLc5Nc1s88tb0aP+ptjX0nb+67aEeYIwMJhylm7SujjUEWe5r3mYUtlFuCGTAwl0ONA me8jYmP6a4jY/svOkl2WSSbfMsodP9jacuOchKz94TYNCtccbeZyHcla5bt67t9GwLcgxKGerQr gnfbElfQ01aNnkz9utwHp+pYoveLBkDI4rNItKHc9/0hyBj8SH6ipgXE0g+UFBjyV3b5wT2wx7u 8VEt3crPBZRLo2K7UavqTGCPSAojLjS+W5shGY01Bk1p59ydUlHW/ncFJlJcLfyB0ajwjyVD+ge CFqSAvPQB06fI0ic3LIQ80dZUGLTnVtuPUC0CRKWPnm08Fpm5UejClf/eNOVicPc/lvs2abjyt+ OWq5yGClv4Wa2G1momMKTL3h2clzsYlU2skmvSu4F8V6npaCKUVBl/ofZQJZsW4Sw5Cr5YyV/8f rnrnLt7I81l1PgA== X-Developer-Key: i=sebastian.reichel@collabora.com; a=openpgp; fpr=EF660D07463F8B726A795413D8EED7F3C83BFA9A Describe ThinkPad Embedded Controller in the T14s device tree, which adds LED and special key support. Tested-by: Neil Armstrong # on Thinkpad T14S OL= ED Reviewed-by: Bryan O'Donoghue Reviewed-by: Konrad Dybcio Signed-off-by: Sebastian Reichel --- .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 24 ++++++++++++++++++= ++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/= arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi index ac1dddf27da30e6a9f7e1d1ecbd5192bf2d0671e..f70489aba870289edbcf84ec22f= db004e010868b 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi @@ -887,6 +887,24 @@ eusb6_repeater: redriver@4f { }; }; =20 +&i2c6 { + clock-frequency =3D <400000>; + + status =3D "okay"; + + embedded-controller@28 { + compatible =3D "lenovo,thinkpad-t14s-ec"; + reg =3D <0x28>; + + interrupts-extended =3D <&tlmm 66 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-0 =3D <&ec_int_n_default>; + pinctrl-names =3D "default"; + + wakeup-source; + }; +}; + &i2c7 { clock-frequency =3D <400000>; =20 @@ -1267,6 +1285,12 @@ &tlmm { <72 2>, /* Secure EC I2C connection (?) */ <238 1>; /* UFS Reset */ =20 + ec_int_n_default: ec-int-n-state { + pins =3D "gpio66"; + function =3D "gpio"; + bias-disable; + }; + eusb3_reset_n: eusb3-reset-n-state { pins =3D "gpio6"; function =3D "gpio"; --=20 2.51.0