* [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver
@ 2025-09-18 21:20 Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC Sebastian Reichel
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Sebastian Reichel @ 2025-09-18 21:20 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Mark Pearson
Cc: Derek J. Clark, Henrique de Moraes Holschuh, Neil Armstrong,
devicetree, linux-kernel, platform-driver-x86, linux-arm-msm,
Krzysztof Kozlowski, Konrad Dybcio
Introduce driver for the ThinkPad T14s Gen6 Snapdragon EC. In theory
it seems to be compatible with the ThinkPad ACPI driver, but these
devices are booted with device tree. As the name implies, the existing
ThinkPad ACPI driver only supports the ACPI interface. Looking at
the implementation, the ACPI DSDT contains many mapping functions
to translate the low level I2C messages into the interface used by
the ThinkPad ACPI driver. Adding DT support to the ThinkPad ACPI driver
would require adding all those translation functions, which would add
more or less the same amount of code as writing a separate driver using
the low level interface directly. I don't think it's sensible to make
the existing ACPI driver even more complicated, so I went for a separate
driver.
I managed to get system LEDs, audio LEDs, extra keys and the keyboard
backlight control working. The EC also seems to be used for some thermal
bits, which I haven't looked into deeply. As far as I understand most
thermal and fan control is handled by a different controller
(0x36@i2c5) anyways.
Apart from that the EC is involved in proper system suspend, which
is something I do not yet understand (I don't have any documentation
apart from the dis-assembled DSDT and existing ACPI driver). Right
now I disabled wake capabilities for the IRQ, since it would wake
up the system when closing the LID. Hopefully a way to mask specific
events will be found in the future.
Changes in v5:
- Link to v4: https://lore.kernel.org/r/20250909-thinkpad-t14s-ec-v4-0-caf6159daaee@collabora.com
- Change order of u8 buf[4] in a couple of places to be closer to for reverse Christmas order
- Drop thinkpad_ prefix from all symbols
Changes in v4:
- Link to v3: https://lore.kernel.org/r/20250906-thinkpad-t14s-ec-v3-0-3ce6ec21ae89@collabora.com
- Add thermal zone event IDs and handle them with a custom dev_dbg() message
- Use lower case letters in all hexadecimal numbers
- Improve comment when userspace does not choose blink timings
- Change logic to use == instead of != comparison for led cache check
Changes in v3:
- Link to v2: https://lore.kernel.org/r/20250905-thinkpad-t14s-ec-v2-0-7da5d70aa423@collabora.com
- Add <linux/container_of.h> include (Ilpo Järvinen)
- Add <linux/dev_printk.h> include (Ilpo Järvinen)
- Add <linux/interrupt.h> include (Ilpo Järvinen)
- Align CMD defines (Ilpo Järvinen)
- Rename thinkpad_t14s_led_set() to thinkpad_t14s_led_brightness_set() (Ilpo Järvinen)
- Replace && with & in thinkpad_t14s_audio_led_get(); good catch! (Konrad Dybcio)
- Use regmap_assign_bits in thinkpad_t14s_audio_led_set (Konrad Dybcio)
- Directly return input_register_device() at the end of
thinkpad_t14s_input_probe (Konrad Dybcio)
- Remove THINKPAD_ prefix (Konrad Dybcio)
- Also use T14S_EC_ prefix for LEDs states (myself)
- Collect Reviewed-by tags
Changes in v2:
- Link to v1: https://lore.kernel.org/r/20250831-thinkpad-t14s-ec-v1-0-6e06a07afe0f@collabora.com
- Apply Reviewed-by tags from Bryan O'Donoghue
- Apply Tested-by tags from Neil Armstrong
- Update DT binding description, location and examples (Krzysztof Kozlowski)
- Add missing wakeup-source to DT binding (Rob Herring Bot)
- Update DTS newlines, pinctrl order, nodename (Konrad Dybcio)
- Updates to EC driver
- Add bits.h and bitfield.h include (Ilpo Järvinen)
- Drop mutex.h (myself, leftover from development)
- Drop DEBUG define (Ilpo Järvinen)
- Add THINKPAD_T14S_EC_BLINK_RATE_ON_OFF_MS (Bryan O'Donoghue, Ilpo Järvinen)
- Add THINKPAD_T14S_EC_KEY_EVT_OFFSET (Ilpo Järvinen)
- Add THINKPAD_T14S_EC_KEY_ENTRY (myself, to keep line length sane
after THINKPAD_T14S_EC_KEY_EVT_OFFSET)
- Align values of thinkpad_t14s_ec_led_status_t (Ilpo Järvinen)
- Use u8 instead of char for I2C command buffers (Ilpo Järvinen)
- Add some more newlines after goto/return (Bryan O'Donoghue)
- Use FIELD_PREP/FIELD_GET instead of _SHIFT (Ilpo Järvinen)
- Explicitly map to LED_ON/LED_OFF in audio_led_get (Ilpo Järvinen)
- Add missing , after .driver.of_match_table (Ilpo Järvinen)
- Change from KEY_MODE to KEY_PERFORMANCE (myself after seeing a patch
for HID lenovo being sent to the list)
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
Sebastian Reichel (3):
dt-bindings: platform: Add Lenovo Thinkpad T14s EC
platform: arm64: thinkpad-t14s-ec: new driver
arm64: dts: qcom: x1e80100-t14s: add EC
.../lenovo,thinkpad-t14s-ec.yaml | 50 ++
MAINTAINERS | 6 +
.../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi | 24 +
drivers/platform/arm64/Kconfig | 20 +
drivers/platform/arm64/Makefile | 1 +
drivers/platform/arm64/lenovo-thinkpad-t14s.c | 616 +++++++++++++++++++++
6 files changed, 717 insertions(+)
---
base-commit: f83ec76bf285bea5727f478a68b894f5543ca76e
change-id: 20250831-thinkpad-t14s-ec-ddeb23dbdafb
Best regards,
--
Sebastian Reichel <sebastian.reichel@collabora.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC
2025-09-18 21:20 [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
@ 2025-09-18 21:20 ` Sebastian Reichel
2025-09-19 14:40 ` Rob Herring
2025-09-18 21:20 ` [PATCH v5 2/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Sebastian Reichel @ 2025-09-18 21:20 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Mark Pearson
Cc: Derek J. Clark, Henrique de Moraes Holschuh, Neil Armstrong,
devicetree, linux-kernel, platform-driver-x86, linux-arm-msm,
Krzysztof Kozlowski
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 <bryan.odonoghue@linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
.../lenovo,thinkpad-t14s-ec.yaml | 50 ++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/Documentation/devicetree/bindings/embedded-controller/lenovo,thinkpad-t14s-ec.yaml b/Documentation/devicetree/bindings/embedded-controller/lenovo,thinkpad-t14s-ec.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c87ccb5b30868c7a616ec08b869286d627dd7406
--- /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-t14s-ec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Lenovo Thinkpad T14s Embedded Controller
+
+maintainers:
+ - Sebastian Reichel <sre@kernel.org>
+
+description:
+ The Qualcomm Snapdragon-based Lenovo Thinkpad T14s has an Embedded Controller
+ (EC) which handles things such as keyboard backlight, LEDs or non-standard
+ 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 <dt-bindings/interrupt-controller/irq.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ embedded-controller@28 {
+ compatible = "lenovo,thinkpad-t14s-ec";
+ reg = <0x28>;
+ interrupts-extended = <&tlmm 66 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+ };
+...
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 2/3] platform: arm64: thinkpad-t14s-ec: new driver
2025-09-18 21:20 [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC Sebastian Reichel
@ 2025-09-18 21:20 ` Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 3/3] arm64: dts: qcom: x1e80100-t14s: add EC Sebastian Reichel
2025-09-23 8:40 ` [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Ilpo Järvinen
3 siblings, 0 replies; 7+ messages in thread
From: Sebastian Reichel @ 2025-09-18 21:20 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Mark Pearson
Cc: Derek J. Clark, Henrique de Moraes Holschuh, Neil Armstrong,
devicetree, linux-kernel, platform-driver-x86, linux-arm-msm
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 <neil.armstrong@linaro.org> # on Thinkpad T14S OLED
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
MAINTAINERS | 6 +
drivers/platform/arm64/Kconfig | 20 +
drivers/platform/arm64/Makefile | 1 +
drivers/platform/arm64/lenovo-thinkpad-t14s.c | 616 ++++++++++++++++++++++++++
4 files changed, 643 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index f6206963efbf0bdbe3efb9ad818637fc090d487f..5795323291b3a6b8e1d704f2242896bb008009a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25102,6 +25102,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
+THINKPAD T14S EMBEDDED CONTROLLER DRIVER
+M: Sebastian Reichel <sre@kernel.org>
+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 <mpearson-lenovo@squebb.ca>
L: platform-driver-x86@vger.kernel.org
diff --git a/drivers/platform/arm64/Kconfig b/drivers/platform/arm64/Kconfig
index 06288aebc5599435065a37f8dacd046b5def80bd..10f905d7d6bfa5fad30a0689d3a20481268c781e 100644
--- a/drivers/platform/arm64/Kconfig
+++ b/drivers/platform/arm64/Kconfig
@@ -70,4 +70,24 @@ config EC_LENOVO_YOGA_C630
Say M or Y here to include this support.
+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/Makefile
index 46a99eba3264cc40e812567d1533bb86031a6af3..60c131cff6a15bb51a49c9edab95badf513ee0f6 100644
--- a/drivers/platform/arm64/Makefile
+++ b/drivers/platform/arm64/Makefile
@@ -8,3 +8,4 @@
obj-$(CONFIG_EC_ACER_ASPIRE1) += acer-aspire1-ec.o
obj-$(CONFIG_EC_HUAWEI_GAOKUN) += huawei-gaokun-ec.o
obj-$(CONFIG_EC_LENOVO_YOGA_C630) += lenovo-yoga-c630.o
+obj-$(CONFIG_EC_LENOVO_THINKPAD_T14S) += lenovo-thinkpad-t14s.o
diff --git a/drivers/platform/arm64/lenovo-thinkpad-t14s.c b/drivers/platform/arm64/lenovo-thinkpad-t14s.c
new file mode 100644
index 0000000000000000000000000000000000000000..f721763e13cc8aedceb615b9b2c07e54fd6db108
--- /dev/null
+++ b/drivers/platform/arm64/lenovo-thinkpad-t14s.c
@@ -0,0 +1,616 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2025, Sebastian Reichel
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/container_of.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/lockdep.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#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 t14s_ec_led_status_t {
+ T14S_EC_LED_OFF = 0x00,
+ T14S_EC_LED_ON = 0x80,
+ T14S_EC_LED_BLINK = 0xc0,
+};
+
+struct t14s_ec_led_classdev {
+ struct led_classdev led_classdev;
+ int led;
+ enum t14s_ec_led_status_t cache;
+ struct t14s_ec *ec;
+};
+
+struct t14s_ec {
+ struct regmap *regmap;
+ struct device *dev;
+ struct t14s_ec_led_classdev led_pwr_btn;
+ struct t14s_ec_led_classdev led_chrg_orange;
+ struct t14s_ec_led_classdev led_chrg_white;
+ struct 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 t14s_ec_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 0xff,
+};
+
+static int t14s_ec_write(void *context, unsigned int reg,
+ unsigned int val)
+{
+ struct t14s_ec *ec = context;
+ struct i2c_client *client = to_i2c_client(ec->dev);
+ u8 buf[5] = {T14S_EC_CMD_ECWR, reg, 0x00, 0x01, val};
+ int ret;
+
+ ret = i2c_master_send(client, buf, sizeof(buf));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int t14s_ec_read(void *context, unsigned int reg,
+ unsigned int *val)
+{
+ struct t14s_ec *ec = context;
+ struct i2c_client *client = to_i2c_client(ec->dev);
+ u8 buf[4] = {T14S_EC_CMD_ECRD, reg, 0x00, 0x01};
+ struct i2c_msg request, response;
+ u8 result;
+ int ret;
+
+ request.addr = client->addr;
+ request.flags = I2C_M_STOP;
+ request.len = sizeof(buf);
+ request.buf = buf;
+ response.addr = client->addr;
+ response.flags = I2C_M_RD;
+ response.len = 1;
+ response.buf = &result;
+
+ i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
+
+ ret = __i2c_transfer(client->adapter, &request, 1);
+ if (ret < 0)
+ goto out;
+
+ ret = __i2c_transfer(client->adapter, &response, 1);
+ if (ret < 0)
+ goto out;
+
+ *val = result;
+ ret = 0;
+
+out:
+ i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
+ return ret;
+}
+
+static const struct regmap_bus t14s_ec_regmap_bus = {
+ .reg_write = t14s_ec_write,
+ .reg_read = t14s_ec_read,
+};
+
+static int t14s_ec_read_evt(struct t14s_ec *ec, u8 *val)
+{
+ struct i2c_client *client = to_i2c_client(ec->dev);
+ u8 buf[4] = {T14S_EC_CMD_EVT, 0x00, 0x00, 0x01};
+ struct i2c_msg request, response;
+ int ret;
+
+ request.addr = client->addr;
+ request.flags = I2C_M_STOP;
+ request.len = sizeof(buf);
+ request.buf = buf;
+ response.addr = client->addr;
+ response.flags = I2C_M_RD;
+ response.len = 1;
+ response.buf = val;
+
+ i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
+
+ ret = __i2c_transfer(client->adapter, &request, 1);
+ if (ret < 0)
+ goto out;
+
+ ret = __i2c_transfer(client->adapter, &response, 1);
+ if (ret < 0)
+ goto out;
+
+ ret = 0;
+
+out:
+ i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
+ return ret;
+}
+
+static int t14s_led_set_status(struct t14s_ec *ec,
+ struct t14s_ec_led_classdev *led,
+ const enum t14s_ec_led_status_t ledstatus)
+{
+ int ret;
+
+ ret = regmap_write(ec->regmap, T14S_EC_REG_LED,
+ led->led | ledstatus);
+ if (ret < 0)
+ return ret;
+
+ led->cache = ledstatus;
+ return 0;
+}
+
+static int t14s_led_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct t14s_ec_led_classdev *led = container_of(led_cdev,
+ struct t14s_ec_led_classdev, led_classdev);
+ enum t14s_ec_led_status_t new_state;
+
+ if (brightness == LED_OFF)
+ new_state = T14S_EC_LED_OFF;
+ else if (led->cache == T14S_EC_LED_BLINK)
+ new_state = T14S_EC_LED_BLINK;
+ else
+ new_state = T14S_EC_LED_ON;
+
+ return t14s_led_set_status(led->ec, led, new_state);
+}
+
+static int t14s_led_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ struct t14s_ec_led_classdev *led = container_of(led_cdev,
+ struct t14s_ec_led_classdev, led_classdev);
+
+ if (*delay_on == 0 && *delay_off == 0) {
+ /* Userspace does not provide a blink rate; we can choose it */
+ *delay_on = T14S_EC_BLINK_RATE_ON_OFF_MS;
+ *delay_off = T14S_EC_BLINK_RATE_ON_OFF_MS;
+ } else if ((*delay_on != T14S_EC_BLINK_RATE_ON_OFF_MS) ||
+ (*delay_off != T14S_EC_BLINK_RATE_ON_OFF_MS))
+ return -EINVAL;
+
+ return t14s_led_set_status(led->ec, led, T14S_EC_LED_BLINK);
+}
+
+static int t14s_init_led(struct t14s_ec *ec, struct t14s_ec_led_classdev *led,
+ u8 id, const char *name)
+{
+ led->led_classdev.name = name;
+ led->led_classdev.flags = LED_RETAIN_AT_SHUTDOWN;
+ led->led_classdev.max_brightness = 1;
+ led->led_classdev.brightness_set_blocking = t14s_led_brightness_set;
+ led->led_classdev.blink_set = t14s_led_blink_set;
+ led->ec = ec;
+ led->led = id;
+
+ return devm_led_classdev_register(ec->dev, &led->led_classdev);
+}
+
+static int t14s_leds_probe(struct t14s_ec *ec)
+{
+ int ret;
+
+ ret = t14s_init_led(ec, &ec->led_pwr_btn, 0, "platform::power");
+ if (ret)
+ return ret;
+
+ ret = t14s_init_led(ec, &ec->led_chrg_orange, 1,
+ "platform:amber:battery-charging");
+ if (ret)
+ return ret;
+
+ ret = t14s_init_led(ec, &ec->led_chrg_white, 2,
+ "platform:white:battery-full");
+ if (ret)
+ return ret;
+
+ ret = t14s_init_led(ec, &ec->led_lid_logo_dot, 10,
+ "platform::lid_logo_dot");
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int t14s_kbd_bl_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec,
+ kbd_backlight);
+ int ret;
+ u8 val;
+
+ val = FIELD_PREP(T14S_EC_KBD_BL1_MASK, brightness);
+ ret = regmap_update_bits(ec->regmap, T14S_EC_REG_KBD_BL1,
+ T14S_EC_KBD_BL1_MASK, val);
+ if (ret < 0)
+ return ret;
+
+ val = FIELD_PREP(T14S_EC_KBD_BL2_MASK, brightness);
+ ret = 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 t14s_kbd_bl_get(struct led_classdev *led_cdev)
+{
+ struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec,
+ kbd_backlight);
+ unsigned int val;
+ int ret;
+
+ ret = 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 t14s_kbd_bl_update(struct t14s_ec *ec)
+{
+ enum led_brightness brightness = t14s_kbd_bl_get(&ec->kbd_backlight);
+
+ led_classdev_notify_brightness_hw_changed(&ec->kbd_backlight, brightness);
+}
+
+static int t14s_kbd_backlight_probe(struct t14s_ec *ec)
+{
+ ec->kbd_backlight.name = "platform::kbd_backlight";
+ ec->kbd_backlight.flags = LED_BRIGHT_HW_CHANGED;
+ ec->kbd_backlight.max_brightness = 2;
+ ec->kbd_backlight.brightness_set_blocking = t14s_kbd_bl_set;
+ ec->kbd_backlight.brightness_get = t14s_kbd_bl_get;
+
+ return devm_led_classdev_register(ec->dev, &ec->kbd_backlight);
+}
+
+static enum led_brightness t14s_audio_led_get(struct t14s_ec *ec, u8 led_bit)
+{
+ unsigned int val;
+ int ret;
+
+ ret = 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 t14s_audio_led_set(struct t14s_ec *ec,
+ u8 led_mask,
+ enum led_brightness brightness)
+{
+ return regmap_assign_bits(ec->regmap, T14S_EC_REG_AUD, led_mask, brightness > 0);
+}
+
+static enum led_brightness t14s_mic_mute_led_get(struct led_classdev *led_cdev)
+{
+ struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec,
+ led_mic_mute);
+
+ return t14s_audio_led_get(ec, T14S_EC_MIC_MUTE_LED);
+}
+
+static int t14s_mic_mute_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec,
+ led_mic_mute);
+
+ return t14s_audio_led_set(ec, T14S_EC_MIC_MUTE_LED, brightness);
+}
+
+static enum led_brightness t14s_spk_mute_led_get(struct led_classdev *led_cdev)
+{
+ struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec,
+ led_spk_mute);
+
+ return t14s_audio_led_get(ec, T14S_EC_SPK_MUTE_LED);
+}
+
+static int t14s_spk_mute_led_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct t14s_ec *ec = container_of(led_cdev, struct t14s_ec,
+ led_spk_mute);
+
+ return t14s_audio_led_set(ec, T14S_EC_SPK_MUTE_LED, brightness);
+}
+
+static int t14s_kbd_audio_led_probe(struct t14s_ec *ec)
+{
+ int ret;
+
+ ec->led_mic_mute.name = "platform::micmute";
+ ec->led_mic_mute.max_brightness = 1,
+ ec->led_mic_mute.default_trigger = "audio-micmute",
+ ec->led_mic_mute.brightness_set_blocking = t14s_mic_mute_led_set;
+ ec->led_mic_mute.brightness_get = t14s_mic_mute_led_get;
+
+ ec->led_spk_mute.name = "platform::mute";
+ ec->led_spk_mute.max_brightness = 1,
+ ec->led_spk_mute.default_trigger = "audio-mute",
+ ec->led_spk_mute.brightness_set_blocking = t14s_spk_mute_led_set;
+ ec->led_spk_mute.brightness_get = t14s_spk_mute_led_get;
+
+ ret = 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 t14s_keymap[] = {
+ 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 t14s_input_probe(struct t14s_ec *ec)
+{
+ int ret;
+
+ ec->inputdev = devm_input_allocate_device(ec->dev);
+ if (!ec->inputdev)
+ return -ENOMEM;
+
+ ec->inputdev->name = "ThinkPad Extra Buttons";
+ ec->inputdev->phys = "thinkpad/input0";
+ ec->inputdev->id.bustype = BUS_HOST;
+ ec->inputdev->dev.parent = ec->dev;
+
+ ret = sparse_keymap_setup(ec->inputdev, t14s_keymap, NULL);
+ if (ret)
+ return ret;
+
+ return input_register_device(ec->inputdev);
+}
+
+static irqreturn_t t14s_ec_irq_handler(int irq, void *data)
+{
+ struct t14s_ec *ec = data;
+ int ret;
+ u8 val;
+
+ ret = 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:
+ 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 t14s_ec_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct t14s_ec *ec;
+ int ret;
+
+ ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL);
+ if (!ec)
+ return -ENOMEM;
+
+ ec->dev = dev;
+
+ ec->regmap = devm_regmap_init(dev, &t14s_ec_regmap_bus,
+ ec, &t14s_ec_regmap_config);
+ if (IS_ERR(ec->regmap))
+ return dev_err_probe(dev, PTR_ERR(ec->regmap),
+ "Failed to init regmap\n");
+
+ ret = devm_request_threaded_irq(dev, client->irq, NULL,
+ 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 = t14s_leds_probe(ec);
+ if (ret < 0)
+ return ret;
+
+ ret = t14s_kbd_backlight_probe(ec);
+ if (ret < 0)
+ return ret;
+
+ ret = t14s_kbd_audio_led_probe(ec);
+ if (ret < 0)
+ return ret;
+
+ ret = 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 t14s_ec_of_match[] = {
+ { .compatible = "lenovo,thinkpad-t14s-ec" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, t14s_ec_of_match);
+
+static const struct i2c_device_id t14s_ec_i2c_id_table[] = {
+ { "thinkpad-t14s-ec", },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, t14s_ec_i2c_id_table);
+
+static struct i2c_driver t14s_ec_i2c_driver = {
+ .driver = {
+ .name = "thinkpad-t14s-ec",
+ .of_match_table = t14s_ec_of_match,
+ },
+ .probe = t14s_ec_probe,
+ .id_table = t14s_ec_i2c_id_table,
+};
+module_i2c_driver(t14s_ec_i2c_driver);
+
+MODULE_AUTHOR("Sebastian Reichel <sre@kernel.org>");
+MODULE_DESCRIPTION("Lenovo Thinkpad T14s Embedded Controller");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 3/3] arm64: dts: qcom: x1e80100-t14s: add EC
2025-09-18 21:20 [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 2/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
@ 2025-09-18 21:20 ` Sebastian Reichel
2025-09-23 8:40 ` [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Ilpo Järvinen
3 siblings, 0 replies; 7+ messages in thread
From: Sebastian Reichel @ 2025-09-18 21:20 UTC (permalink / raw)
To: Sebastian Reichel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Bjorn Andersson, Konrad Dybcio, Mark Pearson
Cc: Derek J. Clark, Henrique de Moraes Holschuh, Neil Armstrong,
devicetree, linux-kernel, platform-driver-x86, linux-arm-msm,
Konrad Dybcio
Describe ThinkPad Embedded Controller in the T14s device tree,
which adds LED and special key support.
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on Thinkpad T14S OLED
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
---
.../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..f70489aba870289edbcf84ec22fdb004e010868b 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 {
};
};
+&i2c6 {
+ clock-frequency = <400000>;
+
+ status = "okay";
+
+ embedded-controller@28 {
+ compatible = "lenovo,thinkpad-t14s-ec";
+ reg = <0x28>;
+
+ interrupts-extended = <&tlmm 66 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-0 = <&ec_int_n_default>;
+ pinctrl-names = "default";
+
+ wakeup-source;
+ };
+};
+
&i2c7 {
clock-frequency = <400000>;
@@ -1267,6 +1285,12 @@ &tlmm {
<72 2>, /* Secure EC I2C connection (?) */
<238 1>; /* UFS Reset */
+ ec_int_n_default: ec-int-n-state {
+ pins = "gpio66";
+ function = "gpio";
+ bias-disable;
+ };
+
eusb3_reset_n: eusb3-reset-n-state {
pins = "gpio6";
function = "gpio";
--
2.51.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC
2025-09-18 21:20 ` [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC Sebastian Reichel
@ 2025-09-19 14:40 ` Rob Herring
2025-09-23 8:41 ` Ilpo Järvinen
0 siblings, 1 reply; 7+ messages in thread
From: Rob Herring @ 2025-09-19 14:40 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Krzysztof Kozlowski, Conor Dooley, Hans de Goede,
Ilpo Järvinen, Bryan O'Donoghue, Bjorn Andersson,
Konrad Dybcio, Mark Pearson, Derek J. Clark,
Henrique de Moraes Holschuh, Neil Armstrong, devicetree,
linux-kernel, platform-driver-x86, linux-arm-msm,
Krzysztof Kozlowski
On Thu, Sep 18, 2025 at 11:20:26PM +0200, Sebastian Reichel wrote:
> 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.
s/platform/embedded-controller/ in the subject.
>
> Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> Signed-off-by: Sebastian Reichel <sre@kernel.org>
> ---
> .../lenovo,thinkpad-t14s-ec.yaml | 50 ++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
Acked-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver
2025-09-18 21:20 [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
` (2 preceding siblings ...)
2025-09-18 21:20 ` [PATCH v5 3/3] arm64: dts: qcom: x1e80100-t14s: add EC Sebastian Reichel
@ 2025-09-23 8:40 ` Ilpo Järvinen
3 siblings, 0 replies; 7+ messages in thread
From: Ilpo Järvinen @ 2025-09-23 8:40 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans de Goede,
Bryan O'Donoghue, Bjorn Andersson, Konrad Dybcio,
Mark Pearson, Sebastian Reichel
Cc: Derek J. Clark, Henrique de Moraes Holschuh, Neil Armstrong,
devicetree, linux-kernel, platform-driver-x86, linux-arm-msm,
Krzysztof Kozlowski, Konrad Dybcio
On Thu, 18 Sep 2025 23:20:25 +0200, Sebastian Reichel wrote:
> Introduce driver for the ThinkPad T14s Gen6 Snapdragon EC. In theory
> it seems to be compatible with the ThinkPad ACPI driver, but these
> devices are booted with device tree. As the name implies, the existing
> ThinkPad ACPI driver only supports the ACPI interface. Looking at
> the implementation, the ACPI DSDT contains many mapping functions
> to translate the low level I2C messages into the interface used by
> the ThinkPad ACPI driver. Adding DT support to the ThinkPad ACPI driver
> would require adding all those translation functions, which would add
> more or less the same amount of code as writing a separate driver using
> the low level interface directly. I don't think it's sensible to make
> the existing ACPI driver even more complicated, so I went for a separate
> driver.
>
> [...]
Thank you for your contribution, it has been applied to my local
review-ilpo-next branch. Note it will show up in the public
platform-drivers-x86/review-ilpo-next branch only once I've pushed my
local branch there, which might take a while.
The list of commits applied:
[1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC
commit: bee278e18e641a4bc11513b0fa8f5eb2667b8a32
[2/3] platform: arm64: thinkpad-t14s-ec: new driver
commit: 27221f91b83ff1435e550f57b8380a01bab0fc80
[3/3] arm64: dts: qcom: x1e80100-t14s: add EC
commit: 7de8353e082d179a241dc4a4129c5d6916803399
--
i.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC
2025-09-19 14:40 ` Rob Herring
@ 2025-09-23 8:41 ` Ilpo Järvinen
0 siblings, 0 replies; 7+ messages in thread
From: Ilpo Järvinen @ 2025-09-23 8:41 UTC (permalink / raw)
To: Rob Herring
Cc: Sebastian Reichel, Krzysztof Kozlowski, Conor Dooley,
Hans de Goede, Bryan O'Donoghue, Bjorn Andersson,
Konrad Dybcio, Mark Pearson, Derek J. Clark,
Henrique de Moraes Holschuh, Neil Armstrong, devicetree, LKML,
platform-driver-x86, linux-arm-msm, Krzysztof Kozlowski
On Fri, 19 Sep 2025, Rob Herring wrote:
> On Thu, Sep 18, 2025 at 11:20:26PM +0200, Sebastian Reichel wrote:
> > 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.
>
> s/platform/embedded-controller/ in the subject.
Thanks Rob.
I took care of that shortlog change while applying to the review-ilpo-next
branch so no need to submit v6 because of it.
> > Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> > Signed-off-by: Sebastian Reichel <sre@kernel.org>
> > ---
> > .../lenovo,thinkpad-t14s-ec.yaml | 50 ++++++++++++++++++++++
> > 1 file changed, 50 insertions(+)
>
> Acked-by: Rob Herring (Arm) <robh@kernel.org>
>
--
i.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-09-23 8:41 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-18 21:20 [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 1/3] dt-bindings: platform: Add Lenovo Thinkpad T14s EC Sebastian Reichel
2025-09-19 14:40 ` Rob Herring
2025-09-23 8:41 ` Ilpo Järvinen
2025-09-18 21:20 ` [PATCH v5 2/3] platform: arm64: thinkpad-t14s-ec: new driver Sebastian Reichel
2025-09-18 21:20 ` [PATCH v5 3/3] arm64: dts: qcom: x1e80100-t14s: add EC Sebastian Reichel
2025-09-23 8:40 ` [PATCH v5 0/3] platform: arm64: thinkpad-t14s-ec: new driver Ilpo Järvinen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).