From 72a77d7631c6e392677c0134343cf5edcd3a4572 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 29 Jan 2024 16:27:26 +0000 Subject: ASoC: cs35l56: Fix to ensure ASP1 registers match cache Add a dummy SUPPLY widget connected to the ASP that forces the chip registers to match the regmap cache when the ASP is powered-up. On a SoundWire system the ASP is free for use as a chip-to-chip interconnect. This can be either for the firmware on multiple CS35L56 to share reference audio; or as a bridge to another device. If it is a firmware interconnect it is owned by the firmware and the Linux driver should avoid writing the registers. However. If it is a bridge then Linux may take over and handle it as a normal codec-to-codec link. CS35L56 is designed for SDCA and a generic SDCA driver would know nothing about these chip-specific registers. So if the ASP is being used on a SoundWire system the firmware sets up the ASP registers. This means that we can't assume the default state of the ASP registers. But we don't know the initial state that the firmware set them to until after the firmware has been downloaded and booted, which can take several seconds when downloading multiple amps. To avoid blocking probe() for several seconds waiting for the firmware, the silicon defaults are assumed. This allows the machine driver to setup the ASP configuration during probe() without being blocked. If the ASP is hooked up and used, the SUPPLY widget ensures that the chip registers match what was configured in the regmap cache. If the machine driver does not hook up the ASP, it is assumed that it won't call any functions to configure the ASP DAI. Therefore the regmap cache will be clean for these registers so a regcache_sync() will not overwrite the chip registers. If the DAI is not hooked up, the dummy SUPPLY widget will not be invoked so it will never force-overwrite the chip registers. Backport note: This won't apply cleanly to kernels older than v6.6. Signed-off-by: Richard Fitzgerald Fixes: e49611252900 ("ASoC: cs35l56: Add driver for Cirrus Logic CS35L56") Link: https://msgid.link/r/20240129162737.497-8-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/cs35l56.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/sound') diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 8c18e8b6d27d..4db36c893d9d 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -272,6 +272,7 @@ extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC]; extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC]; int cs35l56_set_patch(struct cs35l56_base *cs35l56_base); +int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base *cs35l56_base); int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command); int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base); int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base); -- cgit v1.2.3 From f4ef5149953f2fc04907ca5b34db3df667dcddef Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 29 Jan 2024 16:27:31 +0000 Subject: ASoC: cs35l56: Firmware file must match the version of preloaded firmware Check during initialization whether the firmware is already patched. If so, include the firmware version in the wm_adsp fwf_name string. If the firmware has already been patched by the BIOS the driver can only replace it if it has control of hard RESET. If the driver cannot replace the firmware, it can still load a wmfw (for ALSA control definitions) and/or a bin (for additional tunings). But these must match the version of firmware that is running on the CS35L56. The firmware is pre-patched if FIRMWARE_MISSING == 0. Including the firmware version in the fwf_name string will qualify the firmware file name: Normal (unpatched or replaceable firmware): cs35l56-rev-dsp1-misc[-system_name].[wmfw|bin] Preloaded firmware: cs35l56-rev[-s]-VVVVVV-dsp1-misc[-system_name].[wmfw|bin] Where: [-s] is an optional -s added into the name for a secured CS35L56 VVVVVV is the 24-bit firmware version in hexadecimal. Signed-off-by: Richard Fitzgerald Fixes: 608f1b0dbdde ("ASoC: cs35l56: Move DSP part string generation so that it is done only once") Link: https://msgid.link/r/20240129162737.497-13-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/cs35l56.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/sound') diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 4db36c893d9d..5d6aefc41e64 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -75,6 +75,7 @@ #define CS35L56_DSP1_AHBM_WINDOW_DEBUG_0 0x25E2040 #define CS35L56_DSP1_AHBM_WINDOW_DEBUG_1 0x25E2044 #define CS35L56_DSP1_XMEM_UNPACKED24_0 0x2800000 +#define CS35L56_DSP1_FW_VER 0x2800010 #define CS35L56_DSP1_HALO_STATE_A1 0x2801E58 #define CS35L56_DSP1_HALO_STATE 0x28021E0 #define CS35L56_DSP1_PM_CUR_STATE_A1 0x2804000 @@ -285,6 +286,8 @@ int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base); int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base); int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire); void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp); +int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, + bool *fw_missing, unsigned int *fw_version); int cs35l56_hw_init(struct cs35l56_base *cs35l56_base); int cs35l56_get_bclk_freq_id(unsigned int freq); void cs35l56_fill_supply_names(struct regulator_bulk_data *data); -- cgit v1.2.3 From 245eeff18d7a37693815250ae15979ce98c3d190 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 29 Jan 2024 16:27:32 +0000 Subject: ASoC: cs35l56: Load tunings for the correct speaker models If the "spk-id-gpios" property is present it points to GPIOs whose value must be used to select the correct bin file to match the speakers. Some manufacturers use multiple sources of speakers, which need different tunings for best performance. On these models the type of speaker fitted is indicated by the values of one or more GPIOs. The number formed by the GPIOs identifies the tuning required. The speaker ID must be used in combination with the subsystem ID (either from PCI SSID or cirrus,firmware-uid property), because the GPIOs can only indicate variants of a specific model. Signed-off-by: Richard Fitzgerald Fixes: 1a1c3d794ef6 ("ASoC: cs35l56: Use PCI SSID as the firmware UID") Link: https://msgid.link/r/20240129162737.497-14-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/cs35l56.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/sound') diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 5d6aefc41e64..23da6298ab37 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -289,6 +289,7 @@ void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_ds int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base, bool *fw_missing, unsigned int *fw_version); int cs35l56_hw_init(struct cs35l56_base *cs35l56_base); +int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base); int cs35l56_get_bclk_freq_id(unsigned int freq); void cs35l56_fill_supply_names(struct regulator_bulk_data *data); -- cgit v1.2.3 From 9e92b77ceb6f362eb2e7995dad6c7f9863053d97 Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Mon, 29 Jan 2024 16:27:33 +0000 Subject: ASoC: cs35l56: Allow more time for firmware to boot The original 50ms timeout for firmware boot is not long enough for worst-case time to reboot after a firmware download. Increase the timeout to 250ms. Signed-off-by: Richard Fitzgerald Fixes: e49611252900 ("ASoC: cs35l56: Add driver for Cirrus Logic CS35L56") Link: https://msgid.link/r/20240129162737.497-15-rf@opensource.cirrus.com Signed-off-by: Mark Brown --- include/sound/cs35l56.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/sound') diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index 23da6298ab37..b24716ab2750 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -242,7 +242,7 @@ #define CS35L56_CONTROL_PORT_READY_US 2200 #define CS35L56_HALO_STATE_POLL_US 1000 -#define CS35L56_HALO_STATE_TIMEOUT_US 50000 +#define CS35L56_HALO_STATE_TIMEOUT_US 250000 #define CS35L56_RESET_PULSE_MIN_US 1100 #define CS35L56_WAKE_HOLD_TIME_US 1000 -- cgit v1.2.3 From 34a1066981a967eab619938e7b35a9be6b4c34e1 Mon Sep 17 00:00:00 2001 From: Gergo Koteles Date: Sun, 4 Feb 2024 21:01:17 +0100 Subject: ASoC: tas2781: add module parameter to tascodec_init() The tascodec_init() of the snd-soc-tas2781-comlib module is called from snd-soc-tas2781-i2c and snd-hda-scodec-tas2781-i2c modules. It calls request_firmware_nowait() with parameter THIS_MODULE and a cont/callback from the latter modules. The latter modules can be removed while their callbacks are running, resulting in a general protection failure. Add module parameter to tascodec_init() so request_firmware_nowait() can be called with the module of the callback. Fixes: ef3bcde75d06 ("ASoC: tas2781: Add tas2781 driver") CC: stable@vger.kernel.org Signed-off-by: Gergo Koteles Link: https://lore.kernel.org/r/118dad922cef50525e5aab09badef2fa0eb796e5.1707076603.git.soyer@irl.hu Signed-off-by: Mark Brown --- include/sound/tas2781.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/sound') diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index b00d65417c31..9aff384941de 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -142,6 +142,7 @@ struct tasdevice_priv { void tas2781_reset(struct tasdevice_priv *tas_dev); int tascodec_init(struct tasdevice_priv *tas_priv, void *codec, + struct module *module, void (*cont)(const struct firmware *fw, void *context)); struct tasdevice_priv *tasdevice_kzalloc(struct i2c_client *i2c); int tasdevice_init(struct tasdevice_priv *tas_priv); -- cgit v1.2.3