ASoC: SOF: Intel: lnl: Disable DMIC/SSP offload on remove
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Wed, 3 Apr 2024 11:18:39 +0000 (14:18 +0300)
committerMark Brown <broonie@kernel.org>
Wed, 3 Apr 2024 17:47:08 +0000 (18:47 +0100)
During probe the DMIC/SSP offload is enabled and it is not reversed on
remove.

Add a remove wrapper for LNL to disable the offload for DMIC and SSP
similarly to what is done during probe.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://msgid.link/r/20240403111839.27259-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/lnl.c

index d1c73d407e68e74fb7c0ed2fc7946e9d67643de5..aeb4350cce6bba3b229af876e188c4ead7f2b201 100644 (file)
@@ -29,15 +29,17 @@ static const struct snd_sof_debugfs_map lnl_dsp_debugfs[] = {
 };
 
 /* this helps allows the DSP to setup DMIC/SSP */
-static int hdac_bus_offload_dmic_ssp(struct hdac_bus *bus)
+static int hdac_bus_offload_dmic_ssp(struct hdac_bus *bus, bool enable)
 {
        int ret;
 
-       ret = hdac_bus_eml_enable_offload(bus, true,  AZX_REG_ML_LEPTR_ID_INTEL_SSP, true);
+       ret = hdac_bus_eml_enable_offload(bus, true,
+                                         AZX_REG_ML_LEPTR_ID_INTEL_SSP, enable);
        if (ret < 0)
                return ret;
 
-       ret = hdac_bus_eml_enable_offload(bus, true,  AZX_REG_ML_LEPTR_ID_INTEL_DMIC, true);
+       ret = hdac_bus_eml_enable_offload(bus, true,
+                                         AZX_REG_ML_LEPTR_ID_INTEL_DMIC, enable);
        if (ret < 0)
                return ret;
 
@@ -52,7 +54,19 @@ static int lnl_hda_dsp_probe(struct snd_sof_dev *sdev)
        if (ret < 0)
                return ret;
 
-       return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev));
+       return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev), true);
+}
+
+static void lnl_hda_dsp_remove(struct snd_sof_dev *sdev)
+{
+       int ret;
+
+       ret = hdac_bus_offload_dmic_ssp(sof_to_bus(sdev), false);
+       if (ret < 0)
+               dev_warn(sdev->dev,
+                        "Failed to disable offload for DMIC/SSP: %d\n", ret);
+
+       hda_dsp_remove(sdev);
 }
 
 static int lnl_hda_dsp_resume(struct snd_sof_dev *sdev)
@@ -63,7 +77,7 @@ static int lnl_hda_dsp_resume(struct snd_sof_dev *sdev)
        if (ret < 0)
                return ret;
 
-       return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev));
+       return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev), true);
 }
 
 static int lnl_hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
@@ -74,7 +88,7 @@ static int lnl_hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
        if (ret < 0)
                return ret;
 
-       return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev));
+       return hdac_bus_offload_dmic_ssp(sof_to_bus(sdev), true);
 }
 
 static int lnl_dsp_post_fw_run(struct snd_sof_dev *sdev)
@@ -97,9 +111,11 @@ int sof_lnl_ops_init(struct snd_sof_dev *sdev)
        /* common defaults */
        memcpy(&sof_lnl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
 
-       /* probe */
-       if (!sdev->dspless_mode_selected)
+       /* probe/remove */
+       if (!sdev->dspless_mode_selected) {
                sof_lnl_ops.probe = lnl_hda_dsp_probe;
+               sof_lnl_ops.remove = lnl_hda_dsp_remove;
+       }
 
        /* shutdown */
        sof_lnl_ops.shutdown = hda_dsp_shutdown;