]> exis.tech > repos - linux.git/commitdiff
ASoC: rt712-sdca: reset codec at io_init to fix silent headphone
authorTianze Shao <shaotianze@outlook.com>
Wed, 1 Jul 2026 14:56:06 +0000 (16:56 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 6 Jul 2026 13:40:32 +0000 (14:40 +0100)
On ThinkPad X1 Carbon Gen 13 (Lunar Lake, RT712-SDCA version VA) the
3.5mm headphone jack is silent after rebooting from Windows.
rt712_sdca_va_io_init() gates rt712_sdca_calibration() on the persisted
vendor SW_CONFIG1 flag, and io_init writes SW_CONFIG1=1 at the end
regardless of whether the calibration succeeded. Across a warm reboot
the codec keeps power, so SW_CONFIG1 stays unchanged, the calibration
may be skipped, and the retained state can be invalid, leaving the
headphone amp disabled.

This patch mimics the reset sequence in rt711-sdca.c, it adds an
rt712_sdca_reset() helper, and calls it from io_init so the codec is
reset before initialization. RT712_PARA_VERB_CTL,
RT712_HIDDEN_REG_SW_RESET and RT712_HDA_LEGACY_RESET_CTL are already
defined but were unused. The reset clears SW_CONFIG1 and the analog
state so rt712_sdca_calibration() runs from a clean state and
completes.

Problem reproducible: boot Windows (headphone is good) -> reboot
to Linux (silent).
The reproducibility may depend on Windows' behaviour.

Signed-off-by: Tianze Shao <shaotianze@outlook.com>
Link: https://patch.msgid.link/TYCPR01MB872223CB999D2099A5E0F58DC4F62@TYCPR01MB8722.jpnprd01.prod.outlook.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/rt712-sdca.c

index 4796fce084ff46e601cf80b43d90ca0a3104f4d8..d6353af07380c19fb897148fbd9c3e196b7de0ef 100644 (file)
@@ -1843,6 +1843,15 @@ static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
        }
 }
 
+static void rt712_sdca_reset(struct rt712_sdca_priv *rt712)
+{
+       rt712_sdca_index_update_bits(rt712, RT712_VENDOR_REG,
+               RT712_PARA_VERB_CTL, RT712_HIDDEN_REG_SW_RESET,
+               RT712_HIDDEN_REG_SW_RESET);
+       rt712_sdca_index_update_bits(rt712, RT712_VENDOR_HDA_CTL,
+               RT712_HDA_LEGACY_RESET_CTL, 0x1, 0x1);
+}
+
 int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
 {
        struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev);
@@ -1870,6 +1879,8 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
 
        pm_runtime_get_noresume(&slave->dev);
 
+       rt712_sdca_reset(rt712);
+
        rt712_sdca_index_read(rt712, RT712_VENDOR_REG, RT712_JD_PRODUCT_NUM, &val);
        rt712->hw_id = (val & 0xf000) >> 12;
        rt712->version_id = (val & 0x0f00) >> 8;