]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC/soundwire: Intel: reset the PCMSyCM registers in hda_sdw_bpt_close
authorBard Liao <yung-chuan.liao@linux.intel.com>
Thu, 30 Jul 2026 01:25:18 +0000 (09:25 +0800)
committerMark Brown <broonie@kernel.org>
Fri, 31 Jul 2026 12:23:10 +0000 (13:23 +0100)
Resetting the PCMSyCM registers is required for Intel SoundWire stream. The
same procedure is done in sdw_hda_dai_hw_params() for the normal
SoundWire stream, too.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Acked-by: Vinod Koul <vkoul@kernel.org>
Link: https://patch.msgid.link/20260730012518.2180906-1-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/soundwire/intel_ace2x.c
include/sound/hda-sdw-bpt.h
sound/soc/sof/intel/hda-sdw-bpt.c

index b37933efac5d26e0e0bf313278c7c4132615127b..63f131d5682b386538dff7ab8ba2e2c6b6a6605e 100644 (file)
@@ -261,6 +261,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *
                __func__, str_read_write(command), ret);
 
        ret1 = hda_sdw_bpt_close(cdns->dev->parent, /* PCI device */
+                                sdw->instance,
                                 sdw->bpt_ctx.bpt_tx_stream, &sdw->bpt_ctx.dmab_tx_bdl,
                                 sdw->bpt_ctx.bpt_rx_stream, &sdw->bpt_ctx.dmab_rx_bdl);
        if (ret1 < 0)
@@ -295,7 +296,8 @@ static void intel_ace2x_bpt_close_stream(struct sdw_intel *sdw, struct sdw_slave
        struct sdw_cdns *cdns = &sdw->cdns;
        int ret;
 
-       ret = hda_sdw_bpt_close(cdns->dev->parent /* PCI device */, sdw->bpt_ctx.bpt_tx_stream,
+       ret = hda_sdw_bpt_close(cdns->dev->parent /* PCI device */, sdw->instance,
+                               sdw->bpt_ctx.bpt_tx_stream,
                                &sdw->bpt_ctx.dmab_tx_bdl, sdw->bpt_ctx.bpt_rx_stream,
                                &sdw->bpt_ctx.dmab_rx_bdl);
        if (ret < 0)
index 9b654c31829ad6568ceefd0f0f7be62eb7eb2948..e24a549f7d490bf2c6a009f69c02ea716d1cd697 100644 (file)
@@ -27,7 +27,7 @@ int hda_sdw_bpt_send_async(struct device *dev, struct hdac_ext_stream *bpt_tx_st
 int hda_sdw_bpt_wait(struct device *dev, struct hdac_ext_stream *bpt_tx_stream,
                     struct hdac_ext_stream *bpt_rx_stream);
 
-int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream,
+int hda_sdw_bpt_close(struct device *dev, int link_id, struct hdac_ext_stream *bpt_tx_stream,
                      struct snd_dma_buffer *dmab_tx_bdl, struct hdac_ext_stream *bpt_rx_stream,
                      struct snd_dma_buffer *dmab_rx_bdl);
 
@@ -58,7 +58,8 @@ static inline int hda_sdw_bpt_wait(struct device *dev, struct hdac_ext_stream *b
        return -EOPNOTSUPP;
 }
 
-static inline int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream,
+static inline int hda_sdw_bpt_close(struct device *dev, int link_id,
+                                   struct hdac_ext_stream *bpt_tx_stream,
                                    struct snd_dma_buffer *dmab_tx_bdl,
                                    struct hdac_ext_stream *bpt_rx_stream,
                                    struct snd_dma_buffer *dmab_rx_bdl)
index 728ffe7ae54d8574f8e70234c665e0bd43b9fcbb..7351a0870725743dd451d8e1e9b67bdeeca1df29 100644 (file)
@@ -322,7 +322,8 @@ int hda_sdw_bpt_open(struct device *dev, int link_id, struct hdac_ext_stream **b
                __func__, ret);
 
 close:
-       ret1 = hda_sdw_bpt_close(dev, *bpt_tx_stream, dmab_tx_bdl, *bpt_rx_stream, dmab_rx_bdl);
+       ret1 = hda_sdw_bpt_close(dev, link_id, *bpt_tx_stream, dmab_tx_bdl,
+                                *bpt_rx_stream, dmab_rx_bdl);
        if (ret1 < 0)
                dev_err(dev, "%s: hda_sdw_bpt_close failed: %d\n",
                        __func__, ret1);
@@ -447,14 +448,38 @@ dma_disable:
 }
 EXPORT_SYMBOL_NS(hda_sdw_bpt_wait, "SND_SOC_SOF_INTEL_HDA_SDW_BPT");
 
-int hda_sdw_bpt_close(struct device *dev, struct hdac_ext_stream *bpt_tx_stream,
+int hda_sdw_bpt_close(struct device *dev, int link_id, struct hdac_ext_stream *bpt_tx_stream,
                      struct snd_dma_buffer *dmab_tx_bdl, struct hdac_ext_stream *bpt_rx_stream,
                      struct snd_dma_buffer *dmab_rx_bdl)
 {
+       struct snd_sof_dev *sdev = dev_get_drvdata(dev);
        int ret;
        int ret1;
 
-       ret = hda_sdw_bpt_dma_deprepare(dev, bpt_rx_stream, dmab_rx_bdl);
+       /*
+        * In the case of SoundWire we need to reset the PCMSyCM registers.
+        * Need to continue depreparing the DMA buffers even if this fails.
+        */
+       ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id,
+                                            0, /* PDI0 */
+                                            0, 0, SNDRV_PCM_STREAM_PLAYBACK);
+       if (ret < 0)
+               dev_err(dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d for PDI0\n",
+                       __func__, ret);
+
+       ret1 = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id,
+                                             1, /* PDI1 */
+                                             0, 0, SNDRV_PCM_STREAM_CAPTURE);
+       if (ret1 < 0) {
+               dev_err(dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d for PDI1\n",
+                       __func__, ret1);
+               if (!ret)
+                       ret = ret1;
+       }
+
+       ret1 = hda_sdw_bpt_dma_deprepare(dev, bpt_rx_stream, dmab_rx_bdl);
+       if (!ret)
+               ret = ret1;
 
        ret1 = hda_sdw_bpt_dma_deprepare(dev, bpt_tx_stream, dmab_tx_bdl);
        if (!ret)