diff mbox series

[07/10,SRU,M] ALSA: hda: cs35l41: Force a software reset after hardware reset

Message ID 20231122063541.11346-8-chris.chiu@canonical.com
State New
Headers show
Series Fix system suspend problem for Cirrus CS35L41 HDA codec on HP ZBook Fury 16 G9 | expand

Commit Message

Chris Chiu Nov. 22, 2023, 6:35 a.m. UTC
From: Stefan Binding <sbinding@opensource.cirrus.com>

BugLink: https://bugs.launchpad.net/bugs/2042060

To ensure the chip has correctly reset during probe and system suspend,
we need to force a software reset, in case of systems where the
hardware reset is not available.

The software reset register was labelled as volatile but not readable,
however, it is readable, (just returns 0x0). Adding it to readable
registers means it will be correctly treated as volatile, and thus
will not be cached.

Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20231026150558.2105827-6-sbinding@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
(cherry picked from commit 2ee06ff5d7cf5f68bab2bf65a946bb2ffe9982dd)
Signed-off-by: Chris Chiu <chris.chiu@canonical.com>
---
 include/sound/cs35l41.h        | 1 +
 sound/pci/hda/cs35l41_hda.c    | 5 +++++
 sound/soc/codecs/cs35l41-lib.c | 1 +
 3 files changed, 7 insertions(+)
diff mbox series

Patch

diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h
index 1bf757901d02..29fed4e9f33f 100644
--- a/include/sound/cs35l41.h
+++ b/include/sound/cs35l41.h
@@ -736,6 +736,7 @@ 
 #define CS35L41_REVID_B2		0xB2
 
 #define CS35L41_HALO_CORE_RESET		0x00000200
+#define CS35L41_SOFTWARE_RESET		0x5A000000
 
 #define CS35L41_FS1_WINDOW_MASK		0x000007FF
 #define CS35L41_FS2_WINDOW_MASK		0x00FFF800
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index 1d47779be81d..be74b3c5547b 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -836,6 +836,9 @@  static int cs35l41_system_resume(struct device *dev)
 
 	regcache_cache_only(cs35l41->regmap, false);
 
+	regmap_write(cs35l41->regmap, CS35L41_SFT_RESET, CS35L41_SOFTWARE_RESET);
+	usleep_range(2000, 2100);
+
 	ret = cs35l41_wait_boot_done(cs35l41);
 	if (ret)
 		return ret;
@@ -1610,6 +1613,8 @@  int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
 		gpiod_set_value_cansleep(cs35l41->reset_gpio, 1);
 	}
 
+	usleep_range(2000, 2100);
+	regmap_write(cs35l41->regmap, CS35L41_SFT_RESET, CS35L41_SOFTWARE_RESET);
 	usleep_range(2000, 2100);
 
 	ret = cs35l41_wait_boot_done(cs35l41);
diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c
index a9c559a676e7..60c34ab37395 100644
--- a/sound/soc/codecs/cs35l41-lib.c
+++ b/sound/soc/codecs/cs35l41-lib.c
@@ -74,6 +74,7 @@  static bool cs35l41_readable_reg(struct device *dev, unsigned int reg)
 	case CS35L41_FABID:
 	case CS35L41_RELID:
 	case CS35L41_OTPID:
+	case CS35L41_SFT_RESET:
 	case CS35L41_TEST_KEY_CTL:
 	case CS35L41_USER_KEY_CTL:
 	case CS35L41_OTP_CTRL0: