ALSA: hda: cs35l41: Force a software reset after hardware reset
authorStefan Binding <sbinding@opensource.cirrus.com>
Thu, 26 Oct 2023 15:05:55 +0000 (16:05 +0100)
committerTakashi Iwai <tiwai@suse.de>
Thu, 26 Oct 2023 15:55:20 +0000 (17:55 +0200)
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>
include/sound/cs35l41.h
sound/pci/hda/cs35l41_hda.c
sound/soc/codecs/cs35l41-lib.c

index 2fe8c6b0d4cf389d54a61b74f7443835801269dc..80df80fe31e207fc15c399ac758f535195f501ad 100644 (file)
 #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
index e787788c1be2ce0434f1bf6b47e57790a97e7b9f..9746c64ff0ddbb2a2bb9527bdb6dd78f97fa74e7 100644 (file)
@@ -901,6 +901,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;
@@ -1766,6 +1769,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);
index 2ec5fdc875b13f308631217dbe87c30c01b86c22..ddedb7e63cb6f8382e7fe8cf5dc3b0f2ca2ed3fd 100644 (file)
@@ -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: