Skip to content

Commit fc62cb6

Browse files
sreij-intel
authored andcommitted
platform: arm64: thinkpad-t14s-ec: add system PM hooks
Improve support for system suspend. The register information has been extracted from the ACPI DSDT code handling Windows Modern Standby. I took over the weird multi-write function from the ACPI DSDT code where it is called ECWS. In addition to writing to the 0xE0 register, the ACPI Windows Modern Standby code also does some changes to the thermal configuration. This part is not implemented. After this patch the laptop's power and LID LEDs will switch into the typical breathing animation when the system is suspended and enabled normally again after resuming. Signed-off-by: Sebastian Reichel <sre@kernel.org> Link: https://patch.msgid.link/20251119-thinkpad-t14s-ec-improvements-v2-3-441219857c02@kernel.org Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1 parent f72c8ab commit fc62cb6

1 file changed

Lines changed: 46 additions & 8 deletions

File tree

drivers/platform/arm64/lenovo-thinkpad-t14s.c

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,23 @@
2020
#include <linux/module.h>
2121
#include <linux/regmap.h>
2222
#include <linux/slab.h>
23+
#include <linux/pm.h>
2324

2425
#define T14S_EC_CMD_ECRD 0x02
2526
#define T14S_EC_CMD_ECWR 0x03
2627
#define T14S_EC_CMD_EVT 0xf0
2728

28-
#define T14S_EC_REG_LED 0x0c
29-
#define T14S_EC_REG_KBD_BL1 0x0d
30-
#define T14S_EC_REG_KBD_BL2 0xe1
31-
#define T14S_EC_KBD_BL1_MASK GENMASK_U8(7, 6)
32-
#define T14S_EC_KBD_BL2_MASK GENMASK_U8(3, 2)
33-
#define T14S_EC_REG_AUD 0x30
34-
#define T14S_EC_MIC_MUTE_LED BIT(5)
35-
#define T14S_EC_SPK_MUTE_LED BIT(6)
29+
#define T14S_EC_REG_LED 0x0c
30+
#define T14S_EC_REG_KBD_BL1 0x0d
31+
#define T14S_EC_REG_MODERN_STANDBY 0xe0
32+
#define T14S_EC_MODERN_STANDBY_ENTRY BIT(1)
33+
#define T14S_EC_MODERN_STANDBY_EXIT BIT(0)
34+
#define T14S_EC_REG_KBD_BL2 0xe1
35+
#define T14S_EC_KBD_BL1_MASK GENMASK_U8(7, 6)
36+
#define T14S_EC_KBD_BL2_MASK GENMASK_U8(3, 2)
37+
#define T14S_EC_REG_AUD 0x30
38+
#define T14S_EC_MIC_MUTE_LED BIT(5)
39+
#define T14S_EC_SPK_MUTE_LED BIT(6)
3640

3741
#define T14S_EC_EVT_NONE 0x00
3842
#define T14S_EC_EVT_KEY_FN_4 0x13
@@ -198,6 +202,14 @@ static int t14s_ec_read_evt(struct t14s_ec *ec, u8 *val)
198202
return ret;
199203
}
200204

205+
static void t14s_ec_write_sequence(struct t14s_ec *ec, u8 reg, u8 val, u8 cnt)
206+
{
207+
int i;
208+
209+
for (i = 0; i < cnt; i++)
210+
regmap_write(ec->regmap, reg, val);
211+
}
212+
201213
static int t14s_led_set_status(struct t14s_ec *ec,
202214
struct t14s_ec_led_classdev *led,
203215
const enum t14s_ec_led_status_t ledstatus)
@@ -550,6 +562,7 @@ static int t14s_ec_probe(struct i2c_client *client)
550562
return -ENOMEM;
551563

552564
ec->dev = dev;
565+
i2c_set_clientdata(client, ec);
553566

554567
ec->regmap = devm_regmap_init(dev, &t14s_ec_regmap_bus,
555568
ec, &t14s_ec_regmap_config);
@@ -589,6 +602,26 @@ static int t14s_ec_probe(struct i2c_client *client)
589602
return 0;
590603
}
591604

605+
static int t14s_ec_suspend(struct device *dev)
606+
{
607+
struct t14s_ec *ec = dev_get_drvdata(dev);
608+
609+
t14s_ec_write_sequence(ec, T14S_EC_REG_MODERN_STANDBY,
610+
T14S_EC_MODERN_STANDBY_ENTRY, 3);
611+
612+
return 0;
613+
}
614+
615+
static int t14s_ec_resume(struct device *dev)
616+
{
617+
struct t14s_ec *ec = dev_get_drvdata(dev);
618+
619+
t14s_ec_write_sequence(ec, T14S_EC_REG_MODERN_STANDBY,
620+
T14S_EC_MODERN_STANDBY_EXIT, 3);
621+
622+
return 0;
623+
}
624+
592625
static const struct of_device_id t14s_ec_of_match[] = {
593626
{ .compatible = "lenovo,thinkpad-t14s-ec" },
594627
{}
@@ -601,10 +634,15 @@ static const struct i2c_device_id t14s_ec_i2c_id_table[] = {
601634
};
602635
MODULE_DEVICE_TABLE(i2c, t14s_ec_i2c_id_table);
603636

637+
static const struct dev_pm_ops t14s_ec_pm_ops = {
638+
SYSTEM_SLEEP_PM_OPS(t14s_ec_suspend, t14s_ec_resume)
639+
};
640+
604641
static struct i2c_driver t14s_ec_i2c_driver = {
605642
.driver = {
606643
.name = "thinkpad-t14s-ec",
607644
.of_match_table = t14s_ec_of_match,
645+
.pm = &t14s_ec_pm_ops,
608646
},
609647
.probe = t14s_ec_probe,
610648
.id_table = t14s_ec_i2c_id_table,

0 commit comments

Comments
 (0)